Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 254542
b: refs/heads/master
c: 61aaff4
h: refs/heads/master
v: v3
  • Loading branch information
Jeff Skirvin authored and Dan Williams committed Jul 3, 2011
1 parent 059ef1c commit f0dc868
Show file tree
Hide file tree
Showing 4 changed files with 339 additions and 42 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ff717ab05f0c33f93514eccea6dfe1a15983e1d1
refs/heads/master: 61aaff49e20fdb700f1300a49962bc76effc77fc
115 changes: 75 additions & 40 deletions trunk/drivers/scsi/isci/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,71 @@ static enum sci_status scic_port_get_properties(struct scic_sds_port *port,
return SCI_SUCCESS;
}

static void scic_port_bcn_enable(struct scic_sds_port *sci_port)
{
struct scic_sds_phy *sci_phy;
u32 val;
int i;

for (i = 0; i < ARRAY_SIZE(sci_port->phy_table); i++) {
sci_phy = sci_port->phy_table[i];
if (!sci_phy)
continue;
val = readl(&sci_phy->link_layer_registers->link_layer_control);
/* clear the bit by writing 1. */
writel(val, &sci_phy->link_layer_registers->link_layer_control);
}
}

/* called under scic_lock to stabilize phy:port associations */
void isci_port_bcn_enable(struct isci_host *ihost, struct isci_port *iport)
{
int i;

clear_bit(IPORT_BCN_BLOCKED, &iport->flags);
wake_up(&ihost->eventq);

if (!test_and_clear_bit(IPORT_BCN_PENDING, &iport->flags))
return;

for (i = 0; i < ARRAY_SIZE(iport->sci.phy_table); i++) {
struct scic_sds_phy *sci_phy = iport->sci.phy_table[i];
struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);

if (!sci_phy)
continue;

ihost->sas_ha.notify_port_event(&iphy->sas_phy,
PORTE_BROADCAST_RCVD);
break;
}
}

void isci_port_bc_change_received(struct isci_host *ihost,
struct scic_sds_port *sci_port,
struct scic_sds_phy *sci_phy)
{
struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);
struct isci_port *iport = iphy->isci_port;

if (iport && test_bit(IPORT_BCN_BLOCKED, &iport->flags)) {
dev_dbg(&ihost->pdev->dev,
"%s: disabled BCN; isci_phy = %p, sas_phy = %p\n",
__func__, iphy, &iphy->sas_phy);
set_bit(IPORT_BCN_PENDING, &iport->flags);
atomic_inc(&iport->event);
wake_up(&ihost->eventq);
} else {
dev_dbg(&ihost->pdev->dev,
"%s: isci_phy = %p, sas_phy = %p\n",
__func__, iphy, &iphy->sas_phy);

ihost->sas_ha.notify_port_event(&iphy->sas_phy,
PORTE_BROADCAST_RCVD);
}
scic_port_bcn_enable(sci_port);
}

static void isci_port_link_up(struct isci_host *isci_host,
struct scic_sds_port *port,
struct scic_sds_phy *phy)
Expand Down Expand Up @@ -240,13 +305,15 @@ static void isci_port_link_down(struct isci_host *isci_host,
if (isci_port) {

/* check to see if this is the last phy on this port. */
if (isci_phy->sas_phy.port
&& isci_phy->sas_phy.port->num_phys == 1) {

/* change the state for all devices on this port.
* The next task sent to this device will be returned
* as SAS_TASK_UNDELIVERED, and the scsi mid layer
* will remove the target
if (isci_phy->sas_phy.port &&
isci_phy->sas_phy.port->num_phys == 1) {
atomic_inc(&isci_port->event);
isci_port_bcn_enable(isci_host, isci_port);

/* change the state for all devices on this port. The
* next task sent to this device will be returned as
* SAS_TASK_UNDELIVERED, and the scsi mid layer will
* remove the target
*/
list_for_each_entry(isci_device,
&isci_port->remote_dev_list,
Expand Down Expand Up @@ -1033,26 +1100,6 @@ enum sas_linkrate scic_sds_port_get_max_allowed_speed(
return max_allowed_speed;
}

static void scic_port_enable_broadcast_change_notification(struct scic_sds_port *port)
{
struct scic_sds_phy *phy;
u32 register_value;
u8 index;

/* Loop through all of the phys to enable BCN. */
for (index = 0; index < SCI_MAX_PHYS; index++) {
phy = port->phy_table[index];
if (phy != NULL) {
register_value =
readl(&phy->link_layer_registers->link_layer_control);

/* clear the bit by writing 1. */
writel(register_value,
&phy->link_layer_registers->link_layer_control);
}
}
}

/**
*
* @sci_port: This is the struct scic_sds_port object to suspend.
Expand Down Expand Up @@ -1838,6 +1885,7 @@ void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index)
init_completion(&iport->start_complete);
iport->isci_host = ihost;
isci_port_change_state(iport, isci_freed);
atomic_set(&iport->event, 0);
}

/**
Expand All @@ -1852,19 +1900,6 @@ enum isci_status isci_port_get_state(
return isci_port->status;
}

static void isci_port_bc_change_received(struct isci_host *ihost,
struct scic_sds_port *sci_port,
struct scic_sds_phy *sci_phy)
{
struct isci_phy *iphy = sci_phy_to_iphy(sci_phy);

dev_dbg(&ihost->pdev->dev, "%s: iphy = %p, sas_phy = %p\n",
__func__, iphy, &iphy->sas_phy);

ihost->sas_ha.notify_port_event(&iphy->sas_phy, PORTE_BROADCAST_RCVD);
scic_port_enable_broadcast_change_notification(sci_port);
}

void scic_sds_port_broadcast_change_received(
struct scic_sds_port *sci_port,
struct scic_sds_phy *sci_phy)
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/scsi/isci/port.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ struct scic_sds_port {
*/
struct isci_port {
enum isci_status status;
#define IPORT_BCN_BLOCKED 0
#define IPORT_BCN_PENDING 1
unsigned long flags;
atomic_t event;
struct isci_host *isci_host;
struct asd_sas_port sas_port;
struct list_head remote_dev_list;
Expand Down Expand Up @@ -334,6 +338,7 @@ void scic_sds_port_setup_transports(
struct scic_sds_port *sci_port,
u32 device_id);

void isci_port_bcn_enable(struct isci_host *, struct isci_port *);

void scic_sds_port_deactivate_phy(
struct scic_sds_port *sci_port,
Expand Down
Loading

0 comments on commit f0dc868

Please sign in to comment.