Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 62687
b: refs/heads/master
c: 1acce19
h: refs/heads/master
i:
  62685: d6a19cd
  62683: d39c110
  62679: 29a65d4
  62671: 8cfe0a9
  62655: ab0b4df
v: v3
  • Loading branch information
James Bottomley authored and James Bottomley committed Jul 18, 2007
1 parent 701b489 commit 49adc8d
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 14 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: fa1c1e8f1ece48c7baa3ba529bfd0d10a0bdf4eb
refs/heads/master: 1acce1942a32296f7c25ba82776c97e9c04c8e1e
81 changes: 68 additions & 13 deletions trunk/drivers/scsi/libsas/sas_expander.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,36 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
#define DISCOVER_REQ_SIZE 16
#define DISCOVER_RESP_SIZE 56

static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
u8 *disc_resp, int single)
{
int i, res;

disc_req[9] = single;
for (i = 1 ; i < 3; i++) {
struct discover_resp *dr;

res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
disc_resp, DISCOVER_RESP_SIZE);
if (res)
return res;
/* This is detecting a failure to transmit inital
* dev to host FIS as described in section G.5 of
* sas-2 r 04b */
dr = &((struct smp_resp *)disc_resp)->disc;
if (!(dr->attached_dev_type == 0 &&
dr->attached_sata_dev))
break;
/* In order to generate the dev to host FIS, we
* send a link reset to the expander port */
sas_smp_phy_control(dev, single, PHY_FUNC_LINK_RESET);
/* Wait for the reset to trigger the negotiation */
msleep(500);
}
sas_set_ex_phy(dev, single, disc_resp);
return 0;
}

static int sas_ex_phy_discover(struct domain_device *dev, int single)
{
struct expander_device *ex = &dev->ex_dev;
Expand All @@ -240,23 +270,15 @@ static int sas_ex_phy_discover(struct domain_device *dev, int single)
disc_req[1] = SMP_DISCOVER;

if (0 <= single && single < ex->num_phys) {
disc_req[9] = single;
res = smp_execute_task(dev, disc_req, DISCOVER_REQ_SIZE,
disc_resp, DISCOVER_RESP_SIZE);
if (res)
goto out_err;
sas_set_ex_phy(dev, single, disc_resp);
res = sas_ex_phy_discover_helper(dev, disc_req, disc_resp, single);
} else {
int i;

for (i = 0; i < ex->num_phys; i++) {
disc_req[9] = i;
res = smp_execute_task(dev, disc_req,
DISCOVER_REQ_SIZE, disc_resp,
DISCOVER_RESP_SIZE);
res = sas_ex_phy_discover_helper(dev, disc_req,
disc_resp, i);
if (res)
goto out_err;
sas_set_ex_phy(dev, i, disc_resp);
}
}
out_err:
Expand Down Expand Up @@ -529,6 +551,7 @@ static int sas_get_report_phy_sata(struct domain_device *dev,
{
int res;
u8 *rps_req = alloc_smp_req(RPS_REQ_SIZE);
u8 *resp = (u8 *)rps_resp;

if (!rps_req)
return -ENOMEM;
Expand All @@ -539,8 +562,28 @@ static int sas_get_report_phy_sata(struct domain_device *dev,
res = smp_execute_task(dev, rps_req, RPS_REQ_SIZE,
rps_resp, RPS_RESP_SIZE);

/* 0x34 is the FIS type for the D2H fis. There's a potential
* standards cockup here. sas-2 explicitly specifies the FIS
* should be encoded so that FIS type is in resp[24].
* However, some expanders endian reverse this. Undo the
* reversal here */
if (!res && resp[27] == 0x34 && resp[24] != 0x34) {
int i;

for (i = 0; i < 5; i++) {
int j = 24 + (i*4);
u8 a, b;
a = resp[j + 0];
b = resp[j + 1];
resp[j + 0] = resp[j + 3];
resp[j + 1] = resp[j + 2];
resp[j + 2] = b;
resp[j + 3] = a;
}
}

kfree(rps_req);
return 0;
return res;
}

static void sas_ex_get_linkrate(struct domain_device *parent,
Expand Down Expand Up @@ -625,14 +668,26 @@ static struct domain_device *sas_ex_discover_end_dev(
}
memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis,
sizeof(struct dev_to_host_fis));

rphy = sas_end_device_alloc(phy->port);
/* FIXME: error handling */
BUG_ON(!rphy);

sas_init_dev(child);

child->rphy = rphy;

spin_lock(&parent->port->dev_list_lock);
list_add_tail(&child->dev_list_node, &parent->port->dev_list);
spin_unlock(&parent->port->dev_list_lock);

res = sas_discover_sata(child);
if (res) {
SAS_DPRINTK("sas_discover_sata() for device %16llx at "
"%016llx:0x%x returned 0x%x\n",
SAS_ADDR(child->sas_addr),
SAS_ADDR(parent->sas_addr), phy_id, res);
goto out_free;
goto out_list_del;
}
} else if (phy->attached_tproto & SAS_PROTO_SSP) {
child->dev_type = SAS_END_DEV;
Expand Down

0 comments on commit 49adc8d

Please sign in to comment.