diff options
author | Dan Williams <dan.j.williams@intel.com> | 2012-01-16 14:56:50 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-29 16:28:24 -0500 |
commit | d214d81e883b6fc6f11cc772ff88585565d45cce (patch) | |
tree | 963e3eb05dcbf86a19deb48e262bef6ed9731c9c /drivers/scsi/libsas | |
parent | fdfd9d1b8912991d88fc29a456867c62515218f9 (diff) |
[SCSI] libsas: improve debug statements
It's difficult to determine which domain_device is triggering error recovery,
so convert messages like:
sas: ex 5001b4da000e703f phy08:T attached: 5001b4da000e7028
sas: ex 5001b4da000e703f phy09:T attached: 5001b4da000e7029
...
ata7: sas eh calling libata port error handler
ata8: sas eh calling libata port error handler
...into:
sas: ex 5001517e85cfefff phy05:T:9 attached: 5001517e85cfefe5 (stp)
sas: ex 5001517e3b0af0bf phy11:T:8 attached: 5001517e3b0af0ab (stp)
...
sas: ata7: end_device-21:1: dev error handler
sas: ata8: end_device-20:0:5: dev error handler
which shows attached link rate, device type, and associates a
domain_device with its ata_port id to correlate messages emitted from
libata-eh.
As Doug notes, we can also take the opportunity to clarify expander phy
routing capabilities.
[dgilbert@interlog.com: clarify table2table with 'U']
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/libsas')
-rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 43 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_expander.c | 74 |
2 files changed, 85 insertions, 32 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 40edf520d69a..ba1ebfe991d7 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -317,6 +317,28 @@ static int local_ata_check_ready(struct ata_link *link) | |||
317 | } | 317 | } |
318 | } | 318 | } |
319 | 319 | ||
320 | static int sas_ata_printk(const char *level, const struct domain_device *ddev, | ||
321 | const char *fmt, ...) | ||
322 | { | ||
323 | struct ata_port *ap = ddev->sata_dev.ap; | ||
324 | struct device *dev = &ddev->rphy->dev; | ||
325 | struct va_format vaf; | ||
326 | va_list args; | ||
327 | int r; | ||
328 | |||
329 | va_start(args, fmt); | ||
330 | |||
331 | vaf.fmt = fmt; | ||
332 | vaf.va = &args; | ||
333 | |||
334 | r = printk("%ssas: ata%u: %s: %pV", | ||
335 | level, ap->print_id, dev_name(dev), &vaf); | ||
336 | |||
337 | va_end(args); | ||
338 | |||
339 | return r; | ||
340 | } | ||
341 | |||
320 | static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, | 342 | static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, |
321 | unsigned long deadline) | 343 | unsigned long deadline) |
322 | { | 344 | { |
@@ -333,7 +355,7 @@ static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, | |||
333 | res = i->dft->lldd_I_T_nexus_reset(dev); | 355 | res = i->dft->lldd_I_T_nexus_reset(dev); |
334 | 356 | ||
335 | if (res != TMF_RESP_FUNC_COMPLETE) | 357 | if (res != TMF_RESP_FUNC_COMPLETE) |
336 | SAS_DPRINTK("%s: Unable to reset ata device?\n", __func__); | 358 | sas_ata_printk(KERN_DEBUG, dev, "Unable to reset ata device?\n"); |
337 | 359 | ||
338 | phy = sas_get_local_phy(dev); | 360 | phy = sas_get_local_phy(dev); |
339 | if (scsi_is_sas_phy_local(phy)) | 361 | if (scsi_is_sas_phy_local(phy)) |
@@ -344,7 +366,7 @@ static int sas_ata_hard_reset(struct ata_link *link, unsigned int *class, | |||
344 | 366 | ||
345 | ret = ata_wait_after_reset(link, deadline, check_ready); | 367 | ret = ata_wait_after_reset(link, deadline, check_ready); |
346 | if (ret && ret != -EAGAIN) | 368 | if (ret && ret != -EAGAIN) |
347 | ata_link_err(link, "COMRESET failed (errno=%d)\n", ret); | 369 | sas_ata_printk(KERN_ERR, dev, "reset failed (errno=%d)\n", ret); |
348 | 370 | ||
349 | /* XXX: if the class changes during the reset the upper layer | 371 | /* XXX: if the class changes during the reset the upper layer |
350 | * should be informed, if the device has gone away we assume | 372 | * should be informed, if the device has gone away we assume |
@@ -665,7 +687,7 @@ static void async_sas_ata_eh(void *data, async_cookie_t cookie) | |||
665 | * remove once all commands are completed | 687 | * remove once all commands are completed |
666 | */ | 688 | */ |
667 | kref_get(&dev->kref); | 689 | kref_get(&dev->kref); |
668 | ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata port error handler"); | 690 | sas_ata_printk(KERN_DEBUG, dev, "dev error handler\n"); |
669 | ata_scsi_port_error_handler(ha->core.shost, ap); | 691 | ata_scsi_port_error_handler(ha->core.shost, ap); |
670 | sas_put_device(dev); | 692 | sas_put_device(dev); |
671 | } | 693 | } |
@@ -703,26 +725,27 @@ void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, | |||
703 | struct list_head *done_q) | 725 | struct list_head *done_q) |
704 | { | 726 | { |
705 | struct scsi_cmnd *cmd, *n; | 727 | struct scsi_cmnd *cmd, *n; |
706 | struct ata_port *ap; | 728 | struct domain_device *eh_dev; |
707 | 729 | ||
708 | do { | 730 | do { |
709 | LIST_HEAD(sata_q); | 731 | LIST_HEAD(sata_q); |
710 | 732 | eh_dev = NULL; | |
711 | ap = NULL; | ||
712 | 733 | ||
713 | list_for_each_entry_safe(cmd, n, work_q, eh_entry) { | 734 | list_for_each_entry_safe(cmd, n, work_q, eh_entry) { |
714 | struct domain_device *ddev = cmd_to_domain_dev(cmd); | 735 | struct domain_device *ddev = cmd_to_domain_dev(cmd); |
715 | 736 | ||
716 | if (!dev_is_sata(ddev) || TO_SAS_TASK(cmd)) | 737 | if (!dev_is_sata(ddev) || TO_SAS_TASK(cmd)) |
717 | continue; | 738 | continue; |
718 | if (ap && ap != ddev->sata_dev.ap) | 739 | if (eh_dev && eh_dev != ddev) |
719 | continue; | 740 | continue; |
720 | ap = ddev->sata_dev.ap; | 741 | eh_dev = ddev; |
721 | list_move(&cmd->eh_entry, &sata_q); | 742 | list_move(&cmd->eh_entry, &sata_q); |
722 | } | 743 | } |
723 | 744 | ||
724 | if (!list_empty(&sata_q)) { | 745 | if (!list_empty(&sata_q)) { |
725 | ata_port_printk(ap, KERN_DEBUG, "sas eh calling libata cmd error handler\n"); | 746 | struct ata_port *ap = eh_dev->sata_dev.ap; |
747 | |||
748 | sas_ata_printk(KERN_DEBUG, eh_dev, "cmd error handler\n"); | ||
726 | ata_scsi_cmd_error_handler(shost, ap, &sata_q); | 749 | ata_scsi_cmd_error_handler(shost, ap, &sata_q); |
727 | /* | 750 | /* |
728 | * ata's error handler may leave the cmd on the list | 751 | * ata's error handler may leave the cmd on the list |
@@ -738,7 +761,7 @@ void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, | |||
738 | while (!list_empty(&sata_q)) | 761 | while (!list_empty(&sata_q)) |
739 | list_del_init(sata_q.next); | 762 | list_del_init(sata_q.next); |
740 | } | 763 | } |
741 | } while (ap); | 764 | } while (eh_dev); |
742 | } | 765 | } |
743 | 766 | ||
744 | void sas_ata_schedule_reset(struct domain_device *dev) | 767 | void sas_ata_schedule_reset(struct domain_device *dev) |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 68a80a00f73f..4b2ecd35dc5a 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -166,7 +166,22 @@ static inline void *alloc_smp_resp(int size) | |||
166 | return kzalloc(size, GFP_KERNEL); | 166 | return kzalloc(size, GFP_KERNEL); |
167 | } | 167 | } |
168 | 168 | ||
169 | /* ---------- Expander configuration ---------- */ | 169 | static char sas_route_char(struct domain_device *dev, struct ex_phy *phy) |
170 | { | ||
171 | switch (phy->routing_attr) { | ||
172 | case TABLE_ROUTING: | ||
173 | if (dev->ex_dev.t2t_supp) | ||
174 | return 'U'; | ||
175 | else | ||
176 | return 'T'; | ||
177 | case DIRECT_ROUTING: | ||
178 | return 'D'; | ||
179 | case SUBTRACTIVE_ROUTING: | ||
180 | return 'S'; | ||
181 | default: | ||
182 | return '?'; | ||
183 | } | ||
184 | } | ||
170 | 185 | ||
171 | static void sas_set_ex_phy(struct domain_device *dev, int phy_id, | 186 | static void sas_set_ex_phy(struct domain_device *dev, int phy_id, |
172 | void *disc_resp) | 187 | void *disc_resp) |
@@ -176,9 +191,10 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, | |||
176 | struct smp_resp *resp = disc_resp; | 191 | struct smp_resp *resp = disc_resp; |
177 | struct discover_resp *dr = &resp->disc; | 192 | struct discover_resp *dr = &resp->disc; |
178 | struct sas_rphy *rphy = dev->rphy; | 193 | struct sas_rphy *rphy = dev->rphy; |
179 | int rediscover = (phy->phy != NULL); | 194 | bool new_phy = !phy->phy; |
195 | char *type; | ||
180 | 196 | ||
181 | if (!rediscover) { | 197 | if (new_phy) { |
182 | phy->phy = sas_phy_alloc(&rphy->dev, phy_id); | 198 | phy->phy = sas_phy_alloc(&rphy->dev, phy_id); |
183 | 199 | ||
184 | /* FIXME: error_handling */ | 200 | /* FIXME: error_handling */ |
@@ -223,20 +239,41 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, | |||
223 | phy->phy->maximum_linkrate = dr->pmax_linkrate; | 239 | phy->phy->maximum_linkrate = dr->pmax_linkrate; |
224 | phy->phy->negotiated_linkrate = phy->linkrate; | 240 | phy->phy->negotiated_linkrate = phy->linkrate; |
225 | 241 | ||
226 | if (!rediscover) | 242 | if (new_phy) |
227 | if (sas_phy_add(phy->phy)) { | 243 | if (sas_phy_add(phy->phy)) { |
228 | sas_phy_free(phy->phy); | 244 | sas_phy_free(phy->phy); |
229 | return; | 245 | return; |
230 | } | 246 | } |
231 | 247 | ||
232 | SAS_DPRINTK("ex %016llx phy%02d:%c attached: %016llx\n", | 248 | switch (phy->attached_dev_type) { |
233 | SAS_ADDR(dev->sas_addr), phy->phy_id, | 249 | case NO_DEVICE: |
234 | phy->routing_attr == TABLE_ROUTING ? 'T' : | 250 | type = "no device"; |
235 | phy->routing_attr == DIRECT_ROUTING ? 'D' : | 251 | break; |
236 | phy->routing_attr == SUBTRACTIVE_ROUTING ? 'S' : '?', | 252 | case SAS_END_DEV: |
237 | SAS_ADDR(phy->attached_sas_addr)); | 253 | if (phy->attached_iproto) { |
254 | if (phy->attached_tproto) | ||
255 | type = "host+target"; | ||
256 | else | ||
257 | type = "host"; | ||
258 | } else { | ||
259 | if (dr->attached_sata_dev) | ||
260 | type = "stp"; | ||
261 | else | ||
262 | type = "ssp"; | ||
263 | } | ||
264 | break; | ||
265 | case EDGE_DEV: | ||
266 | case FANOUT_DEV: | ||
267 | type = "smp"; | ||
268 | break; | ||
269 | default: | ||
270 | type = "unknown"; | ||
271 | } | ||
238 | 272 | ||
239 | return; | 273 | SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", |
274 | SAS_ADDR(dev->sas_addr), phy->phy_id, | ||
275 | sas_route_char(dev, phy), phy->linkrate, | ||
276 | SAS_ADDR(phy->attached_sas_addr), type); | ||
240 | } | 277 | } |
241 | 278 | ||
242 | /* check if we have an existing attached ata device on this expander phy */ | 279 | /* check if we have an existing attached ata device on this expander phy */ |
@@ -1176,32 +1213,25 @@ static void sas_print_parent_topology_bug(struct domain_device *child, | |||
1176 | struct ex_phy *parent_phy, | 1213 | struct ex_phy *parent_phy, |
1177 | struct ex_phy *child_phy) | 1214 | struct ex_phy *child_phy) |
1178 | { | 1215 | { |
1179 | static const char ra_char[] = { | ||
1180 | [DIRECT_ROUTING] = 'D', | ||
1181 | [SUBTRACTIVE_ROUTING] = 'S', | ||
1182 | [TABLE_ROUTING] = 'T', | ||
1183 | }; | ||
1184 | static const char *ex_type[] = { | 1216 | static const char *ex_type[] = { |
1185 | [EDGE_DEV] = "edge", | 1217 | [EDGE_DEV] = "edge", |
1186 | [FANOUT_DEV] = "fanout", | 1218 | [FANOUT_DEV] = "fanout", |
1187 | }; | 1219 | }; |
1188 | struct domain_device *parent = child->parent; | 1220 | struct domain_device *parent = child->parent; |
1189 | 1221 | ||
1190 | sas_printk("%s ex %016llx (T2T supp:%d) phy 0x%x <--> %s ex %016llx " | 1222 | sas_printk("%s ex %016llx phy 0x%x <--> %s ex %016llx " |
1191 | "(T2T supp:%d) phy 0x%x has %c:%c routing link!\n", | 1223 | "phy 0x%x has %c:%c routing link!\n", |
1192 | 1224 | ||
1193 | ex_type[parent->dev_type], | 1225 | ex_type[parent->dev_type], |
1194 | SAS_ADDR(parent->sas_addr), | 1226 | SAS_ADDR(parent->sas_addr), |
1195 | parent->ex_dev.t2t_supp, | ||
1196 | parent_phy->phy_id, | 1227 | parent_phy->phy_id, |
1197 | 1228 | ||
1198 | ex_type[child->dev_type], | 1229 | ex_type[child->dev_type], |
1199 | SAS_ADDR(child->sas_addr), | 1230 | SAS_ADDR(child->sas_addr), |
1200 | child->ex_dev.t2t_supp, | ||
1201 | child_phy->phy_id, | 1231 | child_phy->phy_id, |
1202 | 1232 | ||
1203 | ra_char[parent_phy->routing_attr], | 1233 | sas_route_char(parent, parent_phy), |
1204 | ra_char[child_phy->routing_attr]); | 1234 | sas_route_char(child, child_phy)); |
1205 | } | 1235 | } |
1206 | 1236 | ||
1207 | static int sas_check_eeds(struct domain_device *child, | 1237 | static int sas_check_eeds(struct domain_device *child, |