diff options
Diffstat (limited to 'drivers/scsi')
42 files changed, 2506 insertions, 1741 deletions
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 3c683dc23541..bff04797739a 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c | |||
@@ -2044,7 +2044,7 @@ NCR_700_slave_configure(struct scsi_device *SDp) | |||
2044 | struct NCR_700_Host_Parameters *hostdata = | 2044 | struct NCR_700_Host_Parameters *hostdata = |
2045 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; | 2045 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; |
2046 | 2046 | ||
2047 | SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense)); | 2047 | SDp->hostdata = kmalloc(sizeof(struct NCR_700_sense), GFP_KERNEL); |
2048 | 2048 | ||
2049 | if (!SDp->hostdata) | 2049 | if (!SDp->hostdata) |
2050 | return -ENOMEM; | 2050 | return -ENOMEM; |
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 7cea514e810a..1cd3584ba7ff 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -92,31 +92,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
92 | init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys); | 92 | init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys); |
93 | init->AdapterFibsSize = cpu_to_le32(fibsize); | 93 | init->AdapterFibsSize = cpu_to_le32(fibsize); |
94 | init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib)); | 94 | init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib)); |
95 | /* | 95 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); |
96 | * number of 4k pages of host physical memory. The aacraid fw needs | ||
97 | * this number to be less than 4gb worth of pages. num_physpages is in | ||
98 | * system page units. New firmware doesn't have any issues with the | ||
99 | * mapping system, but older Firmware did, and had *troubles* dealing | ||
100 | * with the math overloading past 32 bits, thus we must limit this | ||
101 | * field. | ||
102 | * | ||
103 | * This assumes the memory is mapped zero->n, which isnt | ||
104 | * always true on real computers. It also has some slight problems | ||
105 | * with the GART on x86-64. I've btw never tried DMA from PCI space | ||
106 | * on this platform but don't be surprised if its problematic. | ||
107 | * [AK: something is very very wrong when a driver tests this symbol. | ||
108 | * Someone should figure out what the comment writer really meant here and fix | ||
109 | * the code. Or just remove that bad code. ] | ||
110 | */ | ||
111 | #ifndef CONFIG_IOMMU | ||
112 | if ((num_physpages << (PAGE_SHIFT - 12)) <= AAC_MAX_HOSTPHYSMEMPAGES) { | ||
113 | init->HostPhysMemPages = | ||
114 | cpu_to_le32(num_physpages << (PAGE_SHIFT-12)); | ||
115 | } else | ||
116 | #endif | ||
117 | { | ||
118 | init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); | ||
119 | } | ||
120 | 96 | ||
121 | init->InitFlags = 0; | 97 | init->InitFlags = 0; |
122 | if (dev->new_comm_interface) { | 98 | if (dev->new_comm_interface) { |
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index eb7745692682..df3346b5caf8 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h | |||
@@ -1487,6 +1487,7 @@ typedef enum { | |||
1487 | } ahd_queue_alg; | 1487 | } ahd_queue_alg; |
1488 | 1488 | ||
1489 | void ahd_set_tags(struct ahd_softc *ahd, | 1489 | void ahd_set_tags(struct ahd_softc *ahd, |
1490 | struct scsi_cmnd *cmd, | ||
1490 | struct ahd_devinfo *devinfo, | 1491 | struct ahd_devinfo *devinfo, |
1491 | ahd_queue_alg alg); | 1492 | ahd_queue_alg alg); |
1492 | 1493 | ||
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 801fc81d0b20..a1e8ca758594 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -1090,7 +1090,7 @@ ahd_handle_seqint(struct ahd_softc *ahd, u_int intstat) | |||
1090 | 1090 | ||
1091 | /* Notify XPT */ | 1091 | /* Notify XPT */ |
1092 | ahd_send_async(ahd, devinfo.channel, devinfo.target, | 1092 | ahd_send_async(ahd, devinfo.channel, devinfo.target, |
1093 | CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); | 1093 | CAM_LUN_WILDCARD, AC_SENT_BDR); |
1094 | 1094 | ||
1095 | /* | 1095 | /* |
1096 | * Allow the sequencer to continue with | 1096 | * Allow the sequencer to continue with |
@@ -3062,7 +3062,7 @@ ahd_set_syncrate(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3062 | tinfo->curr.ppr_options = ppr_options; | 3062 | tinfo->curr.ppr_options = ppr_options; |
3063 | 3063 | ||
3064 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 3064 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
3065 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); | 3065 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG); |
3066 | if (bootverbose) { | 3066 | if (bootverbose) { |
3067 | if (offset != 0) { | 3067 | if (offset != 0) { |
3068 | int options; | 3068 | int options; |
@@ -3184,7 +3184,7 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3184 | 3184 | ||
3185 | tinfo->curr.width = width; | 3185 | tinfo->curr.width = width; |
3186 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 3186 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
3187 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG, NULL); | 3187 | CAM_LUN_WILDCARD, AC_TRANSFER_NEG); |
3188 | if (bootverbose) { | 3188 | if (bootverbose) { |
3189 | printf("%s: target %d using %dbit transfers\n", | 3189 | printf("%s: target %d using %dbit transfers\n", |
3190 | ahd_name(ahd), devinfo->target, | 3190 | ahd_name(ahd), devinfo->target, |
@@ -3211,12 +3211,14 @@ ahd_set_width(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
3211 | * Update the current state of tagged queuing for a given target. | 3211 | * Update the current state of tagged queuing for a given target. |
3212 | */ | 3212 | */ |
3213 | void | 3213 | void |
3214 | ahd_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | 3214 | ahd_set_tags(struct ahd_softc *ahd, struct scsi_cmnd *cmd, |
3215 | ahd_queue_alg alg) | 3215 | struct ahd_devinfo *devinfo, ahd_queue_alg alg) |
3216 | { | 3216 | { |
3217 | ahd_platform_set_tags(ahd, devinfo, alg); | 3217 | struct scsi_device *sdev = cmd->device; |
3218 | |||
3219 | ahd_platform_set_tags(ahd, sdev, devinfo, alg); | ||
3218 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 3220 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
3219 | devinfo->lun, AC_TRANSFER_NEG, &alg); | 3221 | devinfo->lun, AC_TRANSFER_NEG); |
3220 | } | 3222 | } |
3221 | 3223 | ||
3222 | static void | 3224 | static void |
@@ -4746,7 +4748,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) | |||
4746 | printf("(%s:%c:%d:%d): refuses tagged commands. " | 4748 | printf("(%s:%c:%d:%d): refuses tagged commands. " |
4747 | "Performing non-tagged I/O\n", ahd_name(ahd), | 4749 | "Performing non-tagged I/O\n", ahd_name(ahd), |
4748 | devinfo->channel, devinfo->target, devinfo->lun); | 4750 | devinfo->channel, devinfo->target, devinfo->lun); |
4749 | ahd_set_tags(ahd, devinfo, AHD_QUEUE_NONE); | 4751 | ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_NONE); |
4750 | mask = ~0x23; | 4752 | mask = ~0x23; |
4751 | } else { | 4753 | } else { |
4752 | printf("(%s:%c:%d:%d): refuses %s tagged commands. " | 4754 | printf("(%s:%c:%d:%d): refuses %s tagged commands. " |
@@ -4754,7 +4756,7 @@ ahd_handle_msg_reject(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) | |||
4754 | ahd_name(ahd), devinfo->channel, devinfo->target, | 4756 | ahd_name(ahd), devinfo->channel, devinfo->target, |
4755 | devinfo->lun, tag_type == MSG_ORDERED_TASK | 4757 | devinfo->lun, tag_type == MSG_ORDERED_TASK |
4756 | ? "ordered" : "head of queue"); | 4758 | ? "ordered" : "head of queue"); |
4757 | ahd_set_tags(ahd, devinfo, AHD_QUEUE_BASIC); | 4759 | ahd_set_tags(ahd, scb->io_ctx, devinfo, AHD_QUEUE_BASIC); |
4758 | mask = ~0x03; | 4760 | mask = ~0x03; |
4759 | } | 4761 | } |
4760 | 4762 | ||
@@ -5098,7 +5100,7 @@ ahd_handle_devreset(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | |||
5098 | 5100 | ||
5099 | if (status != CAM_SEL_TIMEOUT) | 5101 | if (status != CAM_SEL_TIMEOUT) |
5100 | ahd_send_async(ahd, devinfo->channel, devinfo->target, | 5102 | ahd_send_async(ahd, devinfo->channel, devinfo->target, |
5101 | CAM_LUN_WILDCARD, AC_SENT_BDR, NULL); | 5103 | CAM_LUN_WILDCARD, AC_SENT_BDR); |
5102 | 5104 | ||
5103 | if (message != NULL && bootverbose) | 5105 | if (message != NULL && bootverbose) |
5104 | printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), | 5106 | printf("%s: %s on %c:%d. %d SCBs aborted\n", ahd_name(ahd), |
@@ -7952,7 +7954,7 @@ ahd_reset_channel(struct ahd_softc *ahd, char channel, int initiate_reset) | |||
7952 | #endif | 7954 | #endif |
7953 | /* Notify the XPT that a bus reset occurred */ | 7955 | /* Notify the XPT that a bus reset occurred */ |
7954 | ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, | 7956 | ahd_send_async(ahd, devinfo.channel, CAM_TARGET_WILDCARD, |
7955 | CAM_LUN_WILDCARD, AC_BUS_RESET, NULL); | 7957 | CAM_LUN_WILDCARD, AC_BUS_RESET); |
7956 | 7958 | ||
7957 | /* | 7959 | /* |
7958 | * Revert to async/narrow transfers until we renegotiate. | 7960 | * Revert to async/narrow transfers until we renegotiate. |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index e0ccdf362200..b244c7124179 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -484,7 +484,6 @@ ahd_linux_target_alloc(struct scsi_target *starget) | |||
484 | struct seeprom_config *sc = ahd->seep_config; | 484 | struct seeprom_config *sc = ahd->seep_config; |
485 | unsigned long flags; | 485 | unsigned long flags; |
486 | struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget); | 486 | struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget); |
487 | struct ahd_linux_target *targ = scsi_transport_target_data(starget); | ||
488 | struct ahd_devinfo devinfo; | 487 | struct ahd_devinfo devinfo; |
489 | struct ahd_initiator_tinfo *tinfo; | 488 | struct ahd_initiator_tinfo *tinfo; |
490 | struct ahd_tmode_tstate *tstate; | 489 | struct ahd_tmode_tstate *tstate; |
@@ -495,7 +494,6 @@ ahd_linux_target_alloc(struct scsi_target *starget) | |||
495 | BUG_ON(*ahd_targp != NULL); | 494 | BUG_ON(*ahd_targp != NULL); |
496 | 495 | ||
497 | *ahd_targp = starget; | 496 | *ahd_targp = starget; |
498 | memset(targ, 0, sizeof(*targ)); | ||
499 | 497 | ||
500 | if (sc) { | 498 | if (sc) { |
501 | int flags = sc->device_flags[starget->id]; | 499 | int flags = sc->device_flags[starget->id]; |
@@ -551,15 +549,11 @@ ahd_linux_slave_alloc(struct scsi_device *sdev) | |||
551 | { | 549 | { |
552 | struct ahd_softc *ahd = | 550 | struct ahd_softc *ahd = |
553 | *((struct ahd_softc **)sdev->host->hostdata); | 551 | *((struct ahd_softc **)sdev->host->hostdata); |
554 | struct scsi_target *starget = sdev->sdev_target; | ||
555 | struct ahd_linux_target *targ = scsi_transport_target_data(starget); | ||
556 | struct ahd_linux_device *dev; | 552 | struct ahd_linux_device *dev; |
557 | 553 | ||
558 | if (bootverbose) | 554 | if (bootverbose) |
559 | printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id); | 555 | printf("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id); |
560 | 556 | ||
561 | BUG_ON(targ->sdev[sdev->lun] != NULL); | ||
562 | |||
563 | dev = scsi_transport_device_data(sdev); | 557 | dev = scsi_transport_device_data(sdev); |
564 | memset(dev, 0, sizeof(*dev)); | 558 | memset(dev, 0, sizeof(*dev)); |
565 | 559 | ||
@@ -576,8 +570,6 @@ ahd_linux_slave_alloc(struct scsi_device *sdev) | |||
576 | */ | 570 | */ |
577 | dev->maxtags = 0; | 571 | dev->maxtags = 0; |
578 | 572 | ||
579 | targ->sdev[sdev->lun] = sdev; | ||
580 | |||
581 | return (0); | 573 | return (0); |
582 | } | 574 | } |
583 | 575 | ||
@@ -599,23 +591,6 @@ ahd_linux_slave_configure(struct scsi_device *sdev) | |||
599 | return 0; | 591 | return 0; |
600 | } | 592 | } |
601 | 593 | ||
602 | static void | ||
603 | ahd_linux_slave_destroy(struct scsi_device *sdev) | ||
604 | { | ||
605 | struct ahd_softc *ahd; | ||
606 | struct ahd_linux_device *dev = scsi_transport_device_data(sdev); | ||
607 | struct ahd_linux_target *targ = scsi_transport_target_data(sdev->sdev_target); | ||
608 | |||
609 | ahd = *((struct ahd_softc **)sdev->host->hostdata); | ||
610 | if (bootverbose) | ||
611 | printf("%s: Slave Destroy %d\n", ahd_name(ahd), sdev->id); | ||
612 | |||
613 | BUG_ON(dev->active); | ||
614 | |||
615 | targ->sdev[sdev->lun] = NULL; | ||
616 | |||
617 | } | ||
618 | |||
619 | #if defined(__i386__) | 594 | #if defined(__i386__) |
620 | /* | 595 | /* |
621 | * Return the disk geometry for the given SCSI device. | 596 | * Return the disk geometry for the given SCSI device. |
@@ -822,7 +797,6 @@ struct scsi_host_template aic79xx_driver_template = { | |||
822 | .use_clustering = ENABLE_CLUSTERING, | 797 | .use_clustering = ENABLE_CLUSTERING, |
823 | .slave_alloc = ahd_linux_slave_alloc, | 798 | .slave_alloc = ahd_linux_slave_alloc, |
824 | .slave_configure = ahd_linux_slave_configure, | 799 | .slave_configure = ahd_linux_slave_configure, |
825 | .slave_destroy = ahd_linux_slave_destroy, | ||
826 | .target_alloc = ahd_linux_target_alloc, | 800 | .target_alloc = ahd_linux_target_alloc, |
827 | .target_destroy = ahd_linux_target_destroy, | 801 | .target_destroy = ahd_linux_target_destroy, |
828 | }; | 802 | }; |
@@ -1249,20 +1223,13 @@ void | |||
1249 | ahd_platform_free(struct ahd_softc *ahd) | 1223 | ahd_platform_free(struct ahd_softc *ahd) |
1250 | { | 1224 | { |
1251 | struct scsi_target *starget; | 1225 | struct scsi_target *starget; |
1252 | int i, j; | 1226 | int i; |
1253 | 1227 | ||
1254 | if (ahd->platform_data != NULL) { | 1228 | if (ahd->platform_data != NULL) { |
1255 | /* destroy all of the device and target objects */ | 1229 | /* destroy all of the device and target objects */ |
1256 | for (i = 0; i < AHD_NUM_TARGETS; i++) { | 1230 | for (i = 0; i < AHD_NUM_TARGETS; i++) { |
1257 | starget = ahd->platform_data->starget[i]; | 1231 | starget = ahd->platform_data->starget[i]; |
1258 | if (starget != NULL) { | 1232 | if (starget != NULL) { |
1259 | for (j = 0; j < AHD_NUM_LUNS; j++) { | ||
1260 | struct ahd_linux_target *targ = | ||
1261 | scsi_transport_target_data(starget); | ||
1262 | if (targ->sdev[j] == NULL) | ||
1263 | continue; | ||
1264 | targ->sdev[j] = NULL; | ||
1265 | } | ||
1266 | ahd->platform_data->starget[i] = NULL; | 1233 | ahd->platform_data->starget[i] = NULL; |
1267 | } | 1234 | } |
1268 | } | 1235 | } |
@@ -1318,20 +1285,13 @@ ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb) | |||
1318 | } | 1285 | } |
1319 | 1286 | ||
1320 | void | 1287 | void |
1321 | ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo, | 1288 | ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev, |
1322 | ahd_queue_alg alg) | 1289 | struct ahd_devinfo *devinfo, ahd_queue_alg alg) |
1323 | { | 1290 | { |
1324 | struct scsi_target *starget; | ||
1325 | struct ahd_linux_target *targ; | ||
1326 | struct ahd_linux_device *dev; | 1291 | struct ahd_linux_device *dev; |
1327 | struct scsi_device *sdev; | ||
1328 | int was_queuing; | 1292 | int was_queuing; |
1329 | int now_queuing; | 1293 | int now_queuing; |
1330 | 1294 | ||
1331 | starget = ahd->platform_data->starget[devinfo->target]; | ||
1332 | targ = scsi_transport_target_data(starget); | ||
1333 | BUG_ON(targ == NULL); | ||
1334 | sdev = targ->sdev[devinfo->lun]; | ||
1335 | if (sdev == NULL) | 1295 | if (sdev == NULL) |
1336 | return; | 1296 | return; |
1337 | 1297 | ||
@@ -1467,11 +1427,15 @@ ahd_linux_device_queue_depth(struct scsi_device *sdev) | |||
1467 | tags = ahd_linux_user_tagdepth(ahd, &devinfo); | 1427 | tags = ahd_linux_user_tagdepth(ahd, &devinfo); |
1468 | if (tags != 0 && sdev->tagged_supported != 0) { | 1428 | if (tags != 0 && sdev->tagged_supported != 0) { |
1469 | 1429 | ||
1470 | ahd_set_tags(ahd, &devinfo, AHD_QUEUE_TAGGED); | 1430 | ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_TAGGED); |
1431 | ahd_send_async(ahd, devinfo.channel, devinfo.target, | ||
1432 | devinfo.lun, AC_TRANSFER_NEG); | ||
1471 | ahd_print_devinfo(ahd, &devinfo); | 1433 | ahd_print_devinfo(ahd, &devinfo); |
1472 | printf("Tagged Queuing enabled. Depth %d\n", tags); | 1434 | printf("Tagged Queuing enabled. Depth %d\n", tags); |
1473 | } else { | 1435 | } else { |
1474 | ahd_set_tags(ahd, &devinfo, AHD_QUEUE_NONE); | 1436 | ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE); |
1437 | ahd_send_async(ahd, devinfo.channel, devinfo.target, | ||
1438 | devinfo.lun, AC_TRANSFER_NEG); | ||
1475 | } | 1439 | } |
1476 | } | 1440 | } |
1477 | 1441 | ||
@@ -1629,7 +1593,7 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs) | |||
1629 | 1593 | ||
1630 | void | 1594 | void |
1631 | ahd_send_async(struct ahd_softc *ahd, char channel, | 1595 | ahd_send_async(struct ahd_softc *ahd, char channel, |
1632 | u_int target, u_int lun, ac_code code, void *arg) | 1596 | u_int target, u_int lun, ac_code code) |
1633 | { | 1597 | { |
1634 | switch (code) { | 1598 | switch (code) { |
1635 | case AC_TRANSFER_NEG: | 1599 | case AC_TRANSFER_NEG: |
@@ -1956,7 +1920,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, | |||
1956 | } | 1920 | } |
1957 | ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); | 1921 | ahd_set_transaction_status(scb, CAM_REQUEUE_REQ); |
1958 | ahd_set_scsi_status(scb, SCSI_STATUS_OK); | 1922 | ahd_set_scsi_status(scb, SCSI_STATUS_OK); |
1959 | ahd_platform_set_tags(ahd, &devinfo, | 1923 | ahd_platform_set_tags(ahd, sdev, &devinfo, |
1960 | (dev->flags & AHD_DEV_Q_BASIC) | 1924 | (dev->flags & AHD_DEV_Q_BASIC) |
1961 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); | 1925 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); |
1962 | break; | 1926 | break; |
@@ -1966,7 +1930,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd, | |||
1966 | * as if the target returned BUSY SCSI status. | 1930 | * as if the target returned BUSY SCSI status. |
1967 | */ | 1931 | */ |
1968 | dev->openings = 1; | 1932 | dev->openings = 1; |
1969 | ahd_platform_set_tags(ahd, &devinfo, | 1933 | ahd_platform_set_tags(ahd, sdev, &devinfo, |
1970 | (dev->flags & AHD_DEV_Q_BASIC) | 1934 | (dev->flags & AHD_DEV_Q_BASIC) |
1971 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); | 1935 | ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED); |
1972 | ahd_set_scsi_status(scb, SCSI_STATUS_BUSY); | 1936 | ahd_set_scsi_status(scb, SCSI_STATUS_BUSY); |
@@ -2778,8 +2742,6 @@ ahd_linux_init(void) | |||
2778 | if (!ahd_linux_transport_template) | 2742 | if (!ahd_linux_transport_template) |
2779 | return -ENODEV; | 2743 | return -ENODEV; |
2780 | 2744 | ||
2781 | scsi_transport_reserve_target(ahd_linux_transport_template, | ||
2782 | sizeof(struct ahd_linux_target)); | ||
2783 | scsi_transport_reserve_device(ahd_linux_transport_template, | 2745 | scsi_transport_reserve_device(ahd_linux_transport_template, |
2784 | sizeof(struct ahd_linux_device)); | 2746 | sizeof(struct ahd_linux_device)); |
2785 | 2747 | ||
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 2b8331649eeb..b2e65e10ad2b 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h | |||
@@ -263,7 +263,6 @@ typedef enum { | |||
263 | AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ | 263 | AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ |
264 | } ahd_linux_dev_flags; | 264 | } ahd_linux_dev_flags; |
265 | 265 | ||
266 | struct ahd_linux_target; | ||
267 | struct ahd_linux_device { | 266 | struct ahd_linux_device { |
268 | TAILQ_ENTRY(ahd_linux_device) links; | 267 | TAILQ_ENTRY(ahd_linux_device) links; |
269 | 268 | ||
@@ -343,12 +342,6 @@ struct ahd_linux_device { | |||
343 | #define AHD_OTAG_THRESH 500 | 342 | #define AHD_OTAG_THRESH 500 |
344 | }; | 343 | }; |
345 | 344 | ||
346 | struct ahd_linux_target { | ||
347 | struct scsi_device *sdev[AHD_NUM_LUNS]; | ||
348 | struct ahd_transinfo last_tinfo; | ||
349 | struct ahd_softc *ahd; | ||
350 | }; | ||
351 | |||
352 | /********************* Definitions Required by the Core ***********************/ | 345 | /********************* Definitions Required by the Core ***********************/ |
353 | /* | 346 | /* |
354 | * Number of SG segments we require. So long as the S/G segments for | 347 | * Number of SG segments we require. So long as the S/G segments for |
@@ -865,7 +858,7 @@ ahd_freeze_scb(struct scb *scb) | |||
865 | } | 858 | } |
866 | } | 859 | } |
867 | 860 | ||
868 | void ahd_platform_set_tags(struct ahd_softc *ahd, | 861 | void ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev, |
869 | struct ahd_devinfo *devinfo, ahd_queue_alg); | 862 | struct ahd_devinfo *devinfo, ahd_queue_alg); |
870 | int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, | 863 | int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, |
871 | char channel, int lun, u_int tag, | 864 | char channel, int lun, u_int tag, |
@@ -874,7 +867,7 @@ irqreturn_t | |||
874 | ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); | 867 | ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); |
875 | void ahd_done(struct ahd_softc*, struct scb*); | 868 | void ahd_done(struct ahd_softc*, struct scb*); |
876 | void ahd_send_async(struct ahd_softc *, char channel, | 869 | void ahd_send_async(struct ahd_softc *, char channel, |
877 | u_int target, u_int lun, ac_code, void *); | 870 | u_int target, u_int lun, ac_code); |
878 | void ahd_print_path(struct ahd_softc *, struct scb *); | 871 | void ahd_print_path(struct ahd_softc *, struct scb *); |
879 | 872 | ||
880 | #ifdef CONFIG_PCI | 873 | #ifdef CONFIG_PCI |
diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index 24fd59a230bf..c5f0ee591509 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c | |||
@@ -47,7 +47,7 @@ static int copy_info(struct info_str *info, char *fmt, ...); | |||
47 | static void ahd_dump_target_state(struct ahd_softc *ahd, | 47 | static void ahd_dump_target_state(struct ahd_softc *ahd, |
48 | struct info_str *info, | 48 | struct info_str *info, |
49 | u_int our_id, char channel, | 49 | u_int our_id, char channel, |
50 | u_int target_id, u_int target_offset); | 50 | u_int target_id); |
51 | static void ahd_dump_device_state(struct info_str *info, | 51 | static void ahd_dump_device_state(struct info_str *info, |
52 | struct scsi_device *sdev); | 52 | struct scsi_device *sdev); |
53 | static int ahd_proc_write_seeprom(struct ahd_softc *ahd, | 53 | static int ahd_proc_write_seeprom(struct ahd_softc *ahd, |
@@ -204,10 +204,8 @@ ahd_format_transinfo(struct info_str *info, struct ahd_transinfo *tinfo) | |||
204 | 204 | ||
205 | static void | 205 | static void |
206 | ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | 206 | ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, |
207 | u_int our_id, char channel, u_int target_id, | 207 | u_int our_id, char channel, u_int target_id) |
208 | u_int target_offset) | ||
209 | { | 208 | { |
210 | struct ahd_linux_target *targ; | ||
211 | struct scsi_target *starget; | 209 | struct scsi_target *starget; |
212 | struct ahd_initiator_tinfo *tinfo; | 210 | struct ahd_initiator_tinfo *tinfo; |
213 | struct ahd_tmode_tstate *tstate; | 211 | struct ahd_tmode_tstate *tstate; |
@@ -218,10 +216,9 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | |||
218 | copy_info(info, "Target %d Negotiation Settings\n", target_id); | 216 | copy_info(info, "Target %d Negotiation Settings\n", target_id); |
219 | copy_info(info, "\tUser: "); | 217 | copy_info(info, "\tUser: "); |
220 | ahd_format_transinfo(info, &tinfo->user); | 218 | ahd_format_transinfo(info, &tinfo->user); |
221 | starget = ahd->platform_data->starget[target_offset]; | 219 | starget = ahd->platform_data->starget[target_id]; |
222 | if (starget == NULL) | 220 | if (starget == NULL) |
223 | return; | 221 | return; |
224 | targ = scsi_transport_target_data(starget); | ||
225 | 222 | ||
226 | copy_info(info, "\tGoal: "); | 223 | copy_info(info, "\tGoal: "); |
227 | ahd_format_transinfo(info, &tinfo->goal); | 224 | ahd_format_transinfo(info, &tinfo->goal); |
@@ -231,7 +228,7 @@ ahd_dump_target_state(struct ahd_softc *ahd, struct info_str *info, | |||
231 | for (lun = 0; lun < AHD_NUM_LUNS; lun++) { | 228 | for (lun = 0; lun < AHD_NUM_LUNS; lun++) { |
232 | struct scsi_device *dev; | 229 | struct scsi_device *dev; |
233 | 230 | ||
234 | dev = targ->sdev[lun]; | 231 | dev = scsi_device_lookup_by_target(starget, lun); |
235 | 232 | ||
236 | if (dev == NULL) | 233 | if (dev == NULL) |
237 | continue; | 234 | continue; |
@@ -355,7 +352,7 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
355 | copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n", | 352 | copy_info(&info, "Allocated SCBs: %d, SG List Length: %d\n\n", |
356 | ahd->scb_data.numscbs, AHD_NSEG); | 353 | ahd->scb_data.numscbs, AHD_NSEG); |
357 | 354 | ||
358 | max_targ = 15; | 355 | max_targ = 16; |
359 | 356 | ||
360 | if (ahd->seep_config == NULL) | 357 | if (ahd->seep_config == NULL) |
361 | copy_info(&info, "No Serial EEPROM\n"); | 358 | copy_info(&info, "No Serial EEPROM\n"); |
@@ -373,12 +370,12 @@ ahd_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
373 | copy_info(&info, "\n"); | 370 | copy_info(&info, "\n"); |
374 | 371 | ||
375 | if ((ahd->features & AHD_WIDE) == 0) | 372 | if ((ahd->features & AHD_WIDE) == 0) |
376 | max_targ = 7; | 373 | max_targ = 8; |
377 | 374 | ||
378 | for (i = 0; i <= max_targ; i++) { | 375 | for (i = 0; i < max_targ; i++) { |
379 | 376 | ||
380 | ahd_dump_target_state(ahd, &info, ahd->our_id, 'A', | 377 | ahd_dump_target_state(ahd, &info, ahd->our_id, 'A', |
381 | /*target_id*/i, /*target_offset*/i); | 378 | /*target_id*/i); |
382 | } | 379 | } |
383 | retval = info.pos > info.offset ? info.pos - info.offset : 0; | 380 | retval = info.pos > info.offset ? info.pos - info.offset : 0; |
384 | done: | 381 | done: |
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 3ee4d4d3f445..69e6e9821c9e 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c | |||
@@ -2625,29 +2625,32 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2625 | unsigned int base_io, tmport, error,n; | 2625 | unsigned int base_io, tmport, error,n; |
2626 | unsigned char host_id; | 2626 | unsigned char host_id; |
2627 | struct Scsi_Host *shpnt = NULL; | 2627 | struct Scsi_Host *shpnt = NULL; |
2628 | struct atp_unit atp_dev, *p; | 2628 | struct atp_unit *atpdev, *p; |
2629 | unsigned char setupdata[2][16]; | 2629 | unsigned char setupdata[2][16]; |
2630 | int count = 0; | 2630 | int count = 0; |
2631 | 2631 | ||
2632 | atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL); | ||
2633 | if (!atpdev) | ||
2634 | return -ENOMEM; | ||
2635 | |||
2632 | if (pci_enable_device(pdev)) | 2636 | if (pci_enable_device(pdev)) |
2633 | return -EIO; | 2637 | goto err_eio; |
2634 | 2638 | ||
2635 | if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | 2639 | if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
2636 | printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); | 2640 | printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); |
2637 | } else { | 2641 | } else { |
2638 | printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); | 2642 | printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); |
2639 | return -EIO; | 2643 | goto err_eio; |
2640 | } | 2644 | } |
2641 | 2645 | ||
2642 | memset(&atp_dev, 0, sizeof atp_dev); | ||
2643 | /* | 2646 | /* |
2644 | * It's probably easier to weed out some revisions like | 2647 | * It's probably easier to weed out some revisions like |
2645 | * this than via the PCI device table | 2648 | * this than via the PCI device table |
2646 | */ | 2649 | */ |
2647 | if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { | 2650 | if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { |
2648 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); | 2651 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); |
2649 | if (atp_dev.chip_ver < 2) | 2652 | if (atpdev->chip_ver < 2) |
2650 | return -EIO; | 2653 | goto err_eio; |
2651 | } | 2654 | } |
2652 | 2655 | ||
2653 | switch (ent->device) { | 2656 | switch (ent->device) { |
@@ -2656,15 +2659,15 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2656 | case ATP880_DEVID1: | 2659 | case ATP880_DEVID1: |
2657 | case ATP880_DEVID2: | 2660 | case ATP880_DEVID2: |
2658 | case ATP885_DEVID: | 2661 | case ATP885_DEVID: |
2659 | atp_dev.chip_ver = 0x04; | 2662 | atpdev->chip_ver = 0x04; |
2660 | default: | 2663 | default: |
2661 | break; | 2664 | break; |
2662 | } | 2665 | } |
2663 | base_io = pci_resource_start(pdev, 0); | 2666 | base_io = pci_resource_start(pdev, 0); |
2664 | base_io &= 0xfffffff8; | 2667 | base_io &= 0xfffffff8; |
2665 | 2668 | ||
2666 | if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { | 2669 | if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { |
2667 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); | 2670 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); |
2668 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 | 2671 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 |
2669 | 2672 | ||
2670 | host_id = inb(base_io + 0x39); | 2673 | host_id = inb(base_io + 0x39); |
@@ -2672,17 +2675,17 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2672 | 2675 | ||
2673 | printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" | 2676 | printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" |
2674 | " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); | 2677 | " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); |
2675 | atp_dev.ioport[0] = base_io + 0x40; | 2678 | atpdev->ioport[0] = base_io + 0x40; |
2676 | atp_dev.pciport[0] = base_io + 0x28; | 2679 | atpdev->pciport[0] = base_io + 0x28; |
2677 | atp_dev.dev_id = ent->device; | 2680 | atpdev->dev_id = ent->device; |
2678 | atp_dev.host_id[0] = host_id; | 2681 | atpdev->host_id[0] = host_id; |
2679 | 2682 | ||
2680 | tmport = base_io + 0x22; | 2683 | tmport = base_io + 0x22; |
2681 | atp_dev.scam_on = inb(tmport); | 2684 | atpdev->scam_on = inb(tmport); |
2682 | tmport += 0x13; | 2685 | tmport += 0x13; |
2683 | atp_dev.global_map[0] = inb(tmport); | 2686 | atpdev->global_map[0] = inb(tmport); |
2684 | tmport += 0x07; | 2687 | tmport += 0x07; |
2685 | atp_dev.ultra_map[0] = inw(tmport); | 2688 | atpdev->ultra_map[0] = inw(tmport); |
2686 | 2689 | ||
2687 | n = 0x3f09; | 2690 | n = 0x3f09; |
2688 | next_fblk_880: | 2691 | next_fblk_880: |
@@ -2695,57 +2698,57 @@ next_fblk_880: | |||
2695 | if (inb(base_io + 0x30) == 0xff) | 2698 | if (inb(base_io + 0x30) == 0xff) |
2696 | goto flash_ok_880; | 2699 | goto flash_ok_880; |
2697 | 2700 | ||
2698 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2701 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2699 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2702 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2700 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2703 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2701 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2704 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2702 | outw(n, base_io + 0x34); | 2705 | outw(n, base_io + 0x34); |
2703 | n += 0x0002; | 2706 | n += 0x0002; |
2704 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2707 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2705 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2708 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2706 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2709 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2707 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2710 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2708 | outw(n, base_io + 0x34); | 2711 | outw(n, base_io + 0x34); |
2709 | n += 0x0002; | 2712 | n += 0x0002; |
2710 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2713 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2711 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2714 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2712 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2715 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2713 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2716 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2714 | outw(n, base_io + 0x34); | 2717 | outw(n, base_io + 0x34); |
2715 | n += 0x0002; | 2718 | n += 0x0002; |
2716 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2719 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
2717 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2720 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
2718 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2721 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
2719 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2722 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
2720 | n += 0x0018; | 2723 | n += 0x0018; |
2721 | goto next_fblk_880; | 2724 | goto next_fblk_880; |
2722 | flash_ok_880: | 2725 | flash_ok_880: |
2723 | outw(0, base_io + 0x34); | 2726 | outw(0, base_io + 0x34); |
2724 | atp_dev.ultra_map[0] = 0; | 2727 | atpdev->ultra_map[0] = 0; |
2725 | atp_dev.async[0] = 0; | 2728 | atpdev->async[0] = 0; |
2726 | for (k = 0; k < 16; k++) { | 2729 | for (k = 0; k < 16; k++) { |
2727 | n = 1; | 2730 | n = 1; |
2728 | n = n << k; | 2731 | n = n << k; |
2729 | if (atp_dev.sp[0][k] > 1) { | 2732 | if (atpdev->sp[0][k] > 1) { |
2730 | atp_dev.ultra_map[0] |= n; | 2733 | atpdev->ultra_map[0] |= n; |
2731 | } else { | 2734 | } else { |
2732 | if (atp_dev.sp[0][k] == 0) | 2735 | if (atpdev->sp[0][k] == 0) |
2733 | atp_dev.async[0] |= n; | 2736 | atpdev->async[0] |= n; |
2734 | } | 2737 | } |
2735 | } | 2738 | } |
2736 | atp_dev.async[0] = ~(atp_dev.async[0]); | 2739 | atpdev->async[0] = ~(atpdev->async[0]); |
2737 | outb(atp_dev.global_map[0], base_io + 0x35); | 2740 | outb(atpdev->global_map[0], base_io + 0x35); |
2738 | 2741 | ||
2739 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2742 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
2740 | if (!shpnt) | 2743 | if (!shpnt) |
2741 | return -ENOMEM; | 2744 | goto err_nomem; |
2742 | 2745 | ||
2743 | p = (struct atp_unit *)&shpnt->hostdata; | 2746 | p = (struct atp_unit *)&shpnt->hostdata; |
2744 | 2747 | ||
2745 | atp_dev.host = shpnt; | 2748 | atpdev->host = shpnt; |
2746 | atp_dev.pdev = pdev; | 2749 | atpdev->pdev = pdev; |
2747 | pci_set_drvdata(pdev, p); | 2750 | pci_set_drvdata(pdev, p); |
2748 | memcpy(p, &atp_dev, sizeof atp_dev); | 2751 | memcpy(p, atpdev, sizeof(*atpdev)); |
2749 | if (atp870u_init_tables(shpnt) < 0) { | 2752 | if (atp870u_init_tables(shpnt) < 0) { |
2750 | printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); | 2753 | printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); |
2751 | goto unregister; | 2754 | goto unregister; |
@@ -2798,24 +2801,24 @@ flash_ok_880: | |||
2798 | printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" | 2801 | printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" |
2799 | , base_io, pdev->irq); | 2802 | , base_io, pdev->irq); |
2800 | 2803 | ||
2801 | atp_dev.pdev = pdev; | 2804 | atpdev->pdev = pdev; |
2802 | atp_dev.dev_id = ent->device; | 2805 | atpdev->dev_id = ent->device; |
2803 | atp_dev.baseport = base_io; | 2806 | atpdev->baseport = base_io; |
2804 | atp_dev.ioport[0] = base_io + 0x80; | 2807 | atpdev->ioport[0] = base_io + 0x80; |
2805 | atp_dev.ioport[1] = base_io + 0xc0; | 2808 | atpdev->ioport[1] = base_io + 0xc0; |
2806 | atp_dev.pciport[0] = base_io + 0x40; | 2809 | atpdev->pciport[0] = base_io + 0x40; |
2807 | atp_dev.pciport[1] = base_io + 0x50; | 2810 | atpdev->pciport[1] = base_io + 0x50; |
2808 | 2811 | ||
2809 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2812 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
2810 | if (!shpnt) | 2813 | if (!shpnt) |
2811 | return -ENOMEM; | 2814 | goto err_nomem; |
2812 | 2815 | ||
2813 | p = (struct atp_unit *)&shpnt->hostdata; | 2816 | p = (struct atp_unit *)&shpnt->hostdata; |
2814 | 2817 | ||
2815 | atp_dev.host = shpnt; | 2818 | atpdev->host = shpnt; |
2816 | atp_dev.pdev = pdev; | 2819 | atpdev->pdev = pdev; |
2817 | pci_set_drvdata(pdev, p); | 2820 | pci_set_drvdata(pdev, p); |
2818 | memcpy(p, &atp_dev, sizeof(struct atp_unit)); | 2821 | memcpy(p, atpdev, sizeof(struct atp_unit)); |
2819 | if (atp870u_init_tables(shpnt) < 0) | 2822 | if (atp870u_init_tables(shpnt) < 0) |
2820 | goto unregister; | 2823 | goto unregister; |
2821 | 2824 | ||
@@ -2974,33 +2977,33 @@ flash_ok_885: | |||
2974 | printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " | 2977 | printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " |
2975 | "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); | 2978 | "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); |
2976 | 2979 | ||
2977 | atp_dev.ioport[0] = base_io; | 2980 | atpdev->ioport[0] = base_io; |
2978 | atp_dev.pciport[0] = base_io + 0x20; | 2981 | atpdev->pciport[0] = base_io + 0x20; |
2979 | atp_dev.dev_id = ent->device; | 2982 | atpdev->dev_id = ent->device; |
2980 | host_id &= 0x07; | 2983 | host_id &= 0x07; |
2981 | atp_dev.host_id[0] = host_id; | 2984 | atpdev->host_id[0] = host_id; |
2982 | tmport = base_io + 0x22; | 2985 | tmport = base_io + 0x22; |
2983 | atp_dev.scam_on = inb(tmport); | 2986 | atpdev->scam_on = inb(tmport); |
2984 | tmport += 0x0b; | 2987 | tmport += 0x0b; |
2985 | atp_dev.global_map[0] = inb(tmport++); | 2988 | atpdev->global_map[0] = inb(tmport++); |
2986 | atp_dev.ultra_map[0] = inw(tmport); | 2989 | atpdev->ultra_map[0] = inw(tmport); |
2987 | 2990 | ||
2988 | if (atp_dev.ultra_map[0] == 0) { | 2991 | if (atpdev->ultra_map[0] == 0) { |
2989 | atp_dev.scam_on = 0x00; | 2992 | atpdev->scam_on = 0x00; |
2990 | atp_dev.global_map[0] = 0x20; | 2993 | atpdev->global_map[0] = 0x20; |
2991 | atp_dev.ultra_map[0] = 0xffff; | 2994 | atpdev->ultra_map[0] = 0xffff; |
2992 | } | 2995 | } |
2993 | 2996 | ||
2994 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2997 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
2995 | if (!shpnt) | 2998 | if (!shpnt) |
2996 | return -ENOMEM; | 2999 | goto err_nomem; |
2997 | 3000 | ||
2998 | p = (struct atp_unit *)&shpnt->hostdata; | 3001 | p = (struct atp_unit *)&shpnt->hostdata; |
2999 | 3002 | ||
3000 | atp_dev.host = shpnt; | 3003 | atpdev->host = shpnt; |
3001 | atp_dev.pdev = pdev; | 3004 | atpdev->pdev = pdev; |
3002 | pci_set_drvdata(pdev, p); | 3005 | pci_set_drvdata(pdev, p); |
3003 | memcpy(p, &atp_dev, sizeof atp_dev); | 3006 | memcpy(p, atpdev, sizeof(*atpdev)); |
3004 | if (atp870u_init_tables(shpnt) < 0) | 3007 | if (atp870u_init_tables(shpnt) < 0) |
3005 | goto unregister; | 3008 | goto unregister; |
3006 | 3009 | ||
@@ -3010,7 +3013,7 @@ flash_ok_885: | |||
3010 | } | 3013 | } |
3011 | 3014 | ||
3012 | spin_lock_irqsave(shpnt->host_lock, flags); | 3015 | spin_lock_irqsave(shpnt->host_lock, flags); |
3013 | if (atp_dev.chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ | 3016 | if (atpdev->chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ |
3014 | tmport = base_io + 0x3e; | 3017 | tmport = base_io + 0x3e; |
3015 | outb(0x00, tmport); | 3018 | outb(0x00, tmport); |
3016 | } | 3019 | } |
@@ -3044,7 +3047,7 @@ flash_ok_885: | |||
3044 | outb((inb(tmport) & 0xef), tmport); | 3047 | outb((inb(tmport) & 0xef), tmport); |
3045 | tmport++; | 3048 | tmport++; |
3046 | outb((inb(tmport) | 0x20), tmport); | 3049 | outb((inb(tmport) | 0x20), tmport); |
3047 | if (atp_dev.chip_ver == 4) | 3050 | if (atpdev->chip_ver == 4) |
3048 | shpnt->max_id = 16; | 3051 | shpnt->max_id = 16; |
3049 | else | 3052 | else |
3050 | shpnt->max_id = 8; | 3053 | shpnt->max_id = 8; |
@@ -3093,6 +3096,12 @@ unregister: | |||
3093 | printk("atp870u_prob:unregister\n"); | 3096 | printk("atp870u_prob:unregister\n"); |
3094 | scsi_host_put(shpnt); | 3097 | scsi_host_put(shpnt); |
3095 | return -1; | 3098 | return -1; |
3099 | err_eio: | ||
3100 | kfree(atpdev); | ||
3101 | return -EIO; | ||
3102 | err_nomem: | ||
3103 | kfree(atpdev); | ||
3104 | return -ENOMEM; | ||
3096 | } | 3105 | } |
3097 | 3106 | ||
3098 | /* The abort command does not leave the device in a clean state where | 3107 | /* The abort command does not leave the device in a clean state where |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 944fc1203ebd..669ea4fff166 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -535,6 +535,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
535 | struct ibmvscsi_host_data *hostdata) | 535 | struct ibmvscsi_host_data *hostdata) |
536 | { | 536 | { |
537 | u64 *crq_as_u64 = (u64 *) &evt_struct->crq; | 537 | u64 *crq_as_u64 = (u64 *) &evt_struct->crq; |
538 | int request_status; | ||
538 | int rc; | 539 | int rc; |
539 | 540 | ||
540 | /* If we have exhausted our request limit, just fail this request. | 541 | /* If we have exhausted our request limit, just fail this request. |
@@ -542,9 +543,18 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
542 | * (such as task management requests) that the mid layer may think we | 543 | * (such as task management requests) that the mid layer may think we |
543 | * can handle more requests (can_queue) when we actually can't | 544 | * can handle more requests (can_queue) when we actually can't |
544 | */ | 545 | */ |
545 | if ((evt_struct->crq.format == VIOSRP_SRP_FORMAT) && | 546 | if (evt_struct->crq.format == VIOSRP_SRP_FORMAT) { |
546 | (atomic_dec_if_positive(&hostdata->request_limit) < 0)) | 547 | request_status = |
547 | goto send_error; | 548 | atomic_dec_if_positive(&hostdata->request_limit); |
549 | /* If request limit was -1 when we started, it is now even | ||
550 | * less than that | ||
551 | */ | ||
552 | if (request_status < -1) | ||
553 | goto send_error; | ||
554 | /* Otherwise, if we have run out of requests */ | ||
555 | else if (request_status < 0) | ||
556 | goto send_busy; | ||
557 | } | ||
548 | 558 | ||
549 | /* Copy the IU into the transfer area */ | 559 | /* Copy the IU into the transfer area */ |
550 | *evt_struct->xfer_iu = evt_struct->iu; | 560 | *evt_struct->xfer_iu = evt_struct->iu; |
@@ -567,11 +577,23 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
567 | 577 | ||
568 | return 0; | 578 | return 0; |
569 | 579 | ||
570 | send_error: | 580 | send_busy: |
571 | unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); | 581 | unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); |
572 | 582 | ||
573 | free_event_struct(&hostdata->pool, evt_struct); | 583 | free_event_struct(&hostdata->pool, evt_struct); |
574 | return SCSI_MLQUEUE_HOST_BUSY; | 584 | return SCSI_MLQUEUE_HOST_BUSY; |
585 | |||
586 | send_error: | ||
587 | unmap_cmd_data(&evt_struct->iu.srp.cmd, evt_struct, hostdata->dev); | ||
588 | |||
589 | if (evt_struct->cmnd != NULL) { | ||
590 | evt_struct->cmnd->result = DID_ERROR << 16; | ||
591 | evt_struct->cmnd_done(evt_struct->cmnd); | ||
592 | } else if (evt_struct->done) | ||
593 | evt_struct->done(evt_struct); | ||
594 | |||
595 | free_event_struct(&hostdata->pool, evt_struct); | ||
596 | return 0; | ||
575 | } | 597 | } |
576 | 598 | ||
577 | /** | 599 | /** |
@@ -1184,27 +1206,37 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1184 | return; | 1206 | return; |
1185 | case 0xFF: /* Hypervisor telling us the connection is closed */ | 1207 | case 0xFF: /* Hypervisor telling us the connection is closed */ |
1186 | scsi_block_requests(hostdata->host); | 1208 | scsi_block_requests(hostdata->host); |
1209 | atomic_set(&hostdata->request_limit, 0); | ||
1187 | if (crq->format == 0x06) { | 1210 | if (crq->format == 0x06) { |
1188 | /* We need to re-setup the interpartition connection */ | 1211 | /* We need to re-setup the interpartition connection */ |
1189 | printk(KERN_INFO | 1212 | printk(KERN_INFO |
1190 | "ibmvscsi: Re-enabling adapter!\n"); | 1213 | "ibmvscsi: Re-enabling adapter!\n"); |
1191 | atomic_set(&hostdata->request_limit, -1); | ||
1192 | purge_requests(hostdata, DID_REQUEUE); | 1214 | purge_requests(hostdata, DID_REQUEUE); |
1193 | if (ibmvscsi_reenable_crq_queue(&hostdata->queue, | 1215 | if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, |
1194 | hostdata) == 0) | 1216 | hostdata) == 0) || |
1195 | if (ibmvscsi_send_crq(hostdata, | 1217 | (ibmvscsi_send_crq(hostdata, |
1196 | 0xC001000000000000LL, 0)) | 1218 | 0xC001000000000000LL, 0))) { |
1219 | atomic_set(&hostdata->request_limit, | ||
1220 | -1); | ||
1197 | printk(KERN_ERR | 1221 | printk(KERN_ERR |
1198 | "ibmvscsi: transmit error after" | 1222 | "ibmvscsi: error after" |
1199 | " enable\n"); | 1223 | " enable\n"); |
1224 | } | ||
1200 | } else { | 1225 | } else { |
1201 | printk(KERN_INFO | 1226 | printk(KERN_INFO |
1202 | "ibmvscsi: Virtual adapter failed rc %d!\n", | 1227 | "ibmvscsi: Virtual adapter failed rc %d!\n", |
1203 | crq->format); | 1228 | crq->format); |
1204 | 1229 | ||
1205 | atomic_set(&hostdata->request_limit, -1); | ||
1206 | purge_requests(hostdata, DID_ERROR); | 1230 | purge_requests(hostdata, DID_ERROR); |
1207 | ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata); | 1231 | if ((ibmvscsi_reset_crq_queue(&hostdata->queue, |
1232 | hostdata)) || | ||
1233 | (ibmvscsi_send_crq(hostdata, | ||
1234 | 0xC001000000000000LL, 0))) { | ||
1235 | atomic_set(&hostdata->request_limit, | ||
1236 | -1); | ||
1237 | printk(KERN_ERR | ||
1238 | "ibmvscsi: error after reset\n"); | ||
1239 | } | ||
1208 | } | 1240 | } |
1209 | scsi_unblock_requests(hostdata->host); | 1241 | scsi_unblock_requests(hostdata->host); |
1210 | return; | 1242 | return; |
@@ -1467,6 +1499,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1467 | struct Scsi_Host *host; | 1499 | struct Scsi_Host *host; |
1468 | struct device *dev = &vdev->dev; | 1500 | struct device *dev = &vdev->dev; |
1469 | unsigned long wait_switch = 0; | 1501 | unsigned long wait_switch = 0; |
1502 | int rc; | ||
1470 | 1503 | ||
1471 | vdev->dev.driver_data = NULL; | 1504 | vdev->dev.driver_data = NULL; |
1472 | 1505 | ||
@@ -1484,8 +1517,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1484 | atomic_set(&hostdata->request_limit, -1); | 1517 | atomic_set(&hostdata->request_limit, -1); |
1485 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ | 1518 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ |
1486 | 1519 | ||
1487 | if (ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, | 1520 | rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests); |
1488 | max_requests) != 0) { | 1521 | if (rc != 0 && rc != H_RESOURCE) { |
1489 | printk(KERN_ERR "ibmvscsi: couldn't initialize crq\n"); | 1522 | printk(KERN_ERR "ibmvscsi: couldn't initialize crq\n"); |
1490 | goto init_crq_failed; | 1523 | goto init_crq_failed; |
1491 | } | 1524 | } |
@@ -1505,7 +1538,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1505 | * to fail if the other end is not acive. In that case we don't | 1538 | * to fail if the other end is not acive. In that case we don't |
1506 | * want to scan | 1539 | * want to scan |
1507 | */ | 1540 | */ |
1508 | if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0) { | 1541 | if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0 |
1542 | || rc == H_RESOURCE) { | ||
1509 | /* | 1543 | /* |
1510 | * Wait around max init_timeout secs for the adapter to finish | 1544 | * Wait around max init_timeout secs for the adapter to finish |
1511 | * initializing. When we are done initializing, we will have a | 1545 | * initializing. When we are done initializing, we will have a |
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 1a9992bdfef8..242b8873b333 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c | |||
@@ -208,6 +208,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
208 | int max_requests) | 208 | int max_requests) |
209 | { | 209 | { |
210 | int rc; | 210 | int rc; |
211 | int retrc; | ||
211 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 212 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
212 | 213 | ||
213 | queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL); | 214 | queue->msgs = (struct viosrp_crq *)get_zeroed_page(GFP_KERNEL); |
@@ -226,7 +227,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
226 | gather_partition_info(); | 227 | gather_partition_info(); |
227 | set_adapter_info(hostdata); | 228 | set_adapter_info(hostdata); |
228 | 229 | ||
229 | rc = plpar_hcall_norets(H_REG_CRQ, | 230 | retrc = rc = plpar_hcall_norets(H_REG_CRQ, |
230 | vdev->unit_address, | 231 | vdev->unit_address, |
231 | queue->msg_token, PAGE_SIZE); | 232 | queue->msg_token, PAGE_SIZE); |
232 | if (rc == H_RESOURCE) | 233 | if (rc == H_RESOURCE) |
@@ -263,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
263 | tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, | 264 | tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, |
264 | (unsigned long)hostdata); | 265 | (unsigned long)hostdata); |
265 | 266 | ||
266 | return 0; | 267 | return retrc; |
267 | 268 | ||
268 | req_irq_failed: | 269 | req_irq_failed: |
269 | do { | 270 | do { |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 087c44539a16..f81691fcf177 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -174,7 +174,6 @@ struct lpfc_hba { | |||
174 | dma_addr_t slim2p_mapping; | 174 | dma_addr_t slim2p_mapping; |
175 | uint16_t pci_cfg_value; | 175 | uint16_t pci_cfg_value; |
176 | 176 | ||
177 | struct semaphore hba_can_block; | ||
178 | int32_t hba_state; | 177 | int32_t hba_state; |
179 | 178 | ||
180 | #define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */ | 179 | #define LPFC_STATE_UNKNOWN 0 /* HBA state is unknown */ |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 283b7d824c34..4126fd87956f 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -821,7 +821,7 @@ lpfc_issue_els_plogi(struct lpfc_hba * phba, uint32_t did, uint8_t retry) | |||
821 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ | 821 | pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ |
822 | 822 | ||
823 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); | 823 | cmdsize = (sizeof (uint32_t) + sizeof (struct serv_parm)); |
824 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, 0, did, | 824 | elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, NULL, did, |
825 | ELS_CMD_PLOGI); | 825 | ELS_CMD_PLOGI); |
826 | if (!elsiocb) | 826 | if (!elsiocb) |
827 | return 1; | 827 | return 1; |
@@ -2791,8 +2791,8 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
2791 | 2791 | ||
2792 | ndlp = (struct lpfc_nodelist *) pmb->context2; | 2792 | ndlp = (struct lpfc_nodelist *) pmb->context2; |
2793 | xri = (uint16_t) ((unsigned long)(pmb->context1)); | 2793 | xri = (uint16_t) ((unsigned long)(pmb->context1)); |
2794 | pmb->context1 = 0; | 2794 | pmb->context1 = NULL; |
2795 | pmb->context2 = 0; | 2795 | pmb->context2 = NULL; |
2796 | 2796 | ||
2797 | if (mb->mbxStatus) { | 2797 | if (mb->mbxStatus) { |
2798 | mempool_free( pmb, phba->mbox_mem_pool); | 2798 | mempool_free( pmb, phba->mbox_mem_pool); |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 908d0f27706f..f68ad7654986 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -939,12 +939,12 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | |||
939 | "10-port ", "PCIe"}; | 939 | "10-port ", "PCIe"}; |
940 | break; | 940 | break; |
941 | default: | 941 | default: |
942 | m = (typeof(m)){ 0 }; | 942 | m = (typeof(m)){ NULL }; |
943 | break; | 943 | break; |
944 | } | 944 | } |
945 | break; | 945 | break; |
946 | default: | 946 | default: |
947 | m = (typeof(m)){ 0 }; | 947 | m = (typeof(m)){ NULL }; |
948 | break; | 948 | break; |
949 | } | 949 | } |
950 | 950 | ||
@@ -1451,7 +1451,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1451 | goto out_put_host; | 1451 | goto out_put_host; |
1452 | 1452 | ||
1453 | host->unique_id = phba->brd_no; | 1453 | host->unique_id = phba->brd_no; |
1454 | init_MUTEX(&phba->hba_can_block); | ||
1455 | INIT_LIST_HEAD(&phba->ctrspbuflist); | 1454 | INIT_LIST_HEAD(&phba->ctrspbuflist); |
1456 | INIT_LIST_HEAD(&phba->rnidrspbuflist); | 1455 | INIT_LIST_HEAD(&phba->rnidrspbuflist); |
1457 | INIT_LIST_HEAD(&phba->freebufList); | 1456 | INIT_LIST_HEAD(&phba->freebufList); |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 7dc4c2e6bed2..aea1ee472f3d 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -41,20 +41,6 @@ | |||
41 | #define LPFC_ABORT_WAIT 2 | 41 | #define LPFC_ABORT_WAIT 2 |
42 | 42 | ||
43 | 43 | ||
44 | static inline void | ||
45 | lpfc_block_requests(struct lpfc_hba * phba) | ||
46 | { | ||
47 | down(&phba->hba_can_block); | ||
48 | scsi_block_requests(phba->host); | ||
49 | } | ||
50 | |||
51 | static inline void | ||
52 | lpfc_unblock_requests(struct lpfc_hba * phba) | ||
53 | { | ||
54 | scsi_unblock_requests(phba->host); | ||
55 | up(&phba->hba_can_block); | ||
56 | } | ||
57 | |||
58 | /* | 44 | /* |
59 | * This routine allocates a scsi buffer, which contains all the necessary | 45 | * This routine allocates a scsi buffer, which contains all the necessary |
60 | * information needed to initiate a SCSI I/O. The non-DMAable buffer region | 46 | * information needed to initiate a SCSI I/O. The non-DMAable buffer region |
@@ -859,7 +845,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
859 | unsigned int loop_count = 0; | 845 | unsigned int loop_count = 0; |
860 | int ret = SUCCESS; | 846 | int ret = SUCCESS; |
861 | 847 | ||
862 | lpfc_block_requests(phba); | ||
863 | spin_lock_irq(shost->host_lock); | 848 | spin_lock_irq(shost->host_lock); |
864 | 849 | ||
865 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; | 850 | lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble; |
@@ -945,7 +930,6 @@ lpfc_abort_handler(struct scsi_cmnd *cmnd) | |||
945 | cmnd->device->lun, cmnd->serial_number); | 930 | cmnd->device->lun, cmnd->serial_number); |
946 | 931 | ||
947 | spin_unlock_irq(shost->host_lock); | 932 | spin_unlock_irq(shost->host_lock); |
948 | lpfc_unblock_requests(phba); | ||
949 | 933 | ||
950 | return ret; | 934 | return ret; |
951 | } | 935 | } |
@@ -963,7 +947,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
963 | int ret = FAILED; | 947 | int ret = FAILED; |
964 | int cnt, loopcnt; | 948 | int cnt, loopcnt; |
965 | 949 | ||
966 | lpfc_block_requests(phba); | ||
967 | spin_lock_irq(shost->host_lock); | 950 | spin_lock_irq(shost->host_lock); |
968 | /* | 951 | /* |
969 | * If target is not in a MAPPED state, delay the reset until | 952 | * If target is not in a MAPPED state, delay the reset until |
@@ -1065,7 +1048,6 @@ out_free_scsi_buf: | |||
1065 | 1048 | ||
1066 | out: | 1049 | out: |
1067 | spin_unlock_irq(shost->host_lock); | 1050 | spin_unlock_irq(shost->host_lock); |
1068 | lpfc_unblock_requests(phba); | ||
1069 | return ret; | 1051 | return ret; |
1070 | } | 1052 | } |
1071 | 1053 | ||
@@ -1080,7 +1062,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1080 | int cnt, loopcnt; | 1062 | int cnt, loopcnt; |
1081 | struct lpfc_scsi_buf * lpfc_cmd; | 1063 | struct lpfc_scsi_buf * lpfc_cmd; |
1082 | 1064 | ||
1083 | lpfc_block_requests(phba); | ||
1084 | spin_lock_irq(shost->host_lock); | 1065 | spin_lock_irq(shost->host_lock); |
1085 | 1066 | ||
1086 | lpfc_cmd = lpfc_get_scsi_buf(phba); | 1067 | lpfc_cmd = lpfc_get_scsi_buf(phba); |
@@ -1163,7 +1144,6 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
1163 | phba->brd_no, ret); | 1144 | phba->brd_no, ret); |
1164 | out: | 1145 | out: |
1165 | spin_unlock_irq(shost->host_lock); | 1146 | spin_unlock_irq(shost->host_lock); |
1166 | lpfc_unblock_requests(phba); | ||
1167 | return ret; | 1147 | return ret; |
1168 | } | 1148 | } |
1169 | 1149 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 0c9516ff636f..3e6f9feaf69d 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * 2 of the License, or (at your option) any later version. | 10 | * 2 of the License, or (at your option) any later version. |
11 | * | 11 | * |
12 | * FILE : megaraid_sas.c | 12 | * FILE : megaraid_sas.c |
13 | * Version : v00.00.02.04 | 13 | * Version : v00.00.03.01 |
14 | * | 14 | * |
15 | * Authors: | 15 | * Authors: |
16 | * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> | 16 | * Sreenivas Bagalkote <Sreenivas.Bagalkote@lsil.com> |
@@ -55,19 +55,25 @@ static struct pci_device_id megasas_pci_table[] = { | |||
55 | 55 | ||
56 | { | 56 | { |
57 | PCI_VENDOR_ID_LSI_LOGIC, | 57 | PCI_VENDOR_ID_LSI_LOGIC, |
58 | PCI_DEVICE_ID_LSI_SAS1064R, // xscale IOP | 58 | PCI_DEVICE_ID_LSI_SAS1064R, /* xscale IOP */ |
59 | PCI_ANY_ID, | 59 | PCI_ANY_ID, |
60 | PCI_ANY_ID, | 60 | PCI_ANY_ID, |
61 | }, | 61 | }, |
62 | { | 62 | { |
63 | PCI_VENDOR_ID_LSI_LOGIC, | 63 | PCI_VENDOR_ID_LSI_LOGIC, |
64 | PCI_DEVICE_ID_LSI_SAS1078R, // ppc IOP | 64 | PCI_DEVICE_ID_LSI_SAS1078R, /* ppc IOP */ |
65 | PCI_ANY_ID, | 65 | PCI_ANY_ID, |
66 | PCI_ANY_ID, | 66 | PCI_ANY_ID, |
67 | }, | 67 | }, |
68 | { | 68 | { |
69 | PCI_VENDOR_ID_LSI_LOGIC, | ||
70 | PCI_DEVICE_ID_LSI_VERDE_ZCR, /* xscale IOP, vega */ | ||
71 | PCI_ANY_ID, | ||
72 | PCI_ANY_ID, | ||
73 | }, | ||
74 | { | ||
69 | PCI_VENDOR_ID_DELL, | 75 | PCI_VENDOR_ID_DELL, |
70 | PCI_DEVICE_ID_DELL_PERC5, // xscale IOP | 76 | PCI_DEVICE_ID_DELL_PERC5, /* xscale IOP */ |
71 | PCI_ANY_ID, | 77 | PCI_ANY_ID, |
72 | PCI_ANY_ID, | 78 | PCI_ANY_ID, |
73 | }, | 79 | }, |
@@ -289,9 +295,14 @@ static struct megasas_instance_template megasas_instance_template_ppc = { | |||
289 | * @regs: MFI register set | 295 | * @regs: MFI register set |
290 | */ | 296 | */ |
291 | static inline void | 297 | static inline void |
292 | megasas_disable_intr(struct megasas_register_set __iomem * regs) | 298 | megasas_disable_intr(struct megasas_instance *instance) |
293 | { | 299 | { |
294 | u32 mask = 0x1f; | 300 | u32 mask = 0x1f; |
301 | struct megasas_register_set __iomem *regs = instance->reg_set; | ||
302 | |||
303 | if(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078R) | ||
304 | mask = 0xffffffff; | ||
305 | |||
295 | writel(mask, ®s->outbound_intr_mask); | 306 | writel(mask, ®s->outbound_intr_mask); |
296 | 307 | ||
297 | /* Dummy readl to force pci flush */ | 308 | /* Dummy readl to force pci flush */ |
@@ -1260,7 +1271,7 @@ megasas_transition_to_ready(struct megasas_instance* instance) | |||
1260 | /* | 1271 | /* |
1261 | * Bring it to READY state; assuming max wait 2 secs | 1272 | * Bring it to READY state; assuming max wait 2 secs |
1262 | */ | 1273 | */ |
1263 | megasas_disable_intr(instance->reg_set); | 1274 | megasas_disable_intr(instance); |
1264 | writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); | 1275 | writel(MFI_INIT_READY, &instance->reg_set->inbound_doorbell); |
1265 | 1276 | ||
1266 | max_wait = 10; | 1277 | max_wait = 10; |
@@ -1757,6 +1768,11 @@ static int megasas_init_mfi(struct megasas_instance *instance) | |||
1757 | init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); | 1768 | init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info); |
1758 | 1769 | ||
1759 | /* | 1770 | /* |
1771 | * disable the intr before firing the init frame to FW | ||
1772 | */ | ||
1773 | megasas_disable_intr(instance); | ||
1774 | |||
1775 | /* | ||
1760 | * Issue the init frame in polled mode | 1776 | * Issue the init frame in polled mode |
1761 | */ | 1777 | */ |
1762 | if (megasas_issue_polled(instance, cmd)) { | 1778 | if (megasas_issue_polled(instance, cmd)) { |
@@ -2234,7 +2250,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2234 | megasas_mgmt_info.max_index--; | 2250 | megasas_mgmt_info.max_index--; |
2235 | 2251 | ||
2236 | pci_set_drvdata(pdev, NULL); | 2252 | pci_set_drvdata(pdev, NULL); |
2237 | megasas_disable_intr(instance->reg_set); | 2253 | megasas_disable_intr(instance); |
2238 | free_irq(instance->pdev->irq, instance); | 2254 | free_irq(instance->pdev->irq, instance); |
2239 | 2255 | ||
2240 | megasas_release_mfi(instance); | 2256 | megasas_release_mfi(instance); |
@@ -2364,7 +2380,7 @@ static void megasas_detach_one(struct pci_dev *pdev) | |||
2364 | 2380 | ||
2365 | pci_set_drvdata(instance->pdev, NULL); | 2381 | pci_set_drvdata(instance->pdev, NULL); |
2366 | 2382 | ||
2367 | megasas_disable_intr(instance->reg_set); | 2383 | megasas_disable_intr(instance); |
2368 | 2384 | ||
2369 | free_irq(instance->pdev->irq, instance); | 2385 | free_irq(instance->pdev->irq, instance); |
2370 | 2386 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 927d6ffef05f..3531a14222a7 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -18,9 +18,16 @@ | |||
18 | /** | 18 | /** |
19 | * MegaRAID SAS Driver meta data | 19 | * MegaRAID SAS Driver meta data |
20 | */ | 20 | */ |
21 | #define MEGASAS_VERSION "00.00.02.04" | 21 | #define MEGASAS_VERSION "00.00.03.01" |
22 | #define MEGASAS_RELDATE "Feb 03, 2006" | 22 | #define MEGASAS_RELDATE "May 14, 2006" |
23 | #define MEGASAS_EXT_VERSION "Fri Feb 03 14:31:44 PST 2006" | 23 | #define MEGASAS_EXT_VERSION "Sun May 14 22:49:52 PDT 2006" |
24 | |||
25 | /* | ||
26 | * Device IDs | ||
27 | */ | ||
28 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 | ||
29 | #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 | ||
30 | |||
24 | /* | 31 | /* |
25 | * ===================================== | 32 | * ===================================== |
26 | * MegaRAID SAS MFI firmware definitions | 33 | * MegaRAID SAS MFI firmware definitions |
@@ -554,7 +561,11 @@ struct megasas_ctrl_info { | |||
554 | #define MFI_POLL_TIMEOUT_SECS 10 | 561 | #define MFI_POLL_TIMEOUT_SECS 10 |
555 | 562 | ||
556 | #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 | 563 | #define MFI_REPLY_1078_MESSAGE_INTERRUPT 0x80000000 |
557 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x00000060 | 564 | |
565 | /* | ||
566 | * register set for both 1068 and 1078 controllers | ||
567 | * structure extended for 1078 registers | ||
568 | */ | ||
558 | 569 | ||
559 | struct megasas_register_set { | 570 | struct megasas_register_set { |
560 | u32 reserved_0[4]; /*0000h*/ | 571 | u32 reserved_0[4]; /*0000h*/ |
@@ -1150,10 +1161,10 @@ struct compat_megasas_iocpacket { | |||
1150 | struct compat_iovec sgl[MAX_IOCTL_SGE]; | 1161 | struct compat_iovec sgl[MAX_IOCTL_SGE]; |
1151 | } __attribute__ ((packed)); | 1162 | } __attribute__ ((packed)); |
1152 | 1163 | ||
1164 | #define MEGASAS_IOC_FIRMWARE32 _IOWR('M', 1, struct compat_megasas_iocpacket) | ||
1153 | #endif | 1165 | #endif |
1154 | 1166 | ||
1155 | #define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket) | 1167 | #define MEGASAS_IOC_FIRMWARE _IOWR('M', 1, struct megasas_iocpacket) |
1156 | #define MEGASAS_IOC_FIRMWARE32 _IOWR('M', 1, struct compat_megasas_iocpacket) | ||
1157 | #define MEGASAS_IOC_GET_AEN _IOW('M', 3, struct megasas_aen) | 1168 | #define MEGASAS_IOC_GET_AEN _IOW('M', 3, struct megasas_aen) |
1158 | 1169 | ||
1159 | struct megasas_mgmt_info { | 1170 | struct megasas_mgmt_info { |
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 5c55e152e718..4190788f14be 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c | |||
@@ -2866,8 +2866,7 @@ static int nsp32_detect(struct scsi_host_template *sht) | |||
2866 | */ | 2866 | */ |
2867 | nsp32_do_bus_reset(data); | 2867 | nsp32_do_bus_reset(data); |
2868 | 2868 | ||
2869 | ret = request_irq(host->irq, do_nsp32_isr, | 2869 | ret = request_irq(host->irq, do_nsp32_isr, SA_SHIRQ, "nsp32", data); |
2870 | SA_SHIRQ | SA_SAMPLE_RANDOM, "nsp32", data); | ||
2871 | if (ret < 0) { | 2870 | if (ret < 0) { |
2872 | nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NinjaSCSI32 " | 2871 | nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NinjaSCSI32 " |
2873 | "SCSI PCI controller. Interrupt: %d", host->irq); | 2872 | "SCSI PCI controller. Interrupt: %d", host->irq); |
@@ -2886,12 +2885,19 @@ static int nsp32_detect(struct scsi_host_template *sht) | |||
2886 | } | 2885 | } |
2887 | 2886 | ||
2888 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) | 2887 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) |
2889 | scsi_add_host (host, &PCIDEV->dev); | 2888 | ret = scsi_add_host(host, &PCIDEV->dev); |
2889 | if (ret) { | ||
2890 | nsp32_msg(KERN_ERR, "failed to add scsi host"); | ||
2891 | goto free_region; | ||
2892 | } | ||
2890 | scsi_scan_host(host); | 2893 | scsi_scan_host(host); |
2891 | #endif | 2894 | #endif |
2892 | pci_set_drvdata(PCIDEV, host); | 2895 | pci_set_drvdata(PCIDEV, host); |
2893 | return DETECT_OK; | 2896 | return DETECT_OK; |
2894 | 2897 | ||
2898 | free_region: | ||
2899 | release_region(host->io_port, host->n_io_port); | ||
2900 | |||
2895 | free_irq: | 2901 | free_irq: |
2896 | free_irq(host->irq, data); | 2902 | free_irq(host->irq, data); |
2897 | 2903 | ||
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 231f9c311c69..bb81218b8d19 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -1623,7 +1623,7 @@ static int nsp_cs_probe(struct pcmcia_device *link) | |||
1623 | /* Interrupt handler */ | 1623 | /* Interrupt handler */ |
1624 | link->irq.Handler = &nspintr; | 1624 | link->irq.Handler = &nspintr; |
1625 | link->irq.Instance = info; | 1625 | link->irq.Instance = info; |
1626 | link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM); | 1626 | link->irq.Attributes |= SA_SHIRQ; |
1627 | 1627 | ||
1628 | /* General socket configuration */ | 1628 | /* General socket configuration */ |
1629 | link->conf.Attributes = CONF_ENABLE_IRQ; | 1629 | link->conf.Attributes = CONF_ENABLE_IRQ; |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index e96d58ded57c..87f90c4f08e9 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -16,15 +16,16 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
16 | { | 16 | { |
17 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 17 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, |
18 | struct device, kobj))); | 18 | struct device, kobj))); |
19 | char *rbuf = (char *)ha->fw_dump; | ||
19 | 20 | ||
20 | if (ha->fw_dump_reading == 0) | 21 | if (ha->fw_dump_reading == 0) |
21 | return 0; | 22 | return 0; |
22 | if (off > ha->fw_dump_buffer_len) | 23 | if (off > ha->fw_dump_len) |
23 | return 0; | 24 | return 0; |
24 | if (off + count > ha->fw_dump_buffer_len) | 25 | if (off + count > ha->fw_dump_len) |
25 | count = ha->fw_dump_buffer_len - off; | 26 | count = ha->fw_dump_len - off; |
26 | 27 | ||
27 | memcpy(buf, &ha->fw_dump_buffer[off], count); | 28 | memcpy(buf, &rbuf[off], count); |
28 | 29 | ||
29 | return (count); | 30 | return (count); |
30 | } | 31 | } |
@@ -36,7 +37,6 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
36 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 37 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, |
37 | struct device, kobj))); | 38 | struct device, kobj))); |
38 | int reading; | 39 | int reading; |
39 | uint32_t dump_size; | ||
40 | 40 | ||
41 | if (off != 0) | 41 | if (off != 0) |
42 | return (0); | 42 | return (0); |
@@ -44,46 +44,27 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, | |||
44 | reading = simple_strtol(buf, NULL, 10); | 44 | reading = simple_strtol(buf, NULL, 10); |
45 | switch (reading) { | 45 | switch (reading) { |
46 | case 0: | 46 | case 0: |
47 | if (ha->fw_dump_reading == 1) { | 47 | if (!ha->fw_dump_reading) |
48 | qla_printk(KERN_INFO, ha, | 48 | break; |
49 | "Firmware dump cleared on (%ld).\n", ha->host_no); | ||
50 | 49 | ||
51 | vfree(ha->fw_dump_buffer); | 50 | qla_printk(KERN_INFO, ha, |
52 | ha->fw_dump_buffer = NULL; | 51 | "Firmware dump cleared on (%ld).\n", ha->host_no); |
53 | ha->fw_dump_reading = 0; | 52 | |
54 | ha->fw_dumped = 0; | 53 | ha->fw_dump_reading = 0; |
55 | } | 54 | ha->fw_dumped = 0; |
56 | break; | 55 | break; |
57 | case 1: | 56 | case 1: |
58 | if (ha->fw_dumped && !ha->fw_dump_reading) { | 57 | if (ha->fw_dumped && !ha->fw_dump_reading) { |
59 | ha->fw_dump_reading = 1; | 58 | ha->fw_dump_reading = 1; |
60 | 59 | ||
61 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | ||
62 | dump_size = FW_DUMP_SIZE_24XX; | ||
63 | else { | ||
64 | dump_size = FW_DUMP_SIZE_1M; | ||
65 | if (ha->fw_memory_size < 0x20000) | ||
66 | dump_size = FW_DUMP_SIZE_128K; | ||
67 | else if (ha->fw_memory_size < 0x80000) | ||
68 | dump_size = FW_DUMP_SIZE_512K; | ||
69 | } | ||
70 | ha->fw_dump_buffer = (char *)vmalloc(dump_size); | ||
71 | if (ha->fw_dump_buffer == NULL) { | ||
72 | qla_printk(KERN_WARNING, ha, | ||
73 | "Unable to allocate memory for firmware " | ||
74 | "dump buffer (%d).\n", dump_size); | ||
75 | |||
76 | ha->fw_dump_reading = 0; | ||
77 | return (count); | ||
78 | } | ||
79 | qla_printk(KERN_INFO, ha, | 60 | qla_printk(KERN_INFO, ha, |
80 | "Firmware dump ready for read on (%ld).\n", | 61 | "Raw firmware dump ready for read on (%ld).\n", |
81 | ha->host_no); | 62 | ha->host_no); |
82 | memset(ha->fw_dump_buffer, 0, dump_size); | ||
83 | ha->isp_ops.ascii_fw_dump(ha); | ||
84 | ha->fw_dump_buffer_len = strlen(ha->fw_dump_buffer); | ||
85 | } | 63 | } |
86 | break; | 64 | break; |
65 | case 2: | ||
66 | qla2x00_alloc_fw_dump(ha); | ||
67 | break; | ||
87 | } | 68 | } |
88 | return (count); | 69 | return (count); |
89 | } | 70 | } |
@@ -313,9 +294,6 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off, | |||
313 | if (!capable(CAP_SYS_ADMIN) || off != 0) | 294 | if (!capable(CAP_SYS_ADMIN) || off != 0) |
314 | return 0; | 295 | return 0; |
315 | 296 | ||
316 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
317 | return -ENOTSUPP; | ||
318 | |||
319 | /* Read NVRAM. */ | 297 | /* Read NVRAM. */ |
320 | spin_lock_irqsave(&ha->hardware_lock, flags); | 298 | spin_lock_irqsave(&ha->hardware_lock, flags); |
321 | ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size); | 299 | ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size); |
@@ -335,9 +313,6 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off, | |||
335 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) | 313 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) |
336 | return 0; | 314 | return 0; |
337 | 315 | ||
338 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
339 | return -ENOTSUPP; | ||
340 | |||
341 | /* Write NVRAM. */ | 316 | /* Write NVRAM. */ |
342 | spin_lock_irqsave(&ha->hardware_lock, flags); | 317 | spin_lock_irqsave(&ha->hardware_lock, flags); |
343 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); | 318 | ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); |
@@ -357,6 +332,53 @@ static struct bin_attribute sysfs_vpd_attr = { | |||
357 | .write = qla2x00_sysfs_write_vpd, | 332 | .write = qla2x00_sysfs_write_vpd, |
358 | }; | 333 | }; |
359 | 334 | ||
335 | static ssize_t | ||
336 | qla2x00_sysfs_read_sfp(struct kobject *kobj, char *buf, loff_t off, | ||
337 | size_t count) | ||
338 | { | ||
339 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | ||
340 | struct device, kobj))); | ||
341 | uint16_t iter, addr, offset; | ||
342 | int rval; | ||
343 | |||
344 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2) | ||
345 | return 0; | ||
346 | |||
347 | addr = 0xa0; | ||
348 | for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE; | ||
349 | iter++, offset += SFP_BLOCK_SIZE) { | ||
350 | if (iter == 4) { | ||
351 | /* Skip to next device address. */ | ||
352 | addr = 0xa2; | ||
353 | offset = 0; | ||
354 | } | ||
355 | |||
356 | rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset, | ||
357 | SFP_BLOCK_SIZE); | ||
358 | if (rval != QLA_SUCCESS) { | ||
359 | qla_printk(KERN_WARNING, ha, | ||
360 | "Unable to read SFP data (%x/%x/%x).\n", rval, | ||
361 | addr, offset); | ||
362 | count = 0; | ||
363 | break; | ||
364 | } | ||
365 | memcpy(buf, ha->sfp_data, SFP_BLOCK_SIZE); | ||
366 | buf += SFP_BLOCK_SIZE; | ||
367 | } | ||
368 | |||
369 | return count; | ||
370 | } | ||
371 | |||
372 | static struct bin_attribute sysfs_sfp_attr = { | ||
373 | .attr = { | ||
374 | .name = "sfp", | ||
375 | .mode = S_IRUSR | S_IWUSR, | ||
376 | .owner = THIS_MODULE, | ||
377 | }, | ||
378 | .size = SFP_DEV_SIZE * 2, | ||
379 | .read = qla2x00_sysfs_read_sfp, | ||
380 | }; | ||
381 | |||
360 | void | 382 | void |
361 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | 383 | qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) |
362 | { | 384 | { |
@@ -367,7 +389,12 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) | |||
367 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | 389 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); |
368 | sysfs_create_bin_file(&host->shost_gendev.kobj, | 390 | sysfs_create_bin_file(&host->shost_gendev.kobj, |
369 | &sysfs_optrom_ctl_attr); | 391 | &sysfs_optrom_ctl_attr); |
370 | sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); | 392 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
393 | sysfs_create_bin_file(&host->shost_gendev.kobj, | ||
394 | &sysfs_vpd_attr); | ||
395 | sysfs_create_bin_file(&host->shost_gendev.kobj, | ||
396 | &sysfs_sfp_attr); | ||
397 | } | ||
371 | } | 398 | } |
372 | 399 | ||
373 | void | 400 | void |
@@ -380,7 +407,12 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) | |||
380 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); | 407 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); |
381 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | 408 | sysfs_remove_bin_file(&host->shost_gendev.kobj, |
382 | &sysfs_optrom_ctl_attr); | 409 | &sysfs_optrom_ctl_attr); |
383 | sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_vpd_attr); | 410 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
411 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | ||
412 | &sysfs_vpd_attr); | ||
413 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | ||
414 | &sysfs_sfp_attr); | ||
415 | } | ||
384 | 416 | ||
385 | if (ha->beacon_blink_led == 1) | 417 | if (ha->beacon_blink_led == 1) |
386 | ha->isp_ops.beacon_off(ha); | 418 | ha->isp_ops.beacon_off(ha); |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 74e54713aa7c..f6ed6962bc2b 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -8,7 +8,34 @@ | |||
8 | 8 | ||
9 | #include <linux/delay.h> | 9 | #include <linux/delay.h> |
10 | 10 | ||
11 | static int qla_uprintf(char **, char *, ...); | 11 | static inline void |
12 | qla2xxx_prep_dump(scsi_qla_host_t *ha, struct qla2xxx_fw_dump *fw_dump) | ||
13 | { | ||
14 | fw_dump->fw_major_version = htonl(ha->fw_major_version); | ||
15 | fw_dump->fw_minor_version = htonl(ha->fw_minor_version); | ||
16 | fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version); | ||
17 | fw_dump->fw_attributes = htonl(ha->fw_attributes); | ||
18 | |||
19 | fw_dump->vendor = htonl(ha->pdev->vendor); | ||
20 | fw_dump->device = htonl(ha->pdev->device); | ||
21 | fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor); | ||
22 | fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device); | ||
23 | } | ||
24 | |||
25 | static inline void * | ||
26 | qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr) | ||
27 | { | ||
28 | /* Request queue. */ | ||
29 | memcpy(ptr, ha->request_ring, ha->request_q_length * | ||
30 | sizeof(request_t)); | ||
31 | |||
32 | /* Response queue. */ | ||
33 | ptr += ha->request_q_length * sizeof(request_t); | ||
34 | memcpy(ptr, ha->response_ring, ha->response_q_length * | ||
35 | sizeof(response_t)); | ||
36 | |||
37 | return ptr + (ha->response_q_length * sizeof(response_t)); | ||
38 | } | ||
12 | 39 | ||
13 | /** | 40 | /** |
14 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. | 41 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. |
@@ -49,10 +76,11 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
49 | "request...\n", ha->fw_dump); | 76 | "request...\n", ha->fw_dump); |
50 | goto qla2300_fw_dump_failed; | 77 | goto qla2300_fw_dump_failed; |
51 | } | 78 | } |
52 | fw = ha->fw_dump; | 79 | fw = &ha->fw_dump->isp.isp23; |
80 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
53 | 81 | ||
54 | rval = QLA_SUCCESS; | 82 | rval = QLA_SUCCESS; |
55 | fw->hccr = RD_REG_WORD(®->hccr); | 83 | fw->hccr = htons(RD_REG_WORD(®->hccr)); |
56 | 84 | ||
57 | /* Pause RISC. */ | 85 | /* Pause RISC. */ |
58 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); | 86 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); |
@@ -73,85 +101,86 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
73 | if (rval == QLA_SUCCESS) { | 101 | if (rval == QLA_SUCCESS) { |
74 | dmp_reg = (uint16_t __iomem *)(reg + 0); | 102 | dmp_reg = (uint16_t __iomem *)(reg + 0); |
75 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) | 103 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) |
76 | fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++); | 104 | fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
77 | 105 | ||
78 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); | 106 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); |
79 | for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) | 107 | for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) |
80 | fw->risc_host_reg[cnt] = RD_REG_WORD(dmp_reg++); | 108 | fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
81 | 109 | ||
82 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40); | 110 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40); |
83 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | 111 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) |
84 | fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++); | 112 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
85 | 113 | ||
86 | WRT_REG_WORD(®->ctrl_status, 0x40); | 114 | WRT_REG_WORD(®->ctrl_status, 0x40); |
87 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 115 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
88 | for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++) | 116 | for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++) |
89 | fw->resp_dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | 117 | fw->resp_dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
90 | 118 | ||
91 | WRT_REG_WORD(®->ctrl_status, 0x50); | 119 | WRT_REG_WORD(®->ctrl_status, 0x50); |
92 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 120 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
93 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) | 121 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) |
94 | fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | 122 | fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
95 | 123 | ||
96 | WRT_REG_WORD(®->ctrl_status, 0x00); | 124 | WRT_REG_WORD(®->ctrl_status, 0x00); |
97 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); | 125 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); |
98 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) | 126 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) |
99 | fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 127 | fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
100 | 128 | ||
101 | WRT_REG_WORD(®->pcr, 0x2000); | 129 | WRT_REG_WORD(®->pcr, 0x2000); |
102 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 130 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
103 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) | 131 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) |
104 | fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 132 | fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
105 | 133 | ||
106 | WRT_REG_WORD(®->pcr, 0x2200); | 134 | WRT_REG_WORD(®->pcr, 0x2200); |
107 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 135 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
108 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) | 136 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) |
109 | fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 137 | fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
110 | 138 | ||
111 | WRT_REG_WORD(®->pcr, 0x2400); | 139 | WRT_REG_WORD(®->pcr, 0x2400); |
112 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 140 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
113 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) | 141 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) |
114 | fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++); | 142 | fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
115 | 143 | ||
116 | WRT_REG_WORD(®->pcr, 0x2600); | 144 | WRT_REG_WORD(®->pcr, 0x2600); |
117 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 145 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
118 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) | 146 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) |
119 | fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++); | 147 | fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
120 | 148 | ||
121 | WRT_REG_WORD(®->pcr, 0x2800); | 149 | WRT_REG_WORD(®->pcr, 0x2800); |
122 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 150 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
123 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) | 151 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) |
124 | fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++); | 152 | fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
125 | 153 | ||
126 | WRT_REG_WORD(®->pcr, 0x2A00); | 154 | WRT_REG_WORD(®->pcr, 0x2A00); |
127 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 155 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
128 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) | 156 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) |
129 | fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++); | 157 | fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
130 | 158 | ||
131 | WRT_REG_WORD(®->pcr, 0x2C00); | 159 | WRT_REG_WORD(®->pcr, 0x2C00); |
132 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 160 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
133 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) | 161 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) |
134 | fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++); | 162 | fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
135 | 163 | ||
136 | WRT_REG_WORD(®->pcr, 0x2E00); | 164 | WRT_REG_WORD(®->pcr, 0x2E00); |
137 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 165 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
138 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) | 166 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) |
139 | fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++); | 167 | fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
140 | 168 | ||
141 | WRT_REG_WORD(®->ctrl_status, 0x10); | 169 | WRT_REG_WORD(®->ctrl_status, 0x10); |
142 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 170 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
143 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) | 171 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) |
144 | fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 172 | fw->frame_buf_hdw_reg[cnt] = |
173 | htons(RD_REG_WORD(dmp_reg++)); | ||
145 | 174 | ||
146 | WRT_REG_WORD(®->ctrl_status, 0x20); | 175 | WRT_REG_WORD(®->ctrl_status, 0x20); |
147 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 176 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
148 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) | 177 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) |
149 | fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 178 | fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
150 | 179 | ||
151 | WRT_REG_WORD(®->ctrl_status, 0x30); | 180 | WRT_REG_WORD(®->ctrl_status, 0x30); |
152 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 181 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
153 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) | 182 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) |
154 | fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 183 | fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
155 | 184 | ||
156 | /* Reset RISC. */ | 185 | /* Reset RISC. */ |
157 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | 186 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); |
@@ -226,7 +255,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
226 | 255 | ||
227 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 256 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
228 | rval = mb0 & MBS_MASK; | 257 | rval = mb0 & MBS_MASK; |
229 | fw->risc_ram[cnt] = mb2; | 258 | fw->risc_ram[cnt] = htons(mb2); |
230 | } else { | 259 | } else { |
231 | rval = QLA_FUNCTION_FAILED; | 260 | rval = QLA_FUNCTION_FAILED; |
232 | } | 261 | } |
@@ -285,7 +314,7 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
285 | 314 | ||
286 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 315 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
287 | rval = mb0 & MBS_MASK; | 316 | rval = mb0 & MBS_MASK; |
288 | fw->stack_ram[cnt] = mb2; | 317 | fw->stack_ram[cnt] = htons(mb2); |
289 | } else { | 318 | } else { |
290 | rval = QLA_FUNCTION_FAILED; | 319 | rval = QLA_FUNCTION_FAILED; |
291 | } | 320 | } |
@@ -345,12 +374,15 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
345 | 374 | ||
346 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 375 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
347 | rval = mb0 & MBS_MASK; | 376 | rval = mb0 & MBS_MASK; |
348 | fw->data_ram[cnt] = mb2; | 377 | fw->data_ram[cnt] = htons(mb2); |
349 | } else { | 378 | } else { |
350 | rval = QLA_FUNCTION_FAILED; | 379 | rval = QLA_FUNCTION_FAILED; |
351 | } | 380 | } |
352 | } | 381 | } |
353 | 382 | ||
383 | if (rval == QLA_SUCCESS) | ||
384 | qla2xxx_copy_queues(ha, &fw->data_ram[cnt]); | ||
385 | |||
354 | if (rval != QLA_SUCCESS) { | 386 | if (rval != QLA_SUCCESS) { |
355 | qla_printk(KERN_WARNING, ha, | 387 | qla_printk(KERN_WARNING, ha, |
356 | "Failed to dump firmware (%x)!!!\n", rval); | 388 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -369,193 +401,6 @@ qla2300_fw_dump_failed: | |||
369 | } | 401 | } |
370 | 402 | ||
371 | /** | 403 | /** |
372 | * qla2300_ascii_fw_dump() - Converts a binary firmware dump to ASCII. | ||
373 | * @ha: HA context | ||
374 | */ | ||
375 | void | ||
376 | qla2300_ascii_fw_dump(scsi_qla_host_t *ha) | ||
377 | { | ||
378 | uint32_t cnt; | ||
379 | char *uiter; | ||
380 | char fw_info[30]; | ||
381 | struct qla2300_fw_dump *fw; | ||
382 | uint32_t data_ram_cnt; | ||
383 | |||
384 | uiter = ha->fw_dump_buffer; | ||
385 | fw = ha->fw_dump; | ||
386 | |||
387 | qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number, | ||
388 | ha->isp_ops.fw_version_str(ha, fw_info)); | ||
389 | |||
390 | qla_uprintf(&uiter, "\n[==>BEG]\n"); | ||
391 | |||
392 | qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr); | ||
393 | |||
394 | qla_uprintf(&uiter, "PBIU Registers:"); | ||
395 | for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) { | ||
396 | if (cnt % 8 == 0) { | ||
397 | qla_uprintf(&uiter, "\n"); | ||
398 | } | ||
399 | qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]); | ||
400 | } | ||
401 | |||
402 | qla_uprintf(&uiter, "\n\nReqQ-RspQ-Risc2Host Status registers:"); | ||
403 | for (cnt = 0; cnt < sizeof (fw->risc_host_reg) / 2; cnt++) { | ||
404 | if (cnt % 8 == 0) { | ||
405 | qla_uprintf(&uiter, "\n"); | ||
406 | } | ||
407 | qla_uprintf(&uiter, "%04x ", fw->risc_host_reg[cnt]); | ||
408 | } | ||
409 | |||
410 | qla_uprintf(&uiter, "\n\nMailbox Registers:"); | ||
411 | for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) { | ||
412 | if (cnt % 8 == 0) { | ||
413 | qla_uprintf(&uiter, "\n"); | ||
414 | } | ||
415 | qla_uprintf(&uiter, "%04x ", fw->mailbox_reg[cnt]); | ||
416 | } | ||
417 | |||
418 | qla_uprintf(&uiter, "\n\nAuto Request Response DMA Registers:"); | ||
419 | for (cnt = 0; cnt < sizeof (fw->resp_dma_reg) / 2; cnt++) { | ||
420 | if (cnt % 8 == 0) { | ||
421 | qla_uprintf(&uiter, "\n"); | ||
422 | } | ||
423 | qla_uprintf(&uiter, "%04x ", fw->resp_dma_reg[cnt]); | ||
424 | } | ||
425 | |||
426 | qla_uprintf(&uiter, "\n\nDMA Registers:"); | ||
427 | for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) { | ||
428 | if (cnt % 8 == 0) { | ||
429 | qla_uprintf(&uiter, "\n"); | ||
430 | } | ||
431 | qla_uprintf(&uiter, "%04x ", fw->dma_reg[cnt]); | ||
432 | } | ||
433 | |||
434 | qla_uprintf(&uiter, "\n\nRISC Hardware Registers:"); | ||
435 | for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) { | ||
436 | if (cnt % 8 == 0) { | ||
437 | qla_uprintf(&uiter, "\n"); | ||
438 | } | ||
439 | qla_uprintf(&uiter, "%04x ", fw->risc_hdw_reg[cnt]); | ||
440 | } | ||
441 | |||
442 | qla_uprintf(&uiter, "\n\nRISC GP0 Registers:"); | ||
443 | for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) { | ||
444 | if (cnt % 8 == 0) { | ||
445 | qla_uprintf(&uiter, "\n"); | ||
446 | } | ||
447 | qla_uprintf(&uiter, "%04x ", fw->risc_gp0_reg[cnt]); | ||
448 | } | ||
449 | |||
450 | qla_uprintf(&uiter, "\n\nRISC GP1 Registers:"); | ||
451 | for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) { | ||
452 | if (cnt % 8 == 0) { | ||
453 | qla_uprintf(&uiter, "\n"); | ||
454 | } | ||
455 | qla_uprintf(&uiter, "%04x ", fw->risc_gp1_reg[cnt]); | ||
456 | } | ||
457 | |||
458 | qla_uprintf(&uiter, "\n\nRISC GP2 Registers:"); | ||
459 | for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) { | ||
460 | if (cnt % 8 == 0) { | ||
461 | qla_uprintf(&uiter, "\n"); | ||
462 | } | ||
463 | qla_uprintf(&uiter, "%04x ", fw->risc_gp2_reg[cnt]); | ||
464 | } | ||
465 | |||
466 | qla_uprintf(&uiter, "\n\nRISC GP3 Registers:"); | ||
467 | for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) { | ||
468 | if (cnt % 8 == 0) { | ||
469 | qla_uprintf(&uiter, "\n"); | ||
470 | } | ||
471 | qla_uprintf(&uiter, "%04x ", fw->risc_gp3_reg[cnt]); | ||
472 | } | ||
473 | |||
474 | qla_uprintf(&uiter, "\n\nRISC GP4 Registers:"); | ||
475 | for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) { | ||
476 | if (cnt % 8 == 0) { | ||
477 | qla_uprintf(&uiter, "\n"); | ||
478 | } | ||
479 | qla_uprintf(&uiter, "%04x ", fw->risc_gp4_reg[cnt]); | ||
480 | } | ||
481 | |||
482 | qla_uprintf(&uiter, "\n\nRISC GP5 Registers:"); | ||
483 | for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) { | ||
484 | if (cnt % 8 == 0) { | ||
485 | qla_uprintf(&uiter, "\n"); | ||
486 | } | ||
487 | qla_uprintf(&uiter, "%04x ", fw->risc_gp5_reg[cnt]); | ||
488 | } | ||
489 | |||
490 | qla_uprintf(&uiter, "\n\nRISC GP6 Registers:"); | ||
491 | for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) { | ||
492 | if (cnt % 8 == 0) { | ||
493 | qla_uprintf(&uiter, "\n"); | ||
494 | } | ||
495 | qla_uprintf(&uiter, "%04x ", fw->risc_gp6_reg[cnt]); | ||
496 | } | ||
497 | |||
498 | qla_uprintf(&uiter, "\n\nRISC GP7 Registers:"); | ||
499 | for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) { | ||
500 | if (cnt % 8 == 0) { | ||
501 | qla_uprintf(&uiter, "\n"); | ||
502 | } | ||
503 | qla_uprintf(&uiter, "%04x ", fw->risc_gp7_reg[cnt]); | ||
504 | } | ||
505 | |||
506 | qla_uprintf(&uiter, "\n\nFrame Buffer Hardware Registers:"); | ||
507 | for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) { | ||
508 | if (cnt % 8 == 0) { | ||
509 | qla_uprintf(&uiter, "\n"); | ||
510 | } | ||
511 | qla_uprintf(&uiter, "%04x ", fw->frame_buf_hdw_reg[cnt]); | ||
512 | } | ||
513 | |||
514 | qla_uprintf(&uiter, "\n\nFPM B0 Registers:"); | ||
515 | for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) { | ||
516 | if (cnt % 8 == 0) { | ||
517 | qla_uprintf(&uiter, "\n"); | ||
518 | } | ||
519 | qla_uprintf(&uiter, "%04x ", fw->fpm_b0_reg[cnt]); | ||
520 | } | ||
521 | |||
522 | qla_uprintf(&uiter, "\n\nFPM B1 Registers:"); | ||
523 | for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) { | ||
524 | if (cnt % 8 == 0) { | ||
525 | qla_uprintf(&uiter, "\n"); | ||
526 | } | ||
527 | qla_uprintf(&uiter, "%04x ", fw->fpm_b1_reg[cnt]); | ||
528 | } | ||
529 | |||
530 | qla_uprintf(&uiter, "\n\nCode RAM Dump:"); | ||
531 | for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) { | ||
532 | if (cnt % 8 == 0) { | ||
533 | qla_uprintf(&uiter, "\n%04x: ", cnt + 0x0800); | ||
534 | } | ||
535 | qla_uprintf(&uiter, "%04x ", fw->risc_ram[cnt]); | ||
536 | } | ||
537 | |||
538 | qla_uprintf(&uiter, "\n\nStack RAM Dump:"); | ||
539 | for (cnt = 0; cnt < sizeof (fw->stack_ram) / 2; cnt++) { | ||
540 | if (cnt % 8 == 0) { | ||
541 | qla_uprintf(&uiter, "\n%05x: ", cnt + 0x10000); | ||
542 | } | ||
543 | qla_uprintf(&uiter, "%04x ", fw->stack_ram[cnt]); | ||
544 | } | ||
545 | |||
546 | qla_uprintf(&uiter, "\n\nData RAM Dump:"); | ||
547 | data_ram_cnt = ha->fw_memory_size - 0x11000 + 1; | ||
548 | for (cnt = 0; cnt < data_ram_cnt; cnt++) { | ||
549 | if (cnt % 8 == 0) { | ||
550 | qla_uprintf(&uiter, "\n%05x: ", cnt + 0x11000); | ||
551 | } | ||
552 | qla_uprintf(&uiter, "%04x ", fw->data_ram[cnt]); | ||
553 | } | ||
554 | |||
555 | qla_uprintf(&uiter, "\n\n[<==END] ISP Debug Dump."); | ||
556 | } | ||
557 | |||
558 | /** | ||
559 | * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. | 404 | * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. |
560 | * @ha: HA context | 405 | * @ha: HA context |
561 | * @hardware_locked: Called with the hardware_lock | 406 | * @hardware_locked: Called with the hardware_lock |
@@ -591,10 +436,11 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
591 | "request...\n", ha->fw_dump); | 436 | "request...\n", ha->fw_dump); |
592 | goto qla2100_fw_dump_failed; | 437 | goto qla2100_fw_dump_failed; |
593 | } | 438 | } |
594 | fw = ha->fw_dump; | 439 | fw = &ha->fw_dump->isp.isp21; |
440 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
595 | 441 | ||
596 | rval = QLA_SUCCESS; | 442 | rval = QLA_SUCCESS; |
597 | fw->hccr = RD_REG_WORD(®->hccr); | 443 | fw->hccr = htons(RD_REG_WORD(®->hccr)); |
598 | 444 | ||
599 | /* Pause RISC. */ | 445 | /* Pause RISC. */ |
600 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); | 446 | WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); |
@@ -608,79 +454,81 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
608 | if (rval == QLA_SUCCESS) { | 454 | if (rval == QLA_SUCCESS) { |
609 | dmp_reg = (uint16_t __iomem *)(reg + 0); | 455 | dmp_reg = (uint16_t __iomem *)(reg + 0); |
610 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) | 456 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) |
611 | fw->pbiu_reg[cnt] = RD_REG_WORD(dmp_reg++); | 457 | fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
612 | 458 | ||
613 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); | 459 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); |
614 | for (cnt = 0; cnt < ha->mbx_count; cnt++) { | 460 | for (cnt = 0; cnt < ha->mbx_count; cnt++) { |
615 | if (cnt == 8) { | 461 | if (cnt == 8) { |
616 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xe0); | 462 | dmp_reg = (uint16_t __iomem *) |
463 | ((uint8_t __iomem *)reg + 0xe0); | ||
617 | } | 464 | } |
618 | fw->mailbox_reg[cnt] = RD_REG_WORD(dmp_reg++); | 465 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
619 | } | 466 | } |
620 | 467 | ||
621 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20); | 468 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20); |
622 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) | 469 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) |
623 | fw->dma_reg[cnt] = RD_REG_WORD(dmp_reg++); | 470 | fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
624 | 471 | ||
625 | WRT_REG_WORD(®->ctrl_status, 0x00); | 472 | WRT_REG_WORD(®->ctrl_status, 0x00); |
626 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); | 473 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); |
627 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) | 474 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) |
628 | fw->risc_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 475 | fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
629 | 476 | ||
630 | WRT_REG_WORD(®->pcr, 0x2000); | 477 | WRT_REG_WORD(®->pcr, 0x2000); |
631 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 478 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
632 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) | 479 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) |
633 | fw->risc_gp0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 480 | fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
634 | 481 | ||
635 | WRT_REG_WORD(®->pcr, 0x2100); | 482 | WRT_REG_WORD(®->pcr, 0x2100); |
636 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 483 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
637 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) | 484 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) |
638 | fw->risc_gp1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 485 | fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
639 | 486 | ||
640 | WRT_REG_WORD(®->pcr, 0x2200); | 487 | WRT_REG_WORD(®->pcr, 0x2200); |
641 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 488 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
642 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) | 489 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) |
643 | fw->risc_gp2_reg[cnt] = RD_REG_WORD(dmp_reg++); | 490 | fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
644 | 491 | ||
645 | WRT_REG_WORD(®->pcr, 0x2300); | 492 | WRT_REG_WORD(®->pcr, 0x2300); |
646 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 493 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
647 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) | 494 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) |
648 | fw->risc_gp3_reg[cnt] = RD_REG_WORD(dmp_reg++); | 495 | fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
649 | 496 | ||
650 | WRT_REG_WORD(®->pcr, 0x2400); | 497 | WRT_REG_WORD(®->pcr, 0x2400); |
651 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 498 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
652 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) | 499 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) |
653 | fw->risc_gp4_reg[cnt] = RD_REG_WORD(dmp_reg++); | 500 | fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
654 | 501 | ||
655 | WRT_REG_WORD(®->pcr, 0x2500); | 502 | WRT_REG_WORD(®->pcr, 0x2500); |
656 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 503 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
657 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) | 504 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) |
658 | fw->risc_gp5_reg[cnt] = RD_REG_WORD(dmp_reg++); | 505 | fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
659 | 506 | ||
660 | WRT_REG_WORD(®->pcr, 0x2600); | 507 | WRT_REG_WORD(®->pcr, 0x2600); |
661 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 508 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
662 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) | 509 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) |
663 | fw->risc_gp6_reg[cnt] = RD_REG_WORD(dmp_reg++); | 510 | fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
664 | 511 | ||
665 | WRT_REG_WORD(®->pcr, 0x2700); | 512 | WRT_REG_WORD(®->pcr, 0x2700); |
666 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 513 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
667 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) | 514 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) |
668 | fw->risc_gp7_reg[cnt] = RD_REG_WORD(dmp_reg++); | 515 | fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
669 | 516 | ||
670 | WRT_REG_WORD(®->ctrl_status, 0x10); | 517 | WRT_REG_WORD(®->ctrl_status, 0x10); |
671 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 518 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
672 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) | 519 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) |
673 | fw->frame_buf_hdw_reg[cnt] = RD_REG_WORD(dmp_reg++); | 520 | fw->frame_buf_hdw_reg[cnt] = |
521 | htons(RD_REG_WORD(dmp_reg++)); | ||
674 | 522 | ||
675 | WRT_REG_WORD(®->ctrl_status, 0x20); | 523 | WRT_REG_WORD(®->ctrl_status, 0x20); |
676 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 524 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
677 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) | 525 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) |
678 | fw->fpm_b0_reg[cnt] = RD_REG_WORD(dmp_reg++); | 526 | fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
679 | 527 | ||
680 | WRT_REG_WORD(®->ctrl_status, 0x30); | 528 | WRT_REG_WORD(®->ctrl_status, 0x30); |
681 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 529 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
682 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) | 530 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) |
683 | fw->fpm_b1_reg[cnt] = RD_REG_WORD(dmp_reg++); | 531 | fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
684 | 532 | ||
685 | /* Reset the ISP. */ | 533 | /* Reset the ISP. */ |
686 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | 534 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); |
@@ -755,12 +603,15 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
755 | 603 | ||
756 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 604 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
757 | rval = mb0 & MBS_MASK; | 605 | rval = mb0 & MBS_MASK; |
758 | fw->risc_ram[cnt] = mb2; | 606 | fw->risc_ram[cnt] = htons(mb2); |
759 | } else { | 607 | } else { |
760 | rval = QLA_FUNCTION_FAILED; | 608 | rval = QLA_FUNCTION_FAILED; |
761 | } | 609 | } |
762 | } | 610 | } |
763 | 611 | ||
612 | if (rval == QLA_SUCCESS) | ||
613 | qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]); | ||
614 | |||
764 | if (rval != QLA_SUCCESS) { | 615 | if (rval != QLA_SUCCESS) { |
765 | qla_printk(KERN_WARNING, ha, | 616 | qla_printk(KERN_WARNING, ha, |
766 | "Failed to dump firmware (%x)!!!\n", rval); | 617 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -778,179 +629,6 @@ qla2100_fw_dump_failed: | |||
778 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 629 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
779 | } | 630 | } |
780 | 631 | ||
781 | /** | ||
782 | * qla2100_ascii_fw_dump() - Converts a binary firmware dump to ASCII. | ||
783 | * @ha: HA context | ||
784 | */ | ||
785 | void | ||
786 | qla2100_ascii_fw_dump(scsi_qla_host_t *ha) | ||
787 | { | ||
788 | uint32_t cnt; | ||
789 | char *uiter; | ||
790 | char fw_info[30]; | ||
791 | struct qla2100_fw_dump *fw; | ||
792 | |||
793 | uiter = ha->fw_dump_buffer; | ||
794 | fw = ha->fw_dump; | ||
795 | |||
796 | qla_uprintf(&uiter, "%s Firmware Version %s\n", ha->model_number, | ||
797 | ha->isp_ops.fw_version_str(ha, fw_info)); | ||
798 | |||
799 | qla_uprintf(&uiter, "\n[==>BEG]\n"); | ||
800 | |||
801 | qla_uprintf(&uiter, "HCCR Register:\n%04x\n\n", fw->hccr); | ||
802 | |||
803 | qla_uprintf(&uiter, "PBIU Registers:"); | ||
804 | for (cnt = 0; cnt < sizeof (fw->pbiu_reg) / 2; cnt++) { | ||
805 | if (cnt % 8 == 0) { | ||
806 | qla_uprintf(&uiter, "\n"); | ||
807 | } | ||
808 | qla_uprintf(&uiter, "%04x ", fw->pbiu_reg[cnt]); | ||
809 | } | ||
810 | |||
811 | qla_uprintf(&uiter, "\n\nMailbox Registers:"); | ||
812 | for (cnt = 0; cnt < sizeof (fw->mailbox_reg) / 2; cnt++) { | ||
813 | if (cnt % 8 == 0) { | ||
814 | qla_uprintf(&uiter, "\n"); | ||
815 | } | ||
816 | qla_uprintf(&uiter, "%04x ", fw->mailbox_reg[cnt]); | ||
817 | } | ||
818 | |||
819 | qla_uprintf(&uiter, "\n\nDMA Registers:"); | ||
820 | for (cnt = 0; cnt < sizeof (fw->dma_reg) / 2; cnt++) { | ||
821 | if (cnt % 8 == 0) { | ||
822 | qla_uprintf(&uiter, "\n"); | ||
823 | } | ||
824 | qla_uprintf(&uiter, "%04x ", fw->dma_reg[cnt]); | ||
825 | } | ||
826 | |||
827 | qla_uprintf(&uiter, "\n\nRISC Hardware Registers:"); | ||
828 | for (cnt = 0; cnt < sizeof (fw->risc_hdw_reg) / 2; cnt++) { | ||
829 | if (cnt % 8 == 0) { | ||
830 | qla_uprintf(&uiter, "\n"); | ||
831 | } | ||
832 | qla_uprintf(&uiter, "%04x ", fw->risc_hdw_reg[cnt]); | ||
833 | } | ||
834 | |||
835 | qla_uprintf(&uiter, "\n\nRISC GP0 Registers:"); | ||
836 | for (cnt = 0; cnt < sizeof (fw->risc_gp0_reg) / 2; cnt++) { | ||
837 | if (cnt % 8 == 0) { | ||
838 | qla_uprintf(&uiter, "\n"); | ||
839 | } | ||
840 | qla_uprintf(&uiter, "%04x ", fw->risc_gp0_reg[cnt]); | ||
841 | } | ||
842 | |||
843 | qla_uprintf(&uiter, "\n\nRISC GP1 Registers:"); | ||
844 | for (cnt = 0; cnt < sizeof (fw->risc_gp1_reg) / 2; cnt++) { | ||
845 | if (cnt % 8 == 0) { | ||
846 | qla_uprintf(&uiter, "\n"); | ||
847 | } | ||
848 | qla_uprintf(&uiter, "%04x ", fw->risc_gp1_reg[cnt]); | ||
849 | } | ||
850 | |||
851 | qla_uprintf(&uiter, "\n\nRISC GP2 Registers:"); | ||
852 | for (cnt = 0; cnt < sizeof (fw->risc_gp2_reg) / 2; cnt++) { | ||
853 | if (cnt % 8 == 0) { | ||
854 | qla_uprintf(&uiter, "\n"); | ||
855 | } | ||
856 | qla_uprintf(&uiter, "%04x ", fw->risc_gp2_reg[cnt]); | ||
857 | } | ||
858 | |||
859 | qla_uprintf(&uiter, "\n\nRISC GP3 Registers:"); | ||
860 | for (cnt = 0; cnt < sizeof (fw->risc_gp3_reg) / 2; cnt++) { | ||
861 | if (cnt % 8 == 0) { | ||
862 | qla_uprintf(&uiter, "\n"); | ||
863 | } | ||
864 | qla_uprintf(&uiter, "%04x ", fw->risc_gp3_reg[cnt]); | ||
865 | } | ||
866 | |||
867 | qla_uprintf(&uiter, "\n\nRISC GP4 Registers:"); | ||
868 | for (cnt = 0; cnt < sizeof (fw->risc_gp4_reg) / 2; cnt++) { | ||
869 | if (cnt % 8 == 0) { | ||
870 | qla_uprintf(&uiter, "\n"); | ||
871 | } | ||
872 | qla_uprintf(&uiter, "%04x ", fw->risc_gp4_reg[cnt]); | ||
873 | } | ||
874 | |||
875 | qla_uprintf(&uiter, "\n\nRISC GP5 Registers:"); | ||
876 | for (cnt = 0; cnt < sizeof (fw->risc_gp5_reg) / 2; cnt++) { | ||
877 | if (cnt % 8 == 0) { | ||
878 | qla_uprintf(&uiter, "\n"); | ||
879 | } | ||
880 | qla_uprintf(&uiter, "%04x ", fw->risc_gp5_reg[cnt]); | ||
881 | } | ||
882 | |||
883 | qla_uprintf(&uiter, "\n\nRISC GP6 Registers:"); | ||
884 | for (cnt = 0; cnt < sizeof (fw->risc_gp6_reg) / 2; cnt++) { | ||
885 | if (cnt % 8 == 0) { | ||
886 | qla_uprintf(&uiter, "\n"); | ||
887 | } | ||
888 | qla_uprintf(&uiter, "%04x ", fw->risc_gp6_reg[cnt]); | ||
889 | } | ||
890 | |||
891 | qla_uprintf(&uiter, "\n\nRISC GP7 Registers:"); | ||
892 | for (cnt = 0; cnt < sizeof (fw->risc_gp7_reg) / 2; cnt++) { | ||
893 | if (cnt % 8 == 0) { | ||
894 | qla_uprintf(&uiter, "\n"); | ||
895 | } | ||
896 | qla_uprintf(&uiter, "%04x ", fw->risc_gp7_reg[cnt]); | ||
897 | } | ||
898 | |||
899 | qla_uprintf(&uiter, "\n\nFrame Buffer Hardware Registers:"); | ||
900 | for (cnt = 0; cnt < sizeof (fw->frame_buf_hdw_reg) / 2; cnt++) { | ||
901 | if (cnt % 8 == 0) { | ||
902 | qla_uprintf(&uiter, "\n"); | ||
903 | } | ||
904 | qla_uprintf(&uiter, "%04x ", fw->frame_buf_hdw_reg[cnt]); | ||
905 | } | ||
906 | |||
907 | qla_uprintf(&uiter, "\n\nFPM B0 Registers:"); | ||
908 | for (cnt = 0; cnt < sizeof (fw->fpm_b0_reg) / 2; cnt++) { | ||
909 | if (cnt % 8 == 0) { | ||
910 | qla_uprintf(&uiter, "\n"); | ||
911 | } | ||
912 | qla_uprintf(&uiter, "%04x ", fw->fpm_b0_reg[cnt]); | ||
913 | } | ||
914 | |||
915 | qla_uprintf(&uiter, "\n\nFPM B1 Registers:"); | ||
916 | for (cnt = 0; cnt < sizeof (fw->fpm_b1_reg) / 2; cnt++) { | ||
917 | if (cnt % 8 == 0) { | ||
918 | qla_uprintf(&uiter, "\n"); | ||
919 | } | ||
920 | qla_uprintf(&uiter, "%04x ", fw->fpm_b1_reg[cnt]); | ||
921 | } | ||
922 | |||
923 | qla_uprintf(&uiter, "\n\nRISC SRAM:"); | ||
924 | for (cnt = 0; cnt < sizeof (fw->risc_ram) / 2; cnt++) { | ||
925 | if (cnt % 8 == 0) { | ||
926 | qla_uprintf(&uiter, "\n%04x: ", cnt + 0x1000); | ||
927 | } | ||
928 | qla_uprintf(&uiter, "%04x ", fw->risc_ram[cnt]); | ||
929 | } | ||
930 | |||
931 | qla_uprintf(&uiter, "\n\n[<==END] ISP Debug Dump."); | ||
932 | |||
933 | return; | ||
934 | } | ||
935 | |||
936 | static int | ||
937 | qla_uprintf(char **uiter, char *fmt, ...) | ||
938 | { | ||
939 | int iter, len; | ||
940 | char buf[128]; | ||
941 | va_list args; | ||
942 | |||
943 | va_start(args, fmt); | ||
944 | len = vsprintf(buf, fmt, args); | ||
945 | va_end(args); | ||
946 | |||
947 | for (iter = 0; iter < len; iter++, *uiter += 1) | ||
948 | *uiter[0] = buf[iter]; | ||
949 | |||
950 | return (len); | ||
951 | } | ||
952 | |||
953 | |||
954 | void | 632 | void |
955 | qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | 633 | qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) |
956 | { | 634 | { |
@@ -967,6 +645,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
967 | unsigned long flags; | 645 | unsigned long flags; |
968 | struct qla24xx_fw_dump *fw; | 646 | struct qla24xx_fw_dump *fw; |
969 | uint32_t ext_mem_cnt; | 647 | uint32_t ext_mem_cnt; |
648 | void *eft; | ||
970 | 649 | ||
971 | risc_address = ext_mem_cnt = 0; | 650 | risc_address = ext_mem_cnt = 0; |
972 | memset(mb, 0, sizeof(mb)); | 651 | memset(mb, 0, sizeof(mb)); |
@@ -987,10 +666,11 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
987 | "request...\n", ha->fw_dump); | 666 | "request...\n", ha->fw_dump); |
988 | goto qla24xx_fw_dump_failed; | 667 | goto qla24xx_fw_dump_failed; |
989 | } | 668 | } |
990 | fw = ha->fw_dump; | 669 | fw = &ha->fw_dump->isp.isp24; |
670 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
991 | 671 | ||
992 | rval = QLA_SUCCESS; | 672 | rval = QLA_SUCCESS; |
993 | fw->host_status = RD_REG_DWORD(®->host_status); | 673 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); |
994 | 674 | ||
995 | /* Pause RISC. */ | 675 | /* Pause RISC. */ |
996 | if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { | 676 | if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { |
@@ -1012,7 +692,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1012 | /* Host interface registers. */ | 692 | /* Host interface registers. */ |
1013 | dmp_reg = (uint32_t __iomem *)(reg + 0); | 693 | dmp_reg = (uint32_t __iomem *)(reg + 0); |
1014 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) | 694 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) |
1015 | fw->host_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 695 | fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1016 | 696 | ||
1017 | /* Disable interrupts. */ | 697 | /* Disable interrupts. */ |
1018 | WRT_REG_DWORD(®->ictrl, 0); | 698 | WRT_REG_DWORD(®->ictrl, 0); |
@@ -1024,470 +704,471 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1024 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 704 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1025 | WRT_REG_DWORD(dmp_reg, 0xB0000000); | 705 | WRT_REG_DWORD(dmp_reg, 0xB0000000); |
1026 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 706 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1027 | fw->shadow_reg[0] = RD_REG_DWORD(dmp_reg); | 707 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(dmp_reg)); |
1028 | 708 | ||
1029 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 709 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1030 | WRT_REG_DWORD(dmp_reg, 0xB0100000); | 710 | WRT_REG_DWORD(dmp_reg, 0xB0100000); |
1031 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 711 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1032 | fw->shadow_reg[1] = RD_REG_DWORD(dmp_reg); | 712 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(dmp_reg)); |
1033 | 713 | ||
1034 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 714 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1035 | WRT_REG_DWORD(dmp_reg, 0xB0200000); | 715 | WRT_REG_DWORD(dmp_reg, 0xB0200000); |
1036 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 716 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1037 | fw->shadow_reg[2] = RD_REG_DWORD(dmp_reg); | 717 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(dmp_reg)); |
1038 | 718 | ||
1039 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 719 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1040 | WRT_REG_DWORD(dmp_reg, 0xB0300000); | 720 | WRT_REG_DWORD(dmp_reg, 0xB0300000); |
1041 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 721 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1042 | fw->shadow_reg[3] = RD_REG_DWORD(dmp_reg); | 722 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(dmp_reg)); |
1043 | 723 | ||
1044 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 724 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1045 | WRT_REG_DWORD(dmp_reg, 0xB0400000); | 725 | WRT_REG_DWORD(dmp_reg, 0xB0400000); |
1046 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 726 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1047 | fw->shadow_reg[4] = RD_REG_DWORD(dmp_reg); | 727 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(dmp_reg)); |
1048 | 728 | ||
1049 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 729 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1050 | WRT_REG_DWORD(dmp_reg, 0xB0500000); | 730 | WRT_REG_DWORD(dmp_reg, 0xB0500000); |
1051 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 731 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1052 | fw->shadow_reg[5] = RD_REG_DWORD(dmp_reg); | 732 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(dmp_reg)); |
1053 | 733 | ||
1054 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); | 734 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xF0); |
1055 | WRT_REG_DWORD(dmp_reg, 0xB0600000); | 735 | WRT_REG_DWORD(dmp_reg, 0xB0600000); |
1056 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); | 736 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xFC); |
1057 | fw->shadow_reg[6] = RD_REG_DWORD(dmp_reg); | 737 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(dmp_reg)); |
1058 | 738 | ||
1059 | /* Mailbox registers. */ | 739 | /* Mailbox registers. */ |
1060 | mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 740 | mbx_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); |
1061 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | 741 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) |
1062 | fw->mailbox_reg[cnt] = RD_REG_WORD(mbx_reg++); | 742 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); |
1063 | 743 | ||
1064 | /* Transfer sequence registers. */ | 744 | /* Transfer sequence registers. */ |
1065 | iter_reg = fw->xseq_gp_reg; | 745 | iter_reg = fw->xseq_gp_reg; |
1066 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); | 746 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); |
1067 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 747 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1068 | for (cnt = 0; cnt < 16; cnt++) | 748 | for (cnt = 0; cnt < 16; cnt++) |
1069 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 749 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1070 | 750 | ||
1071 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); | 751 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); |
1072 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 752 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1073 | for (cnt = 0; cnt < 16; cnt++) | 753 | for (cnt = 0; cnt < 16; cnt++) |
1074 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 754 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1075 | 755 | ||
1076 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); | 756 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); |
1077 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 757 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1078 | for (cnt = 0; cnt < 16; cnt++) | 758 | for (cnt = 0; cnt < 16; cnt++) |
1079 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 759 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1080 | 760 | ||
1081 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); | 761 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); |
1082 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 762 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1083 | for (cnt = 0; cnt < 16; cnt++) | 763 | for (cnt = 0; cnt < 16; cnt++) |
1084 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 764 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1085 | 765 | ||
1086 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); | 766 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); |
1087 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 767 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1088 | for (cnt = 0; cnt < 16; cnt++) | 768 | for (cnt = 0; cnt < 16; cnt++) |
1089 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 769 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1090 | 770 | ||
1091 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); | 771 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); |
1092 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 772 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1093 | for (cnt = 0; cnt < 16; cnt++) | 773 | for (cnt = 0; cnt < 16; cnt++) |
1094 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 774 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1095 | 775 | ||
1096 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); | 776 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); |
1097 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 777 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1098 | for (cnt = 0; cnt < 16; cnt++) | 778 | for (cnt = 0; cnt < 16; cnt++) |
1099 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 779 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1100 | 780 | ||
1101 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); | 781 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); |
1102 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 782 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1103 | for (cnt = 0; cnt < 16; cnt++) | 783 | for (cnt = 0; cnt < 16; cnt++) |
1104 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 784 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1105 | 785 | ||
1106 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); | 786 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); |
1107 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 787 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1108 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) | 788 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) |
1109 | fw->xseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 789 | fw->xseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1110 | 790 | ||
1111 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); | 791 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); |
1112 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 792 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1113 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) | 793 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) |
1114 | fw->xseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 794 | fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1115 | 795 | ||
1116 | /* Receive sequence registers. */ | 796 | /* Receive sequence registers. */ |
1117 | iter_reg = fw->rseq_gp_reg; | 797 | iter_reg = fw->rseq_gp_reg; |
1118 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); | 798 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); |
1119 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 799 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1120 | for (cnt = 0; cnt < 16; cnt++) | 800 | for (cnt = 0; cnt < 16; cnt++) |
1121 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 801 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1122 | 802 | ||
1123 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); | 803 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); |
1124 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 804 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1125 | for (cnt = 0; cnt < 16; cnt++) | 805 | for (cnt = 0; cnt < 16; cnt++) |
1126 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 806 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1127 | 807 | ||
1128 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); | 808 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); |
1129 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 809 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1130 | for (cnt = 0; cnt < 16; cnt++) | 810 | for (cnt = 0; cnt < 16; cnt++) |
1131 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 811 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1132 | 812 | ||
1133 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); | 813 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); |
1134 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 814 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1135 | for (cnt = 0; cnt < 16; cnt++) | 815 | for (cnt = 0; cnt < 16; cnt++) |
1136 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 816 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1137 | 817 | ||
1138 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); | 818 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); |
1139 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 819 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1140 | for (cnt = 0; cnt < 16; cnt++) | 820 | for (cnt = 0; cnt < 16; cnt++) |
1141 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 821 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1142 | 822 | ||
1143 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); | 823 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); |
1144 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 824 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1145 | for (cnt = 0; cnt < 16; cnt++) | 825 | for (cnt = 0; cnt < 16; cnt++) |
1146 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 826 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1147 | 827 | ||
1148 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); | 828 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); |
1149 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 829 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1150 | for (cnt = 0; cnt < 16; cnt++) | 830 | for (cnt = 0; cnt < 16; cnt++) |
1151 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 831 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1152 | 832 | ||
1153 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); | 833 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); |
1154 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 834 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1155 | for (cnt = 0; cnt < 16; cnt++) | 835 | for (cnt = 0; cnt < 16; cnt++) |
1156 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 836 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1157 | 837 | ||
1158 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); | 838 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); |
1159 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 839 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1160 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) | 840 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) |
1161 | fw->rseq_0_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 841 | fw->rseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1162 | 842 | ||
1163 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); | 843 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); |
1164 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 844 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1165 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) | 845 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) |
1166 | fw->rseq_1_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 846 | fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1167 | 847 | ||
1168 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); | 848 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); |
1169 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 849 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1170 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) | 850 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) |
1171 | fw->rseq_2_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 851 | fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1172 | 852 | ||
1173 | /* Command DMA registers. */ | 853 | /* Command DMA registers. */ |
1174 | WRT_REG_DWORD(®->iobase_addr, 0x7100); | 854 | WRT_REG_DWORD(®->iobase_addr, 0x7100); |
1175 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 855 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1176 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) | 856 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) |
1177 | fw->cmd_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 857 | fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
1178 | 858 | ||
1179 | /* Queues. */ | 859 | /* Queues. */ |
1180 | iter_reg = fw->req0_dma_reg; | 860 | iter_reg = fw->req0_dma_reg; |
1181 | WRT_REG_DWORD(®->iobase_addr, 0x7200); | 861 | WRT_REG_DWORD(®->iobase_addr, 0x7200); |
1182 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 862 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1183 | for (cnt = 0; cnt < 8; cnt++) | 863 | for (cnt = 0; cnt < 8; cnt++) |
1184 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 864 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1185 | 865 | ||
1186 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 866 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); |
1187 | for (cnt = 0; cnt < 7; cnt++) | 867 | for (cnt = 0; cnt < 7; cnt++) |
1188 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 868 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1189 | 869 | ||
1190 | iter_reg = fw->resp0_dma_reg; | 870 | iter_reg = fw->resp0_dma_reg; |
1191 | WRT_REG_DWORD(®->iobase_addr, 0x7300); | 871 | WRT_REG_DWORD(®->iobase_addr, 0x7300); |
1192 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 872 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1193 | for (cnt = 0; cnt < 8; cnt++) | 873 | for (cnt = 0; cnt < 8; cnt++) |
1194 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 874 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1195 | 875 | ||
1196 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 876 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); |
1197 | for (cnt = 0; cnt < 7; cnt++) | 877 | for (cnt = 0; cnt < 7; cnt++) |
1198 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 878 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1199 | 879 | ||
1200 | iter_reg = fw->req1_dma_reg; | 880 | iter_reg = fw->req1_dma_reg; |
1201 | WRT_REG_DWORD(®->iobase_addr, 0x7400); | 881 | WRT_REG_DWORD(®->iobase_addr, 0x7400); |
1202 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 882 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1203 | for (cnt = 0; cnt < 8; cnt++) | 883 | for (cnt = 0; cnt < 8; cnt++) |
1204 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 884 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1205 | 885 | ||
1206 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); | 886 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xE4); |
1207 | for (cnt = 0; cnt < 7; cnt++) | 887 | for (cnt = 0; cnt < 7; cnt++) |
1208 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 888 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1209 | 889 | ||
1210 | /* Transmit DMA registers. */ | 890 | /* Transmit DMA registers. */ |
1211 | iter_reg = fw->xmt0_dma_reg; | 891 | iter_reg = fw->xmt0_dma_reg; |
1212 | WRT_REG_DWORD(®->iobase_addr, 0x7600); | 892 | WRT_REG_DWORD(®->iobase_addr, 0x7600); |
1213 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 893 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1214 | for (cnt = 0; cnt < 16; cnt++) | 894 | for (cnt = 0; cnt < 16; cnt++) |
1215 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 895 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1216 | 896 | ||
1217 | WRT_REG_DWORD(®->iobase_addr, 0x7610); | 897 | WRT_REG_DWORD(®->iobase_addr, 0x7610); |
1218 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 898 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1219 | for (cnt = 0; cnt < 16; cnt++) | 899 | for (cnt = 0; cnt < 16; cnt++) |
1220 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 900 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1221 | 901 | ||
1222 | iter_reg = fw->xmt1_dma_reg; | 902 | iter_reg = fw->xmt1_dma_reg; |
1223 | WRT_REG_DWORD(®->iobase_addr, 0x7620); | 903 | WRT_REG_DWORD(®->iobase_addr, 0x7620); |
1224 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 904 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1225 | for (cnt = 0; cnt < 16; cnt++) | 905 | for (cnt = 0; cnt < 16; cnt++) |
1226 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 906 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1227 | 907 | ||
1228 | WRT_REG_DWORD(®->iobase_addr, 0x7630); | 908 | WRT_REG_DWORD(®->iobase_addr, 0x7630); |
1229 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 909 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1230 | for (cnt = 0; cnt < 16; cnt++) | 910 | for (cnt = 0; cnt < 16; cnt++) |
1231 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 911 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1232 | 912 | ||
1233 | iter_reg = fw->xmt2_dma_reg; | 913 | iter_reg = fw->xmt2_dma_reg; |
1234 | WRT_REG_DWORD(®->iobase_addr, 0x7640); | 914 | WRT_REG_DWORD(®->iobase_addr, 0x7640); |
1235 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 915 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1236 | for (cnt = 0; cnt < 16; cnt++) | 916 | for (cnt = 0; cnt < 16; cnt++) |
1237 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 917 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1238 | 918 | ||
1239 | WRT_REG_DWORD(®->iobase_addr, 0x7650); | 919 | WRT_REG_DWORD(®->iobase_addr, 0x7650); |
1240 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 920 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1241 | for (cnt = 0; cnt < 16; cnt++) | 921 | for (cnt = 0; cnt < 16; cnt++) |
1242 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 922 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1243 | 923 | ||
1244 | iter_reg = fw->xmt3_dma_reg; | 924 | iter_reg = fw->xmt3_dma_reg; |
1245 | WRT_REG_DWORD(®->iobase_addr, 0x7660); | 925 | WRT_REG_DWORD(®->iobase_addr, 0x7660); |
1246 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 926 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1247 | for (cnt = 0; cnt < 16; cnt++) | 927 | for (cnt = 0; cnt < 16; cnt++) |
1248 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 928 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1249 | 929 | ||
1250 | WRT_REG_DWORD(®->iobase_addr, 0x7670); | 930 | WRT_REG_DWORD(®->iobase_addr, 0x7670); |
1251 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 931 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1252 | for (cnt = 0; cnt < 16; cnt++) | 932 | for (cnt = 0; cnt < 16; cnt++) |
1253 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 933 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1254 | 934 | ||
1255 | iter_reg = fw->xmt4_dma_reg; | 935 | iter_reg = fw->xmt4_dma_reg; |
1256 | WRT_REG_DWORD(®->iobase_addr, 0x7680); | 936 | WRT_REG_DWORD(®->iobase_addr, 0x7680); |
1257 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 937 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1258 | for (cnt = 0; cnt < 16; cnt++) | 938 | for (cnt = 0; cnt < 16; cnt++) |
1259 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 939 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1260 | 940 | ||
1261 | WRT_REG_DWORD(®->iobase_addr, 0x7690); | 941 | WRT_REG_DWORD(®->iobase_addr, 0x7690); |
1262 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 942 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1263 | for (cnt = 0; cnt < 16; cnt++) | 943 | for (cnt = 0; cnt < 16; cnt++) |
1264 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 944 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1265 | 945 | ||
1266 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); | 946 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); |
1267 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 947 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1268 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) | 948 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) |
1269 | fw->xmt_data_dma_reg[cnt] = RD_REG_DWORD(dmp_reg++); | 949 | fw->xmt_data_dma_reg[cnt] = |
950 | htonl(RD_REG_DWORD(dmp_reg++)); | ||
1270 | 951 | ||
1271 | /* Receive DMA registers. */ | 952 | /* Receive DMA registers. */ |
1272 | iter_reg = fw->rcvt0_data_dma_reg; | 953 | iter_reg = fw->rcvt0_data_dma_reg; |
1273 | WRT_REG_DWORD(®->iobase_addr, 0x7700); | 954 | WRT_REG_DWORD(®->iobase_addr, 0x7700); |
1274 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 955 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1275 | for (cnt = 0; cnt < 16; cnt++) | 956 | for (cnt = 0; cnt < 16; cnt++) |
1276 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 957 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1277 | 958 | ||
1278 | WRT_REG_DWORD(®->iobase_addr, 0x7710); | 959 | WRT_REG_DWORD(®->iobase_addr, 0x7710); |
1279 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 960 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1280 | for (cnt = 0; cnt < 16; cnt++) | 961 | for (cnt = 0; cnt < 16; cnt++) |
1281 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 962 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1282 | 963 | ||
1283 | iter_reg = fw->rcvt1_data_dma_reg; | 964 | iter_reg = fw->rcvt1_data_dma_reg; |
1284 | WRT_REG_DWORD(®->iobase_addr, 0x7720); | 965 | WRT_REG_DWORD(®->iobase_addr, 0x7720); |
1285 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 966 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1286 | for (cnt = 0; cnt < 16; cnt++) | 967 | for (cnt = 0; cnt < 16; cnt++) |
1287 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 968 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1288 | 969 | ||
1289 | WRT_REG_DWORD(®->iobase_addr, 0x7730); | 970 | WRT_REG_DWORD(®->iobase_addr, 0x7730); |
1290 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 971 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1291 | for (cnt = 0; cnt < 16; cnt++) | 972 | for (cnt = 0; cnt < 16; cnt++) |
1292 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 973 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1293 | 974 | ||
1294 | /* RISC registers. */ | 975 | /* RISC registers. */ |
1295 | iter_reg = fw->risc_gp_reg; | 976 | iter_reg = fw->risc_gp_reg; |
1296 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); | 977 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); |
1297 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 978 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1298 | for (cnt = 0; cnt < 16; cnt++) | 979 | for (cnt = 0; cnt < 16; cnt++) |
1299 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 980 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1300 | 981 | ||
1301 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); | 982 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); |
1302 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 983 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1303 | for (cnt = 0; cnt < 16; cnt++) | 984 | for (cnt = 0; cnt < 16; cnt++) |
1304 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 985 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1305 | 986 | ||
1306 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); | 987 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); |
1307 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 988 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1308 | for (cnt = 0; cnt < 16; cnt++) | 989 | for (cnt = 0; cnt < 16; cnt++) |
1309 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 990 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1310 | 991 | ||
1311 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); | 992 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); |
1312 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 993 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1313 | for (cnt = 0; cnt < 16; cnt++) | 994 | for (cnt = 0; cnt < 16; cnt++) |
1314 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 995 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1315 | 996 | ||
1316 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); | 997 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); |
1317 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 998 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1318 | for (cnt = 0; cnt < 16; cnt++) | 999 | for (cnt = 0; cnt < 16; cnt++) |
1319 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1000 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1320 | 1001 | ||
1321 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); | 1002 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); |
1322 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1003 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1323 | for (cnt = 0; cnt < 16; cnt++) | 1004 | for (cnt = 0; cnt < 16; cnt++) |
1324 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1005 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1325 | 1006 | ||
1326 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); | 1007 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); |
1327 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1008 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1328 | for (cnt = 0; cnt < 16; cnt++) | 1009 | for (cnt = 0; cnt < 16; cnt++) |
1329 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1010 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1330 | 1011 | ||
1331 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | 1012 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); |
1332 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1013 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1333 | for (cnt = 0; cnt < 16; cnt++) | 1014 | for (cnt = 0; cnt < 16; cnt++) |
1334 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1015 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1335 | 1016 | ||
1336 | /* Local memory controller registers. */ | 1017 | /* Local memory controller registers. */ |
1337 | iter_reg = fw->lmc_reg; | 1018 | iter_reg = fw->lmc_reg; |
1338 | WRT_REG_DWORD(®->iobase_addr, 0x3000); | 1019 | WRT_REG_DWORD(®->iobase_addr, 0x3000); |
1339 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1020 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1340 | for (cnt = 0; cnt < 16; cnt++) | 1021 | for (cnt = 0; cnt < 16; cnt++) |
1341 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1022 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1342 | 1023 | ||
1343 | WRT_REG_DWORD(®->iobase_addr, 0x3010); | 1024 | WRT_REG_DWORD(®->iobase_addr, 0x3010); |
1344 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1025 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1345 | for (cnt = 0; cnt < 16; cnt++) | 1026 | for (cnt = 0; cnt < 16; cnt++) |
1346 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1027 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1347 | 1028 | ||
1348 | WRT_REG_DWORD(®->iobase_addr, 0x3020); | 1029 | WRT_REG_DWORD(®->iobase_addr, 0x3020); |
1349 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1030 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1350 | for (cnt = 0; cnt < 16; cnt++) | 1031 | for (cnt = 0; cnt < 16; cnt++) |
1351 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1032 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1352 | 1033 | ||
1353 | WRT_REG_DWORD(®->iobase_addr, 0x3030); | 1034 | WRT_REG_DWORD(®->iobase_addr, 0x3030); |
1354 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1035 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1355 | for (cnt = 0; cnt < 16; cnt++) | 1036 | for (cnt = 0; cnt < 16; cnt++) |
1356 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1037 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1357 | 1038 | ||
1358 | WRT_REG_DWORD(®->iobase_addr, 0x3040); | 1039 | WRT_REG_DWORD(®->iobase_addr, 0x3040); |
1359 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1040 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1360 | for (cnt = 0; cnt < 16; cnt++) | 1041 | for (cnt = 0; cnt < 16; cnt++) |
1361 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1042 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1362 | 1043 | ||
1363 | WRT_REG_DWORD(®->iobase_addr, 0x3050); | 1044 | WRT_REG_DWORD(®->iobase_addr, 0x3050); |
1364 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1045 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1365 | for (cnt = 0; cnt < 16; cnt++) | 1046 | for (cnt = 0; cnt < 16; cnt++) |
1366 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1047 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1367 | 1048 | ||
1368 | WRT_REG_DWORD(®->iobase_addr, 0x3060); | 1049 | WRT_REG_DWORD(®->iobase_addr, 0x3060); |
1369 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1050 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1370 | for (cnt = 0; cnt < 16; cnt++) | 1051 | for (cnt = 0; cnt < 16; cnt++) |
1371 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1052 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1372 | 1053 | ||
1373 | /* Fibre Protocol Module registers. */ | 1054 | /* Fibre Protocol Module registers. */ |
1374 | iter_reg = fw->fpm_hdw_reg; | 1055 | iter_reg = fw->fpm_hdw_reg; |
1375 | WRT_REG_DWORD(®->iobase_addr, 0x4000); | 1056 | WRT_REG_DWORD(®->iobase_addr, 0x4000); |
1376 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1057 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1377 | for (cnt = 0; cnt < 16; cnt++) | 1058 | for (cnt = 0; cnt < 16; cnt++) |
1378 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1059 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1379 | 1060 | ||
1380 | WRT_REG_DWORD(®->iobase_addr, 0x4010); | 1061 | WRT_REG_DWORD(®->iobase_addr, 0x4010); |
1381 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1062 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1382 | for (cnt = 0; cnt < 16; cnt++) | 1063 | for (cnt = 0; cnt < 16; cnt++) |
1383 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1064 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1384 | 1065 | ||
1385 | WRT_REG_DWORD(®->iobase_addr, 0x4020); | 1066 | WRT_REG_DWORD(®->iobase_addr, 0x4020); |
1386 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1067 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1387 | for (cnt = 0; cnt < 16; cnt++) | 1068 | for (cnt = 0; cnt < 16; cnt++) |
1388 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1069 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1389 | 1070 | ||
1390 | WRT_REG_DWORD(®->iobase_addr, 0x4030); | 1071 | WRT_REG_DWORD(®->iobase_addr, 0x4030); |
1391 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1072 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1392 | for (cnt = 0; cnt < 16; cnt++) | 1073 | for (cnt = 0; cnt < 16; cnt++) |
1393 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1074 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1394 | 1075 | ||
1395 | WRT_REG_DWORD(®->iobase_addr, 0x4040); | 1076 | WRT_REG_DWORD(®->iobase_addr, 0x4040); |
1396 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1077 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1397 | for (cnt = 0; cnt < 16; cnt++) | 1078 | for (cnt = 0; cnt < 16; cnt++) |
1398 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1079 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1399 | 1080 | ||
1400 | WRT_REG_DWORD(®->iobase_addr, 0x4050); | 1081 | WRT_REG_DWORD(®->iobase_addr, 0x4050); |
1401 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1082 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1402 | for (cnt = 0; cnt < 16; cnt++) | 1083 | for (cnt = 0; cnt < 16; cnt++) |
1403 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1084 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1404 | 1085 | ||
1405 | WRT_REG_DWORD(®->iobase_addr, 0x4060); | 1086 | WRT_REG_DWORD(®->iobase_addr, 0x4060); |
1406 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1087 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1407 | for (cnt = 0; cnt < 16; cnt++) | 1088 | for (cnt = 0; cnt < 16; cnt++) |
1408 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1089 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1409 | 1090 | ||
1410 | WRT_REG_DWORD(®->iobase_addr, 0x4070); | 1091 | WRT_REG_DWORD(®->iobase_addr, 0x4070); |
1411 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1092 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1412 | for (cnt = 0; cnt < 16; cnt++) | 1093 | for (cnt = 0; cnt < 16; cnt++) |
1413 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1094 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1414 | 1095 | ||
1415 | WRT_REG_DWORD(®->iobase_addr, 0x4080); | 1096 | WRT_REG_DWORD(®->iobase_addr, 0x4080); |
1416 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1097 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1417 | for (cnt = 0; cnt < 16; cnt++) | 1098 | for (cnt = 0; cnt < 16; cnt++) |
1418 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1099 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1419 | 1100 | ||
1420 | WRT_REG_DWORD(®->iobase_addr, 0x4090); | 1101 | WRT_REG_DWORD(®->iobase_addr, 0x4090); |
1421 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1102 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1422 | for (cnt = 0; cnt < 16; cnt++) | 1103 | for (cnt = 0; cnt < 16; cnt++) |
1423 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1104 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1424 | 1105 | ||
1425 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); | 1106 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); |
1426 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1107 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1427 | for (cnt = 0; cnt < 16; cnt++) | 1108 | for (cnt = 0; cnt < 16; cnt++) |
1428 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1109 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1429 | 1110 | ||
1430 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); | 1111 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); |
1431 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1112 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1432 | for (cnt = 0; cnt < 16; cnt++) | 1113 | for (cnt = 0; cnt < 16; cnt++) |
1433 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1114 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1434 | 1115 | ||
1435 | /* Frame Buffer registers. */ | 1116 | /* Frame Buffer registers. */ |
1436 | iter_reg = fw->fb_hdw_reg; | 1117 | iter_reg = fw->fb_hdw_reg; |
1437 | WRT_REG_DWORD(®->iobase_addr, 0x6000); | 1118 | WRT_REG_DWORD(®->iobase_addr, 0x6000); |
1438 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1119 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1439 | for (cnt = 0; cnt < 16; cnt++) | 1120 | for (cnt = 0; cnt < 16; cnt++) |
1440 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1121 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1441 | 1122 | ||
1442 | WRT_REG_DWORD(®->iobase_addr, 0x6010); | 1123 | WRT_REG_DWORD(®->iobase_addr, 0x6010); |
1443 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1124 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1444 | for (cnt = 0; cnt < 16; cnt++) | 1125 | for (cnt = 0; cnt < 16; cnt++) |
1445 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1126 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1446 | 1127 | ||
1447 | WRT_REG_DWORD(®->iobase_addr, 0x6020); | 1128 | WRT_REG_DWORD(®->iobase_addr, 0x6020); |
1448 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1129 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1449 | for (cnt = 0; cnt < 16; cnt++) | 1130 | for (cnt = 0; cnt < 16; cnt++) |
1450 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1131 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1451 | 1132 | ||
1452 | WRT_REG_DWORD(®->iobase_addr, 0x6030); | 1133 | WRT_REG_DWORD(®->iobase_addr, 0x6030); |
1453 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1134 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1454 | for (cnt = 0; cnt < 16; cnt++) | 1135 | for (cnt = 0; cnt < 16; cnt++) |
1455 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1136 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1456 | 1137 | ||
1457 | WRT_REG_DWORD(®->iobase_addr, 0x6040); | 1138 | WRT_REG_DWORD(®->iobase_addr, 0x6040); |
1458 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1139 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1459 | for (cnt = 0; cnt < 16; cnt++) | 1140 | for (cnt = 0; cnt < 16; cnt++) |
1460 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1141 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1461 | 1142 | ||
1462 | WRT_REG_DWORD(®->iobase_addr, 0x6100); | 1143 | WRT_REG_DWORD(®->iobase_addr, 0x6100); |
1463 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1144 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1464 | for (cnt = 0; cnt < 16; cnt++) | 1145 | for (cnt = 0; cnt < 16; cnt++) |
1465 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1146 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1466 | 1147 | ||
1467 | WRT_REG_DWORD(®->iobase_addr, 0x6130); | 1148 | WRT_REG_DWORD(®->iobase_addr, 0x6130); |
1468 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1149 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1469 | for (cnt = 0; cnt < 16; cnt++) | 1150 | for (cnt = 0; cnt < 16; cnt++) |
1470 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1151 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1471 | 1152 | ||
1472 | WRT_REG_DWORD(®->iobase_addr, 0x6150); | 1153 | WRT_REG_DWORD(®->iobase_addr, 0x6150); |
1473 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1154 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1474 | for (cnt = 0; cnt < 16; cnt++) | 1155 | for (cnt = 0; cnt < 16; cnt++) |
1475 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1156 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1476 | 1157 | ||
1477 | WRT_REG_DWORD(®->iobase_addr, 0x6170); | 1158 | WRT_REG_DWORD(®->iobase_addr, 0x6170); |
1478 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1159 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1479 | for (cnt = 0; cnt < 16; cnt++) | 1160 | for (cnt = 0; cnt < 16; cnt++) |
1480 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1161 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1481 | 1162 | ||
1482 | WRT_REG_DWORD(®->iobase_addr, 0x6190); | 1163 | WRT_REG_DWORD(®->iobase_addr, 0x6190); |
1483 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1164 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1484 | for (cnt = 0; cnt < 16; cnt++) | 1165 | for (cnt = 0; cnt < 16; cnt++) |
1485 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1166 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1486 | 1167 | ||
1487 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); | 1168 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); |
1488 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); | 1169 | dmp_reg = (uint32_t __iomem *)((uint8_t __iomem *)reg + 0xC0); |
1489 | for (cnt = 0; cnt < 16; cnt++) | 1170 | for (cnt = 0; cnt < 16; cnt++) |
1490 | *iter_reg++ = RD_REG_DWORD(dmp_reg++); | 1171 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1491 | 1172 | ||
1492 | /* Reset RISC. */ | 1173 | /* Reset RISC. */ |
1493 | WRT_REG_DWORD(®->ctrl_status, | 1174 | WRT_REG_DWORD(®->ctrl_status, |
@@ -1577,7 +1258,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1577 | 1258 | ||
1578 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 1259 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
1579 | rval = mb[0] & MBS_MASK; | 1260 | rval = mb[0] & MBS_MASK; |
1580 | fw->code_ram[cnt] = (mb[3] << 16) | mb[2]; | 1261 | fw->code_ram[cnt] = htonl((mb[3] << 16) | mb[2]); |
1581 | } else { | 1262 | } else { |
1582 | rval = QLA_FUNCTION_FAILED; | 1263 | rval = QLA_FUNCTION_FAILED; |
1583 | } | 1264 | } |
@@ -1627,12 +1308,18 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1627 | 1308 | ||
1628 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { | 1309 | if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { |
1629 | rval = mb[0] & MBS_MASK; | 1310 | rval = mb[0] & MBS_MASK; |
1630 | fw->ext_mem[cnt] = (mb[3] << 16) | mb[2]; | 1311 | fw->ext_mem[cnt] = htonl((mb[3] << 16) | mb[2]); |
1631 | } else { | 1312 | } else { |
1632 | rval = QLA_FUNCTION_FAILED; | 1313 | rval = QLA_FUNCTION_FAILED; |
1633 | } | 1314 | } |
1634 | } | 1315 | } |
1635 | 1316 | ||
1317 | if (rval == QLA_SUCCESS) { | ||
1318 | eft = qla2xxx_copy_queues(ha, &fw->ext_mem[cnt]); | ||
1319 | if (ha->eft) | ||
1320 | memcpy(eft, ha->eft, ntohl(ha->fw_dump->eft_size)); | ||
1321 | } | ||
1322 | |||
1636 | if (rval != QLA_SUCCESS) { | 1323 | if (rval != QLA_SUCCESS) { |
1637 | qla_printk(KERN_WARNING, ha, | 1324 | qla_printk(KERN_WARNING, ha, |
1638 | "Failed to dump firmware (%x)!!!\n", rval); | 1325 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -1650,252 +1337,6 @@ qla24xx_fw_dump_failed: | |||
1650 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1337 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1651 | } | 1338 | } |
1652 | 1339 | ||
1653 | void | ||
1654 | qla24xx_ascii_fw_dump(scsi_qla_host_t *ha) | ||
1655 | { | ||
1656 | uint32_t cnt; | ||
1657 | char *uiter; | ||
1658 | struct qla24xx_fw_dump *fw; | ||
1659 | uint32_t ext_mem_cnt; | ||
1660 | |||
1661 | uiter = ha->fw_dump_buffer; | ||
1662 | fw = ha->fw_dump; | ||
1663 | |||
1664 | qla_uprintf(&uiter, "ISP FW Version %d.%02d.%02d Attributes %04x\n", | ||
1665 | ha->fw_major_version, ha->fw_minor_version, | ||
1666 | ha->fw_subminor_version, ha->fw_attributes); | ||
1667 | |||
1668 | qla_uprintf(&uiter, "\nR2H Status Register\n%04x\n", fw->host_status); | ||
1669 | |||
1670 | qla_uprintf(&uiter, "\nHost Interface Registers"); | ||
1671 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) { | ||
1672 | if (cnt % 8 == 0) | ||
1673 | qla_uprintf(&uiter, "\n"); | ||
1674 | |||
1675 | qla_uprintf(&uiter, "%08x ", fw->host_reg[cnt]); | ||
1676 | } | ||
1677 | |||
1678 | qla_uprintf(&uiter, "\n\nShadow Registers"); | ||
1679 | for (cnt = 0; cnt < sizeof(fw->shadow_reg) / 4; cnt++) { | ||
1680 | if (cnt % 8 == 0) | ||
1681 | qla_uprintf(&uiter, "\n"); | ||
1682 | |||
1683 | qla_uprintf(&uiter, "%08x ", fw->shadow_reg[cnt]); | ||
1684 | } | ||
1685 | |||
1686 | qla_uprintf(&uiter, "\n\nMailbox Registers"); | ||
1687 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) { | ||
1688 | if (cnt % 8 == 0) | ||
1689 | qla_uprintf(&uiter, "\n"); | ||
1690 | |||
1691 | qla_uprintf(&uiter, "%08x ", fw->mailbox_reg[cnt]); | ||
1692 | } | ||
1693 | |||
1694 | qla_uprintf(&uiter, "\n\nXSEQ GP Registers"); | ||
1695 | for (cnt = 0; cnt < sizeof(fw->xseq_gp_reg) / 4; cnt++) { | ||
1696 | if (cnt % 8 == 0) | ||
1697 | qla_uprintf(&uiter, "\n"); | ||
1698 | |||
1699 | qla_uprintf(&uiter, "%08x ", fw->xseq_gp_reg[cnt]); | ||
1700 | } | ||
1701 | |||
1702 | qla_uprintf(&uiter, "\n\nXSEQ-0 Registers"); | ||
1703 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) { | ||
1704 | if (cnt % 8 == 0) | ||
1705 | qla_uprintf(&uiter, "\n"); | ||
1706 | |||
1707 | qla_uprintf(&uiter, "%08x ", fw->xseq_0_reg[cnt]); | ||
1708 | } | ||
1709 | |||
1710 | qla_uprintf(&uiter, "\n\nXSEQ-1 Registers"); | ||
1711 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) { | ||
1712 | if (cnt % 8 == 0) | ||
1713 | qla_uprintf(&uiter, "\n"); | ||
1714 | |||
1715 | qla_uprintf(&uiter, "%08x ", fw->xseq_1_reg[cnt]); | ||
1716 | } | ||
1717 | |||
1718 | qla_uprintf(&uiter, "\n\nRSEQ GP Registers"); | ||
1719 | for (cnt = 0; cnt < sizeof(fw->rseq_gp_reg) / 4; cnt++) { | ||
1720 | if (cnt % 8 == 0) | ||
1721 | qla_uprintf(&uiter, "\n"); | ||
1722 | |||
1723 | qla_uprintf(&uiter, "%08x ", fw->rseq_gp_reg[cnt]); | ||
1724 | } | ||
1725 | |||
1726 | qla_uprintf(&uiter, "\n\nRSEQ-0 Registers"); | ||
1727 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) { | ||
1728 | if (cnt % 8 == 0) | ||
1729 | qla_uprintf(&uiter, "\n"); | ||
1730 | |||
1731 | qla_uprintf(&uiter, "%08x ", fw->rseq_0_reg[cnt]); | ||
1732 | } | ||
1733 | |||
1734 | qla_uprintf(&uiter, "\n\nRSEQ-1 Registers"); | ||
1735 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) { | ||
1736 | if (cnt % 8 == 0) | ||
1737 | qla_uprintf(&uiter, "\n"); | ||
1738 | |||
1739 | qla_uprintf(&uiter, "%08x ", fw->rseq_1_reg[cnt]); | ||
1740 | } | ||
1741 | |||
1742 | qla_uprintf(&uiter, "\n\nRSEQ-2 Registers"); | ||
1743 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) { | ||
1744 | if (cnt % 8 == 0) | ||
1745 | qla_uprintf(&uiter, "\n"); | ||
1746 | |||
1747 | qla_uprintf(&uiter, "%08x ", fw->rseq_2_reg[cnt]); | ||
1748 | } | ||
1749 | |||
1750 | qla_uprintf(&uiter, "\n\nCommand DMA Registers"); | ||
1751 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) { | ||
1752 | if (cnt % 8 == 0) | ||
1753 | qla_uprintf(&uiter, "\n"); | ||
1754 | |||
1755 | qla_uprintf(&uiter, "%08x ", fw->cmd_dma_reg[cnt]); | ||
1756 | } | ||
1757 | |||
1758 | qla_uprintf(&uiter, "\n\nRequest0 Queue DMA Channel Registers"); | ||
1759 | for (cnt = 0; cnt < sizeof(fw->req0_dma_reg) / 4; cnt++) { | ||
1760 | if (cnt % 8 == 0) | ||
1761 | qla_uprintf(&uiter, "\n"); | ||
1762 | |||
1763 | qla_uprintf(&uiter, "%08x ", fw->req0_dma_reg[cnt]); | ||
1764 | } | ||
1765 | |||
1766 | qla_uprintf(&uiter, "\n\nResponse0 Queue DMA Channel Registers"); | ||
1767 | for (cnt = 0; cnt < sizeof(fw->resp0_dma_reg) / 4; cnt++) { | ||
1768 | if (cnt % 8 == 0) | ||
1769 | qla_uprintf(&uiter, "\n"); | ||
1770 | |||
1771 | qla_uprintf(&uiter, "%08x ", fw->resp0_dma_reg[cnt]); | ||
1772 | } | ||
1773 | |||
1774 | qla_uprintf(&uiter, "\n\nRequest1 Queue DMA Channel Registers"); | ||
1775 | for (cnt = 0; cnt < sizeof(fw->req1_dma_reg) / 4; cnt++) { | ||
1776 | if (cnt % 8 == 0) | ||
1777 | qla_uprintf(&uiter, "\n"); | ||
1778 | |||
1779 | qla_uprintf(&uiter, "%08x ", fw->req1_dma_reg[cnt]); | ||
1780 | } | ||
1781 | |||
1782 | qla_uprintf(&uiter, "\n\nXMT0 Data DMA Registers"); | ||
1783 | for (cnt = 0; cnt < sizeof(fw->xmt0_dma_reg) / 4; cnt++) { | ||
1784 | if (cnt % 8 == 0) | ||
1785 | qla_uprintf(&uiter, "\n"); | ||
1786 | |||
1787 | qla_uprintf(&uiter, "%08x ", fw->xmt0_dma_reg[cnt]); | ||
1788 | } | ||
1789 | |||
1790 | qla_uprintf(&uiter, "\n\nXMT1 Data DMA Registers"); | ||
1791 | for (cnt = 0; cnt < sizeof(fw->xmt1_dma_reg) / 4; cnt++) { | ||
1792 | if (cnt % 8 == 0) | ||
1793 | qla_uprintf(&uiter, "\n"); | ||
1794 | |||
1795 | qla_uprintf(&uiter, "%08x ", fw->xmt1_dma_reg[cnt]); | ||
1796 | } | ||
1797 | |||
1798 | qla_uprintf(&uiter, "\n\nXMT2 Data DMA Registers"); | ||
1799 | for (cnt = 0; cnt < sizeof(fw->xmt2_dma_reg) / 4; cnt++) { | ||
1800 | if (cnt % 8 == 0) | ||
1801 | qla_uprintf(&uiter, "\n"); | ||
1802 | |||
1803 | qla_uprintf(&uiter, "%08x ", fw->xmt2_dma_reg[cnt]); | ||
1804 | } | ||
1805 | |||
1806 | qla_uprintf(&uiter, "\n\nXMT3 Data DMA Registers"); | ||
1807 | for (cnt = 0; cnt < sizeof(fw->xmt3_dma_reg) / 4; cnt++) { | ||
1808 | if (cnt % 8 == 0) | ||
1809 | qla_uprintf(&uiter, "\n"); | ||
1810 | |||
1811 | qla_uprintf(&uiter, "%08x ", fw->xmt3_dma_reg[cnt]); | ||
1812 | } | ||
1813 | |||
1814 | qla_uprintf(&uiter, "\n\nXMT4 Data DMA Registers"); | ||
1815 | for (cnt = 0; cnt < sizeof(fw->xmt4_dma_reg) / 4; cnt++) { | ||
1816 | if (cnt % 8 == 0) | ||
1817 | qla_uprintf(&uiter, "\n"); | ||
1818 | |||
1819 | qla_uprintf(&uiter, "%08x ", fw->xmt4_dma_reg[cnt]); | ||
1820 | } | ||
1821 | |||
1822 | qla_uprintf(&uiter, "\n\nXMT Data DMA Common Registers"); | ||
1823 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) { | ||
1824 | if (cnt % 8 == 0) | ||
1825 | qla_uprintf(&uiter, "\n"); | ||
1826 | |||
1827 | qla_uprintf(&uiter, "%08x ", fw->xmt_data_dma_reg[cnt]); | ||
1828 | } | ||
1829 | |||
1830 | qla_uprintf(&uiter, "\n\nRCV Thread 0 Data DMA Registers"); | ||
1831 | for (cnt = 0; cnt < sizeof(fw->rcvt0_data_dma_reg) / 4; cnt++) { | ||
1832 | if (cnt % 8 == 0) | ||
1833 | qla_uprintf(&uiter, "\n"); | ||
1834 | |||
1835 | qla_uprintf(&uiter, "%08x ", fw->rcvt0_data_dma_reg[cnt]); | ||
1836 | } | ||
1837 | |||
1838 | qla_uprintf(&uiter, "\n\nRCV Thread 1 Data DMA Registers"); | ||
1839 | for (cnt = 0; cnt < sizeof(fw->rcvt1_data_dma_reg) / 4; cnt++) { | ||
1840 | if (cnt % 8 == 0) | ||
1841 | qla_uprintf(&uiter, "\n"); | ||
1842 | |||
1843 | qla_uprintf(&uiter, "%08x ", fw->rcvt1_data_dma_reg[cnt]); | ||
1844 | } | ||
1845 | |||
1846 | qla_uprintf(&uiter, "\n\nRISC GP Registers"); | ||
1847 | for (cnt = 0; cnt < sizeof(fw->risc_gp_reg) / 4; cnt++) { | ||
1848 | if (cnt % 8 == 0) | ||
1849 | qla_uprintf(&uiter, "\n"); | ||
1850 | |||
1851 | qla_uprintf(&uiter, "%08x ", fw->risc_gp_reg[cnt]); | ||
1852 | } | ||
1853 | |||
1854 | qla_uprintf(&uiter, "\n\nLMC Registers"); | ||
1855 | for (cnt = 0; cnt < sizeof(fw->lmc_reg) / 4; cnt++) { | ||
1856 | if (cnt % 8 == 0) | ||
1857 | qla_uprintf(&uiter, "\n"); | ||
1858 | |||
1859 | qla_uprintf(&uiter, "%08x ", fw->lmc_reg[cnt]); | ||
1860 | } | ||
1861 | |||
1862 | qla_uprintf(&uiter, "\n\nFPM Hardware Registers"); | ||
1863 | for (cnt = 0; cnt < sizeof(fw->fpm_hdw_reg) / 4; cnt++) { | ||
1864 | if (cnt % 8 == 0) | ||
1865 | qla_uprintf(&uiter, "\n"); | ||
1866 | |||
1867 | qla_uprintf(&uiter, "%08x ", fw->fpm_hdw_reg[cnt]); | ||
1868 | } | ||
1869 | |||
1870 | qla_uprintf(&uiter, "\n\nFB Hardware Registers"); | ||
1871 | for (cnt = 0; cnt < sizeof(fw->fb_hdw_reg) / 4; cnt++) { | ||
1872 | if (cnt % 8 == 0) | ||
1873 | qla_uprintf(&uiter, "\n"); | ||
1874 | |||
1875 | qla_uprintf(&uiter, "%08x ", fw->fb_hdw_reg[cnt]); | ||
1876 | } | ||
1877 | |||
1878 | qla_uprintf(&uiter, "\n\nCode RAM"); | ||
1879 | for (cnt = 0; cnt < sizeof (fw->code_ram) / 4; cnt++) { | ||
1880 | if (cnt % 8 == 0) { | ||
1881 | qla_uprintf(&uiter, "\n%08x: ", cnt + 0x20000); | ||
1882 | } | ||
1883 | qla_uprintf(&uiter, "%08x ", fw->code_ram[cnt]); | ||
1884 | } | ||
1885 | |||
1886 | qla_uprintf(&uiter, "\n\nExternal Memory"); | ||
1887 | ext_mem_cnt = ha->fw_memory_size - 0x100000 + 1; | ||
1888 | for (cnt = 0; cnt < ext_mem_cnt; cnt++) { | ||
1889 | if (cnt % 8 == 0) { | ||
1890 | qla_uprintf(&uiter, "\n%08x: ", cnt + 0x100000); | ||
1891 | } | ||
1892 | qla_uprintf(&uiter, "%08x ", fw->ext_mem[cnt]); | ||
1893 | } | ||
1894 | |||
1895 | qla_uprintf(&uiter, "\n[<==END] ISP Debug Dump"); | ||
1896 | } | ||
1897 | |||
1898 | |||
1899 | /****************************************************************************/ | 1340 | /****************************************************************************/ |
1900 | /* Driver Debug Functions. */ | 1341 | /* Driver Debug Functions. */ |
1901 | /****************************************************************************/ | 1342 | /****************************************************************************/ |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index ab6afeaa2f2c..533425338e05 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -37,134 +37,86 @@ | |||
37 | /* | 37 | /* |
38 | * Macros use for debugging the driver. | 38 | * Macros use for debugging the driver. |
39 | */ | 39 | */ |
40 | #undef ENTER_TRACE | ||
41 | #if defined(ENTER_TRACE) | ||
42 | #define ENTER(x) do { printk("qla2100 : Entering %s()\n", x); } while (0) | ||
43 | #define LEAVE(x) do { printk("qla2100 : Leaving %s()\n", x); } while (0) | ||
44 | #define ENTER_INTR(x) do { printk("qla2100 : Entering %s()\n", x); } while (0) | ||
45 | #define LEAVE_INTR(x) do { printk("qla2100 : Leaving %s()\n", x); } while (0) | ||
46 | #else | ||
47 | #define ENTER(x) do {} while (0) | ||
48 | #define LEAVE(x) do {} while (0) | ||
49 | #define ENTER_INTR(x) do {} while (0) | ||
50 | #define LEAVE_INTR(x) do {} while (0) | ||
51 | #endif | ||
52 | 40 | ||
53 | #if DEBUG_QLA2100 | 41 | #define DEBUG(x) do { if (extended_error_logging) { x; } } while (0) |
54 | #define DEBUG(x) do {x;} while (0); | ||
55 | #else | ||
56 | #define DEBUG(x) do {} while (0); | ||
57 | #endif | ||
58 | 42 | ||
59 | #if defined(QL_DEBUG_LEVEL_1) | 43 | #if defined(QL_DEBUG_LEVEL_1) |
60 | #define DEBUG1(x) do {x;} while (0); | 44 | #define DEBUG1(x) do {x;} while (0) |
61 | #else | 45 | #else |
62 | #define DEBUG1(x) do {} while (0); | 46 | #define DEBUG1(x) do {} while (0) |
63 | #endif | 47 | #endif |
64 | 48 | ||
65 | #if defined(QL_DEBUG_LEVEL_2) | 49 | #define DEBUG2(x) do { if (extended_error_logging) { x; } } while (0) |
66 | #define DEBUG2(x) do {x;} while (0); | 50 | #define DEBUG2_3(x) do { if (extended_error_logging) { x; } } while (0) |
67 | #define DEBUG2_3(x) do {x;} while (0); | 51 | #define DEBUG2_3_11(x) do { if (extended_error_logging) { x; } } while (0) |
68 | #define DEBUG2_3_11(x) do {x;} while (0); | 52 | #define DEBUG2_9_10(x) do { if (extended_error_logging) { x; } } while (0) |
69 | #define DEBUG2_9_10(x) do {x;} while (0); | 53 | #define DEBUG2_11(x) do { if (extended_error_logging) { x; } } while (0) |
70 | #define DEBUG2_11(x) do {x;} while (0); | 54 | #define DEBUG2_13(x) do { if (extended_error_logging) { x; } } while (0) |
71 | #define DEBUG2_13(x) do {x;} while (0); | ||
72 | #else | ||
73 | #define DEBUG2(x) do {} while (0); | ||
74 | #endif | ||
75 | 55 | ||
76 | #if defined(QL_DEBUG_LEVEL_3) | 56 | #if defined(QL_DEBUG_LEVEL_3) |
77 | #define DEBUG3(x) do {x;} while (0); | 57 | #define DEBUG3(x) do {x;} while (0) |
78 | #define DEBUG2_3(x) do {x;} while (0); | 58 | #define DEBUG3_11(x) do {x;} while (0) |
79 | #define DEBUG2_3_11(x) do {x;} while (0); | ||
80 | #define DEBUG3_11(x) do {x;} while (0); | ||
81 | #else | 59 | #else |
82 | #define DEBUG3(x) do {} while (0); | 60 | #define DEBUG3(x) do {} while (0) |
83 | #if !defined(QL_DEBUG_LEVEL_2) | ||
84 | #define DEBUG2_3(x) do {} while (0); | ||
85 | #endif | ||
86 | #endif | 61 | #endif |
87 | 62 | ||
88 | #if defined(QL_DEBUG_LEVEL_4) | 63 | #if defined(QL_DEBUG_LEVEL_4) |
89 | #define DEBUG4(x) do {x;} while (0); | 64 | #define DEBUG4(x) do {x;} while (0) |
90 | #else | 65 | #else |
91 | #define DEBUG4(x) do {} while (0); | 66 | #define DEBUG4(x) do {} while (0) |
92 | #endif | 67 | #endif |
93 | 68 | ||
94 | #if defined(QL_DEBUG_LEVEL_5) | 69 | #if defined(QL_DEBUG_LEVEL_5) |
95 | #define DEBUG5(x) do {x;} while (0); | 70 | #define DEBUG5(x) do {x;} while (0) |
96 | #else | 71 | #else |
97 | #define DEBUG5(x) do {} while (0); | 72 | #define DEBUG5(x) do {} while (0) |
98 | #endif | 73 | #endif |
99 | 74 | ||
100 | #if defined(QL_DEBUG_LEVEL_7) | 75 | #if defined(QL_DEBUG_LEVEL_7) |
101 | #define DEBUG7(x) do {x;} while (0); | 76 | #define DEBUG7(x) do {x;} while (0) |
102 | #else | 77 | #else |
103 | #define DEBUG7(x) do {} while (0); | 78 | #define DEBUG7(x) do {} while (0) |
104 | #endif | 79 | #endif |
105 | 80 | ||
106 | #if defined(QL_DEBUG_LEVEL_9) | 81 | #if defined(QL_DEBUG_LEVEL_9) |
107 | #define DEBUG9(x) do {x;} while (0); | 82 | #define DEBUG9(x) do {x;} while (0) |
108 | #define DEBUG9_10(x) do {x;} while (0); | 83 | #define DEBUG9_10(x) do {x;} while (0) |
109 | #define DEBUG2_9_10(x) do {x;} while (0); | ||
110 | #else | 84 | #else |
111 | #define DEBUG9(x) do {} while (0); | 85 | #define DEBUG9(x) do {} while (0) |
112 | #endif | 86 | #endif |
113 | 87 | ||
114 | #if defined(QL_DEBUG_LEVEL_10) | 88 | #if defined(QL_DEBUG_LEVEL_10) |
115 | #define DEBUG10(x) do {x;} while (0); | 89 | #define DEBUG10(x) do {x;} while (0) |
116 | #define DEBUG2_9_10(x) do {x;} while (0); | 90 | #define DEBUG9_10(x) do {x;} while (0) |
117 | #define DEBUG9_10(x) do {x;} while (0); | ||
118 | #else | 91 | #else |
119 | #define DEBUG10(x) do {} while (0); | 92 | #define DEBUG10(x) do {} while (0) |
120 | #if !defined(DEBUG2_9_10) | ||
121 | #define DEBUG2_9_10(x) do {} while (0); | ||
122 | #endif | ||
123 | #if !defined(DEBUG9_10) | 93 | #if !defined(DEBUG9_10) |
124 | #define DEBUG9_10(x) do {} while (0); | 94 | #define DEBUG9_10(x) do {} while (0) |
125 | #endif | 95 | #endif |
126 | #endif | 96 | #endif |
127 | 97 | ||
128 | #if defined(QL_DEBUG_LEVEL_11) | 98 | #if defined(QL_DEBUG_LEVEL_11) |
129 | #define DEBUG11(x) do{x;} while(0); | 99 | #define DEBUG11(x) do{x;} while(0) |
130 | #if !defined(DEBUG2_11) | ||
131 | #define DEBUG2_11(x) do{x;} while(0); | ||
132 | #endif | ||
133 | #if !defined(DEBUG2_3_11) | ||
134 | #define DEBUG2_3_11(x) do{x;} while(0); | ||
135 | #endif | ||
136 | #if !defined(DEBUG3_11) | 100 | #if !defined(DEBUG3_11) |
137 | #define DEBUG3_11(x) do{x;} while(0); | 101 | #define DEBUG3_11(x) do{x;} while(0) |
138 | #endif | 102 | #endif |
139 | #else | 103 | #else |
140 | #define DEBUG11(x) do{} while(0); | 104 | #define DEBUG11(x) do{} while(0) |
141 | #if !defined(QL_DEBUG_LEVEL_2) | ||
142 | #define DEBUG2_11(x) do{} while(0); | ||
143 | #if !defined(QL_DEBUG_LEVEL_3) | ||
144 | #define DEBUG2_3_11(x) do{} while(0); | ||
145 | #endif | ||
146 | #endif | ||
147 | #if !defined(QL_DEBUG_LEVEL_3) | 105 | #if !defined(QL_DEBUG_LEVEL_3) |
148 | #define DEBUG3_11(x) do{} while(0); | 106 | #define DEBUG3_11(x) do{} while(0) |
149 | #endif | 107 | #endif |
150 | #endif | 108 | #endif |
151 | 109 | ||
152 | #if defined(QL_DEBUG_LEVEL_12) | 110 | #if defined(QL_DEBUG_LEVEL_12) |
153 | #define DEBUG12(x) do {x;} while (0); | 111 | #define DEBUG12(x) do {x;} while (0) |
154 | #else | 112 | #else |
155 | #define DEBUG12(x) do {} while (0); | 113 | #define DEBUG12(x) do {} while (0) |
156 | #endif | 114 | #endif |
157 | 115 | ||
158 | #if defined(QL_DEBUG_LEVEL_13) | 116 | #if defined(QL_DEBUG_LEVEL_13) |
159 | #define DEBUG13(x) do {x;} while (0) | 117 | #define DEBUG13(x) do {x;} while (0) |
160 | #if !defined(DEBUG2_13) | ||
161 | #define DEBUG2_13(x) do {x;} while(0) | ||
162 | #endif | ||
163 | #else | 118 | #else |
164 | #define DEBUG13(x) do {} while (0) | 119 | #define DEBUG13(x) do {} while (0) |
165 | #if !defined(QL_DEBUG_LEVEL_2) | ||
166 | #define DEBUG2_13(x) do {} while(0) | ||
167 | #endif | ||
168 | #endif | 120 | #endif |
169 | 121 | ||
170 | #if defined(QL_DEBUG_LEVEL_14) | 122 | #if defined(QL_DEBUG_LEVEL_14) |
@@ -176,9 +128,6 @@ | |||
176 | /* | 128 | /* |
177 | * Firmware Dump structure definition | 129 | * Firmware Dump structure definition |
178 | */ | 130 | */ |
179 | #define FW_DUMP_SIZE_128K 0xBC000 | ||
180 | #define FW_DUMP_SIZE_512K 0x2FC000 | ||
181 | #define FW_DUMP_SIZE_1M 0x5FC000 | ||
182 | 131 | ||
183 | struct qla2300_fw_dump { | 132 | struct qla2300_fw_dump { |
184 | uint16_t hccr; | 133 | uint16_t hccr; |
@@ -224,8 +173,6 @@ struct qla2100_fw_dump { | |||
224 | uint16_t risc_ram[0xf000]; | 173 | uint16_t risc_ram[0xf000]; |
225 | }; | 174 | }; |
226 | 175 | ||
227 | #define FW_DUMP_SIZE_24XX 0x2B0000 | ||
228 | |||
229 | struct qla24xx_fw_dump { | 176 | struct qla24xx_fw_dump { |
230 | uint32_t host_status; | 177 | uint32_t host_status; |
231 | uint32_t host_reg[32]; | 178 | uint32_t host_reg[32]; |
@@ -257,3 +204,39 @@ struct qla24xx_fw_dump { | |||
257 | uint32_t code_ram[0x2000]; | 204 | uint32_t code_ram[0x2000]; |
258 | uint32_t ext_mem[1]; | 205 | uint32_t ext_mem[1]; |
259 | }; | 206 | }; |
207 | |||
208 | #define EFT_NUM_BUFFERS 4 | ||
209 | #define EFT_BYTES_PER_BUFFER 0x4000 | ||
210 | #define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS)) | ||
211 | |||
212 | struct qla2xxx_fw_dump { | ||
213 | uint8_t signature[4]; | ||
214 | uint32_t version; | ||
215 | |||
216 | uint32_t fw_major_version; | ||
217 | uint32_t fw_minor_version; | ||
218 | uint32_t fw_subminor_version; | ||
219 | uint32_t fw_attributes; | ||
220 | |||
221 | uint32_t vendor; | ||
222 | uint32_t device; | ||
223 | uint32_t subsystem_vendor; | ||
224 | uint32_t subsystem_device; | ||
225 | |||
226 | uint32_t fixed_size; | ||
227 | uint32_t mem_size; | ||
228 | uint32_t req_q_size; | ||
229 | uint32_t rsp_q_size; | ||
230 | |||
231 | uint32_t eft_size; | ||
232 | uint32_t eft_addr_l; | ||
233 | uint32_t eft_addr_h; | ||
234 | |||
235 | uint32_t header_size; | ||
236 | |||
237 | union { | ||
238 | struct qla2100_fw_dump isp21; | ||
239 | struct qla2300_fw_dump isp23; | ||
240 | struct qla24xx_fw_dump isp24; | ||
241 | } isp; | ||
242 | }; | ||
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index d6f6579cfd27..bb0b5f5e31a5 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -608,7 +608,9 @@ typedef struct { | |||
608 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ | 608 | #define MBC_SERDES_PARAMS 0x10 /* Serdes Tx Parameters. */ |
609 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ | 609 | #define MBC_GET_IOCB_STATUS 0x12 /* Get IOCB status command. */ |
610 | #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ | 610 | #define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */ |
611 | #define MBC_TRACE_CONTROL 0x27 /* Trace control command. */ | ||
611 | #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ | 612 | #define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */ |
613 | #define MBC_READ_SFP 0x31 /* Read SFP Data. */ | ||
612 | #define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */ | 614 | #define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */ |
613 | #define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */ | 615 | #define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */ |
614 | #define MBC_MID_GET_VP_DATABASE 0x49 /* MID Get VP Database. */ | 616 | #define MBC_MID_GET_VP_DATABASE 0x49 /* MID Get VP Database. */ |
@@ -618,6 +620,9 @@ typedef struct { | |||
618 | #define MBC_GET_LINK_PRIV_STATS 0x6d /* Get link & private data. */ | 620 | #define MBC_GET_LINK_PRIV_STATS 0x6d /* Get link & private data. */ |
619 | #define MBC_SET_VENDOR_ID 0x76 /* Set Vendor ID. */ | 621 | #define MBC_SET_VENDOR_ID 0x76 /* Set Vendor ID. */ |
620 | 622 | ||
623 | #define TC_ENABLE 4 | ||
624 | #define TC_DISABLE 5 | ||
625 | |||
621 | /* Firmware return data sizes */ | 626 | /* Firmware return data sizes */ |
622 | #define FCAL_MAP_SIZE 128 | 627 | #define FCAL_MAP_SIZE 128 |
623 | 628 | ||
@@ -1997,7 +2002,6 @@ struct isp_operations { | |||
1997 | uint32_t); | 2002 | uint32_t); |
1998 | 2003 | ||
1999 | void (*fw_dump) (struct scsi_qla_host *, int); | 2004 | void (*fw_dump) (struct scsi_qla_host *, int); |
2000 | void (*ascii_fw_dump) (struct scsi_qla_host *); | ||
2001 | 2005 | ||
2002 | int (*beacon_on) (struct scsi_qla_host *); | 2006 | int (*beacon_on) (struct scsi_qla_host *); |
2003 | int (*beacon_off) (struct scsi_qla_host *); | 2007 | int (*beacon_off) (struct scsi_qla_host *); |
@@ -2041,6 +2045,7 @@ typedef struct scsi_qla_host { | |||
2041 | uint32_t enable_led_scheme :1; | 2045 | uint32_t enable_led_scheme :1; |
2042 | uint32_t msi_enabled :1; | 2046 | uint32_t msi_enabled :1; |
2043 | uint32_t msix_enabled :1; | 2047 | uint32_t msix_enabled :1; |
2048 | uint32_t disable_serdes :1; | ||
2044 | } flags; | 2049 | } flags; |
2045 | 2050 | ||
2046 | atomic_t loop_state; | 2051 | atomic_t loop_state; |
@@ -2238,6 +2243,11 @@ typedef struct scsi_qla_host { | |||
2238 | struct sns_cmd_pkt *sns_cmd; | 2243 | struct sns_cmd_pkt *sns_cmd; |
2239 | dma_addr_t sns_cmd_dma; | 2244 | dma_addr_t sns_cmd_dma; |
2240 | 2245 | ||
2246 | #define SFP_DEV_SIZE 256 | ||
2247 | #define SFP_BLOCK_SIZE 64 | ||
2248 | void *sfp_data; | ||
2249 | dma_addr_t sfp_data_dma; | ||
2250 | |||
2241 | struct task_struct *dpc_thread; | 2251 | struct task_struct *dpc_thread; |
2242 | uint8_t dpc_active; /* DPC routine is active */ | 2252 | uint8_t dpc_active; /* DPC routine is active */ |
2243 | 2253 | ||
@@ -2303,11 +2313,12 @@ typedef struct scsi_qla_host { | |||
2303 | uint16_t fw_seriallink_options24[4]; | 2313 | uint16_t fw_seriallink_options24[4]; |
2304 | 2314 | ||
2305 | /* Firmware dump information. */ | 2315 | /* Firmware dump information. */ |
2306 | void *fw_dump; | 2316 | struct qla2xxx_fw_dump *fw_dump; |
2317 | uint32_t fw_dump_len; | ||
2307 | int fw_dumped; | 2318 | int fw_dumped; |
2308 | int fw_dump_reading; | 2319 | int fw_dump_reading; |
2309 | char *fw_dump_buffer; | 2320 | dma_addr_t eft_dma; |
2310 | int fw_dump_buffer_len; | 2321 | void *eft; |
2311 | 2322 | ||
2312 | uint8_t host_str[16]; | 2323 | uint8_t host_str[16]; |
2313 | uint32_t pci_attr; | 2324 | uint32_t pci_attr; |
diff --git a/drivers/scsi/qla2xxx/qla_devtbl.h b/drivers/scsi/qla2xxx/qla_devtbl.h index a8fc0ffc7fc5..dd435410dfa2 100644 --- a/drivers/scsi/qla2xxx/qla_devtbl.h +++ b/drivers/scsi/qla2xxx/qla_devtbl.h | |||
@@ -1,4 +1,4 @@ | |||
1 | #define QLA_MODEL_NAMES 0x4A | 1 | #define QLA_MODEL_NAMES 0x57 |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Adapter model names and descriptions. | 4 | * Adapter model names and descriptions. |
@@ -76,6 +76,19 @@ static char *qla2x00_model_name[QLA_MODEL_NAMES*2] = { | |||
76 | "QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */ | 76 | "QLE2440", "PCI-Express to 4Gb FC, Single Channel", /* 0x145 */ |
77 | "QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */ | 77 | "QLE2464", "PCI-Express to 4Gb FC, Quad Channel", /* 0x146 */ |
78 | "QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */ | 78 | "QLA2440", "PCI-X 2.0 to 4Gb FC, Single Channel", /* 0x147 */ |
79 | " ", " ", /* 0x148 */ | 79 | "HP AE369A", "PCI-X 2.0 to 4Gb FC, Dual Channel", /* 0x148 */ |
80 | "QLA2340", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x149 */ | 80 | "QLA2340", "Sun 133MHz PCI-X to 2Gb FC, Single Channel", /* 0x149 */ |
81 | " ", " ", /* 0x14a */ | ||
82 | " ", " ", /* 0x14b */ | ||
83 | "QMC2432M", "IBM eServer BC 4Gb FC Expansion Card CFFE", /* 0x14c */ | ||
84 | "QMC2422M", "IBM eServer BC 4Gb FC Expansion Card CFFX", /* 0x14d */ | ||
85 | "QLE220", "Sun PCI-Express to 4Gb FC, Single Channel", /* 0x14e */ | ||
86 | " ", " ", /* 0x14f */ | ||
87 | " ", " ", /* 0x150 */ | ||
88 | " ", " ", /* 0x151 */ | ||
89 | "QME2462", "PCI-Express to 4Gb FC, Dual Channel Mezz HBA", /* 0x152 */ | ||
90 | "QMH2462", "PCI-Express to 4Gb FC, Dual Channel Mezz HBA", /* 0x153 */ | ||
91 | " ", " ", /* 0x154 */ | ||
92 | "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x155 */ | ||
93 | "QLE220", "PCI-Express to 4Gb FC, Single Channel", /* 0x156 */ | ||
81 | }; | 94 | }; |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 3af478663be7..a0a722cf4237 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -141,7 +141,7 @@ struct nvram_24xx { | |||
141 | * BIT 2 = Enable Memory Map BIOS | 141 | * BIT 2 = Enable Memory Map BIOS |
142 | * BIT 3 = Enable Selectable Boot | 142 | * BIT 3 = Enable Selectable Boot |
143 | * BIT 4 = Disable RISC code load | 143 | * BIT 4 = Disable RISC code load |
144 | * BIT 5 = | 144 | * BIT 5 = Disable Serdes |
145 | * BIT 6 = | 145 | * BIT 6 = |
146 | * BIT 7 = | 146 | * BIT 7 = |
147 | * | 147 | * |
@@ -278,7 +278,7 @@ struct init_cb_24xx { | |||
278 | uint16_t response_q_length; | 278 | uint16_t response_q_length; |
279 | uint16_t request_q_length; | 279 | uint16_t request_q_length; |
280 | 280 | ||
281 | uint16_t link_down_timeout; /* Milliseconds. */ | 281 | uint16_t link_down_on_nos; /* Milliseconds. */ |
282 | 282 | ||
283 | uint16_t prio_request_q_length; | 283 | uint16_t prio_request_q_length; |
284 | 284 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 164d53ccbfd0..750aef11c2ef 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -51,6 +51,8 @@ extern int qla2x00_abort_isp(scsi_qla_host_t *); | |||
51 | extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | 51 | extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); |
52 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); | 52 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); |
53 | 53 | ||
54 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); | ||
55 | |||
54 | /* | 56 | /* |
55 | * Global Data in qla_os.c source file. | 57 | * Global Data in qla_os.c source file. |
56 | */ | 58 | */ |
@@ -61,6 +63,8 @@ extern int qlport_down_retry; | |||
61 | extern int ql2xplogiabsentdevice; | 63 | extern int ql2xplogiabsentdevice; |
62 | extern int ql2xloginretrycount; | 64 | extern int ql2xloginretrycount; |
63 | extern int ql2xfdmienable; | 65 | extern int ql2xfdmienable; |
66 | extern int ql2xallocfwdump; | ||
67 | extern int extended_error_logging; | ||
64 | 68 | ||
65 | extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); | 69 | extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); |
66 | 70 | ||
@@ -204,6 +208,12 @@ qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | |||
204 | extern int | 208 | extern int |
205 | qla2x00_stop_firmware(scsi_qla_host_t *); | 209 | qla2x00_stop_firmware(scsi_qla_host_t *); |
206 | 210 | ||
211 | extern int | ||
212 | qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t); | ||
213 | |||
214 | extern int | ||
215 | qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); | ||
216 | |||
207 | /* | 217 | /* |
208 | * Global Function Prototypes in qla_isr.c source file. | 218 | * Global Function Prototypes in qla_isr.c source file. |
209 | */ | 219 | */ |
@@ -254,9 +264,6 @@ extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, | |||
254 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); | 264 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); |
255 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); | 265 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); |
256 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); | 266 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); |
257 | extern void qla2100_ascii_fw_dump(scsi_qla_host_t *); | ||
258 | extern void qla2300_ascii_fw_dump(scsi_qla_host_t *); | ||
259 | extern void qla24xx_ascii_fw_dump(scsi_qla_host_t *); | ||
260 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | 267 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
261 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 268 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
262 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); | 269 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); |
@@ -280,13 +287,6 @@ extern void *qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *, uint32_t, uint32_t); | |||
280 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); | 287 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); |
281 | 288 | ||
282 | /* | 289 | /* |
283 | * Global Function Prototypes in qla_xioctl.c source file. | ||
284 | */ | ||
285 | #define qla2x00_enqueue_aen(ha, cmd, mode) do { } while (0) | ||
286 | #define qla2x00_alloc_ioctl_mem(ha) (0) | ||
287 | #define qla2x00_free_ioctl_mem(ha) do { } while (0) | ||
288 | |||
289 | /* | ||
290 | * Global Function Prototypes in qla_attr.c source file. | 290 | * Global Function Prototypes in qla_attr.c source file. |
291 | */ | 291 | */ |
292 | struct class_device_attribute; | 292 | struct class_device_attribute; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 3d4487eac9b7..ce74a6025a07 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -89,6 +89,17 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
89 | 89 | ||
90 | ha->isp_ops.nvram_config(ha); | 90 | ha->isp_ops.nvram_config(ha); |
91 | 91 | ||
92 | if (ha->flags.disable_serdes) { | ||
93 | /* Mask HBA via NVRAM settings? */ | ||
94 | qla_printk(KERN_INFO, ha, "Masking HBA WWPN " | ||
95 | "%02x%02x%02x%02x%02x%02x%02x%02x (via NVRAM).\n", | ||
96 | ha->port_name[0], ha->port_name[1], | ||
97 | ha->port_name[2], ha->port_name[3], | ||
98 | ha->port_name[4], ha->port_name[5], | ||
99 | ha->port_name[6], ha->port_name[7]); | ||
100 | return QLA_FUNCTION_FAILED; | ||
101 | } | ||
102 | |||
92 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); | 103 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); |
93 | 104 | ||
94 | retry = 10; | 105 | retry = 10; |
@@ -770,29 +781,104 @@ qla24xx_chip_diag(scsi_qla_host_t *ha) | |||
770 | return rval; | 781 | return rval; |
771 | } | 782 | } |
772 | 783 | ||
773 | static void | 784 | void |
774 | qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | 785 | qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) |
775 | { | 786 | { |
776 | uint32_t dump_size = 0; | 787 | int rval; |
788 | uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, | ||
789 | eft_size; | ||
790 | dma_addr_t eft_dma; | ||
791 | void *eft; | ||
792 | |||
793 | if (ha->fw_dump) { | ||
794 | qla_printk(KERN_WARNING, ha, | ||
795 | "Firmware dump previously allocated.\n"); | ||
796 | return; | ||
797 | } | ||
777 | 798 | ||
778 | ha->fw_dumped = 0; | 799 | ha->fw_dumped = 0; |
800 | fixed_size = mem_size = eft_size = 0; | ||
779 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 801 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
780 | dump_size = sizeof(struct qla2100_fw_dump); | 802 | fixed_size = sizeof(struct qla2100_fw_dump); |
781 | } else if (IS_QLA23XX(ha)) { | 803 | } else if (IS_QLA23XX(ha)) { |
782 | dump_size = sizeof(struct qla2300_fw_dump); | 804 | fixed_size = offsetof(struct qla2300_fw_dump, data_ram); |
783 | dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t); | 805 | mem_size = (ha->fw_memory_size - 0x11000 + 1) * |
784 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 806 | sizeof(uint16_t); |
785 | dump_size = sizeof(struct qla24xx_fw_dump); | 807 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
786 | dump_size += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t); | 808 | fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem); |
809 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | ||
810 | sizeof(uint32_t); | ||
811 | |||
812 | /* Allocate memory for Extended Trace Buffer. */ | ||
813 | eft = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &eft_dma, | ||
814 | GFP_KERNEL); | ||
815 | if (!eft) { | ||
816 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | ||
817 | "(%d KB) for EFT.\n", EFT_SIZE / 1024); | ||
818 | goto cont_alloc; | ||
819 | } | ||
820 | |||
821 | rval = qla2x00_trace_control(ha, TC_ENABLE, eft_dma, | ||
822 | EFT_NUM_BUFFERS); | ||
823 | if (rval) { | ||
824 | qla_printk(KERN_WARNING, ha, "Unable to initialize " | ||
825 | "EFT (%d).\n", rval); | ||
826 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, eft, | ||
827 | eft_dma); | ||
828 | goto cont_alloc; | ||
829 | } | ||
830 | |||
831 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n", | ||
832 | EFT_SIZE / 1024); | ||
833 | |||
834 | eft_size = EFT_SIZE; | ||
835 | memset(eft, 0, eft_size); | ||
836 | ha->eft_dma = eft_dma; | ||
837 | ha->eft = eft; | ||
787 | } | 838 | } |
839 | cont_alloc: | ||
840 | req_q_size = ha->request_q_length * sizeof(request_t); | ||
841 | rsp_q_size = ha->response_q_length * sizeof(response_t); | ||
842 | |||
843 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); | ||
844 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + | ||
845 | eft_size; | ||
788 | 846 | ||
789 | ha->fw_dump = vmalloc(dump_size); | 847 | ha->fw_dump = vmalloc(dump_size); |
790 | if (ha->fw_dump) | 848 | if (!ha->fw_dump) { |
791 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware " | ||
792 | "dump...\n", dump_size / 1024); | ||
793 | else | ||
794 | qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for " | 849 | qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for " |
795 | "firmware dump!!!\n", dump_size / 1024); | 850 | "firmware dump!!!\n", dump_size / 1024); |
851 | |||
852 | if (ha->eft) { | ||
853 | dma_free_coherent(&ha->pdev->dev, eft_size, ha->eft, | ||
854 | ha->eft_dma); | ||
855 | ha->eft = NULL; | ||
856 | ha->eft_dma = 0; | ||
857 | } | ||
858 | return; | ||
859 | } | ||
860 | |||
861 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware dump...\n", | ||
862 | dump_size / 1024); | ||
863 | |||
864 | ha->fw_dump_len = dump_size; | ||
865 | ha->fw_dump->signature[0] = 'Q'; | ||
866 | ha->fw_dump->signature[1] = 'L'; | ||
867 | ha->fw_dump->signature[2] = 'G'; | ||
868 | ha->fw_dump->signature[3] = 'C'; | ||
869 | ha->fw_dump->version = __constant_htonl(1); | ||
870 | |||
871 | ha->fw_dump->fixed_size = htonl(fixed_size); | ||
872 | ha->fw_dump->mem_size = htonl(mem_size); | ||
873 | ha->fw_dump->req_q_size = htonl(req_q_size); | ||
874 | ha->fw_dump->rsp_q_size = htonl(rsp_q_size); | ||
875 | |||
876 | ha->fw_dump->eft_size = htonl(eft_size); | ||
877 | ha->fw_dump->eft_addr_l = htonl(LSD(ha->eft_dma)); | ||
878 | ha->fw_dump->eft_addr_h = htonl(MSD(ha->eft_dma)); | ||
879 | |||
880 | ha->fw_dump->header_size = | ||
881 | htonl(offsetof(struct qla2xxx_fw_dump, isp)); | ||
796 | } | 882 | } |
797 | 883 | ||
798 | /** | 884 | /** |
@@ -810,8 +896,6 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha) | |||
810 | dma_addr_t request_dma; | 896 | dma_addr_t request_dma; |
811 | request_t *request_ring; | 897 | request_t *request_ring; |
812 | 898 | ||
813 | qla2x00_alloc_fw_dump(ha); | ||
814 | |||
815 | /* Valid only on recent ISPs. */ | 899 | /* Valid only on recent ISPs. */ |
816 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 900 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) |
817 | return; | 901 | return; |
@@ -883,6 +967,9 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) | |||
883 | &ha->fw_subminor_version, | 967 | &ha->fw_subminor_version, |
884 | &ha->fw_attributes, &ha->fw_memory_size); | 968 | &ha->fw_attributes, &ha->fw_memory_size); |
885 | qla2x00_resize_request_q(ha); | 969 | qla2x00_resize_request_q(ha); |
970 | |||
971 | if (ql2xallocfwdump) | ||
972 | qla2x00_alloc_fw_dump(ha); | ||
886 | } | 973 | } |
887 | } else { | 974 | } else { |
888 | DEBUG2(printk(KERN_INFO | 975 | DEBUG2(printk(KERN_INFO |
@@ -1186,8 +1273,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1186 | rval = QLA_FUNCTION_FAILED; | 1273 | rval = QLA_FUNCTION_FAILED; |
1187 | 1274 | ||
1188 | if (atomic_read(&ha->loop_down_timer) && | 1275 | if (atomic_read(&ha->loop_down_timer) && |
1189 | (fw_state >= FSTATE_LOSS_OF_SYNC || | 1276 | fw_state != FSTATE_READY) { |
1190 | fw_state == FSTATE_WAIT_AL_PA)) { | ||
1191 | /* Loop down. Timeout on min_wait for states | 1277 | /* Loop down. Timeout on min_wait for states |
1192 | * other than Wait for Login. | 1278 | * other than Wait for Login. |
1193 | */ | 1279 | */ |
@@ -1555,6 +1641,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1555 | /* | 1641 | /* |
1556 | * Set host adapter parameters. | 1642 | * Set host adapter parameters. |
1557 | */ | 1643 | */ |
1644 | if (nv->host_p[0] & BIT_7) | ||
1645 | extended_error_logging = 1; | ||
1558 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); | 1646 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); |
1559 | /* Always load RISC code on non ISP2[12]00 chips. */ | 1647 | /* Always load RISC code on non ISP2[12]00 chips. */ |
1560 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) | 1648 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) |
@@ -1563,6 +1651,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1563 | ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0); | 1651 | ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0); |
1564 | ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0); | 1652 | ha->flags.enable_target_reset = ((nv->host_p[1] & BIT_3) ? 1 : 0); |
1565 | ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0; | 1653 | ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0; |
1654 | ha->flags.disable_serdes = 0; | ||
1566 | 1655 | ||
1567 | ha->operating_mode = | 1656 | ha->operating_mode = |
1568 | (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4; | 1657 | (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4; |
@@ -3048,14 +3137,14 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3048 | ha->isp_abort_cnt--; | 3137 | ha->isp_abort_cnt--; |
3049 | DEBUG(printk("qla%ld: ISP abort - " | 3138 | DEBUG(printk("qla%ld: ISP abort - " |
3050 | "retry remaining %d\n", | 3139 | "retry remaining %d\n", |
3051 | ha->host_no, ha->isp_abort_cnt);) | 3140 | ha->host_no, ha->isp_abort_cnt)); |
3052 | status = 1; | 3141 | status = 1; |
3053 | } | 3142 | } |
3054 | } else { | 3143 | } else { |
3055 | ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT; | 3144 | ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT; |
3056 | DEBUG(printk("qla2x00(%ld): ISP error recovery " | 3145 | DEBUG(printk("qla2x00(%ld): ISP error recovery " |
3057 | "- retrying (%d) more times\n", | 3146 | "- retrying (%d) more times\n", |
3058 | ha->host_no, ha->isp_abort_cnt);) | 3147 | ha->host_no, ha->isp_abort_cnt)); |
3059 | set_bit(ISP_ABORT_RETRY, &ha->dpc_flags); | 3148 | set_bit(ISP_ABORT_RETRY, &ha->dpc_flags); |
3060 | status = 1; | 3149 | status = 1; |
3061 | } | 3150 | } |
@@ -3069,7 +3158,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3069 | } else { | 3158 | } else { |
3070 | DEBUG(printk(KERN_INFO | 3159 | DEBUG(printk(KERN_INFO |
3071 | "qla2x00_abort_isp(%ld): exiting.\n", | 3160 | "qla2x00_abort_isp(%ld): exiting.\n", |
3072 | ha->host_no);) | 3161 | ha->host_no)); |
3073 | } | 3162 | } |
3074 | 3163 | ||
3075 | return(status); | 3164 | return(status); |
@@ -3145,7 +3234,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) | |||
3145 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 3234 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
3146 | if (!(status = qla2x00_fw_ready(ha))) { | 3235 | if (!(status = qla2x00_fw_ready(ha))) { |
3147 | DEBUG(printk("%s(): Start configure loop, " | 3236 | DEBUG(printk("%s(): Start configure loop, " |
3148 | "status = %d\n", __func__, status);) | 3237 | "status = %d\n", __func__, status)); |
3149 | 3238 | ||
3150 | /* Issue a marker after FW becomes ready. */ | 3239 | /* Issue a marker after FW becomes ready. */ |
3151 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | 3240 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); |
@@ -3169,7 +3258,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) | |||
3169 | 3258 | ||
3170 | DEBUG(printk("%s(): Configure loop done, status = 0x%x\n", | 3259 | DEBUG(printk("%s(): Configure loop done, status = 0x%x\n", |
3171 | __func__, | 3260 | __func__, |
3172 | status);) | 3261 | status)); |
3173 | } | 3262 | } |
3174 | return (status); | 3263 | return (status); |
3175 | } | 3264 | } |
@@ -3289,7 +3378,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3289 | nv->node_name[6] = 0x55; | 3378 | nv->node_name[6] = 0x55; |
3290 | nv->node_name[7] = 0x86; | 3379 | nv->node_name[7] = 0x86; |
3291 | nv->login_retry_count = __constant_cpu_to_le16(8); | 3380 | nv->login_retry_count = __constant_cpu_to_le16(8); |
3292 | nv->link_down_timeout = __constant_cpu_to_le16(200); | ||
3293 | nv->interrupt_delay_timer = __constant_cpu_to_le16(0); | 3381 | nv->interrupt_delay_timer = __constant_cpu_to_le16(0); |
3294 | nv->login_timeout = __constant_cpu_to_le16(0); | 3382 | nv->login_timeout = __constant_cpu_to_le16(0); |
3295 | nv->firmware_options_1 = | 3383 | nv->firmware_options_1 = |
@@ -3318,7 +3406,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3318 | *dptr1++ = *dptr2++; | 3406 | *dptr1++ = *dptr2++; |
3319 | 3407 | ||
3320 | icb->login_retry_count = nv->login_retry_count; | 3408 | icb->login_retry_count = nv->login_retry_count; |
3321 | icb->link_down_timeout = nv->link_down_timeout; | 3409 | icb->link_down_on_nos = nv->link_down_on_nos; |
3322 | 3410 | ||
3323 | /* Copy 2nd segment. */ | 3411 | /* Copy 2nd segment. */ |
3324 | dptr1 = (uint8_t *)&icb->interrupt_delay_timer; | 3412 | dptr1 = (uint8_t *)&icb->interrupt_delay_timer; |
@@ -3373,6 +3461,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
3373 | ha->flags.enable_lip_full_login = 1; | 3461 | ha->flags.enable_lip_full_login = 1; |
3374 | ha->flags.enable_target_reset = 1; | 3462 | ha->flags.enable_target_reset = 1; |
3375 | ha->flags.enable_led_scheme = 0; | 3463 | ha->flags.enable_led_scheme = 0; |
3464 | ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0; | ||
3376 | 3465 | ||
3377 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & | 3466 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & |
3378 | (BIT_6 | BIT_5 | BIT_4)) >> 4; | 3467 | (BIT_6 | BIT_5 | BIT_4)) >> 4; |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index b28ac0a27e25..795bf15b1b8f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -395,10 +395,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
395 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); | 395 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); |
396 | 396 | ||
397 | ha->flags.management_server_logged_in = 0; | 397 | ha->flags.management_server_logged_in = 0; |
398 | |||
399 | /* Update AEN queue. */ | ||
400 | qla2x00_enqueue_aen(ha, MBA_LIP_OCCURRED, NULL); | ||
401 | |||
402 | break; | 398 | break; |
403 | 399 | ||
404 | case MBA_LOOP_UP: /* Loop Up Event */ | 400 | case MBA_LOOP_UP: /* Loop Up Event */ |
@@ -418,9 +414,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
418 | link_speed); | 414 | link_speed); |
419 | 415 | ||
420 | ha->flags.management_server_logged_in = 0; | 416 | ha->flags.management_server_logged_in = 0; |
421 | |||
422 | /* Update AEN queue. */ | ||
423 | qla2x00_enqueue_aen(ha, MBA_LOOP_UP, NULL); | ||
424 | break; | 417 | break; |
425 | 418 | ||
426 | case MBA_LOOP_DOWN: /* Loop Down Event */ | 419 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
@@ -439,9 +432,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
439 | ha->link_data_rate = LDR_UNKNOWN; | 432 | ha->link_data_rate = LDR_UNKNOWN; |
440 | if (ql2xfdmienable) | 433 | if (ql2xfdmienable) |
441 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 434 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
442 | |||
443 | /* Update AEN queue. */ | ||
444 | qla2x00_enqueue_aen(ha, MBA_LOOP_DOWN, NULL); | ||
445 | break; | 435 | break; |
446 | 436 | ||
447 | case MBA_LIP_RESET: /* LIP reset occurred */ | 437 | case MBA_LIP_RESET: /* LIP reset occurred */ |
@@ -460,10 +450,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
460 | 450 | ||
461 | ha->operating_mode = LOOP; | 451 | ha->operating_mode = LOOP; |
462 | ha->flags.management_server_logged_in = 0; | 452 | ha->flags.management_server_logged_in = 0; |
463 | |||
464 | /* Update AEN queue. */ | ||
465 | qla2x00_enqueue_aen(ha, MBA_LIP_RESET, NULL); | ||
466 | |||
467 | break; | 453 | break; |
468 | 454 | ||
469 | case MBA_POINT_TO_POINT: /* Point-to-Point */ | 455 | case MBA_POINT_TO_POINT: /* Point-to-Point */ |
@@ -545,9 +531,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
545 | 531 | ||
546 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 532 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
547 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 533 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); |
548 | |||
549 | /* Update AEN queue. */ | ||
550 | qla2x00_enqueue_aen(ha, MBA_PORT_UPDATE, NULL); | ||
551 | break; | 534 | break; |
552 | 535 | ||
553 | case MBA_RSCN_UPDATE: /* State Change Registration */ | 536 | case MBA_RSCN_UPDATE: /* State Change Registration */ |
@@ -584,9 +567,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
584 | 567 | ||
585 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 568 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
586 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 569 | set_bit(RSCN_UPDATE, &ha->dpc_flags); |
587 | |||
588 | /* Update AEN queue. */ | ||
589 | qla2x00_enqueue_aen(ha, MBA_RSCN_UPDATE, &mb[0]); | ||
590 | break; | 570 | break; |
591 | 571 | ||
592 | /* case MBA_RIO_RESPONSE: */ | 572 | /* case MBA_RIO_RESPONSE: */ |
@@ -1452,8 +1432,8 @@ qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt) | |||
1452 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | 1432 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", |
1453 | __func__, ha->host_no, pkt, pkt->handle)); | 1433 | __func__, ha->host_no, pkt, pkt->handle)); |
1454 | 1434 | ||
1455 | DEBUG9(printk("%s: ct pkt dump:\n", __func__);) | 1435 | DEBUG9(printk("%s: ct pkt dump:\n", __func__)); |
1456 | DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx));) | 1436 | DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx))); |
1457 | 1437 | ||
1458 | /* Validate handle. */ | 1438 | /* Validate handle. */ |
1459 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) | 1439 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index d6cb3bd1a29a..879f281e2ea2 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -13,13 +13,13 @@ qla2x00_mbx_sem_timeout(unsigned long data) | |||
13 | { | 13 | { |
14 | struct semaphore *sem_ptr = (struct semaphore *)data; | 14 | struct semaphore *sem_ptr = (struct semaphore *)data; |
15 | 15 | ||
16 | DEBUG11(printk("qla2x00_sem_timeout: entered.\n");) | 16 | DEBUG11(printk("qla2x00_sem_timeout: entered.\n")); |
17 | 17 | ||
18 | if (sem_ptr != NULL) { | 18 | if (sem_ptr != NULL) { |
19 | up(sem_ptr); | 19 | up(sem_ptr); |
20 | } | 20 | } |
21 | 21 | ||
22 | DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n");) | 22 | DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n")); |
23 | } | 23 | } |
24 | 24 | ||
25 | /* | 25 | /* |
@@ -61,7 +61,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
61 | rval = QLA_SUCCESS; | 61 | rval = QLA_SUCCESS; |
62 | abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | 62 | abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); |
63 | 63 | ||
64 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 64 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * Wait for active mailbox commands to finish by waiting at most tov | 67 | * Wait for active mailbox commands to finish by waiting at most tov |
@@ -72,7 +72,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
72 | if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) { | 72 | if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) { |
73 | /* Timeout occurred. Return error. */ | 73 | /* Timeout occurred. Return error. */ |
74 | DEBUG2_3_11(printk("%s(%ld): cmd access timeout. " | 74 | DEBUG2_3_11(printk("%s(%ld): cmd access timeout. " |
75 | "Exiting.\n", __func__, ha->host_no);) | 75 | "Exiting.\n", __func__, ha->host_no)); |
76 | return QLA_FUNCTION_TIMEOUT; | 76 | return QLA_FUNCTION_TIMEOUT; |
77 | } | 77 | } |
78 | } | 78 | } |
@@ -86,7 +86,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
86 | spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); | 86 | spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); |
87 | 87 | ||
88 | DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n", | 88 | DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n", |
89 | ha->host_no, mcp->mb[0]);) | 89 | ha->host_no, mcp->mb[0])); |
90 | 90 | ||
91 | spin_lock_irqsave(&ha->hardware_lock, flags); | 91 | spin_lock_irqsave(&ha->hardware_lock, flags); |
92 | 92 | ||
@@ -131,14 +131,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
131 | 131 | ||
132 | /* Unlock mbx registers and wait for interrupt */ | 132 | /* Unlock mbx registers and wait for interrupt */ |
133 | DEBUG11(printk("%s(%ld): going to unlock irq & waiting for interrupt. " | 133 | DEBUG11(printk("%s(%ld): going to unlock irq & waiting for interrupt. " |
134 | "jiffies=%lx.\n", __func__, ha->host_no, jiffies);) | 134 | "jiffies=%lx.\n", __func__, ha->host_no, jiffies)); |
135 | 135 | ||
136 | /* Wait for mbx cmd completion until timeout */ | 136 | /* Wait for mbx cmd completion until timeout */ |
137 | 137 | ||
138 | if (!abort_active && io_lock_on) { | 138 | if (!abort_active && io_lock_on) { |
139 | /* sleep on completion semaphore */ | 139 | /* sleep on completion semaphore */ |
140 | DEBUG11(printk("%s(%ld): INTERRUPT MODE. Initializing timer.\n", | 140 | DEBUG11(printk("%s(%ld): INTERRUPT MODE. Initializing timer.\n", |
141 | __func__, ha->host_no);) | 141 | __func__, ha->host_no)); |
142 | 142 | ||
143 | init_timer(&tmp_intr_timer); | 143 | init_timer(&tmp_intr_timer); |
144 | tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem; | 144 | tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem; |
@@ -147,11 +147,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
147 | (void (*)(unsigned long))qla2x00_mbx_sem_timeout; | 147 | (void (*)(unsigned long))qla2x00_mbx_sem_timeout; |
148 | 148 | ||
149 | DEBUG11(printk("%s(%ld): Adding timer.\n", __func__, | 149 | DEBUG11(printk("%s(%ld): Adding timer.\n", __func__, |
150 | ha->host_no);) | 150 | ha->host_no)); |
151 | add_timer(&tmp_intr_timer); | 151 | add_timer(&tmp_intr_timer); |
152 | 152 | ||
153 | DEBUG11(printk("%s(%ld): going to unlock & sleep. " | 153 | DEBUG11(printk("%s(%ld): going to unlock & sleep. " |
154 | "time=0x%lx.\n", __func__, ha->host_no, jiffies);) | 154 | "time=0x%lx.\n", __func__, ha->host_no, jiffies)); |
155 | 155 | ||
156 | set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | 156 | set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); |
157 | 157 | ||
@@ -170,14 +170,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
170 | down(&ha->mbx_intr_sem); | 170 | down(&ha->mbx_intr_sem); |
171 | 171 | ||
172 | DEBUG11(printk("%s(%ld): waking up. time=0x%lx\n", __func__, | 172 | DEBUG11(printk("%s(%ld): waking up. time=0x%lx\n", __func__, |
173 | ha->host_no, jiffies);) | 173 | ha->host_no, jiffies)); |
174 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); | 174 | clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); |
175 | 175 | ||
176 | /* delete the timer */ | 176 | /* delete the timer */ |
177 | del_timer(&tmp_intr_timer); | 177 | del_timer(&tmp_intr_timer); |
178 | } else { | 178 | } else { |
179 | DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, | 179 | DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, |
180 | ha->host_no, command);) | 180 | ha->host_no, command)); |
181 | 181 | ||
182 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 182 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) |
183 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); | 183 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); |
@@ -209,7 +209,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
209 | uint16_t *iptr2; | 209 | uint16_t *iptr2; |
210 | 210 | ||
211 | DEBUG3_11(printk("%s(%ld): cmd %x completed.\n", __func__, | 211 | DEBUG3_11(printk("%s(%ld): cmd %x completed.\n", __func__, |
212 | ha->host_no, command);) | 212 | ha->host_no, command)); |
213 | 213 | ||
214 | /* Got interrupt. Clear the flag. */ | 214 | /* Got interrupt. Clear the flag. */ |
215 | ha->flags.mbox_int = 0; | 215 | ha->flags.mbox_int = 0; |
@@ -266,7 +266,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
266 | 266 | ||
267 | if (!abort_active) { | 267 | if (!abort_active) { |
268 | DEBUG11(printk("%s(%ld): checking for additional resp " | 268 | DEBUG11(printk("%s(%ld): checking for additional resp " |
269 | "interrupt.\n", __func__, ha->host_no);) | 269 | "interrupt.\n", __func__, ha->host_no)); |
270 | 270 | ||
271 | /* polling mode for non isp_abort commands. */ | 271 | /* polling mode for non isp_abort commands. */ |
272 | qla2x00_poll(ha); | 272 | qla2x00_poll(ha); |
@@ -277,9 +277,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
277 | if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { | 277 | if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { |
278 | /* not in dpc. schedule it for dpc to take over. */ | 278 | /* not in dpc. schedule it for dpc to take over. */ |
279 | DEBUG(printk("%s(%ld): timeout schedule " | 279 | DEBUG(printk("%s(%ld): timeout schedule " |
280 | "isp_abort_needed.\n", __func__, ha->host_no);) | 280 | "isp_abort_needed.\n", __func__, ha->host_no)); |
281 | DEBUG2_3_11(printk("%s(%ld): timeout schedule " | 281 | DEBUG2_3_11(printk("%s(%ld): timeout schedule " |
282 | "isp_abort_needed.\n", __func__, ha->host_no);) | 282 | "isp_abort_needed.\n", __func__, ha->host_no)); |
283 | qla_printk(KERN_WARNING, ha, | 283 | qla_printk(KERN_WARNING, ha, |
284 | "Mailbox command timeout occured. Scheduling ISP " | 284 | "Mailbox command timeout occured. Scheduling ISP " |
285 | "abort.\n"); | 285 | "abort.\n"); |
@@ -288,9 +288,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
288 | } else if (!abort_active) { | 288 | } else if (!abort_active) { |
289 | /* call abort directly since we are in the DPC thread */ | 289 | /* call abort directly since we are in the DPC thread */ |
290 | DEBUG(printk("%s(%ld): timeout calling abort_isp\n", | 290 | DEBUG(printk("%s(%ld): timeout calling abort_isp\n", |
291 | __func__, ha->host_no);) | 291 | __func__, ha->host_no)); |
292 | DEBUG2_3_11(printk("%s(%ld): timeout calling " | 292 | DEBUG2_3_11(printk("%s(%ld): timeout calling " |
293 | "abort_isp\n", __func__, ha->host_no);) | 293 | "abort_isp\n", __func__, ha->host_no)); |
294 | qla_printk(KERN_WARNING, ha, | 294 | qla_printk(KERN_WARNING, ha, |
295 | "Mailbox command timeout occured. Issuing ISP " | 295 | "Mailbox command timeout occured. Issuing ISP " |
296 | "abort.\n"); | 296 | "abort.\n"); |
@@ -303,9 +303,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
303 | } | 303 | } |
304 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | 304 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); |
305 | DEBUG(printk("%s(%ld): finished abort_isp\n", __func__, | 305 | DEBUG(printk("%s(%ld): finished abort_isp\n", __func__, |
306 | ha->host_no);) | 306 | ha->host_no)); |
307 | DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n", | 307 | DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n", |
308 | __func__, ha->host_no);) | 308 | __func__, ha->host_no)); |
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
@@ -316,9 +316,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) | |||
316 | if (rval) { | 316 | if (rval) { |
317 | DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, " | 317 | DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, " |
318 | "mbx2=%x, cmd=%x ****\n", __func__, ha->host_no, | 318 | "mbx2=%x, cmd=%x ****\n", __func__, ha->host_no, |
319 | mcp->mb[0], mcp->mb[1], mcp->mb[2], command);) | 319 | mcp->mb[0], mcp->mb[1], mcp->mb[2], command)); |
320 | } else { | 320 | } else { |
321 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 321 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
322 | } | 322 | } |
323 | 323 | ||
324 | return rval; | 324 | return rval; |
@@ -394,7 +394,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
394 | mbx_cmd_t mc; | 394 | mbx_cmd_t mc; |
395 | mbx_cmd_t *mcp = &mc; | 395 | mbx_cmd_t *mcp = &mc; |
396 | 396 | ||
397 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 397 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
398 | 398 | ||
399 | mcp->mb[0] = MBC_EXECUTE_FIRMWARE; | 399 | mcp->mb[0] = MBC_EXECUTE_FIRMWARE; |
400 | mcp->out_mb = MBX_0; | 400 | mcp->out_mb = MBX_0; |
@@ -424,10 +424,10 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
424 | } else { | 424 | } else { |
425 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 425 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
426 | DEBUG11(printk("%s(%ld): done exchanges=%x.\n", | 426 | DEBUG11(printk("%s(%ld): done exchanges=%x.\n", |
427 | __func__, ha->host_no, mcp->mb[1]);) | 427 | __func__, ha->host_no, mcp->mb[1])); |
428 | } else { | 428 | } else { |
429 | DEBUG11(printk("%s(%ld): done.\n", __func__, | 429 | DEBUG11(printk("%s(%ld): done.\n", __func__, |
430 | ha->host_no);) | 430 | ha->host_no)); |
431 | } | 431 | } |
432 | } | 432 | } |
433 | 433 | ||
@@ -611,7 +611,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
611 | mbx_cmd_t mc; | 611 | mbx_cmd_t mc; |
612 | mbx_cmd_t *mcp = &mc; | 612 | mbx_cmd_t *mcp = &mc; |
613 | 613 | ||
614 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no);) | 614 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no)); |
615 | 615 | ||
616 | mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; | 616 | mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; |
617 | mcp->mb[1] = 0xAAAA; | 617 | mcp->mb[1] = 0xAAAA; |
@@ -639,11 +639,11 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
639 | if (rval != QLA_SUCCESS) { | 639 | if (rval != QLA_SUCCESS) { |
640 | /*EMPTY*/ | 640 | /*EMPTY*/ |
641 | DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n", | 641 | DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n", |
642 | ha->host_no, rval);) | 642 | ha->host_no, rval)); |
643 | } else { | 643 | } else { |
644 | /*EMPTY*/ | 644 | /*EMPTY*/ |
645 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n", | 645 | DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n", |
646 | ha->host_no);) | 646 | ha->host_no)); |
647 | } | 647 | } |
648 | 648 | ||
649 | return rval; | 649 | return rval; |
@@ -671,7 +671,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
671 | mbx_cmd_t mc; | 671 | mbx_cmd_t mc; |
672 | mbx_cmd_t *mcp = &mc; | 672 | mbx_cmd_t *mcp = &mc; |
673 | 673 | ||
674 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 674 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
675 | 675 | ||
676 | mcp->mb[0] = MBC_VERIFY_CHECKSUM; | 676 | mcp->mb[0] = MBC_VERIFY_CHECKSUM; |
677 | mcp->out_mb = MBX_0; | 677 | mcp->out_mb = MBX_0; |
@@ -694,9 +694,9 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
694 | if (rval != QLA_SUCCESS) { | 694 | if (rval != QLA_SUCCESS) { |
695 | DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__, | 695 | DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__, |
696 | ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ? | 696 | ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA54XX(ha) ? |
697 | (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));) | 697 | (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]))); |
698 | } else { | 698 | } else { |
699 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 699 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
700 | } | 700 | } |
701 | 701 | ||
702 | return rval; | 702 | return rval; |
@@ -743,9 +743,9 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
743 | if (rval != QLA_SUCCESS) { | 743 | if (rval != QLA_SUCCESS) { |
744 | /*EMPTY*/ | 744 | /*EMPTY*/ |
745 | DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", | 745 | DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", |
746 | ha->host_no, rval);) | 746 | ha->host_no, rval)); |
747 | DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", | 747 | DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", |
748 | ha->host_no, rval);) | 748 | ha->host_no, rval)); |
749 | } else { | 749 | } else { |
750 | sts_entry_t *sts_entry = (sts_entry_t *) buffer; | 750 | sts_entry_t *sts_entry = (sts_entry_t *) buffer; |
751 | 751 | ||
@@ -781,7 +781,7 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
781 | mbx_cmd_t mc; | 781 | mbx_cmd_t mc; |
782 | mbx_cmd_t *mcp = &mc; | 782 | mbx_cmd_t *mcp = &mc; |
783 | 783 | ||
784 | DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);) | 784 | DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no)); |
785 | 785 | ||
786 | fcport = sp->fcport; | 786 | fcport = sp->fcport; |
787 | 787 | ||
@@ -813,11 +813,11 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
813 | 813 | ||
814 | if (rval != QLA_SUCCESS) { | 814 | if (rval != QLA_SUCCESS) { |
815 | DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n", | 815 | DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n", |
816 | ha->host_no, rval);) | 816 | ha->host_no, rval)); |
817 | } else { | 817 | } else { |
818 | sp->flags |= SRB_ABORT_PENDING; | 818 | sp->flags |= SRB_ABORT_PENDING; |
819 | DEBUG11(printk("qla2x00_abort_command(%ld): done.\n", | 819 | DEBUG11(printk("qla2x00_abort_command(%ld): done.\n", |
820 | ha->host_no);) | 820 | ha->host_no)); |
821 | } | 821 | } |
822 | 822 | ||
823 | return rval; | 823 | return rval; |
@@ -848,7 +848,7 @@ qla2x00_abort_target(fc_port_t *fcport) | |||
848 | if (fcport == NULL) | 848 | if (fcport == NULL) |
849 | return 0; | 849 | return 0; |
850 | 850 | ||
851 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);) | 851 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
852 | 852 | ||
853 | ha = fcport->ha; | 853 | ha = fcport->ha; |
854 | mcp->mb[0] = MBC_ABORT_TARGET; | 854 | mcp->mb[0] = MBC_ABORT_TARGET; |
@@ -872,11 +872,11 @@ qla2x00_abort_target(fc_port_t *fcport) | |||
872 | 872 | ||
873 | if (rval != QLA_SUCCESS) { | 873 | if (rval != QLA_SUCCESS) { |
874 | DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", | 874 | DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", |
875 | ha->host_no, rval);) | 875 | ha->host_no, rval)); |
876 | } else { | 876 | } else { |
877 | /*EMPTY*/ | 877 | /*EMPTY*/ |
878 | DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", | 878 | DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", |
879 | ha->host_no);) | 879 | ha->host_no)); |
880 | } | 880 | } |
881 | 881 | ||
882 | return rval; | 882 | return rval; |
@@ -912,7 +912,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
912 | mbx_cmd_t *mcp = &mc; | 912 | mbx_cmd_t *mcp = &mc; |
913 | 913 | ||
914 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n", | 914 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n", |
915 | ha->host_no);) | 915 | ha->host_no)); |
916 | 916 | ||
917 | mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; | 917 | mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; |
918 | mcp->out_mb = MBX_0; | 918 | mcp->out_mb = MBX_0; |
@@ -933,11 +933,11 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
933 | if (rval != QLA_SUCCESS) { | 933 | if (rval != QLA_SUCCESS) { |
934 | /*EMPTY*/ | 934 | /*EMPTY*/ |
935 | DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n", | 935 | DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n", |
936 | ha->host_no, rval);) | 936 | ha->host_no, rval)); |
937 | } else { | 937 | } else { |
938 | /*EMPTY*/ | 938 | /*EMPTY*/ |
939 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n", | 939 | DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n", |
940 | ha->host_no);) | 940 | ha->host_no)); |
941 | } | 941 | } |
942 | 942 | ||
943 | return rval; | 943 | return rval; |
@@ -968,7 +968,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
968 | mbx_cmd_t *mcp = &mc; | 968 | mbx_cmd_t *mcp = &mc; |
969 | 969 | ||
970 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n", | 970 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n", |
971 | ha->host_no);) | 971 | ha->host_no)); |
972 | 972 | ||
973 | mcp->mb[0] = MBC_GET_RETRY_COUNT; | 973 | mcp->mb[0] = MBC_GET_RETRY_COUNT; |
974 | mcp->out_mb = MBX_0; | 974 | mcp->out_mb = MBX_0; |
@@ -980,7 +980,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
980 | if (rval != QLA_SUCCESS) { | 980 | if (rval != QLA_SUCCESS) { |
981 | /*EMPTY*/ | 981 | /*EMPTY*/ |
982 | DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n", | 982 | DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n", |
983 | ha->host_no, mcp->mb[0]);) | 983 | ha->host_no, mcp->mb[0])); |
984 | } else { | 984 | } else { |
985 | /* Convert returned data and check our values. */ | 985 | /* Convert returned data and check our values. */ |
986 | *r_a_tov = mcp->mb[3] / 2; | 986 | *r_a_tov = mcp->mb[3] / 2; |
@@ -992,7 +992,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
992 | } | 992 | } |
993 | 993 | ||
994 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d " | 994 | DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d " |
995 | "ratov=%d.\n", ha->host_no, mcp->mb[3], ratov);) | 995 | "ratov=%d.\n", ha->host_no, mcp->mb[3], ratov)); |
996 | } | 996 | } |
997 | 997 | ||
998 | return rval; | 998 | return rval; |
@@ -1023,7 +1023,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) | |||
1023 | mbx_cmd_t *mcp = &mc; | 1023 | mbx_cmd_t *mcp = &mc; |
1024 | 1024 | ||
1025 | DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n", | 1025 | DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n", |
1026 | ha->host_no);) | 1026 | ha->host_no)); |
1027 | 1027 | ||
1028 | mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; | 1028 | mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; |
1029 | mcp->mb[2] = MSW(ha->init_cb_dma); | 1029 | mcp->mb[2] = MSW(ha->init_cb_dma); |
@@ -1043,11 +1043,11 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) | |||
1043 | /*EMPTY*/ | 1043 | /*EMPTY*/ |
1044 | DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x " | 1044 | DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x " |
1045 | "mb0=%x.\n", | 1045 | "mb0=%x.\n", |
1046 | ha->host_no, rval, mcp->mb[0]);) | 1046 | ha->host_no, rval, mcp->mb[0])); |
1047 | } else { | 1047 | } else { |
1048 | /*EMPTY*/ | 1048 | /*EMPTY*/ |
1049 | DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n", | 1049 | DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n", |
1050 | ha->host_no);) | 1050 | ha->host_no)); |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | return rval; | 1053 | return rval; |
@@ -1079,7 +1079,7 @@ qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) | |||
1079 | struct port_database_24xx *pd24; | 1079 | struct port_database_24xx *pd24; |
1080 | dma_addr_t pd_dma; | 1080 | dma_addr_t pd_dma; |
1081 | 1081 | ||
1082 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1082 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1083 | 1083 | ||
1084 | pd24 = NULL; | 1084 | pd24 = NULL; |
1085 | pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); | 1085 | pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); |
@@ -1220,7 +1220,7 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | |||
1220 | mbx_cmd_t *mcp = &mc; | 1220 | mbx_cmd_t *mcp = &mc; |
1221 | 1221 | ||
1222 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n", | 1222 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n", |
1223 | ha->host_no);) | 1223 | ha->host_no)); |
1224 | 1224 | ||
1225 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; | 1225 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; |
1226 | mcp->out_mb = MBX_0; | 1226 | mcp->out_mb = MBX_0; |
@@ -1235,11 +1235,11 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | |||
1235 | if (rval != QLA_SUCCESS) { | 1235 | if (rval != QLA_SUCCESS) { |
1236 | /*EMPTY*/ | 1236 | /*EMPTY*/ |
1237 | DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): " | 1237 | DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): " |
1238 | "failed=%x.\n", ha->host_no, rval);) | 1238 | "failed=%x.\n", ha->host_no, rval)); |
1239 | } else { | 1239 | } else { |
1240 | /*EMPTY*/ | 1240 | /*EMPTY*/ |
1241 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n", | 1241 | DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n", |
1242 | ha->host_no);) | 1242 | ha->host_no)); |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | return rval; | 1245 | return rval; |
@@ -1272,7 +1272,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1272 | mbx_cmd_t *mcp = &mc; | 1272 | mbx_cmd_t *mcp = &mc; |
1273 | 1273 | ||
1274 | DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n", | 1274 | DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n", |
1275 | ha->host_no);) | 1275 | ha->host_no)); |
1276 | 1276 | ||
1277 | mcp->mb[0] = MBC_GET_PORT_NAME; | 1277 | mcp->mb[0] = MBC_GET_PORT_NAME; |
1278 | mcp->out_mb = MBX_1|MBX_0; | 1278 | mcp->out_mb = MBX_1|MBX_0; |
@@ -1292,7 +1292,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1292 | if (rval != QLA_SUCCESS) { | 1292 | if (rval != QLA_SUCCESS) { |
1293 | /*EMPTY*/ | 1293 | /*EMPTY*/ |
1294 | DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n", | 1294 | DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n", |
1295 | ha->host_no, rval);) | 1295 | ha->host_no, rval)); |
1296 | } else { | 1296 | } else { |
1297 | if (name != NULL) { | 1297 | if (name != NULL) { |
1298 | /* This function returns name in big endian. */ | 1298 | /* This function returns name in big endian. */ |
@@ -1307,7 +1307,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n", | 1309 | DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n", |
1310 | ha->host_no);) | 1310 | ha->host_no)); |
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | return rval; | 1313 | return rval; |
@@ -1335,7 +1335,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) | |||
1335 | mbx_cmd_t mc; | 1335 | mbx_cmd_t mc; |
1336 | mbx_cmd_t *mcp = &mc; | 1336 | mbx_cmd_t *mcp = &mc; |
1337 | 1337 | ||
1338 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1338 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1339 | 1339 | ||
1340 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1340 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
1341 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; | 1341 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; |
@@ -1364,10 +1364,10 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) | |||
1364 | if (rval != QLA_SUCCESS) { | 1364 | if (rval != QLA_SUCCESS) { |
1365 | /*EMPTY*/ | 1365 | /*EMPTY*/ |
1366 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", | 1366 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", |
1367 | __func__, ha->host_no, rval);) | 1367 | __func__, ha->host_no, rval)); |
1368 | } else { | 1368 | } else { |
1369 | /*EMPTY*/ | 1369 | /*EMPTY*/ |
1370 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1370 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1371 | } | 1371 | } |
1372 | 1372 | ||
1373 | return rval; | 1373 | return rval; |
@@ -1400,10 +1400,10 @@ qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address, | |||
1400 | mbx_cmd_t *mcp = &mc; | 1400 | mbx_cmd_t *mcp = &mc; |
1401 | 1401 | ||
1402 | DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n", | 1402 | DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n", |
1403 | ha->host_no);) | 1403 | ha->host_no)); |
1404 | 1404 | ||
1405 | DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total " | 1405 | DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total " |
1406 | "tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov);) | 1406 | "tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov)); |
1407 | 1407 | ||
1408 | mcp->mb[0] = MBC_SEND_SNS_COMMAND; | 1408 | mcp->mb[0] = MBC_SEND_SNS_COMMAND; |
1409 | mcp->mb[1] = cmd_size; | 1409 | mcp->mb[1] = cmd_size; |
@@ -1421,12 +1421,12 @@ qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address, | |||
1421 | if (rval != QLA_SUCCESS) { | 1421 | if (rval != QLA_SUCCESS) { |
1422 | /*EMPTY*/ | 1422 | /*EMPTY*/ |
1423 | DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " | 1423 | DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " |
1424 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);) | 1424 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1])); |
1425 | DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " | 1425 | DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " |
1426 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);) | 1426 | "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1])); |
1427 | } else { | 1427 | } else { |
1428 | /*EMPTY*/ | 1428 | /*EMPTY*/ |
1429 | DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no);) | 1429 | DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no)); |
1430 | } | 1430 | } |
1431 | 1431 | ||
1432 | return rval; | 1432 | return rval; |
@@ -1442,7 +1442,7 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1442 | dma_addr_t lg_dma; | 1442 | dma_addr_t lg_dma; |
1443 | uint32_t iop[2]; | 1443 | uint32_t iop[2]; |
1444 | 1444 | ||
1445 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1445 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1446 | 1446 | ||
1447 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); | 1447 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); |
1448 | if (lg == NULL) { | 1448 | if (lg == NULL) { |
@@ -1458,13 +1458,15 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1458 | lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI); | 1458 | lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI); |
1459 | if (opt & BIT_0) | 1459 | if (opt & BIT_0) |
1460 | lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI); | 1460 | lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI); |
1461 | if (opt & BIT_1) | ||
1462 | lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI); | ||
1461 | lg->port_id[0] = al_pa; | 1463 | lg->port_id[0] = al_pa; |
1462 | lg->port_id[1] = area; | 1464 | lg->port_id[1] = area; |
1463 | lg->port_id[2] = domain; | 1465 | lg->port_id[2] = domain; |
1464 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); | 1466 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); |
1465 | if (rval != QLA_SUCCESS) { | 1467 | if (rval != QLA_SUCCESS) { |
1466 | DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB " | 1468 | DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB " |
1467 | "(%x).\n", __func__, ha->host_no, rval);) | 1469 | "(%x).\n", __func__, ha->host_no, rval)); |
1468 | } else if (lg->entry_status != 0) { | 1470 | } else if (lg->entry_status != 0) { |
1469 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 1471 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
1470 | "-- error status (%x).\n", __func__, ha->host_no, | 1472 | "-- error status (%x).\n", __func__, ha->host_no, |
@@ -1505,7 +1507,7 @@ qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1505 | break; | 1507 | break; |
1506 | } | 1508 | } |
1507 | } else { | 1509 | } else { |
1508 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1510 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1509 | 1511 | ||
1510 | iop[0] = le32_to_cpu(lg->io_parameter[0]); | 1512 | iop[0] = le32_to_cpu(lg->io_parameter[0]); |
1511 | 1513 | ||
@@ -1559,7 +1561,7 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1559 | mbx_cmd_t mc; | 1561 | mbx_cmd_t mc; |
1560 | mbx_cmd_t *mcp = &mc; | 1562 | mbx_cmd_t *mcp = &mc; |
1561 | 1563 | ||
1562 | DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no);) | 1564 | DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no)); |
1563 | 1565 | ||
1564 | mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; | 1566 | mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; |
1565 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 1567 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
@@ -1604,11 +1606,11 @@ qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1604 | /*EMPTY*/ | 1606 | /*EMPTY*/ |
1605 | DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x " | 1607 | DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x " |
1606 | "mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval, | 1608 | "mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval, |
1607 | mcp->mb[0], mcp->mb[1], mcp->mb[2]);) | 1609 | mcp->mb[0], mcp->mb[1], mcp->mb[2])); |
1608 | } else { | 1610 | } else { |
1609 | /*EMPTY*/ | 1611 | /*EMPTY*/ |
1610 | DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n", | 1612 | DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n", |
1611 | ha->host_no);) | 1613 | ha->host_no)); |
1612 | } | 1614 | } |
1613 | 1615 | ||
1614 | return rval; | 1616 | return rval; |
@@ -1643,7 +1645,7 @@ qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
1643 | fcport->d_id.b.domain, fcport->d_id.b.area, | 1645 | fcport->d_id.b.domain, fcport->d_id.b.area, |
1644 | fcport->d_id.b.al_pa, mb_ret, opt); | 1646 | fcport->d_id.b.al_pa, mb_ret, opt); |
1645 | 1647 | ||
1646 | DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1648 | DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1647 | 1649 | ||
1648 | mcp->mb[0] = MBC_LOGIN_LOOP_PORT; | 1650 | mcp->mb[0] = MBC_LOGIN_LOOP_PORT; |
1649 | if (HAS_EXTENDED_IDS(ha)) | 1651 | if (HAS_EXTENDED_IDS(ha)) |
@@ -1677,13 +1679,13 @@ qla2x00_login_local_device(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
1677 | 1679 | ||
1678 | DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " | 1680 | DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " |
1679 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, | 1681 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, |
1680 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);) | 1682 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7])); |
1681 | DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " | 1683 | DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " |
1682 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, | 1684 | "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, |
1683 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);) | 1685 | mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7])); |
1684 | } else { | 1686 | } else { |
1685 | /*EMPTY*/ | 1687 | /*EMPTY*/ |
1686 | DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1688 | DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1687 | } | 1689 | } |
1688 | 1690 | ||
1689 | return (rval); | 1691 | return (rval); |
@@ -1697,7 +1699,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1697 | struct logio_entry_24xx *lg; | 1699 | struct logio_entry_24xx *lg; |
1698 | dma_addr_t lg_dma; | 1700 | dma_addr_t lg_dma; |
1699 | 1701 | ||
1700 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 1702 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
1701 | 1703 | ||
1702 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); | 1704 | lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); |
1703 | if (lg == NULL) { | 1705 | if (lg == NULL) { |
@@ -1718,7 +1720,7 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1718 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); | 1720 | rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); |
1719 | if (rval != QLA_SUCCESS) { | 1721 | if (rval != QLA_SUCCESS) { |
1720 | DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB " | 1722 | DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB " |
1721 | "(%x).\n", __func__, ha->host_no, rval);) | 1723 | "(%x).\n", __func__, ha->host_no, rval)); |
1722 | } else if (lg->entry_status != 0) { | 1724 | } else if (lg->entry_status != 0) { |
1723 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 1725 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
1724 | "-- error status (%x).\n", __func__, ha->host_no, | 1726 | "-- error status (%x).\n", __func__, ha->host_no, |
@@ -1729,10 +1731,10 @@ qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1729 | "-- completion status (%x) ioparam=%x/%x.\n", __func__, | 1731 | "-- completion status (%x) ioparam=%x/%x.\n", __func__, |
1730 | ha->host_no, le16_to_cpu(lg->comp_status), | 1732 | ha->host_no, le16_to_cpu(lg->comp_status), |
1731 | le32_to_cpu(lg->io_parameter[0]), | 1733 | le32_to_cpu(lg->io_parameter[0]), |
1732 | le32_to_cpu(lg->io_parameter[1]));) | 1734 | le32_to_cpu(lg->io_parameter[1]))); |
1733 | } else { | 1735 | } else { |
1734 | /*EMPTY*/ | 1736 | /*EMPTY*/ |
1735 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 1737 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
1736 | } | 1738 | } |
1737 | 1739 | ||
1738 | dma_pool_free(ha->s_dma_pool, lg, lg_dma); | 1740 | dma_pool_free(ha->s_dma_pool, lg, lg_dma); |
@@ -1765,7 +1767,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1765 | mbx_cmd_t *mcp = &mc; | 1767 | mbx_cmd_t *mcp = &mc; |
1766 | 1768 | ||
1767 | DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n", | 1769 | DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n", |
1768 | ha->host_no);) | 1770 | ha->host_no)); |
1769 | 1771 | ||
1770 | mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; | 1772 | mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; |
1771 | mcp->out_mb = MBX_1|MBX_0; | 1773 | mcp->out_mb = MBX_1|MBX_0; |
@@ -1785,11 +1787,11 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1785 | if (rval != QLA_SUCCESS) { | 1787 | if (rval != QLA_SUCCESS) { |
1786 | /*EMPTY*/ | 1788 | /*EMPTY*/ |
1787 | DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x " | 1789 | DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x " |
1788 | "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1]);) | 1790 | "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1])); |
1789 | } else { | 1791 | } else { |
1790 | /*EMPTY*/ | 1792 | /*EMPTY*/ |
1791 | DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n", | 1793 | DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n", |
1792 | ha->host_no);) | 1794 | ha->host_no)); |
1793 | } | 1795 | } |
1794 | 1796 | ||
1795 | return rval; | 1797 | return rval; |
@@ -1818,7 +1820,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) | |||
1818 | mbx_cmd_t *mcp = &mc; | 1820 | mbx_cmd_t *mcp = &mc; |
1819 | 1821 | ||
1820 | DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n", | 1822 | DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n", |
1821 | ha->host_no);) | 1823 | ha->host_no)); |
1822 | 1824 | ||
1823 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; | 1825 | mcp->mb[0] = MBC_LIP_FULL_LOGIN; |
1824 | mcp->mb[1] = 0; | 1826 | mcp->mb[1] = 0; |
@@ -1833,11 +1835,11 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) | |||
1833 | if (rval != QLA_SUCCESS) { | 1835 | if (rval != QLA_SUCCESS) { |
1834 | /*EMPTY*/ | 1836 | /*EMPTY*/ |
1835 | DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n", | 1837 | DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n", |
1836 | ha->host_no, rval);) | 1838 | ha->host_no, rval)); |
1837 | } else { | 1839 | } else { |
1838 | /*EMPTY*/ | 1840 | /*EMPTY*/ |
1839 | DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n", | 1841 | DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n", |
1840 | ha->host_no);) | 1842 | ha->host_no)); |
1841 | } | 1843 | } |
1842 | 1844 | ||
1843 | return rval; | 1845 | return rval; |
@@ -1864,7 +1866,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1864 | mbx_cmd_t *mcp = &mc; | 1866 | mbx_cmd_t *mcp = &mc; |
1865 | 1867 | ||
1866 | DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n", | 1868 | DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n", |
1867 | ha->host_no);) | 1869 | ha->host_no)); |
1868 | 1870 | ||
1869 | if (id_list == NULL) | 1871 | if (id_list == NULL) |
1870 | return QLA_FUNCTION_FAILED; | 1872 | return QLA_FUNCTION_FAILED; |
@@ -1893,11 +1895,11 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1893 | if (rval != QLA_SUCCESS) { | 1895 | if (rval != QLA_SUCCESS) { |
1894 | /*EMPTY*/ | 1896 | /*EMPTY*/ |
1895 | DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n", | 1897 | DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n", |
1896 | ha->host_no, rval);) | 1898 | ha->host_no, rval)); |
1897 | } else { | 1899 | } else { |
1898 | *entries = mcp->mb[1]; | 1900 | *entries = mcp->mb[1]; |
1899 | DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n", | 1901 | DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n", |
1900 | ha->host_no);) | 1902 | ha->host_no)); |
1901 | } | 1903 | } |
1902 | 1904 | ||
1903 | return rval; | 1905 | return rval; |
@@ -1936,7 +1938,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | |||
1936 | if (rval != QLA_SUCCESS) { | 1938 | if (rval != QLA_SUCCESS) { |
1937 | /*EMPTY*/ | 1939 | /*EMPTY*/ |
1938 | DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__, | 1940 | DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__, |
1939 | ha->host_no, mcp->mb[0]);) | 1941 | ha->host_no, mcp->mb[0])); |
1940 | } else { | 1942 | } else { |
1941 | DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " | 1943 | DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " |
1942 | "mb7=%x mb10=%x.\n", __func__, ha->host_no, | 1944 | "mb7=%x mb10=%x.\n", __func__, ha->host_no, |
@@ -2045,7 +2047,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2045 | link_stat_t *stat_buf; | 2047 | link_stat_t *stat_buf; |
2046 | dma_addr_t stat_buf_dma; | 2048 | dma_addr_t stat_buf_dma; |
2047 | 2049 | ||
2048 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 2050 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2049 | 2051 | ||
2050 | stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma); | 2052 | stat_buf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &stat_buf_dma); |
2051 | if (stat_buf == NULL) { | 2053 | if (stat_buf == NULL) { |
@@ -2083,7 +2085,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2083 | if (rval == QLA_SUCCESS) { | 2085 | if (rval == QLA_SUCCESS) { |
2084 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { | 2086 | if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { |
2085 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", | 2087 | DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", |
2086 | __func__, ha->host_no, mcp->mb[0]);) | 2088 | __func__, ha->host_no, mcp->mb[0])); |
2087 | status[0] = mcp->mb[0]; | 2089 | status[0] = mcp->mb[0]; |
2088 | rval = BIT_1; | 2090 | rval = BIT_1; |
2089 | } else { | 2091 | } else { |
@@ -2108,12 +2110,12 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2108 | stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt, | 2110 | stat_buf->loss_sync_cnt, stat_buf->loss_sig_cnt, |
2109 | stat_buf->prim_seq_err_cnt, | 2111 | stat_buf->prim_seq_err_cnt, |
2110 | stat_buf->inval_xmit_word_cnt, | 2112 | stat_buf->inval_xmit_word_cnt, |
2111 | stat_buf->inval_crc_cnt);) | 2113 | stat_buf->inval_crc_cnt)); |
2112 | } | 2114 | } |
2113 | } else { | 2115 | } else { |
2114 | /* Failed. */ | 2116 | /* Failed. */ |
2115 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | 2117 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, |
2116 | ha->host_no, rval);) | 2118 | ha->host_no, rval)); |
2117 | rval = BIT_1; | 2119 | rval = BIT_1; |
2118 | } | 2120 | } |
2119 | 2121 | ||
@@ -2132,7 +2134,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, | |||
2132 | uint32_t *sbuf, *siter; | 2134 | uint32_t *sbuf, *siter; |
2133 | dma_addr_t sbuf_dma; | 2135 | dma_addr_t sbuf_dma; |
2134 | 2136 | ||
2135 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 2137 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2136 | 2138 | ||
2137 | if (dwords > (DMA_POOL_SIZE / 4)) { | 2139 | if (dwords > (DMA_POOL_SIZE / 4)) { |
2138 | DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs " | 2140 | DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs " |
@@ -2196,7 +2198,7 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2196 | dma_addr_t abt_dma; | 2198 | dma_addr_t abt_dma; |
2197 | uint32_t handle; | 2199 | uint32_t handle; |
2198 | 2200 | ||
2199 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) | 2201 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2200 | 2202 | ||
2201 | fcport = sp->fcport; | 2203 | fcport = sp->fcport; |
2202 | 2204 | ||
@@ -2229,7 +2231,7 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2229 | rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0); | 2231 | rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0); |
2230 | if (rval != QLA_SUCCESS) { | 2232 | if (rval != QLA_SUCCESS) { |
2231 | DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n", | 2233 | DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n", |
2232 | __func__, ha->host_no, rval);) | 2234 | __func__, ha->host_no, rval)); |
2233 | } else if (abt->entry_status != 0) { | 2235 | } else if (abt->entry_status != 0) { |
2234 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2236 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2235 | "-- error status (%x).\n", __func__, ha->host_no, | 2237 | "-- error status (%x).\n", __func__, ha->host_no, |
@@ -2238,10 +2240,10 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2238 | } else if (abt->nport_handle != __constant_cpu_to_le16(0)) { | 2240 | } else if (abt->nport_handle != __constant_cpu_to_le16(0)) { |
2239 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2241 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2240 | "-- completion status (%x).\n", __func__, ha->host_no, | 2242 | "-- completion status (%x).\n", __func__, ha->host_no, |
2241 | le16_to_cpu(abt->nport_handle));) | 2243 | le16_to_cpu(abt->nport_handle))); |
2242 | rval = QLA_FUNCTION_FAILED; | 2244 | rval = QLA_FUNCTION_FAILED; |
2243 | } else { | 2245 | } else { |
2244 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 2246 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
2245 | sp->flags |= SRB_ABORT_PENDING; | 2247 | sp->flags |= SRB_ABORT_PENDING; |
2246 | } | 2248 | } |
2247 | 2249 | ||
@@ -2268,7 +2270,7 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2268 | if (fcport == NULL) | 2270 | if (fcport == NULL) |
2269 | return 0; | 2271 | return 0; |
2270 | 2272 | ||
2271 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);) | 2273 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
2272 | 2274 | ||
2273 | ha = fcport->ha; | 2275 | ha = fcport->ha; |
2274 | tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); | 2276 | tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); |
@@ -2290,7 +2292,7 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2290 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); | 2292 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); |
2291 | if (rval != QLA_SUCCESS) { | 2293 | if (rval != QLA_SUCCESS) { |
2292 | DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " | 2294 | DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " |
2293 | "(%x).\n", __func__, ha->host_no, rval);) | 2295 | "(%x).\n", __func__, ha->host_no, rval)); |
2294 | goto atarget_done; | 2296 | goto atarget_done; |
2295 | } else if (tsk->p.sts.entry_status != 0) { | 2297 | } else if (tsk->p.sts.entry_status != 0) { |
2296 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2298 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
@@ -2302,7 +2304,7 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2302 | __constant_cpu_to_le16(CS_COMPLETE)) { | 2304 | __constant_cpu_to_le16(CS_COMPLETE)) { |
2303 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2305 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2304 | "-- completion status (%x).\n", __func__, | 2306 | "-- completion status (%x).\n", __func__, |
2305 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status));) | 2307 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); |
2306 | rval = QLA_FUNCTION_FAILED; | 2308 | rval = QLA_FUNCTION_FAILED; |
2307 | goto atarget_done; | 2309 | goto atarget_done; |
2308 | } | 2310 | } |
@@ -2311,9 +2313,9 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2311 | rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); | 2313 | rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); |
2312 | if (rval != QLA_SUCCESS) { | 2314 | if (rval != QLA_SUCCESS) { |
2313 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | 2315 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " |
2314 | "(%x).\n", __func__, ha->host_no, rval);) | 2316 | "(%x).\n", __func__, ha->host_no, rval)); |
2315 | } else { | 2317 | } else { |
2316 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) | 2318 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
2317 | } | 2319 | } |
2318 | 2320 | ||
2319 | atarget_done: | 2321 | atarget_done: |
@@ -2460,3 +2462,81 @@ qla2x00_stop_firmware(scsi_qla_host_t *ha) | |||
2460 | 2462 | ||
2461 | return rval; | 2463 | return rval; |
2462 | } | 2464 | } |
2465 | |||
2466 | int | ||
2467 | qla2x00_trace_control(scsi_qla_host_t *ha, uint16_t ctrl, dma_addr_t eft_dma, | ||
2468 | uint16_t buffers) | ||
2469 | { | ||
2470 | int rval; | ||
2471 | mbx_cmd_t mc; | ||
2472 | mbx_cmd_t *mcp = &mc; | ||
2473 | |||
2474 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
2475 | return QLA_FUNCTION_FAILED; | ||
2476 | |||
2477 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2478 | |||
2479 | mcp->mb[0] = MBC_TRACE_CONTROL; | ||
2480 | mcp->mb[1] = ctrl; | ||
2481 | mcp->out_mb = MBX_1|MBX_0; | ||
2482 | mcp->in_mb = MBX_1|MBX_0; | ||
2483 | if (ctrl == TC_ENABLE) { | ||
2484 | mcp->mb[2] = LSW(eft_dma); | ||
2485 | mcp->mb[3] = MSW(eft_dma); | ||
2486 | mcp->mb[4] = LSW(MSD(eft_dma)); | ||
2487 | mcp->mb[5] = MSW(MSD(eft_dma)); | ||
2488 | mcp->mb[6] = buffers; | ||
2489 | mcp->mb[7] = buffers; | ||
2490 | mcp->out_mb |= MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2; | ||
2491 | } | ||
2492 | mcp->tov = 30; | ||
2493 | mcp->flags = 0; | ||
2494 | rval = qla2x00_mailbox_command(ha, mcp); | ||
2495 | |||
2496 | if (rval != QLA_SUCCESS) { | ||
2497 | DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n", | ||
2498 | __func__, ha->host_no, rval, mcp->mb[0], mcp->mb[1])); | ||
2499 | } else { | ||
2500 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
2501 | } | ||
2502 | |||
2503 | return rval; | ||
2504 | } | ||
2505 | |||
2506 | int | ||
2507 | qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, | ||
2508 | uint16_t off, uint16_t count) | ||
2509 | { | ||
2510 | int rval; | ||
2511 | mbx_cmd_t mc; | ||
2512 | mbx_cmd_t *mcp = &mc; | ||
2513 | |||
2514 | if (!IS_QLA24XX(ha) && !IS_QLA54XX(ha)) | ||
2515 | return QLA_FUNCTION_FAILED; | ||
2516 | |||
2517 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2518 | |||
2519 | mcp->mb[0] = MBC_READ_SFP; | ||
2520 | mcp->mb[1] = addr; | ||
2521 | mcp->mb[2] = MSW(sfp_dma); | ||
2522 | mcp->mb[3] = LSW(sfp_dma); | ||
2523 | mcp->mb[6] = MSW(MSD(sfp_dma)); | ||
2524 | mcp->mb[7] = LSW(MSD(sfp_dma)); | ||
2525 | mcp->mb[8] = count; | ||
2526 | mcp->mb[9] = off; | ||
2527 | mcp->mb[10] = 0; | ||
2528 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | ||
2529 | mcp->in_mb = MBX_0; | ||
2530 | mcp->tov = 30; | ||
2531 | mcp->flags = 0; | ||
2532 | rval = qla2x00_mailbox_command(ha, mcp); | ||
2533 | |||
2534 | if (rval != QLA_SUCCESS) { | ||
2535 | DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, | ||
2536 | ha->host_no, rval, mcp->mb[0])); | ||
2537 | } else { | ||
2538 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
2539 | } | ||
2540 | |||
2541 | return rval; | ||
2542 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index ccaad0b08d35..3516e36107b1 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -54,6 +54,19 @@ module_param(ql2xloginretrycount, int, S_IRUGO|S_IRUSR); | |||
54 | MODULE_PARM_DESC(ql2xloginretrycount, | 54 | MODULE_PARM_DESC(ql2xloginretrycount, |
55 | "Specify an alternate value for the NVRAM login retry count."); | 55 | "Specify an alternate value for the NVRAM login retry count."); |
56 | 56 | ||
57 | int ql2xallocfwdump = 1; | ||
58 | module_param(ql2xallocfwdump, int, S_IRUGO|S_IRUSR); | ||
59 | MODULE_PARM_DESC(ql2xallocfwdump, | ||
60 | "Option to enable allocation of memory for a firmware dump " | ||
61 | "during HBA initialization. Memory allocation requirements " | ||
62 | "vary by ISP type. Default is 1 - allocate memory."); | ||
63 | |||
64 | int extended_error_logging; | ||
65 | module_param(extended_error_logging, int, S_IRUGO|S_IRUSR); | ||
66 | MODULE_PARM_DESC(extended_error_logging, | ||
67 | "Option to enable extended error logging, " | ||
68 | "Default is 0 - no logging. 1 - log errors."); | ||
69 | |||
57 | static void qla2x00_free_device(scsi_qla_host_t *); | 70 | static void qla2x00_free_device(scsi_qla_host_t *); |
58 | 71 | ||
59 | static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); | 72 | static void qla2x00_config_dma_addressing(scsi_qla_host_t *ha); |
@@ -624,7 +637,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
624 | 637 | ||
625 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", | 638 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", |
626 | __func__, ha->host_no, sp, serial)); | 639 | __func__, ha->host_no, sp, serial)); |
627 | DEBUG3(qla2x00_print_scsi_cmd(cmd);) | 640 | DEBUG3(qla2x00_print_scsi_cmd(cmd)); |
628 | 641 | ||
629 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 642 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
630 | if (ha->isp_ops.abort_command(ha, sp)) { | 643 | if (ha->isp_ops.abort_command(ha, sp)) { |
@@ -766,7 +779,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
766 | #endif | 779 | #endif |
767 | } else { | 780 | } else { |
768 | DEBUG2(printk(KERN_INFO | 781 | DEBUG2(printk(KERN_INFO |
769 | "%s failed: loop not ready\n",__func__);) | 782 | "%s failed: loop not ready\n",__func__)); |
770 | } | 783 | } |
771 | 784 | ||
772 | if (ret == FAILED) { | 785 | if (ret == FAILED) { |
@@ -1021,12 +1034,12 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) | |||
1021 | /* Empty */ | 1034 | /* Empty */ |
1022 | DEBUG2_3(printk("%s(%ld): **** FAILED ****\n", | 1035 | DEBUG2_3(printk("%s(%ld): **** FAILED ****\n", |
1023 | __func__, | 1036 | __func__, |
1024 | ha->host_no);) | 1037 | ha->host_no)); |
1025 | } else { | 1038 | } else { |
1026 | /* Empty */ | 1039 | /* Empty */ |
1027 | DEBUG3(printk("%s(%ld): exiting normally.\n", | 1040 | DEBUG3(printk("%s(%ld): exiting normally.\n", |
1028 | __func__, | 1041 | __func__, |
1029 | ha->host_no);) | 1042 | ha->host_no)); |
1030 | } | 1043 | } |
1031 | 1044 | ||
1032 | return(status); | 1045 | return(status); |
@@ -1324,7 +1337,8 @@ qla24xx_disable_intrs(scsi_qla_host_t *ha) | |||
1324 | /* | 1337 | /* |
1325 | * PCI driver interface | 1338 | * PCI driver interface |
1326 | */ | 1339 | */ |
1327 | static int qla2x00_probe_one(struct pci_dev *pdev) | 1340 | static int __devinit |
1341 | qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
1328 | { | 1342 | { |
1329 | int ret = -ENODEV; | 1343 | int ret = -ENODEV; |
1330 | device_reg_t __iomem *reg; | 1344 | device_reg_t __iomem *reg; |
@@ -1405,7 +1419,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev) | |||
1405 | ha->isp_ops.read_nvram = qla2x00_read_nvram_data; | 1419 | ha->isp_ops.read_nvram = qla2x00_read_nvram_data; |
1406 | ha->isp_ops.write_nvram = qla2x00_write_nvram_data; | 1420 | ha->isp_ops.write_nvram = qla2x00_write_nvram_data; |
1407 | ha->isp_ops.fw_dump = qla2100_fw_dump; | 1421 | ha->isp_ops.fw_dump = qla2100_fw_dump; |
1408 | ha->isp_ops.ascii_fw_dump = qla2100_ascii_fw_dump; | ||
1409 | ha->isp_ops.read_optrom = qla2x00_read_optrom_data; | 1422 | ha->isp_ops.read_optrom = qla2x00_read_optrom_data; |
1410 | ha->isp_ops.write_optrom = qla2x00_write_optrom_data; | 1423 | ha->isp_ops.write_optrom = qla2x00_write_optrom_data; |
1411 | if (IS_QLA2100(ha)) { | 1424 | if (IS_QLA2100(ha)) { |
@@ -1432,7 +1445,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev) | |||
1432 | ha->isp_ops.pci_config = qla2300_pci_config; | 1445 | ha->isp_ops.pci_config = qla2300_pci_config; |
1433 | ha->isp_ops.intr_handler = qla2300_intr_handler; | 1446 | ha->isp_ops.intr_handler = qla2300_intr_handler; |
1434 | ha->isp_ops.fw_dump = qla2300_fw_dump; | 1447 | ha->isp_ops.fw_dump = qla2300_fw_dump; |
1435 | ha->isp_ops.ascii_fw_dump = qla2300_ascii_fw_dump; | ||
1436 | ha->isp_ops.beacon_on = qla2x00_beacon_on; | 1448 | ha->isp_ops.beacon_on = qla2x00_beacon_on; |
1437 | ha->isp_ops.beacon_off = qla2x00_beacon_off; | 1449 | ha->isp_ops.beacon_off = qla2x00_beacon_off; |
1438 | ha->isp_ops.beacon_blink = qla2x00_beacon_blink; | 1450 | ha->isp_ops.beacon_blink = qla2x00_beacon_blink; |
@@ -1469,7 +1481,6 @@ static int qla2x00_probe_one(struct pci_dev *pdev) | |||
1469 | ha->isp_ops.read_nvram = qla24xx_read_nvram_data; | 1481 | ha->isp_ops.read_nvram = qla24xx_read_nvram_data; |
1470 | ha->isp_ops.write_nvram = qla24xx_write_nvram_data; | 1482 | ha->isp_ops.write_nvram = qla24xx_write_nvram_data; |
1471 | ha->isp_ops.fw_dump = qla24xx_fw_dump; | 1483 | ha->isp_ops.fw_dump = qla24xx_fw_dump; |
1472 | ha->isp_ops.ascii_fw_dump = qla24xx_ascii_fw_dump; | ||
1473 | ha->isp_ops.read_optrom = qla24xx_read_optrom_data; | 1484 | ha->isp_ops.read_optrom = qla24xx_read_optrom_data; |
1474 | ha->isp_ops.write_optrom = qla24xx_write_optrom_data; | 1485 | ha->isp_ops.write_optrom = qla24xx_write_optrom_data; |
1475 | ha->isp_ops.beacon_on = qla24xx_beacon_on; | 1486 | ha->isp_ops.beacon_on = qla24xx_beacon_on; |
@@ -1640,7 +1651,8 @@ probe_out: | |||
1640 | return ret; | 1651 | return ret; |
1641 | } | 1652 | } |
1642 | 1653 | ||
1643 | static void qla2x00_remove_one(struct pci_dev *pdev) | 1654 | static void __devexit |
1655 | qla2x00_remove_one(struct pci_dev *pdev) | ||
1644 | { | 1656 | { |
1645 | scsi_qla_host_t *ha; | 1657 | scsi_qla_host_t *ha; |
1646 | 1658 | ||
@@ -1678,6 +1690,9 @@ qla2x00_free_device(scsi_qla_host_t *ha) | |||
1678 | kthread_stop(t); | 1690 | kthread_stop(t); |
1679 | } | 1691 | } |
1680 | 1692 | ||
1693 | if (ha->eft) | ||
1694 | qla2x00_trace_control(ha, TC_DISABLE, 0, 0); | ||
1695 | |||
1681 | /* Stop currently executing firmware. */ | 1696 | /* Stop currently executing firmware. */ |
1682 | qla2x00_stop_firmware(ha); | 1697 | qla2x00_stop_firmware(ha); |
1683 | 1698 | ||
@@ -1899,17 +1914,6 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) | |||
1899 | } | 1914 | } |
1900 | memset(ha->init_cb, 0, ha->init_cb_size); | 1915 | memset(ha->init_cb, 0, ha->init_cb_size); |
1901 | 1916 | ||
1902 | /* Allocate ioctl related memory. */ | ||
1903 | if (qla2x00_alloc_ioctl_mem(ha)) { | ||
1904 | qla_printk(KERN_WARNING, ha, | ||
1905 | "Memory Allocation failed - ioctl_mem\n"); | ||
1906 | |||
1907 | qla2x00_mem_free(ha); | ||
1908 | msleep(100); | ||
1909 | |||
1910 | continue; | ||
1911 | } | ||
1912 | |||
1913 | if (qla2x00_allocate_sp_pool(ha)) { | 1917 | if (qla2x00_allocate_sp_pool(ha)) { |
1914 | qla_printk(KERN_WARNING, ha, | 1918 | qla_printk(KERN_WARNING, ha, |
1915 | "Memory Allocation failed - " | 1919 | "Memory Allocation failed - " |
@@ -1972,6 +1976,26 @@ qla2x00_mem_alloc(scsi_qla_host_t *ha) | |||
1972 | continue; | 1976 | continue; |
1973 | } | 1977 | } |
1974 | memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); | 1978 | memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); |
1979 | |||
1980 | if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | ||
1981 | /* | ||
1982 | * Get consistent memory allocated for SFP | ||
1983 | * block. | ||
1984 | */ | ||
1985 | ha->sfp_data = dma_pool_alloc(ha->s_dma_pool, | ||
1986 | GFP_KERNEL, &ha->sfp_data_dma); | ||
1987 | if (ha->sfp_data == NULL) { | ||
1988 | qla_printk(KERN_WARNING, ha, | ||
1989 | "Memory Allocation failed - " | ||
1990 | "sfp_data\n"); | ||
1991 | |||
1992 | qla2x00_mem_free(ha); | ||
1993 | msleep(100); | ||
1994 | |||
1995 | continue; | ||
1996 | } | ||
1997 | memset(ha->sfp_data, 0, SFP_BLOCK_SIZE); | ||
1998 | } | ||
1975 | } | 1999 | } |
1976 | 2000 | ||
1977 | /* Done all allocations without any error. */ | 2001 | /* Done all allocations without any error. */ |
@@ -2006,12 +2030,16 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2006 | return; | 2030 | return; |
2007 | } | 2031 | } |
2008 | 2032 | ||
2009 | /* free ioctl memory */ | ||
2010 | qla2x00_free_ioctl_mem(ha); | ||
2011 | |||
2012 | /* free sp pool */ | 2033 | /* free sp pool */ |
2013 | qla2x00_free_sp_pool(ha); | 2034 | qla2x00_free_sp_pool(ha); |
2014 | 2035 | ||
2036 | if (ha->fw_dump) { | ||
2037 | if (ha->eft) | ||
2038 | dma_free_coherent(&ha->pdev->dev, | ||
2039 | ntohl(ha->fw_dump->eft_size), ha->eft, ha->eft_dma); | ||
2040 | vfree(ha->fw_dump); | ||
2041 | } | ||
2042 | |||
2015 | if (ha->sns_cmd) | 2043 | if (ha->sns_cmd) |
2016 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), | 2044 | dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), |
2017 | ha->sns_cmd, ha->sns_cmd_dma); | 2045 | ha->sns_cmd, ha->sns_cmd_dma); |
@@ -2020,6 +2048,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2020 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), | 2048 | dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt), |
2021 | ha->ct_sns, ha->ct_sns_dma); | 2049 | ha->ct_sns, ha->ct_sns_dma); |
2022 | 2050 | ||
2051 | if (ha->sfp_data) | ||
2052 | dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma); | ||
2053 | |||
2023 | if (ha->ms_iocb) | 2054 | if (ha->ms_iocb) |
2024 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); | 2055 | dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); |
2025 | 2056 | ||
@@ -2043,6 +2074,8 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2043 | (ha->request_q_length + 1) * sizeof(request_t), | 2074 | (ha->request_q_length + 1) * sizeof(request_t), |
2044 | ha->request_ring, ha->request_dma); | 2075 | ha->request_ring, ha->request_dma); |
2045 | 2076 | ||
2077 | ha->eft = NULL; | ||
2078 | ha->eft_dma = 0; | ||
2046 | ha->sns_cmd = NULL; | 2079 | ha->sns_cmd = NULL; |
2047 | ha->sns_cmd_dma = 0; | 2080 | ha->sns_cmd_dma = 0; |
2048 | ha->ct_sns = NULL; | 2081 | ha->ct_sns = NULL; |
@@ -2071,13 +2104,9 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2071 | } | 2104 | } |
2072 | INIT_LIST_HEAD(&ha->fcports); | 2105 | INIT_LIST_HEAD(&ha->fcports); |
2073 | 2106 | ||
2074 | vfree(ha->fw_dump); | ||
2075 | vfree(ha->fw_dump_buffer); | ||
2076 | |||
2077 | ha->fw_dump = NULL; | 2107 | ha->fw_dump = NULL; |
2078 | ha->fw_dumped = 0; | 2108 | ha->fw_dumped = 0; |
2079 | ha->fw_dump_reading = 0; | 2109 | ha->fw_dump_reading = 0; |
2080 | ha->fw_dump_buffer = NULL; | ||
2081 | 2110 | ||
2082 | vfree(ha->optrom_buffer); | 2111 | vfree(ha->optrom_buffer); |
2083 | } | 2112 | } |
@@ -2617,40 +2646,16 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { | |||
2617 | }; | 2646 | }; |
2618 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); | 2647 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); |
2619 | 2648 | ||
2620 | static int __devinit | ||
2621 | qla2xxx_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | ||
2622 | { | ||
2623 | return qla2x00_probe_one(pdev); | ||
2624 | } | ||
2625 | |||
2626 | static void __devexit | ||
2627 | qla2xxx_remove_one(struct pci_dev *pdev) | ||
2628 | { | ||
2629 | qla2x00_remove_one(pdev); | ||
2630 | } | ||
2631 | |||
2632 | static struct pci_driver qla2xxx_pci_driver = { | 2649 | static struct pci_driver qla2xxx_pci_driver = { |
2633 | .name = QLA2XXX_DRIVER_NAME, | 2650 | .name = QLA2XXX_DRIVER_NAME, |
2634 | .driver = { | 2651 | .driver = { |
2635 | .owner = THIS_MODULE, | 2652 | .owner = THIS_MODULE, |
2636 | }, | 2653 | }, |
2637 | .id_table = qla2xxx_pci_tbl, | 2654 | .id_table = qla2xxx_pci_tbl, |
2638 | .probe = qla2xxx_probe_one, | 2655 | .probe = qla2x00_probe_one, |
2639 | .remove = __devexit_p(qla2xxx_remove_one), | 2656 | .remove = __devexit_p(qla2x00_remove_one), |
2640 | }; | 2657 | }; |
2641 | 2658 | ||
2642 | static inline int | ||
2643 | qla2x00_pci_module_init(void) | ||
2644 | { | ||
2645 | return pci_module_init(&qla2xxx_pci_driver); | ||
2646 | } | ||
2647 | |||
2648 | static inline void | ||
2649 | qla2x00_pci_module_exit(void) | ||
2650 | { | ||
2651 | pci_unregister_driver(&qla2xxx_pci_driver); | ||
2652 | } | ||
2653 | |||
2654 | /** | 2659 | /** |
2655 | * qla2x00_module_init - Module initialization. | 2660 | * qla2x00_module_init - Module initialization. |
2656 | **/ | 2661 | **/ |
@@ -2670,16 +2675,16 @@ qla2x00_module_init(void) | |||
2670 | 2675 | ||
2671 | /* Derive version string. */ | 2676 | /* Derive version string. */ |
2672 | strcpy(qla2x00_version_str, QLA2XXX_VERSION); | 2677 | strcpy(qla2x00_version_str, QLA2XXX_VERSION); |
2673 | #if DEBUG_QLA2100 | 2678 | if (extended_error_logging) |
2674 | strcat(qla2x00_version_str, "-debug"); | 2679 | strcat(qla2x00_version_str, "-debug"); |
2675 | #endif | 2680 | |
2676 | qla2xxx_transport_template = | 2681 | qla2xxx_transport_template = |
2677 | fc_attach_transport(&qla2xxx_transport_functions); | 2682 | fc_attach_transport(&qla2xxx_transport_functions); |
2678 | if (!qla2xxx_transport_template) | 2683 | if (!qla2xxx_transport_template) |
2679 | return -ENODEV; | 2684 | return -ENODEV; |
2680 | 2685 | ||
2681 | printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); | 2686 | printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); |
2682 | ret = qla2x00_pci_module_init(); | 2687 | ret = pci_register_driver(&qla2xxx_pci_driver); |
2683 | if (ret) { | 2688 | if (ret) { |
2684 | kmem_cache_destroy(srb_cachep); | 2689 | kmem_cache_destroy(srb_cachep); |
2685 | fc_release_transport(qla2xxx_transport_template); | 2690 | fc_release_transport(qla2xxx_transport_template); |
@@ -2693,7 +2698,7 @@ qla2x00_module_init(void) | |||
2693 | static void __exit | 2698 | static void __exit |
2694 | qla2x00_module_exit(void) | 2699 | qla2x00_module_exit(void) |
2695 | { | 2700 | { |
2696 | qla2x00_pci_module_exit(); | 2701 | pci_unregister_driver(&qla2xxx_pci_driver); |
2697 | qla2x00_release_firmware(); | 2702 | qla2x00_release_firmware(); |
2698 | kmem_cache_destroy(srb_cachep); | 2703 | kmem_cache_destroy(srb_cachep); |
2699 | fc_release_transport(qla2xxx_transport_template); | 2704 | fc_release_transport(qla2xxx_transport_template); |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 6b315521bd89..d2d683440659 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.01.05-k2" | 10 | #define QLA2XXX_VERSION "8.01.05-k3" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 1 | 13 | #define QLA_DRIVER_MINOR_VER 1 |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 5a5d2af8ee43..1da8ccde6d14 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -51,18 +51,22 @@ | |||
51 | #include "scsi_logging.h" | 51 | #include "scsi_logging.h" |
52 | #include "scsi_debug.h" | 52 | #include "scsi_debug.h" |
53 | 53 | ||
54 | #define SCSI_DEBUG_VERSION "1.75" | 54 | #define SCSI_DEBUG_VERSION "1.79" |
55 | static const char * scsi_debug_version_date = "20050113"; | 55 | static const char * scsi_debug_version_date = "20060604"; |
56 | 56 | ||
57 | /* Additional Sense Code (ASC) used */ | 57 | /* Additional Sense Code (ASC) used */ |
58 | #define NO_ADDED_SENSE 0x0 | 58 | #define NO_ADDITIONAL_SENSE 0x0 |
59 | #define LOGICAL_UNIT_NOT_READY 0x4 | ||
59 | #define UNRECOVERED_READ_ERR 0x11 | 60 | #define UNRECOVERED_READ_ERR 0x11 |
61 | #define PARAMETER_LIST_LENGTH_ERR 0x1a | ||
60 | #define INVALID_OPCODE 0x20 | 62 | #define INVALID_OPCODE 0x20 |
61 | #define ADDR_OUT_OF_RANGE 0x21 | 63 | #define ADDR_OUT_OF_RANGE 0x21 |
62 | #define INVALID_FIELD_IN_CDB 0x24 | 64 | #define INVALID_FIELD_IN_CDB 0x24 |
65 | #define INVALID_FIELD_IN_PARAM_LIST 0x26 | ||
63 | #define POWERON_RESET 0x29 | 66 | #define POWERON_RESET 0x29 |
64 | #define SAVING_PARAMS_UNSUP 0x39 | 67 | #define SAVING_PARAMS_UNSUP 0x39 |
65 | #define THRESHHOLD_EXCEEDED 0x5d | 68 | #define THRESHOLD_EXCEEDED 0x5d |
69 | #define LOW_POWER_COND_ON 0x5e | ||
66 | 70 | ||
67 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ | 71 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ |
68 | 72 | ||
@@ -81,6 +85,8 @@ static const char * scsi_debug_version_date = "20050113"; | |||
81 | #define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */ | 85 | #define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */ |
82 | #define DEF_PTYPE 0 | 86 | #define DEF_PTYPE 0 |
83 | #define DEF_D_SENSE 0 | 87 | #define DEF_D_SENSE 0 |
88 | #define DEF_NO_LUN_0 0 | ||
89 | #define DEF_VIRTUAL_GB 0 | ||
84 | 90 | ||
85 | /* bit mask values for scsi_debug_opts */ | 91 | /* bit mask values for scsi_debug_opts */ |
86 | #define SCSI_DEBUG_OPT_NOISE 1 | 92 | #define SCSI_DEBUG_OPT_NOISE 1 |
@@ -107,6 +113,7 @@ static const char * scsi_debug_version_date = "20050113"; | |||
107 | /* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) | 113 | /* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) |
108 | * or "peripheral device" addressing (value 0) */ | 114 | * or "peripheral device" addressing (value 0) */ |
109 | #define SAM2_LUN_ADDRESS_METHOD 0 | 115 | #define SAM2_LUN_ADDRESS_METHOD 0 |
116 | #define SAM2_WLUN_REPORT_LUNS 0xc101 | ||
110 | 117 | ||
111 | static int scsi_debug_add_host = DEF_NUM_HOST; | 118 | static int scsi_debug_add_host = DEF_NUM_HOST; |
112 | static int scsi_debug_delay = DEF_DELAY; | 119 | static int scsi_debug_delay = DEF_DELAY; |
@@ -119,13 +126,16 @@ static int scsi_debug_opts = DEF_OPTS; | |||
119 | static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; | 126 | static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; |
120 | static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */ | 127 | static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */ |
121 | static int scsi_debug_dsense = DEF_D_SENSE; | 128 | static int scsi_debug_dsense = DEF_D_SENSE; |
129 | static int scsi_debug_no_lun_0 = DEF_NO_LUN_0; | ||
130 | static int scsi_debug_virtual_gb = DEF_VIRTUAL_GB; | ||
122 | 131 | ||
123 | static int scsi_debug_cmnd_count = 0; | 132 | static int scsi_debug_cmnd_count = 0; |
124 | 133 | ||
125 | #define DEV_READONLY(TGT) (0) | 134 | #define DEV_READONLY(TGT) (0) |
126 | #define DEV_REMOVEABLE(TGT) (0) | 135 | #define DEV_REMOVEABLE(TGT) (0) |
127 | 136 | ||
128 | static unsigned long sdebug_store_size; /* in bytes */ | 137 | static unsigned int sdebug_store_size; /* in bytes */ |
138 | static unsigned int sdebug_store_sectors; | ||
129 | static sector_t sdebug_capacity; /* in sectors */ | 139 | static sector_t sdebug_capacity; /* in sectors */ |
130 | 140 | ||
131 | /* old BIOS stuff, kernel may get rid of them but some mode sense pages | 141 | /* old BIOS stuff, kernel may get rid of them but some mode sense pages |
@@ -150,7 +160,9 @@ struct sdebug_dev_info { | |||
150 | unsigned int target; | 160 | unsigned int target; |
151 | unsigned int lun; | 161 | unsigned int lun; |
152 | struct sdebug_host_info *sdbg_host; | 162 | struct sdebug_host_info *sdbg_host; |
163 | unsigned int wlun; | ||
153 | char reset; | 164 | char reset; |
165 | char stopped; | ||
154 | char used; | 166 | char used; |
155 | }; | 167 | }; |
156 | 168 | ||
@@ -194,11 +206,11 @@ static struct scsi_host_template sdebug_driver_template = { | |||
194 | .bios_param = scsi_debug_biosparam, | 206 | .bios_param = scsi_debug_biosparam, |
195 | .can_queue = SCSI_DEBUG_CANQUEUE, | 207 | .can_queue = SCSI_DEBUG_CANQUEUE, |
196 | .this_id = 7, | 208 | .this_id = 7, |
197 | .sg_tablesize = 64, | 209 | .sg_tablesize = 256, |
198 | .cmd_per_lun = 3, | 210 | .cmd_per_lun = 16, |
199 | .max_sectors = 4096, | 211 | .max_sectors = 0xffff, |
200 | .unchecked_isa_dma = 0, | 212 | .unchecked_isa_dma = 0, |
201 | .use_clustering = DISABLE_CLUSTERING, | 213 | .use_clustering = ENABLE_CLUSTERING, |
202 | .module = THIS_MODULE, | 214 | .module = THIS_MODULE, |
203 | }; | 215 | }; |
204 | 216 | ||
@@ -226,19 +238,32 @@ static struct device_driver sdebug_driverfs_driver = { | |||
226 | static const int check_condition_result = | 238 | static const int check_condition_result = |
227 | (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | 239 | (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; |
228 | 240 | ||
241 | static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | ||
242 | 0, 0, 0x2, 0x4b}; | ||
243 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | ||
244 | 0, 0, 0x0, 0x0}; | ||
245 | |||
229 | /* function declarations */ | 246 | /* function declarations */ |
230 | static int resp_inquiry(struct scsi_cmnd * SCpnt, int target, | 247 | static int resp_inquiry(struct scsi_cmnd * SCpnt, int target, |
231 | struct sdebug_dev_info * devip); | 248 | struct sdebug_dev_info * devip); |
232 | static int resp_requests(struct scsi_cmnd * SCpnt, | 249 | static int resp_requests(struct scsi_cmnd * SCpnt, |
233 | struct sdebug_dev_info * devip); | 250 | struct sdebug_dev_info * devip); |
251 | static int resp_start_stop(struct scsi_cmnd * scp, | ||
252 | struct sdebug_dev_info * devip); | ||
234 | static int resp_readcap(struct scsi_cmnd * SCpnt, | 253 | static int resp_readcap(struct scsi_cmnd * SCpnt, |
235 | struct sdebug_dev_info * devip); | 254 | struct sdebug_dev_info * devip); |
236 | static int resp_mode_sense(struct scsi_cmnd * SCpnt, int target, | 255 | static int resp_readcap16(struct scsi_cmnd * SCpnt, |
256 | struct sdebug_dev_info * devip); | ||
257 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, | ||
237 | struct sdebug_dev_info * devip); | 258 | struct sdebug_dev_info * devip); |
238 | static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 259 | static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, |
239 | int num, struct sdebug_dev_info * devip); | 260 | struct sdebug_dev_info * devip); |
240 | static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 261 | static int resp_log_sense(struct scsi_cmnd * scp, |
241 | int num, struct sdebug_dev_info * devip); | 262 | struct sdebug_dev_info * devip); |
263 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
264 | unsigned int num, struct sdebug_dev_info * devip); | ||
265 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
266 | unsigned int num, struct sdebug_dev_info * devip); | ||
242 | static int resp_report_luns(struct scsi_cmnd * SCpnt, | 267 | static int resp_report_luns(struct scsi_cmnd * SCpnt, |
243 | struct sdebug_dev_info * devip); | 268 | struct sdebug_dev_info * devip); |
244 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | 269 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, |
@@ -249,8 +274,8 @@ static void timer_intr_handler(unsigned long); | |||
249 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); | 274 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); |
250 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, | 275 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, |
251 | int asc, int asq); | 276 | int asc, int asq); |
252 | static int check_reset(struct scsi_cmnd * SCpnt, | 277 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, |
253 | struct sdebug_dev_info * devip); | 278 | struct sdebug_dev_info * devip); |
254 | static int schedule_resp(struct scsi_cmnd * cmnd, | 279 | static int schedule_resp(struct scsi_cmnd * cmnd, |
255 | struct sdebug_dev_info * devip, | 280 | struct sdebug_dev_info * devip, |
256 | done_funct_t done, int scsi_result, int delta_jiff); | 281 | done_funct_t done, int scsi_result, int delta_jiff); |
@@ -258,8 +283,10 @@ static void __init sdebug_build_parts(unsigned char * ramp); | |||
258 | static void __init init_all_queued(void); | 283 | static void __init init_all_queued(void); |
259 | static void stop_all_queued(void); | 284 | static void stop_all_queued(void); |
260 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); | 285 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); |
261 | static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | 286 | static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, |
262 | const char * dev_id_str, int dev_id_str_len); | 287 | int dev_id_num, const char * dev_id_str, |
288 | int dev_id_str_len); | ||
289 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); | ||
263 | static void do_create_driverfs_files(void); | 290 | static void do_create_driverfs_files(void); |
264 | static void do_remove_driverfs_files(void); | 291 | static void do_remove_driverfs_files(void); |
265 | 292 | ||
@@ -275,18 +302,22 @@ static | |||
275 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | 302 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) |
276 | { | 303 | { |
277 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; | 304 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; |
278 | int block, upper_blk, num, k; | 305 | int len, k, j; |
306 | unsigned int num; | ||
307 | unsigned long long lba; | ||
279 | int errsts = 0; | 308 | int errsts = 0; |
280 | int target = scmd_id(SCpnt); | 309 | int target = SCpnt->device->id; |
281 | struct sdebug_dev_info * devip = NULL; | 310 | struct sdebug_dev_info * devip = NULL; |
282 | int inj_recovered = 0; | 311 | int inj_recovered = 0; |
312 | int delay_override = 0; | ||
283 | 313 | ||
284 | if (done == NULL) | 314 | if (done == NULL) |
285 | return 0; /* assume mid level reprocessing command */ | 315 | return 0; /* assume mid level reprocessing command */ |
286 | 316 | ||
317 | SCpnt->resid = 0; | ||
287 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { | 318 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { |
288 | printk(KERN_INFO "scsi_debug: cmd "); | 319 | printk(KERN_INFO "scsi_debug: cmd "); |
289 | for (k = 0, num = SCpnt->cmd_len; k < num; ++k) | 320 | for (k = 0, len = SCpnt->cmd_len; k < len; ++k) |
290 | printk("%02x ", (int)cmd[k]); | 321 | printk("%02x ", (int)cmd[k]); |
291 | printk("\n"); | 322 | printk("\n"); |
292 | } | 323 | } |
@@ -297,7 +328,8 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
297 | DID_NO_CONNECT << 16, 0); | 328 | DID_NO_CONNECT << 16, 0); |
298 | } | 329 | } |
299 | 330 | ||
300 | if (SCpnt->device->lun >= scsi_debug_max_luns) | 331 | if ((SCpnt->device->lun >= scsi_debug_max_luns) && |
332 | (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) | ||
301 | return schedule_resp(SCpnt, NULL, done, | 333 | return schedule_resp(SCpnt, NULL, done, |
302 | DID_NO_CONNECT << 16, 0); | 334 | DID_NO_CONNECT << 16, 0); |
303 | devip = devInfoReg(SCpnt->device); | 335 | devip = devInfoReg(SCpnt->device); |
@@ -316,118 +348,150 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
316 | inj_recovered = 1; /* to reads and writes below */ | 348 | inj_recovered = 1; /* to reads and writes below */ |
317 | } | 349 | } |
318 | 350 | ||
351 | if (devip->wlun) { | ||
352 | switch (*cmd) { | ||
353 | case INQUIRY: | ||
354 | case REQUEST_SENSE: | ||
355 | case TEST_UNIT_READY: | ||
356 | case REPORT_LUNS: | ||
357 | break; /* only allowable wlun commands */ | ||
358 | default: | ||
359 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
360 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x " | ||
361 | "not supported for wlun\n", *cmd); | ||
362 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
363 | INVALID_OPCODE, 0); | ||
364 | errsts = check_condition_result; | ||
365 | return schedule_resp(SCpnt, devip, done, errsts, | ||
366 | 0); | ||
367 | } | ||
368 | } | ||
369 | |||
319 | switch (*cmd) { | 370 | switch (*cmd) { |
320 | case INQUIRY: /* mandatory, ignore unit attention */ | 371 | case INQUIRY: /* mandatory, ignore unit attention */ |
372 | delay_override = 1; | ||
321 | errsts = resp_inquiry(SCpnt, target, devip); | 373 | errsts = resp_inquiry(SCpnt, target, devip); |
322 | break; | 374 | break; |
323 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ | 375 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ |
376 | delay_override = 1; | ||
324 | errsts = resp_requests(SCpnt, devip); | 377 | errsts = resp_requests(SCpnt, devip); |
325 | break; | 378 | break; |
326 | case REZERO_UNIT: /* actually this is REWIND for SSC */ | 379 | case REZERO_UNIT: /* actually this is REWIND for SSC */ |
327 | case START_STOP: | 380 | case START_STOP: |
328 | errsts = check_reset(SCpnt, devip); | 381 | errsts = resp_start_stop(SCpnt, devip); |
329 | break; | 382 | break; |
330 | case ALLOW_MEDIUM_REMOVAL: | 383 | case ALLOW_MEDIUM_REMOVAL: |
331 | if ((errsts = check_reset(SCpnt, devip))) | 384 | if ((errsts = check_readiness(SCpnt, 1, devip))) |
332 | break; | 385 | break; |
333 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 386 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
334 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", | 387 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", |
335 | cmd[4] ? "inhibited" : "enabled"); | 388 | cmd[4] ? "inhibited" : "enabled"); |
336 | break; | 389 | break; |
337 | case SEND_DIAGNOSTIC: /* mandatory */ | 390 | case SEND_DIAGNOSTIC: /* mandatory */ |
338 | errsts = check_reset(SCpnt, devip); | 391 | errsts = check_readiness(SCpnt, 1, devip); |
339 | break; | 392 | break; |
340 | case TEST_UNIT_READY: /* mandatory */ | 393 | case TEST_UNIT_READY: /* mandatory */ |
341 | errsts = check_reset(SCpnt, devip); | 394 | delay_override = 1; |
395 | errsts = check_readiness(SCpnt, 0, devip); | ||
342 | break; | 396 | break; |
343 | case RESERVE: | 397 | case RESERVE: |
344 | errsts = check_reset(SCpnt, devip); | 398 | errsts = check_readiness(SCpnt, 1, devip); |
345 | break; | 399 | break; |
346 | case RESERVE_10: | 400 | case RESERVE_10: |
347 | errsts = check_reset(SCpnt, devip); | 401 | errsts = check_readiness(SCpnt, 1, devip); |
348 | break; | 402 | break; |
349 | case RELEASE: | 403 | case RELEASE: |
350 | errsts = check_reset(SCpnt, devip); | 404 | errsts = check_readiness(SCpnt, 1, devip); |
351 | break; | 405 | break; |
352 | case RELEASE_10: | 406 | case RELEASE_10: |
353 | errsts = check_reset(SCpnt, devip); | 407 | errsts = check_readiness(SCpnt, 1, devip); |
354 | break; | 408 | break; |
355 | case READ_CAPACITY: | 409 | case READ_CAPACITY: |
356 | errsts = resp_readcap(SCpnt, devip); | 410 | errsts = resp_readcap(SCpnt, devip); |
357 | break; | 411 | break; |
412 | case SERVICE_ACTION_IN: | ||
413 | if (SAI_READ_CAPACITY_16 != cmd[1]) { | ||
414 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
415 | INVALID_OPCODE, 0); | ||
416 | errsts = check_condition_result; | ||
417 | break; | ||
418 | } | ||
419 | errsts = resp_readcap16(SCpnt, devip); | ||
420 | break; | ||
358 | case READ_16: | 421 | case READ_16: |
359 | case READ_12: | 422 | case READ_12: |
360 | case READ_10: | 423 | case READ_10: |
361 | case READ_6: | 424 | case READ_6: |
362 | if ((errsts = check_reset(SCpnt, devip))) | 425 | if ((errsts = check_readiness(SCpnt, 0, devip))) |
363 | break; | 426 | break; |
364 | upper_blk = 0; | ||
365 | if ((*cmd) == READ_16) { | 427 | if ((*cmd) == READ_16) { |
366 | upper_blk = cmd[5] + (cmd[4] << 8) + | 428 | for (lba = 0, j = 0; j < 8; ++j) { |
367 | (cmd[3] << 16) + (cmd[2] << 24); | 429 | if (j > 0) |
368 | block = cmd[9] + (cmd[8] << 8) + | 430 | lba <<= 8; |
369 | (cmd[7] << 16) + (cmd[6] << 24); | 431 | lba += cmd[2 + j]; |
432 | } | ||
370 | num = cmd[13] + (cmd[12] << 8) + | 433 | num = cmd[13] + (cmd[12] << 8) + |
371 | (cmd[11] << 16) + (cmd[10] << 24); | 434 | (cmd[11] << 16) + (cmd[10] << 24); |
372 | } else if ((*cmd) == READ_12) { | 435 | } else if ((*cmd) == READ_12) { |
373 | block = cmd[5] + (cmd[4] << 8) + | 436 | lba = cmd[5] + (cmd[4] << 8) + |
374 | (cmd[3] << 16) + (cmd[2] << 24); | 437 | (cmd[3] << 16) + (cmd[2] << 24); |
375 | num = cmd[9] + (cmd[8] << 8) + | 438 | num = cmd[9] + (cmd[8] << 8) + |
376 | (cmd[7] << 16) + (cmd[6] << 24); | 439 | (cmd[7] << 16) + (cmd[6] << 24); |
377 | } else if ((*cmd) == READ_10) { | 440 | } else if ((*cmd) == READ_10) { |
378 | block = cmd[5] + (cmd[4] << 8) + | 441 | lba = cmd[5] + (cmd[4] << 8) + |
379 | (cmd[3] << 16) + (cmd[2] << 24); | 442 | (cmd[3] << 16) + (cmd[2] << 24); |
380 | num = cmd[8] + (cmd[7] << 8); | 443 | num = cmd[8] + (cmd[7] << 8); |
381 | } else { | 444 | } else { /* READ (6) */ |
382 | block = cmd[3] + (cmd[2] << 8) + | 445 | lba = cmd[3] + (cmd[2] << 8) + |
383 | ((cmd[1] & 0x1f) << 16); | 446 | ((cmd[1] & 0x1f) << 16); |
384 | num = cmd[4]; | 447 | num = (0 == cmd[4]) ? 256 : cmd[4]; |
385 | } | 448 | } |
386 | errsts = resp_read(SCpnt, upper_blk, block, num, devip); | 449 | errsts = resp_read(SCpnt, lba, num, devip); |
387 | if (inj_recovered && (0 == errsts)) { | 450 | if (inj_recovered && (0 == errsts)) { |
388 | mk_sense_buffer(devip, RECOVERED_ERROR, | 451 | mk_sense_buffer(devip, RECOVERED_ERROR, |
389 | THRESHHOLD_EXCEEDED, 0); | 452 | THRESHOLD_EXCEEDED, 0); |
390 | errsts = check_condition_result; | 453 | errsts = check_condition_result; |
391 | } | 454 | } |
392 | break; | 455 | break; |
393 | case REPORT_LUNS: /* mandatory, ignore unit attention */ | 456 | case REPORT_LUNS: /* mandatory, ignore unit attention */ |
457 | delay_override = 1; | ||
394 | errsts = resp_report_luns(SCpnt, devip); | 458 | errsts = resp_report_luns(SCpnt, devip); |
395 | break; | 459 | break; |
396 | case VERIFY: /* 10 byte SBC-2 command */ | 460 | case VERIFY: /* 10 byte SBC-2 command */ |
397 | errsts = check_reset(SCpnt, devip); | 461 | errsts = check_readiness(SCpnt, 0, devip); |
398 | break; | 462 | break; |
399 | case WRITE_16: | 463 | case WRITE_16: |
400 | case WRITE_12: | 464 | case WRITE_12: |
401 | case WRITE_10: | 465 | case WRITE_10: |
402 | case WRITE_6: | 466 | case WRITE_6: |
403 | if ((errsts = check_reset(SCpnt, devip))) | 467 | if ((errsts = check_readiness(SCpnt, 0, devip))) |
404 | break; | 468 | break; |
405 | upper_blk = 0; | ||
406 | if ((*cmd) == WRITE_16) { | 469 | if ((*cmd) == WRITE_16) { |
407 | upper_blk = cmd[5] + (cmd[4] << 8) + | 470 | for (lba = 0, j = 0; j < 8; ++j) { |
408 | (cmd[3] << 16) + (cmd[2] << 24); | 471 | if (j > 0) |
409 | block = cmd[9] + (cmd[8] << 8) + | 472 | lba <<= 8; |
410 | (cmd[7] << 16) + (cmd[6] << 24); | 473 | lba += cmd[2 + j]; |
474 | } | ||
411 | num = cmd[13] + (cmd[12] << 8) + | 475 | num = cmd[13] + (cmd[12] << 8) + |
412 | (cmd[11] << 16) + (cmd[10] << 24); | 476 | (cmd[11] << 16) + (cmd[10] << 24); |
413 | } else if ((*cmd) == WRITE_12) { | 477 | } else if ((*cmd) == WRITE_12) { |
414 | block = cmd[5] + (cmd[4] << 8) + | 478 | lba = cmd[5] + (cmd[4] << 8) + |
415 | (cmd[3] << 16) + (cmd[2] << 24); | 479 | (cmd[3] << 16) + (cmd[2] << 24); |
416 | num = cmd[9] + (cmd[8] << 8) + | 480 | num = cmd[9] + (cmd[8] << 8) + |
417 | (cmd[7] << 16) + (cmd[6] << 24); | 481 | (cmd[7] << 16) + (cmd[6] << 24); |
418 | } else if ((*cmd) == WRITE_10) { | 482 | } else if ((*cmd) == WRITE_10) { |
419 | block = cmd[5] + (cmd[4] << 8) + | 483 | lba = cmd[5] + (cmd[4] << 8) + |
420 | (cmd[3] << 16) + (cmd[2] << 24); | 484 | (cmd[3] << 16) + (cmd[2] << 24); |
421 | num = cmd[8] + (cmd[7] << 8); | 485 | num = cmd[8] + (cmd[7] << 8); |
422 | } else { | 486 | } else { /* WRITE (6) */ |
423 | block = cmd[3] + (cmd[2] << 8) + | 487 | lba = cmd[3] + (cmd[2] << 8) + |
424 | ((cmd[1] & 0x1f) << 16); | 488 | ((cmd[1] & 0x1f) << 16); |
425 | num = cmd[4]; | 489 | num = (0 == cmd[4]) ? 256 : cmd[4]; |
426 | } | 490 | } |
427 | errsts = resp_write(SCpnt, upper_blk, block, num, devip); | 491 | errsts = resp_write(SCpnt, lba, num, devip); |
428 | if (inj_recovered && (0 == errsts)) { | 492 | if (inj_recovered && (0 == errsts)) { |
429 | mk_sense_buffer(devip, RECOVERED_ERROR, | 493 | mk_sense_buffer(devip, RECOVERED_ERROR, |
430 | THRESHHOLD_EXCEEDED, 0); | 494 | THRESHOLD_EXCEEDED, 0); |
431 | errsts = check_condition_result; | 495 | errsts = check_condition_result; |
432 | } | 496 | } |
433 | break; | 497 | break; |
@@ -435,20 +499,31 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
435 | case MODE_SENSE_10: | 499 | case MODE_SENSE_10: |
436 | errsts = resp_mode_sense(SCpnt, target, devip); | 500 | errsts = resp_mode_sense(SCpnt, target, devip); |
437 | break; | 501 | break; |
502 | case MODE_SELECT: | ||
503 | errsts = resp_mode_select(SCpnt, 1, devip); | ||
504 | break; | ||
505 | case MODE_SELECT_10: | ||
506 | errsts = resp_mode_select(SCpnt, 0, devip); | ||
507 | break; | ||
508 | case LOG_SENSE: | ||
509 | errsts = resp_log_sense(SCpnt, devip); | ||
510 | break; | ||
438 | case SYNCHRONIZE_CACHE: | 511 | case SYNCHRONIZE_CACHE: |
439 | errsts = check_reset(SCpnt, devip); | 512 | delay_override = 1; |
513 | errsts = check_readiness(SCpnt, 0, devip); | ||
440 | break; | 514 | break; |
441 | default: | 515 | default: |
442 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 516 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
443 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | 517 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " |
444 | "supported\n", *cmd); | 518 | "supported\n", *cmd); |
445 | if ((errsts = check_reset(SCpnt, devip))) | 519 | if ((errsts = check_readiness(SCpnt, 1, devip))) |
446 | break; /* Unit attention takes precedence */ | 520 | break; /* Unit attention takes precedence */ |
447 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); | 521 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); |
448 | errsts = check_condition_result; | 522 | errsts = check_condition_result; |
449 | break; | 523 | break; |
450 | } | 524 | } |
451 | return schedule_resp(SCpnt, devip, done, errsts, scsi_debug_delay); | 525 | return schedule_resp(SCpnt, devip, done, errsts, |
526 | (delay_override ? 0 : scsi_debug_delay)); | ||
452 | } | 527 | } |
453 | 528 | ||
454 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | 529 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) |
@@ -460,7 +535,8 @@ static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | |||
460 | /* return -ENOTTY; // correct return but upsets fdisk */ | 535 | /* return -ENOTTY; // correct return but upsets fdisk */ |
461 | } | 536 | } |
462 | 537 | ||
463 | static int check_reset(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip) | 538 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, |
539 | struct sdebug_dev_info * devip) | ||
464 | { | 540 | { |
465 | if (devip->reset) { | 541 | if (devip->reset) { |
466 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 542 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
@@ -470,6 +546,14 @@ static int check_reset(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip) | |||
470 | mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0); | 546 | mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0); |
471 | return check_condition_result; | 547 | return check_condition_result; |
472 | } | 548 | } |
549 | if ((0 == reset_only) && devip->stopped) { | ||
550 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
551 | printk(KERN_INFO "scsi_debug: Reporting Not " | ||
552 | "ready: initializing command required\n"); | ||
553 | mk_sense_buffer(devip, NOT_READY, LOGICAL_UNIT_NOT_READY, | ||
554 | 0x2); | ||
555 | return check_condition_result; | ||
556 | } | ||
473 | return 0; | 557 | return 0; |
474 | } | 558 | } |
475 | 559 | ||
@@ -493,7 +577,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | |||
493 | req_len = scp->request_bufflen; | 577 | req_len = scp->request_bufflen; |
494 | act_len = (req_len < arr_len) ? req_len : arr_len; | 578 | act_len = (req_len < arr_len) ? req_len : arr_len; |
495 | memcpy(scp->request_buffer, arr, act_len); | 579 | memcpy(scp->request_buffer, arr, act_len); |
496 | scp->resid = req_len - act_len; | 580 | if (scp->resid) |
581 | scp->resid -= act_len; | ||
582 | else | ||
583 | scp->resid = req_len - act_len; | ||
497 | return 0; | 584 | return 0; |
498 | } | 585 | } |
499 | sgpnt = (struct scatterlist *)scp->request_buffer; | 586 | sgpnt = (struct scatterlist *)scp->request_buffer; |
@@ -516,7 +603,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | |||
516 | } | 603 | } |
517 | req_len += sgpnt->length; | 604 | req_len += sgpnt->length; |
518 | } | 605 | } |
519 | scp->resid = req_len - act_len; | 606 | if (scp->resid) |
607 | scp->resid -= act_len; | ||
608 | else | ||
609 | scp->resid = req_len - act_len; | ||
520 | return 0; | 610 | return 0; |
521 | } | 611 | } |
522 | 612 | ||
@@ -567,12 +657,14 @@ static const char * inq_vendor_id = "Linux "; | |||
567 | static const char * inq_product_id = "scsi_debug "; | 657 | static const char * inq_product_id = "scsi_debug "; |
568 | static const char * inq_product_rev = "0004"; | 658 | static const char * inq_product_rev = "0004"; |
569 | 659 | ||
570 | static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | 660 | static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, |
571 | const char * dev_id_str, int dev_id_str_len) | 661 | int dev_id_num, const char * dev_id_str, |
662 | int dev_id_str_len) | ||
572 | { | 663 | { |
573 | int num; | 664 | int num, port_a; |
665 | char b[32]; | ||
574 | 666 | ||
575 | /* Two identification descriptors: */ | 667 | port_a = target_dev_id + 1; |
576 | /* T10 vendor identifier field format (faked) */ | 668 | /* T10 vendor identifier field format (faked) */ |
577 | arr[0] = 0x2; /* ASCII */ | 669 | arr[0] = 0x2; /* ASCII */ |
578 | arr[1] = 0x1; | 670 | arr[1] = 0x1; |
@@ -583,25 +675,246 @@ static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | |||
583 | num = 8 + 16 + dev_id_str_len; | 675 | num = 8 + 16 + dev_id_str_len; |
584 | arr[3] = num; | 676 | arr[3] = num; |
585 | num += 4; | 677 | num += 4; |
586 | /* NAA IEEE registered identifier (faked) */ | 678 | if (dev_id_num >= 0) { |
587 | arr[num] = 0x1; /* binary */ | 679 | /* NAA-5, Logical unit identifier (binary) */ |
588 | arr[num + 1] = 0x3; | 680 | arr[num++] = 0x1; /* binary (not necessarily sas) */ |
589 | arr[num + 2] = 0x0; | 681 | arr[num++] = 0x3; /* PIV=0, lu, naa */ |
590 | arr[num + 3] = 0x8; | 682 | arr[num++] = 0x0; |
591 | arr[num + 4] = 0x51; /* ieee company id=0x123456 (faked) */ | 683 | arr[num++] = 0x8; |
592 | arr[num + 5] = 0x23; | 684 | arr[num++] = 0x53; /* naa-5 ieee company id=0x333333 (fake) */ |
593 | arr[num + 6] = 0x45; | 685 | arr[num++] = 0x33; |
594 | arr[num + 7] = 0x60; | 686 | arr[num++] = 0x33; |
595 | arr[num + 8] = (dev_id_num >> 24); | 687 | arr[num++] = 0x30; |
596 | arr[num + 9] = (dev_id_num >> 16) & 0xff; | 688 | arr[num++] = (dev_id_num >> 24); |
597 | arr[num + 10] = (dev_id_num >> 8) & 0xff; | 689 | arr[num++] = (dev_id_num >> 16) & 0xff; |
598 | arr[num + 11] = dev_id_num & 0xff; | 690 | arr[num++] = (dev_id_num >> 8) & 0xff; |
599 | return num + 12; | 691 | arr[num++] = dev_id_num & 0xff; |
692 | /* Target relative port number */ | ||
693 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
694 | arr[num++] = 0x94; /* PIV=1, target port, rel port */ | ||
695 | arr[num++] = 0x0; /* reserved */ | ||
696 | arr[num++] = 0x4; /* length */ | ||
697 | arr[num++] = 0x0; /* reserved */ | ||
698 | arr[num++] = 0x0; /* reserved */ | ||
699 | arr[num++] = 0x0; | ||
700 | arr[num++] = 0x1; /* relative port A */ | ||
701 | } | ||
702 | /* NAA-5, Target port identifier */ | ||
703 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
704 | arr[num++] = 0x93; /* piv=1, target port, naa */ | ||
705 | arr[num++] = 0x0; | ||
706 | arr[num++] = 0x8; | ||
707 | arr[num++] = 0x52; /* naa-5, company id=0x222222 (fake) */ | ||
708 | arr[num++] = 0x22; | ||
709 | arr[num++] = 0x22; | ||
710 | arr[num++] = 0x20; | ||
711 | arr[num++] = (port_a >> 24); | ||
712 | arr[num++] = (port_a >> 16) & 0xff; | ||
713 | arr[num++] = (port_a >> 8) & 0xff; | ||
714 | arr[num++] = port_a & 0xff; | ||
715 | /* NAA-5, Target device identifier */ | ||
716 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
717 | arr[num++] = 0xa3; /* piv=1, target device, naa */ | ||
718 | arr[num++] = 0x0; | ||
719 | arr[num++] = 0x8; | ||
720 | arr[num++] = 0x52; /* naa-5, company id=0x222222 (fake) */ | ||
721 | arr[num++] = 0x22; | ||
722 | arr[num++] = 0x22; | ||
723 | arr[num++] = 0x20; | ||
724 | arr[num++] = (target_dev_id >> 24); | ||
725 | arr[num++] = (target_dev_id >> 16) & 0xff; | ||
726 | arr[num++] = (target_dev_id >> 8) & 0xff; | ||
727 | arr[num++] = target_dev_id & 0xff; | ||
728 | /* SCSI name string: Target device identifier */ | ||
729 | arr[num++] = 0x63; /* proto=sas, UTF-8 */ | ||
730 | arr[num++] = 0xa8; /* piv=1, target device, SCSI name string */ | ||
731 | arr[num++] = 0x0; | ||
732 | arr[num++] = 24; | ||
733 | memcpy(arr + num, "naa.52222220", 12); | ||
734 | num += 12; | ||
735 | snprintf(b, sizeof(b), "%08X", target_dev_id); | ||
736 | memcpy(arr + num, b, 8); | ||
737 | num += 8; | ||
738 | memset(arr + num, 0, 4); | ||
739 | num += 4; | ||
740 | return num; | ||
741 | } | ||
742 | |||
743 | |||
744 | static unsigned char vpd84_data[] = { | ||
745 | /* from 4th byte */ 0x22,0x22,0x22,0x0,0xbb,0x0, | ||
746 | 0x22,0x22,0x22,0x0,0xbb,0x1, | ||
747 | 0x22,0x22,0x22,0x0,0xbb,0x2, | ||
748 | }; | ||
749 | |||
750 | static int inquiry_evpd_84(unsigned char * arr) | ||
751 | { | ||
752 | memcpy(arr, vpd84_data, sizeof(vpd84_data)); | ||
753 | return sizeof(vpd84_data); | ||
754 | } | ||
755 | |||
756 | static int inquiry_evpd_85(unsigned char * arr) | ||
757 | { | ||
758 | int num = 0; | ||
759 | const char * na1 = "https://www.kernel.org/config"; | ||
760 | const char * na2 = "http://www.kernel.org/log"; | ||
761 | int plen, olen; | ||
762 | |||
763 | arr[num++] = 0x1; /* lu, storage config */ | ||
764 | arr[num++] = 0x0; /* reserved */ | ||
765 | arr[num++] = 0x0; | ||
766 | olen = strlen(na1); | ||
767 | plen = olen + 1; | ||
768 | if (plen % 4) | ||
769 | plen = ((plen / 4) + 1) * 4; | ||
770 | arr[num++] = plen; /* length, null termianted, padded */ | ||
771 | memcpy(arr + num, na1, olen); | ||
772 | memset(arr + num + olen, 0, plen - olen); | ||
773 | num += plen; | ||
774 | |||
775 | arr[num++] = 0x4; /* lu, logging */ | ||
776 | arr[num++] = 0x0; /* reserved */ | ||
777 | arr[num++] = 0x0; | ||
778 | olen = strlen(na2); | ||
779 | plen = olen + 1; | ||
780 | if (plen % 4) | ||
781 | plen = ((plen / 4) + 1) * 4; | ||
782 | arr[num++] = plen; /* length, null terminated, padded */ | ||
783 | memcpy(arr + num, na2, olen); | ||
784 | memset(arr + num + olen, 0, plen - olen); | ||
785 | num += plen; | ||
786 | |||
787 | return num; | ||
788 | } | ||
789 | |||
790 | /* SCSI ports VPD page */ | ||
791 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id) | ||
792 | { | ||
793 | int num = 0; | ||
794 | int port_a, port_b; | ||
795 | |||
796 | port_a = target_dev_id + 1; | ||
797 | port_b = port_a + 1; | ||
798 | arr[num++] = 0x0; /* reserved */ | ||
799 | arr[num++] = 0x0; /* reserved */ | ||
800 | arr[num++] = 0x0; | ||
801 | arr[num++] = 0x1; /* relative port 1 (primary) */ | ||
802 | memset(arr + num, 0, 6); | ||
803 | num += 6; | ||
804 | arr[num++] = 0x0; | ||
805 | arr[num++] = 12; /* length tp descriptor */ | ||
806 | /* naa-5 target port identifier (A) */ | ||
807 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
808 | arr[num++] = 0x93; /* PIV=1, target port, NAA */ | ||
809 | arr[num++] = 0x0; /* reserved */ | ||
810 | arr[num++] = 0x8; /* length */ | ||
811 | arr[num++] = 0x52; /* NAA-5, company_id=0x222222 (fake) */ | ||
812 | arr[num++] = 0x22; | ||
813 | arr[num++] = 0x22; | ||
814 | arr[num++] = 0x20; | ||
815 | arr[num++] = (port_a >> 24); | ||
816 | arr[num++] = (port_a >> 16) & 0xff; | ||
817 | arr[num++] = (port_a >> 8) & 0xff; | ||
818 | arr[num++] = port_a & 0xff; | ||
819 | |||
820 | arr[num++] = 0x0; /* reserved */ | ||
821 | arr[num++] = 0x0; /* reserved */ | ||
822 | arr[num++] = 0x0; | ||
823 | arr[num++] = 0x2; /* relative port 2 (secondary) */ | ||
824 | memset(arr + num, 0, 6); | ||
825 | num += 6; | ||
826 | arr[num++] = 0x0; | ||
827 | arr[num++] = 12; /* length tp descriptor */ | ||
828 | /* naa-5 target port identifier (B) */ | ||
829 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
830 | arr[num++] = 0x93; /* PIV=1, target port, NAA */ | ||
831 | arr[num++] = 0x0; /* reserved */ | ||
832 | arr[num++] = 0x8; /* length */ | ||
833 | arr[num++] = 0x52; /* NAA-5, company_id=0x222222 (fake) */ | ||
834 | arr[num++] = 0x22; | ||
835 | arr[num++] = 0x22; | ||
836 | arr[num++] = 0x20; | ||
837 | arr[num++] = (port_b >> 24); | ||
838 | arr[num++] = (port_b >> 16) & 0xff; | ||
839 | arr[num++] = (port_b >> 8) & 0xff; | ||
840 | arr[num++] = port_b & 0xff; | ||
841 | |||
842 | return num; | ||
843 | } | ||
844 | |||
845 | |||
846 | static unsigned char vpd89_data[] = { | ||
847 | /* from 4th byte */ 0,0,0,0, | ||
848 | 'l','i','n','u','x',' ',' ',' ', | ||
849 | 'S','A','T',' ','s','c','s','i','_','d','e','b','u','g',' ',' ', | ||
850 | '1','2','3','4', | ||
851 | 0x34,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, | ||
852 | 0xec,0,0,0, | ||
853 | 0x5a,0xc,0xff,0x3f,0x37,0xc8,0x10,0,0,0,0,0,0x3f,0,0,0, | ||
854 | 0,0,0,0,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x20,0x20,0x20,0x20, | ||
855 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0,0,0,0x40,0x4,0,0x2e,0x33, | ||
856 | 0x38,0x31,0x20,0x20,0x20,0x20,0x54,0x53,0x38,0x33,0x30,0x30,0x33,0x31, | ||
857 | 0x53,0x41, | ||
858 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, | ||
859 | 0x20,0x20, | ||
860 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, | ||
861 | 0x10,0x80, | ||
862 | 0,0,0,0x2f,0,0,0,0x2,0,0x2,0x7,0,0xff,0xff,0x1,0, | ||
863 | 0x3f,0,0xc1,0xff,0x3e,0,0x10,0x1,0xb0,0xf8,0x50,0x9,0,0,0x7,0, | ||
864 | 0x3,0,0x78,0,0x78,0,0xf0,0,0x78,0,0,0,0,0,0,0, | ||
865 | 0,0,0,0,0,0,0,0,0x2,0,0,0,0,0,0,0, | ||
866 | 0x7e,0,0x1b,0,0x6b,0x34,0x1,0x7d,0x3,0x40,0x69,0x34,0x1,0x3c,0x3,0x40, | ||
867 | 0x7f,0x40,0,0,0,0,0xfe,0xfe,0,0,0,0,0,0xfe,0,0, | ||
868 | 0,0,0,0,0,0,0,0,0xb0,0xf8,0x50,0x9,0,0,0,0, | ||
869 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
870 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
871 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
872 | 0x1,0,0xb0,0xf8,0x50,0x9,0xb0,0xf8,0x50,0x9,0x20,0x20,0x2,0,0xb6,0x42, | ||
873 | 0,0x80,0x8a,0,0x6,0x3c,0xa,0x3c,0xff,0xff,0xc6,0x7,0,0x1,0,0x8, | ||
874 | 0xf0,0xf,0,0x10,0x2,0,0x30,0,0,0,0,0,0,0,0x6,0xfe, | ||
875 | 0,0,0x2,0,0x50,0,0x8a,0,0x4f,0x95,0,0,0x21,0,0xb,0, | ||
876 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
877 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
878 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
879 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
880 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
881 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
882 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
883 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
884 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
885 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
886 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
887 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xa5,0x51, | ||
888 | }; | ||
889 | |||
890 | static int inquiry_evpd_89(unsigned char * arr) | ||
891 | { | ||
892 | memcpy(arr, vpd89_data, sizeof(vpd89_data)); | ||
893 | return sizeof(vpd89_data); | ||
894 | } | ||
895 | |||
896 | |||
897 | static unsigned char vpdb0_data[] = { | ||
898 | /* from 4th byte */ 0,0,0,4, | ||
899 | 0,0,0x4,0, | ||
900 | 0,0,0,64, | ||
901 | }; | ||
902 | |||
903 | static int inquiry_evpd_b0(unsigned char * arr) | ||
904 | { | ||
905 | memcpy(arr, vpdb0_data, sizeof(vpdb0_data)); | ||
906 | if (sdebug_store_sectors > 0x400) { | ||
907 | arr[4] = (sdebug_store_sectors >> 24) & 0xff; | ||
908 | arr[5] = (sdebug_store_sectors >> 16) & 0xff; | ||
909 | arr[6] = (sdebug_store_sectors >> 8) & 0xff; | ||
910 | arr[7] = sdebug_store_sectors & 0xff; | ||
911 | } | ||
912 | return sizeof(vpdb0_data); | ||
600 | } | 913 | } |
601 | 914 | ||
602 | 915 | ||
603 | #define SDEBUG_LONG_INQ_SZ 96 | 916 | #define SDEBUG_LONG_INQ_SZ 96 |
604 | #define SDEBUG_MAX_INQ_ARR_SZ 128 | 917 | #define SDEBUG_MAX_INQ_ARR_SZ 584 |
605 | 918 | ||
606 | static int resp_inquiry(struct scsi_cmnd * scp, int target, | 919 | static int resp_inquiry(struct scsi_cmnd * scp, int target, |
607 | struct sdebug_dev_info * devip) | 920 | struct sdebug_dev_info * devip) |
@@ -609,64 +922,113 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
609 | unsigned char pq_pdt; | 922 | unsigned char pq_pdt; |
610 | unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; | 923 | unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; |
611 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 924 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
612 | int alloc_len; | 925 | int alloc_len, n; |
613 | 926 | ||
614 | alloc_len = (cmd[3] << 8) + cmd[4]; | 927 | alloc_len = (cmd[3] << 8) + cmd[4]; |
615 | memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); | 928 | memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); |
616 | pq_pdt = (scsi_debug_ptype & 0x1f); | 929 | if (devip->wlun) |
930 | pq_pdt = 0x1e; /* present, wlun */ | ||
931 | else if (scsi_debug_no_lun_0 && (0 == devip->lun)) | ||
932 | pq_pdt = 0x7f; /* not present, no device type */ | ||
933 | else | ||
934 | pq_pdt = (scsi_debug_ptype & 0x1f); | ||
617 | arr[0] = pq_pdt; | 935 | arr[0] = pq_pdt; |
618 | if (0x2 & cmd[1]) { /* CMDDT bit set */ | 936 | if (0x2 & cmd[1]) { /* CMDDT bit set */ |
619 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 937 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
620 | 0); | 938 | 0); |
621 | return check_condition_result; | 939 | return check_condition_result; |
622 | } else if (0x1 & cmd[1]) { /* EVPD bit set */ | 940 | } else if (0x1 & cmd[1]) { /* EVPD bit set */ |
623 | int dev_id_num, len; | 941 | int lu_id_num, target_dev_id, len; |
624 | char dev_id_str[6]; | 942 | char lu_id_str[6]; |
943 | int host_no = devip->sdbg_host->shost->host_no; | ||
625 | 944 | ||
626 | dev_id_num = ((devip->sdbg_host->shost->host_no + 1) * 2000) + | 945 | lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) + |
627 | (devip->target * 1000) + devip->lun; | 946 | (devip->target * 1000) + devip->lun); |
628 | len = scnprintf(dev_id_str, 6, "%d", dev_id_num); | 947 | target_dev_id = ((host_no + 1) * 2000) + |
948 | (devip->target * 1000) - 3; | ||
949 | len = scnprintf(lu_id_str, 6, "%d", lu_id_num); | ||
629 | if (0 == cmd[2]) { /* supported vital product data pages */ | 950 | if (0 == cmd[2]) { /* supported vital product data pages */ |
630 | arr[3] = 3; | 951 | arr[1] = cmd[2]; /*sanity */ |
631 | arr[4] = 0x0; /* this page */ | 952 | n = 4; |
632 | arr[5] = 0x80; /* unit serial number */ | 953 | arr[n++] = 0x0; /* this page */ |
633 | arr[6] = 0x83; /* device identification */ | 954 | arr[n++] = 0x80; /* unit serial number */ |
955 | arr[n++] = 0x83; /* device identification */ | ||
956 | arr[n++] = 0x84; /* software interface ident. */ | ||
957 | arr[n++] = 0x85; /* management network addresses */ | ||
958 | arr[n++] = 0x86; /* extended inquiry */ | ||
959 | arr[n++] = 0x87; /* mode page policy */ | ||
960 | arr[n++] = 0x88; /* SCSI ports */ | ||
961 | arr[n++] = 0x89; /* ATA information */ | ||
962 | arr[n++] = 0xb0; /* Block limits (SBC) */ | ||
963 | arr[3] = n - 4; /* number of supported VPD pages */ | ||
634 | } else if (0x80 == cmd[2]) { /* unit serial number */ | 964 | } else if (0x80 == cmd[2]) { /* unit serial number */ |
635 | arr[1] = 0x80; | 965 | arr[1] = cmd[2]; /*sanity */ |
636 | arr[3] = len; | 966 | arr[3] = len; |
637 | memcpy(&arr[4], dev_id_str, len); | 967 | memcpy(&arr[4], lu_id_str, len); |
638 | } else if (0x83 == cmd[2]) { /* device identification */ | 968 | } else if (0x83 == cmd[2]) { /* device identification */ |
639 | arr[1] = 0x83; | 969 | arr[1] = cmd[2]; /*sanity */ |
640 | arr[3] = inquiry_evpd_83(&arr[4], dev_id_num, | 970 | arr[3] = inquiry_evpd_83(&arr[4], target_dev_id, |
641 | dev_id_str, len); | 971 | lu_id_num, lu_id_str, len); |
972 | } else if (0x84 == cmd[2]) { /* Software interface ident. */ | ||
973 | arr[1] = cmd[2]; /*sanity */ | ||
974 | arr[3] = inquiry_evpd_84(&arr[4]); | ||
975 | } else if (0x85 == cmd[2]) { /* Management network addresses */ | ||
976 | arr[1] = cmd[2]; /*sanity */ | ||
977 | arr[3] = inquiry_evpd_85(&arr[4]); | ||
978 | } else if (0x86 == cmd[2]) { /* extended inquiry */ | ||
979 | arr[1] = cmd[2]; /*sanity */ | ||
980 | arr[3] = 0x3c; /* number of following entries */ | ||
981 | arr[4] = 0x0; /* no protection stuff */ | ||
982 | arr[5] = 0x7; /* head of q, ordered + simple q's */ | ||
983 | } else if (0x87 == cmd[2]) { /* mode page policy */ | ||
984 | arr[1] = cmd[2]; /*sanity */ | ||
985 | arr[3] = 0x8; /* number of following entries */ | ||
986 | arr[4] = 0x2; /* disconnect-reconnect mp */ | ||
987 | arr[6] = 0x80; /* mlus, shared */ | ||
988 | arr[8] = 0x18; /* protocol specific lu */ | ||
989 | arr[10] = 0x82; /* mlus, per initiator port */ | ||
990 | } else if (0x88 == cmd[2]) { /* SCSI Ports */ | ||
991 | arr[1] = cmd[2]; /*sanity */ | ||
992 | arr[3] = inquiry_evpd_88(&arr[4], target_dev_id); | ||
993 | } else if (0x89 == cmd[2]) { /* ATA information */ | ||
994 | arr[1] = cmd[2]; /*sanity */ | ||
995 | n = inquiry_evpd_89(&arr[4]); | ||
996 | arr[2] = (n >> 8); | ||
997 | arr[3] = (n & 0xff); | ||
998 | } else if (0xb0 == cmd[2]) { /* Block limits (SBC) */ | ||
999 | arr[1] = cmd[2]; /*sanity */ | ||
1000 | arr[3] = inquiry_evpd_b0(&arr[4]); | ||
642 | } else { | 1001 | } else { |
643 | /* Illegal request, invalid field in cdb */ | 1002 | /* Illegal request, invalid field in cdb */ |
644 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1003 | mk_sense_buffer(devip, ILLEGAL_REQUEST, |
645 | INVALID_FIELD_IN_CDB, 0); | 1004 | INVALID_FIELD_IN_CDB, 0); |
646 | return check_condition_result; | 1005 | return check_condition_result; |
647 | } | 1006 | } |
1007 | len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); | ||
648 | return fill_from_dev_buffer(scp, arr, | 1008 | return fill_from_dev_buffer(scp, arr, |
649 | min(alloc_len, SDEBUG_MAX_INQ_ARR_SZ)); | 1009 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); |
650 | } | 1010 | } |
651 | /* drops through here for a standard inquiry */ | 1011 | /* drops through here for a standard inquiry */ |
652 | arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ | 1012 | arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ |
653 | arr[2] = scsi_debug_scsi_level; | 1013 | arr[2] = scsi_debug_scsi_level; |
654 | arr[3] = 2; /* response_data_format==2 */ | 1014 | arr[3] = 2; /* response_data_format==2 */ |
655 | arr[4] = SDEBUG_LONG_INQ_SZ - 5; | 1015 | arr[4] = SDEBUG_LONG_INQ_SZ - 5; |
656 | arr[6] = 0x1; /* claim: ADDR16 */ | 1016 | arr[6] = 0x10; /* claim: MultiP */ |
657 | /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ | 1017 | /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ |
658 | arr[7] = 0x3a; /* claim: WBUS16, SYNC, LINKED + CMDQUE */ | 1018 | arr[7] = 0xa; /* claim: LINKED + CMDQUE */ |
659 | memcpy(&arr[8], inq_vendor_id, 8); | 1019 | memcpy(&arr[8], inq_vendor_id, 8); |
660 | memcpy(&arr[16], inq_product_id, 16); | 1020 | memcpy(&arr[16], inq_product_id, 16); |
661 | memcpy(&arr[32], inq_product_rev, 4); | 1021 | memcpy(&arr[32], inq_product_rev, 4); |
662 | /* version descriptors (2 bytes each) follow */ | 1022 | /* version descriptors (2 bytes each) follow */ |
663 | arr[58] = 0x0; arr[59] = 0x40; /* SAM-2 */ | 1023 | arr[58] = 0x0; arr[59] = 0x77; /* SAM-3 ANSI */ |
664 | arr[60] = 0x3; arr[61] = 0x0; /* SPC-3 */ | 1024 | arr[60] = 0x3; arr[61] = 0x14; /* SPC-3 ANSI */ |
1025 | n = 62; | ||
665 | if (scsi_debug_ptype == 0) { | 1026 | if (scsi_debug_ptype == 0) { |
666 | arr[62] = 0x1; arr[63] = 0x80; /* SBC */ | 1027 | arr[n++] = 0x3; arr[n++] = 0x3d; /* SBC-2 ANSI */ |
667 | } else if (scsi_debug_ptype == 1) { | 1028 | } else if (scsi_debug_ptype == 1) { |
668 | arr[62] = 0x2; arr[63] = 0x00; /* SSC */ | 1029 | arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */ |
669 | } | 1030 | } |
1031 | arr[n++] = 0xc; arr[n++] = 0xf; /* SAS-1.1 rev 10 */ | ||
670 | return fill_from_dev_buffer(scp, arr, | 1032 | return fill_from_dev_buffer(scp, arr, |
671 | min(alloc_len, SDEBUG_LONG_INQ_SZ)); | 1033 | min(alloc_len, SDEBUG_LONG_INQ_SZ)); |
672 | } | 1034 | } |
@@ -677,46 +1039,141 @@ static int resp_requests(struct scsi_cmnd * scp, | |||
677 | unsigned char * sbuff; | 1039 | unsigned char * sbuff; |
678 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1040 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
679 | unsigned char arr[SDEBUG_SENSE_LEN]; | 1041 | unsigned char arr[SDEBUG_SENSE_LEN]; |
1042 | int want_dsense; | ||
680 | int len = 18; | 1043 | int len = 18; |
681 | 1044 | ||
682 | memset(arr, 0, SDEBUG_SENSE_LEN); | 1045 | memset(arr, 0, sizeof(arr)); |
683 | if (devip->reset == 1) | 1046 | if (devip->reset == 1) |
684 | mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0); | 1047 | mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0); |
1048 | want_dsense = !!(cmd[1] & 1) || scsi_debug_dsense; | ||
685 | sbuff = devip->sense_buff; | 1049 | sbuff = devip->sense_buff; |
686 | if ((cmd[1] & 1) && (! scsi_debug_dsense)) { | 1050 | if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) { |
687 | /* DESC bit set and sense_buff in fixed format */ | 1051 | if (want_dsense) { |
688 | arr[0] = 0x72; | 1052 | arr[0] = 0x72; |
689 | arr[1] = sbuff[2]; /* sense key */ | 1053 | arr[1] = 0x0; /* NO_SENSE in sense_key */ |
690 | arr[2] = sbuff[12]; /* asc */ | 1054 | arr[2] = THRESHOLD_EXCEEDED; |
691 | arr[3] = sbuff[13]; /* ascq */ | 1055 | arr[3] = 0xff; /* TEST set and MRIE==6 */ |
692 | len = 8; | 1056 | } else { |
693 | } else | 1057 | arr[0] = 0x70; |
1058 | arr[2] = 0x0; /* NO_SENSE in sense_key */ | ||
1059 | arr[7] = 0xa; /* 18 byte sense buffer */ | ||
1060 | arr[12] = THRESHOLD_EXCEEDED; | ||
1061 | arr[13] = 0xff; /* TEST set and MRIE==6 */ | ||
1062 | } | ||
1063 | } else if (devip->stopped) { | ||
1064 | if (want_dsense) { | ||
1065 | arr[0] = 0x72; | ||
1066 | arr[1] = 0x0; /* NO_SENSE in sense_key */ | ||
1067 | arr[2] = LOW_POWER_COND_ON; | ||
1068 | arr[3] = 0x0; /* TEST set and MRIE==6 */ | ||
1069 | } else { | ||
1070 | arr[0] = 0x70; | ||
1071 | arr[2] = 0x0; /* NO_SENSE in sense_key */ | ||
1072 | arr[7] = 0xa; /* 18 byte sense buffer */ | ||
1073 | arr[12] = LOW_POWER_COND_ON; | ||
1074 | arr[13] = 0x0; /* TEST set and MRIE==6 */ | ||
1075 | } | ||
1076 | } else { | ||
694 | memcpy(arr, sbuff, SDEBUG_SENSE_LEN); | 1077 | memcpy(arr, sbuff, SDEBUG_SENSE_LEN); |
695 | mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0); | 1078 | if ((cmd[1] & 1) && (! scsi_debug_dsense)) { |
1079 | /* DESC bit set and sense_buff in fixed format */ | ||
1080 | memset(arr, 0, sizeof(arr)); | ||
1081 | arr[0] = 0x72; | ||
1082 | arr[1] = sbuff[2]; /* sense key */ | ||
1083 | arr[2] = sbuff[12]; /* asc */ | ||
1084 | arr[3] = sbuff[13]; /* ascq */ | ||
1085 | len = 8; | ||
1086 | } | ||
1087 | } | ||
1088 | mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0); | ||
696 | return fill_from_dev_buffer(scp, arr, len); | 1089 | return fill_from_dev_buffer(scp, arr, len); |
697 | } | 1090 | } |
698 | 1091 | ||
1092 | static int resp_start_stop(struct scsi_cmnd * scp, | ||
1093 | struct sdebug_dev_info * devip) | ||
1094 | { | ||
1095 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1096 | int power_cond, errsts, start; | ||
1097 | |||
1098 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1099 | return errsts; | ||
1100 | power_cond = (cmd[4] & 0xf0) >> 4; | ||
1101 | if (power_cond) { | ||
1102 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1103 | 0); | ||
1104 | return check_condition_result; | ||
1105 | } | ||
1106 | start = cmd[4] & 1; | ||
1107 | if (start == devip->stopped) | ||
1108 | devip->stopped = !start; | ||
1109 | return 0; | ||
1110 | } | ||
1111 | |||
699 | #define SDEBUG_READCAP_ARR_SZ 8 | 1112 | #define SDEBUG_READCAP_ARR_SZ 8 |
700 | static int resp_readcap(struct scsi_cmnd * scp, | 1113 | static int resp_readcap(struct scsi_cmnd * scp, |
701 | struct sdebug_dev_info * devip) | 1114 | struct sdebug_dev_info * devip) |
702 | { | 1115 | { |
703 | unsigned char arr[SDEBUG_READCAP_ARR_SZ]; | 1116 | unsigned char arr[SDEBUG_READCAP_ARR_SZ]; |
704 | unsigned long capac; | 1117 | unsigned int capac; |
705 | int errsts; | 1118 | int errsts; |
706 | 1119 | ||
707 | if ((errsts = check_reset(scp, devip))) | 1120 | if ((errsts = check_readiness(scp, 1, devip))) |
708 | return errsts; | 1121 | return errsts; |
1122 | /* following just in case virtual_gb changed */ | ||
1123 | if (scsi_debug_virtual_gb > 0) { | ||
1124 | sdebug_capacity = 2048 * 1024; | ||
1125 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1126 | } else | ||
1127 | sdebug_capacity = sdebug_store_sectors; | ||
709 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); | 1128 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); |
710 | capac = (unsigned long)sdebug_capacity - 1; | 1129 | if (sdebug_capacity < 0xffffffff) { |
711 | arr[0] = (capac >> 24); | 1130 | capac = (unsigned int)sdebug_capacity - 1; |
712 | arr[1] = (capac >> 16) & 0xff; | 1131 | arr[0] = (capac >> 24); |
713 | arr[2] = (capac >> 8) & 0xff; | 1132 | arr[1] = (capac >> 16) & 0xff; |
714 | arr[3] = capac & 0xff; | 1133 | arr[2] = (capac >> 8) & 0xff; |
1134 | arr[3] = capac & 0xff; | ||
1135 | } else { | ||
1136 | arr[0] = 0xff; | ||
1137 | arr[1] = 0xff; | ||
1138 | arr[2] = 0xff; | ||
1139 | arr[3] = 0xff; | ||
1140 | } | ||
715 | arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; | 1141 | arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; |
716 | arr[7] = SECT_SIZE_PER(target) & 0xff; | 1142 | arr[7] = SECT_SIZE_PER(target) & 0xff; |
717 | return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ); | 1143 | return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ); |
718 | } | 1144 | } |
719 | 1145 | ||
1146 | #define SDEBUG_READCAP16_ARR_SZ 32 | ||
1147 | static int resp_readcap16(struct scsi_cmnd * scp, | ||
1148 | struct sdebug_dev_info * devip) | ||
1149 | { | ||
1150 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1151 | unsigned char arr[SDEBUG_READCAP16_ARR_SZ]; | ||
1152 | unsigned long long capac; | ||
1153 | int errsts, k, alloc_len; | ||
1154 | |||
1155 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1156 | return errsts; | ||
1157 | alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) | ||
1158 | + cmd[13]); | ||
1159 | /* following just in case virtual_gb changed */ | ||
1160 | if (scsi_debug_virtual_gb > 0) { | ||
1161 | sdebug_capacity = 2048 * 1024; | ||
1162 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1163 | } else | ||
1164 | sdebug_capacity = sdebug_store_sectors; | ||
1165 | memset(arr, 0, SDEBUG_READCAP16_ARR_SZ); | ||
1166 | capac = sdebug_capacity - 1; | ||
1167 | for (k = 0; k < 8; ++k, capac >>= 8) | ||
1168 | arr[7 - k] = capac & 0xff; | ||
1169 | arr[8] = (SECT_SIZE_PER(target) >> 24) & 0xff; | ||
1170 | arr[9] = (SECT_SIZE_PER(target) >> 16) & 0xff; | ||
1171 | arr[10] = (SECT_SIZE_PER(target) >> 8) & 0xff; | ||
1172 | arr[11] = SECT_SIZE_PER(target) & 0xff; | ||
1173 | return fill_from_dev_buffer(scp, arr, | ||
1174 | min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); | ||
1175 | } | ||
1176 | |||
720 | /* <<Following mode page info copied from ST318451LW>> */ | 1177 | /* <<Following mode page info copied from ST318451LW>> */ |
721 | 1178 | ||
722 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) | 1179 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) |
@@ -772,27 +1229,98 @@ static int resp_caching_pg(unsigned char * p, int pcontrol, int target) | |||
772 | 1229 | ||
773 | static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) | 1230 | static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) |
774 | { /* Control mode page for mode_sense */ | 1231 | { /* Control mode page for mode_sense */ |
775 | unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | 1232 | unsigned char ch_ctrl_m_pg[] = {/* 0xa, 10, */ 0x6, 0, 0, 0, 0, 0, |
1233 | 0, 0, 0, 0}; | ||
1234 | unsigned char d_ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | ||
776 | 0, 0, 0x2, 0x4b}; | 1235 | 0, 0, 0x2, 0x4b}; |
777 | 1236 | ||
778 | if (scsi_debug_dsense) | 1237 | if (scsi_debug_dsense) |
779 | ctrl_m_pg[2] |= 0x4; | 1238 | ctrl_m_pg[2] |= 0x4; |
1239 | else | ||
1240 | ctrl_m_pg[2] &= ~0x4; | ||
780 | memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); | 1241 | memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); |
781 | if (1 == pcontrol) | 1242 | if (1 == pcontrol) |
782 | memset(p + 2, 0, sizeof(ctrl_m_pg) - 2); | 1243 | memcpy(p + 2, ch_ctrl_m_pg, sizeof(ch_ctrl_m_pg)); |
1244 | else if (2 == pcontrol) | ||
1245 | memcpy(p, d_ctrl_m_pg, sizeof(d_ctrl_m_pg)); | ||
783 | return sizeof(ctrl_m_pg); | 1246 | return sizeof(ctrl_m_pg); |
784 | } | 1247 | } |
785 | 1248 | ||
1249 | |||
786 | static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target) | 1250 | static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target) |
787 | { /* Informational Exceptions control mode page for mode_sense */ | 1251 | { /* Informational Exceptions control mode page for mode_sense */ |
788 | unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | 1252 | unsigned char ch_iec_m_pg[] = {/* 0x1c, 0xa, */ 0x4, 0xf, 0, 0, 0, 0, |
789 | 0, 0, 0x0, 0x0}; | 1253 | 0, 0, 0x0, 0x0}; |
1254 | unsigned char d_iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | ||
1255 | 0, 0, 0x0, 0x0}; | ||
1256 | |||
790 | memcpy(p, iec_m_pg, sizeof(iec_m_pg)); | 1257 | memcpy(p, iec_m_pg, sizeof(iec_m_pg)); |
791 | if (1 == pcontrol) | 1258 | if (1 == pcontrol) |
792 | memset(p + 2, 0, sizeof(iec_m_pg) - 2); | 1259 | memcpy(p + 2, ch_iec_m_pg, sizeof(ch_iec_m_pg)); |
1260 | else if (2 == pcontrol) | ||
1261 | memcpy(p, d_iec_m_pg, sizeof(d_iec_m_pg)); | ||
793 | return sizeof(iec_m_pg); | 1262 | return sizeof(iec_m_pg); |
794 | } | 1263 | } |
795 | 1264 | ||
1265 | static int resp_sas_sf_m_pg(unsigned char * p, int pcontrol, int target) | ||
1266 | { /* SAS SSP mode page - short format for mode_sense */ | ||
1267 | unsigned char sas_sf_m_pg[] = {0x19, 0x6, | ||
1268 | 0x6, 0x0, 0x7, 0xd0, 0x0, 0x0}; | ||
1269 | |||
1270 | memcpy(p, sas_sf_m_pg, sizeof(sas_sf_m_pg)); | ||
1271 | if (1 == pcontrol) | ||
1272 | memset(p + 2, 0, sizeof(sas_sf_m_pg) - 2); | ||
1273 | return sizeof(sas_sf_m_pg); | ||
1274 | } | ||
1275 | |||
1276 | |||
1277 | static int resp_sas_pcd_m_spg(unsigned char * p, int pcontrol, int target, | ||
1278 | int target_dev_id) | ||
1279 | { /* SAS phy control and discover mode page for mode_sense */ | ||
1280 | unsigned char sas_pcd_m_pg[] = {0x59, 0x1, 0, 0x64, 0, 0x6, 0, 2, | ||
1281 | 0, 0, 0, 0, 0x10, 0x9, 0x8, 0x0, | ||
1282 | 0x52, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x0, | ||
1283 | 0x51, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1, | ||
1284 | 0x2, 0, 0, 0, 0, 0, 0, 0, | ||
1285 | 0x88, 0x99, 0, 0, 0, 0, 0, 0, | ||
1286 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
1287 | 0, 1, 0, 0, 0x10, 0x9, 0x8, 0x0, | ||
1288 | 0x52, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x0, | ||
1289 | 0x51, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1, | ||
1290 | 0x3, 0, 0, 0, 0, 0, 0, 0, | ||
1291 | 0x88, 0x99, 0, 0, 0, 0, 0, 0, | ||
1292 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
1293 | }; | ||
1294 | int port_a, port_b; | ||
1295 | |||
1296 | port_a = target_dev_id + 1; | ||
1297 | port_b = port_a + 1; | ||
1298 | memcpy(p, sas_pcd_m_pg, sizeof(sas_pcd_m_pg)); | ||
1299 | p[20] = (port_a >> 24); | ||
1300 | p[21] = (port_a >> 16) & 0xff; | ||
1301 | p[22] = (port_a >> 8) & 0xff; | ||
1302 | p[23] = port_a & 0xff; | ||
1303 | p[48 + 20] = (port_b >> 24); | ||
1304 | p[48 + 21] = (port_b >> 16) & 0xff; | ||
1305 | p[48 + 22] = (port_b >> 8) & 0xff; | ||
1306 | p[48 + 23] = port_b & 0xff; | ||
1307 | if (1 == pcontrol) | ||
1308 | memset(p + 4, 0, sizeof(sas_pcd_m_pg) - 4); | ||
1309 | return sizeof(sas_pcd_m_pg); | ||
1310 | } | ||
1311 | |||
1312 | static int resp_sas_sha_m_spg(unsigned char * p, int pcontrol) | ||
1313 | { /* SAS SSP shared protocol specific port mode subpage */ | ||
1314 | unsigned char sas_sha_m_pg[] = {0x59, 0x2, 0, 0xc, 0, 0x6, 0x10, 0, | ||
1315 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
1316 | }; | ||
1317 | |||
1318 | memcpy(p, sas_sha_m_pg, sizeof(sas_sha_m_pg)); | ||
1319 | if (1 == pcontrol) | ||
1320 | memset(p + 4, 0, sizeof(sas_sha_m_pg) - 4); | ||
1321 | return sizeof(sas_sha_m_pg); | ||
1322 | } | ||
1323 | |||
796 | #define SDEBUG_MAX_MSENSE_SZ 256 | 1324 | #define SDEBUG_MAX_MSENSE_SZ 256 |
797 | 1325 | ||
798 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, | 1326 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, |
@@ -801,12 +1329,12 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
801 | unsigned char dbd; | 1329 | unsigned char dbd; |
802 | int pcontrol, pcode, subpcode; | 1330 | int pcontrol, pcode, subpcode; |
803 | unsigned char dev_spec; | 1331 | unsigned char dev_spec; |
804 | int alloc_len, msense_6, offset, len, errsts; | 1332 | int alloc_len, msense_6, offset, len, errsts, target_dev_id; |
805 | unsigned char * ap; | 1333 | unsigned char * ap; |
806 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; | 1334 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; |
807 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1335 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
808 | 1336 | ||
809 | if ((errsts = check_reset(scp, devip))) | 1337 | if ((errsts = check_readiness(scp, 1, devip))) |
810 | return errsts; | 1338 | return errsts; |
811 | dbd = cmd[1] & 0x8; | 1339 | dbd = cmd[1] & 0x8; |
812 | pcontrol = (cmd[2] & 0xc0) >> 6; | 1340 | pcontrol = (cmd[2] & 0xc0) >> 6; |
@@ -820,6 +1348,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
820 | 0); | 1348 | 0); |
821 | return check_condition_result; | 1349 | return check_condition_result; |
822 | } | 1350 | } |
1351 | target_dev_id = ((devip->sdbg_host->shost->host_no + 1) * 2000) + | ||
1352 | (devip->target * 1000) - 3; | ||
823 | dev_spec = DEV_READONLY(target) ? 0x80 : 0x0; | 1353 | dev_spec = DEV_READONLY(target) ? 0x80 : 0x0; |
824 | if (msense_6) { | 1354 | if (msense_6) { |
825 | arr[2] = dev_spec; | 1355 | arr[2] = dev_spec; |
@@ -830,7 +1360,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
830 | } | 1360 | } |
831 | ap = arr + offset; | 1361 | ap = arr + offset; |
832 | 1362 | ||
833 | if (0 != subpcode) { /* TODO: Control Extension page */ | 1363 | if ((subpcode > 0x0) && (subpcode < 0xff) && (0x19 != pcode)) { |
1364 | /* TODO: Control Extension page */ | ||
834 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1365 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
835 | 0); | 1366 | 0); |
836 | return check_condition_result; | 1367 | return check_condition_result; |
@@ -856,17 +1387,45 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
856 | len = resp_ctrl_m_pg(ap, pcontrol, target); | 1387 | len = resp_ctrl_m_pg(ap, pcontrol, target); |
857 | offset += len; | 1388 | offset += len; |
858 | break; | 1389 | break; |
1390 | case 0x19: /* if spc==1 then sas phy, control+discover */ | ||
1391 | if ((subpcode > 0x2) && (subpcode < 0xff)) { | ||
1392 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1393 | INVALID_FIELD_IN_CDB, 0); | ||
1394 | return check_condition_result; | ||
1395 | } | ||
1396 | len = 0; | ||
1397 | if ((0x0 == subpcode) || (0xff == subpcode)) | ||
1398 | len += resp_sas_sf_m_pg(ap + len, pcontrol, target); | ||
1399 | if ((0x1 == subpcode) || (0xff == subpcode)) | ||
1400 | len += resp_sas_pcd_m_spg(ap + len, pcontrol, target, | ||
1401 | target_dev_id); | ||
1402 | if ((0x2 == subpcode) || (0xff == subpcode)) | ||
1403 | len += resp_sas_sha_m_spg(ap + len, pcontrol); | ||
1404 | offset += len; | ||
1405 | break; | ||
859 | case 0x1c: /* Informational Exceptions Mode page, all devices */ | 1406 | case 0x1c: /* Informational Exceptions Mode page, all devices */ |
860 | len = resp_iec_m_pg(ap, pcontrol, target); | 1407 | len = resp_iec_m_pg(ap, pcontrol, target); |
861 | offset += len; | 1408 | offset += len; |
862 | break; | 1409 | break; |
863 | case 0x3f: /* Read all Mode pages */ | 1410 | case 0x3f: /* Read all Mode pages */ |
864 | len = resp_err_recov_pg(ap, pcontrol, target); | 1411 | if ((0 == subpcode) || (0xff == subpcode)) { |
865 | len += resp_disconnect_pg(ap + len, pcontrol, target); | 1412 | len = resp_err_recov_pg(ap, pcontrol, target); |
866 | len += resp_format_pg(ap + len, pcontrol, target); | 1413 | len += resp_disconnect_pg(ap + len, pcontrol, target); |
867 | len += resp_caching_pg(ap + len, pcontrol, target); | 1414 | len += resp_format_pg(ap + len, pcontrol, target); |
868 | len += resp_ctrl_m_pg(ap + len, pcontrol, target); | 1415 | len += resp_caching_pg(ap + len, pcontrol, target); |
869 | len += resp_iec_m_pg(ap + len, pcontrol, target); | 1416 | len += resp_ctrl_m_pg(ap + len, pcontrol, target); |
1417 | len += resp_sas_sf_m_pg(ap + len, pcontrol, target); | ||
1418 | if (0xff == subpcode) { | ||
1419 | len += resp_sas_pcd_m_spg(ap + len, pcontrol, | ||
1420 | target, target_dev_id); | ||
1421 | len += resp_sas_sha_m_spg(ap + len, pcontrol); | ||
1422 | } | ||
1423 | len += resp_iec_m_pg(ap + len, pcontrol, target); | ||
1424 | } else { | ||
1425 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1426 | INVALID_FIELD_IN_CDB, 0); | ||
1427 | return check_condition_result; | ||
1428 | } | ||
870 | offset += len; | 1429 | offset += len; |
871 | break; | 1430 | break; |
872 | default: | 1431 | default: |
@@ -883,71 +1442,274 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
883 | return fill_from_dev_buffer(scp, arr, min(alloc_len, offset)); | 1442 | return fill_from_dev_buffer(scp, arr, min(alloc_len, offset)); |
884 | } | 1443 | } |
885 | 1444 | ||
886 | static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 1445 | #define SDEBUG_MAX_MSELECT_SZ 512 |
887 | int num, struct sdebug_dev_info * devip) | 1446 | |
1447 | static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, | ||
1448 | struct sdebug_dev_info * devip) | ||
1449 | { | ||
1450 | int pf, sp, ps, md_len, bd_len, off, spf, pg_len; | ||
1451 | int param_len, res, errsts, mpage; | ||
1452 | unsigned char arr[SDEBUG_MAX_MSELECT_SZ]; | ||
1453 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1454 | |||
1455 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1456 | return errsts; | ||
1457 | memset(arr, 0, sizeof(arr)); | ||
1458 | pf = cmd[1] & 0x10; | ||
1459 | sp = cmd[1] & 0x1; | ||
1460 | param_len = mselect6 ? cmd[4] : ((cmd[7] << 8) + cmd[8]); | ||
1461 | if ((0 == pf) || sp || (param_len > SDEBUG_MAX_MSELECT_SZ)) { | ||
1462 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1463 | INVALID_FIELD_IN_CDB, 0); | ||
1464 | return check_condition_result; | ||
1465 | } | ||
1466 | res = fetch_to_dev_buffer(scp, arr, param_len); | ||
1467 | if (-1 == res) | ||
1468 | return (DID_ERROR << 16); | ||
1469 | else if ((res < param_len) && | ||
1470 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | ||
1471 | printk(KERN_INFO "scsi_debug: mode_select: cdb indicated=%d, " | ||
1472 | " IO sent=%d bytes\n", param_len, res); | ||
1473 | md_len = mselect6 ? (arr[0] + 1) : ((arr[0] << 8) + arr[1] + 2); | ||
1474 | bd_len = mselect6 ? arr[3] : ((arr[6] << 8) + arr[7]); | ||
1475 | if ((md_len > 2) || (0 != bd_len)) { | ||
1476 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1477 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
1478 | return check_condition_result; | ||
1479 | } | ||
1480 | off = bd_len + (mselect6 ? 4 : 8); | ||
1481 | mpage = arr[off] & 0x3f; | ||
1482 | ps = !!(arr[off] & 0x80); | ||
1483 | if (ps) { | ||
1484 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1485 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
1486 | return check_condition_result; | ||
1487 | } | ||
1488 | spf = !!(arr[off] & 0x40); | ||
1489 | pg_len = spf ? ((arr[off + 2] << 8) + arr[off + 3] + 4) : | ||
1490 | (arr[off + 1] + 2); | ||
1491 | if ((pg_len + off) > param_len) { | ||
1492 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1493 | PARAMETER_LIST_LENGTH_ERR, 0); | ||
1494 | return check_condition_result; | ||
1495 | } | ||
1496 | switch (mpage) { | ||
1497 | case 0xa: /* Control Mode page */ | ||
1498 | if (ctrl_m_pg[1] == arr[off + 1]) { | ||
1499 | memcpy(ctrl_m_pg + 2, arr + off + 2, | ||
1500 | sizeof(ctrl_m_pg) - 2); | ||
1501 | scsi_debug_dsense = !!(ctrl_m_pg[2] & 0x4); | ||
1502 | return 0; | ||
1503 | } | ||
1504 | break; | ||
1505 | case 0x1c: /* Informational Exceptions Mode page */ | ||
1506 | if (iec_m_pg[1] == arr[off + 1]) { | ||
1507 | memcpy(iec_m_pg + 2, arr + off + 2, | ||
1508 | sizeof(iec_m_pg) - 2); | ||
1509 | return 0; | ||
1510 | } | ||
1511 | break; | ||
1512 | default: | ||
1513 | break; | ||
1514 | } | ||
1515 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1516 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
1517 | return check_condition_result; | ||
1518 | } | ||
1519 | |||
1520 | static int resp_temp_l_pg(unsigned char * arr) | ||
1521 | { | ||
1522 | unsigned char temp_l_pg[] = {0x0, 0x0, 0x3, 0x2, 0x0, 38, | ||
1523 | 0x0, 0x1, 0x3, 0x2, 0x0, 65, | ||
1524 | }; | ||
1525 | |||
1526 | memcpy(arr, temp_l_pg, sizeof(temp_l_pg)); | ||
1527 | return sizeof(temp_l_pg); | ||
1528 | } | ||
1529 | |||
1530 | static int resp_ie_l_pg(unsigned char * arr) | ||
1531 | { | ||
1532 | unsigned char ie_l_pg[] = {0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 38, | ||
1533 | }; | ||
1534 | |||
1535 | memcpy(arr, ie_l_pg, sizeof(ie_l_pg)); | ||
1536 | if (iec_m_pg[2] & 0x4) { /* TEST bit set */ | ||
1537 | arr[4] = THRESHOLD_EXCEEDED; | ||
1538 | arr[5] = 0xff; | ||
1539 | } | ||
1540 | return sizeof(ie_l_pg); | ||
1541 | } | ||
1542 | |||
1543 | #define SDEBUG_MAX_LSENSE_SZ 512 | ||
1544 | |||
1545 | static int resp_log_sense(struct scsi_cmnd * scp, | ||
1546 | struct sdebug_dev_info * devip) | ||
1547 | { | ||
1548 | int ppc, sp, pcontrol, pcode, alloc_len, errsts, len, n; | ||
1549 | unsigned char arr[SDEBUG_MAX_LSENSE_SZ]; | ||
1550 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
1551 | |||
1552 | if ((errsts = check_readiness(scp, 1, devip))) | ||
1553 | return errsts; | ||
1554 | memset(arr, 0, sizeof(arr)); | ||
1555 | ppc = cmd[1] & 0x2; | ||
1556 | sp = cmd[1] & 0x1; | ||
1557 | if (ppc || sp) { | ||
1558 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1559 | INVALID_FIELD_IN_CDB, 0); | ||
1560 | return check_condition_result; | ||
1561 | } | ||
1562 | pcontrol = (cmd[2] & 0xc0) >> 6; | ||
1563 | pcode = cmd[2] & 0x3f; | ||
1564 | alloc_len = (cmd[7] << 8) + cmd[8]; | ||
1565 | arr[0] = pcode; | ||
1566 | switch (pcode) { | ||
1567 | case 0x0: /* Supported log pages log page */ | ||
1568 | n = 4; | ||
1569 | arr[n++] = 0x0; /* this page */ | ||
1570 | arr[n++] = 0xd; /* Temperature */ | ||
1571 | arr[n++] = 0x2f; /* Informational exceptions */ | ||
1572 | arr[3] = n - 4; | ||
1573 | break; | ||
1574 | case 0xd: /* Temperature log page */ | ||
1575 | arr[3] = resp_temp_l_pg(arr + 4); | ||
1576 | break; | ||
1577 | case 0x2f: /* Informational exceptions log page */ | ||
1578 | arr[3] = resp_ie_l_pg(arr + 4); | ||
1579 | break; | ||
1580 | default: | ||
1581 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
1582 | INVALID_FIELD_IN_CDB, 0); | ||
1583 | return check_condition_result; | ||
1584 | } | ||
1585 | len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); | ||
1586 | return fill_from_dev_buffer(scp, arr, | ||
1587 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); | ||
1588 | } | ||
1589 | |||
1590 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
1591 | unsigned int num, struct sdebug_dev_info * devip) | ||
888 | { | 1592 | { |
889 | unsigned long iflags; | 1593 | unsigned long iflags; |
1594 | unsigned int block, from_bottom; | ||
1595 | unsigned long long u; | ||
890 | int ret; | 1596 | int ret; |
891 | 1597 | ||
892 | if (upper_blk || (block + num > sdebug_capacity)) { | 1598 | if (lba + num > sdebug_capacity) { |
893 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1599 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, |
894 | 0); | 1600 | 0); |
895 | return check_condition_result; | 1601 | return check_condition_result; |
896 | } | 1602 | } |
1603 | /* transfer length excessive (tie in to block limits VPD page) */ | ||
1604 | if (num > sdebug_store_sectors) { | ||
1605 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1606 | 0); | ||
1607 | return check_condition_result; | ||
1608 | } | ||
897 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && | 1609 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && |
898 | (block <= OPT_MEDIUM_ERR_ADDR) && | 1610 | (lba <= OPT_MEDIUM_ERR_ADDR) && |
899 | ((block + num) > OPT_MEDIUM_ERR_ADDR)) { | 1611 | ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { |
1612 | /* claim unrecoverable read error */ | ||
900 | mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, | 1613 | mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, |
901 | 0); | 1614 | 0); |
902 | /* claim unrecoverable read error */ | 1615 | /* set info field and valid bit for fixed descriptor */ |
1616 | if (0x70 == (devip->sense_buff[0] & 0x7f)) { | ||
1617 | devip->sense_buff[0] |= 0x80; /* Valid bit */ | ||
1618 | ret = OPT_MEDIUM_ERR_ADDR; | ||
1619 | devip->sense_buff[3] = (ret >> 24) & 0xff; | ||
1620 | devip->sense_buff[4] = (ret >> 16) & 0xff; | ||
1621 | devip->sense_buff[5] = (ret >> 8) & 0xff; | ||
1622 | devip->sense_buff[6] = ret & 0xff; | ||
1623 | } | ||
903 | return check_condition_result; | 1624 | return check_condition_result; |
904 | } | 1625 | } |
905 | read_lock_irqsave(&atomic_rw, iflags); | 1626 | read_lock_irqsave(&atomic_rw, iflags); |
906 | ret = fill_from_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE), | 1627 | if ((lba + num) <= sdebug_store_sectors) |
907 | num * SECT_SIZE); | 1628 | ret = fill_from_dev_buffer(SCpnt, |
1629 | fake_storep + (lba * SECT_SIZE), | ||
1630 | num * SECT_SIZE); | ||
1631 | else { | ||
1632 | /* modulo when one arg is 64 bits needs do_div() */ | ||
1633 | u = lba; | ||
1634 | block = do_div(u, sdebug_store_sectors); | ||
1635 | from_bottom = 0; | ||
1636 | if ((block + num) > sdebug_store_sectors) | ||
1637 | from_bottom = (block + num) - sdebug_store_sectors; | ||
1638 | ret = fill_from_dev_buffer(SCpnt, | ||
1639 | fake_storep + (block * SECT_SIZE), | ||
1640 | (num - from_bottom) * SECT_SIZE); | ||
1641 | if ((0 == ret) && (from_bottom > 0)) | ||
1642 | ret = fill_from_dev_buffer(SCpnt, fake_storep, | ||
1643 | from_bottom * SECT_SIZE); | ||
1644 | } | ||
908 | read_unlock_irqrestore(&atomic_rw, iflags); | 1645 | read_unlock_irqrestore(&atomic_rw, iflags); |
909 | return ret; | 1646 | return ret; |
910 | } | 1647 | } |
911 | 1648 | ||
912 | static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 1649 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, |
913 | int num, struct sdebug_dev_info * devip) | 1650 | unsigned int num, struct sdebug_dev_info * devip) |
914 | { | 1651 | { |
915 | unsigned long iflags; | 1652 | unsigned long iflags; |
1653 | unsigned int block, to_bottom; | ||
1654 | unsigned long long u; | ||
916 | int res; | 1655 | int res; |
917 | 1656 | ||
918 | if (upper_blk || (block + num > sdebug_capacity)) { | 1657 | if (lba + num > sdebug_capacity) { |
919 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1658 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, |
920 | 0); | 1659 | 0); |
921 | return check_condition_result; | 1660 | return check_condition_result; |
922 | } | 1661 | } |
1662 | /* transfer length excessive (tie in to block limits VPD page) */ | ||
1663 | if (num > sdebug_store_sectors) { | ||
1664 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1665 | 0); | ||
1666 | return check_condition_result; | ||
1667 | } | ||
923 | 1668 | ||
924 | write_lock_irqsave(&atomic_rw, iflags); | 1669 | write_lock_irqsave(&atomic_rw, iflags); |
925 | res = fetch_to_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE), | 1670 | if ((lba + num) <= sdebug_store_sectors) |
926 | num * SECT_SIZE); | 1671 | res = fetch_to_dev_buffer(SCpnt, |
1672 | fake_storep + (lba * SECT_SIZE), | ||
1673 | num * SECT_SIZE); | ||
1674 | else { | ||
1675 | /* modulo when one arg is 64 bits needs do_div() */ | ||
1676 | u = lba; | ||
1677 | block = do_div(u, sdebug_store_sectors); | ||
1678 | to_bottom = 0; | ||
1679 | if ((block + num) > sdebug_store_sectors) | ||
1680 | to_bottom = (block + num) - sdebug_store_sectors; | ||
1681 | res = fetch_to_dev_buffer(SCpnt, | ||
1682 | fake_storep + (block * SECT_SIZE), | ||
1683 | (num - to_bottom) * SECT_SIZE); | ||
1684 | if ((0 == res) && (to_bottom > 0)) | ||
1685 | res = fetch_to_dev_buffer(SCpnt, fake_storep, | ||
1686 | to_bottom * SECT_SIZE); | ||
1687 | } | ||
927 | write_unlock_irqrestore(&atomic_rw, iflags); | 1688 | write_unlock_irqrestore(&atomic_rw, iflags); |
928 | if (-1 == res) | 1689 | if (-1 == res) |
929 | return (DID_ERROR << 16); | 1690 | return (DID_ERROR << 16); |
930 | else if ((res < (num * SECT_SIZE)) && | 1691 | else if ((res < (num * SECT_SIZE)) && |
931 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 1692 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
932 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%d, " | 1693 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, " |
933 | " IO sent=%d bytes\n", num * SECT_SIZE, res); | 1694 | " IO sent=%d bytes\n", num * SECT_SIZE, res); |
934 | return 0; | 1695 | return 0; |
935 | } | 1696 | } |
936 | 1697 | ||
937 | #define SDEBUG_RLUN_ARR_SZ 128 | 1698 | #define SDEBUG_RLUN_ARR_SZ 256 |
938 | 1699 | ||
939 | static int resp_report_luns(struct scsi_cmnd * scp, | 1700 | static int resp_report_luns(struct scsi_cmnd * scp, |
940 | struct sdebug_dev_info * devip) | 1701 | struct sdebug_dev_info * devip) |
941 | { | 1702 | { |
942 | unsigned int alloc_len; | 1703 | unsigned int alloc_len; |
943 | int lun_cnt, i, upper; | 1704 | int lun_cnt, i, upper, num, n, wlun, lun; |
944 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1705 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
945 | int select_report = (int)cmd[2]; | 1706 | int select_report = (int)cmd[2]; |
946 | struct scsi_lun *one_lun; | 1707 | struct scsi_lun *one_lun; |
947 | unsigned char arr[SDEBUG_RLUN_ARR_SZ]; | 1708 | unsigned char arr[SDEBUG_RLUN_ARR_SZ]; |
1709 | unsigned char * max_addr; | ||
948 | 1710 | ||
949 | alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); | 1711 | alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); |
950 | if ((alloc_len < 16) || (select_report > 2)) { | 1712 | if ((alloc_len < 4) || (select_report > 2)) { |
951 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1713 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
952 | 0); | 1714 | 0); |
953 | return check_condition_result; | 1715 | return check_condition_result; |
@@ -955,18 +1717,37 @@ static int resp_report_luns(struct scsi_cmnd * scp, | |||
955 | /* can produce response with up to 16k luns (lun 0 to lun 16383) */ | 1717 | /* can produce response with up to 16k luns (lun 0 to lun 16383) */ |
956 | memset(arr, 0, SDEBUG_RLUN_ARR_SZ); | 1718 | memset(arr, 0, SDEBUG_RLUN_ARR_SZ); |
957 | lun_cnt = scsi_debug_max_luns; | 1719 | lun_cnt = scsi_debug_max_luns; |
958 | arr[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff; | 1720 | if (1 == select_report) |
959 | arr[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff; | 1721 | lun_cnt = 0; |
960 | lun_cnt = min((int)((SDEBUG_RLUN_ARR_SZ - 8) / | 1722 | else if (scsi_debug_no_lun_0 && (lun_cnt > 0)) |
961 | sizeof(struct scsi_lun)), lun_cnt); | 1723 | --lun_cnt; |
1724 | wlun = (select_report > 0) ? 1 : 0; | ||
1725 | num = lun_cnt + wlun; | ||
1726 | arr[2] = ((sizeof(struct scsi_lun) * num) >> 8) & 0xff; | ||
1727 | arr[3] = (sizeof(struct scsi_lun) * num) & 0xff; | ||
1728 | n = min((int)((SDEBUG_RLUN_ARR_SZ - 8) / | ||
1729 | sizeof(struct scsi_lun)), num); | ||
1730 | if (n < num) { | ||
1731 | wlun = 0; | ||
1732 | lun_cnt = n; | ||
1733 | } | ||
962 | one_lun = (struct scsi_lun *) &arr[8]; | 1734 | one_lun = (struct scsi_lun *) &arr[8]; |
963 | for (i = 0; i < lun_cnt; i++) { | 1735 | max_addr = arr + SDEBUG_RLUN_ARR_SZ; |
964 | upper = (i >> 8) & 0x3f; | 1736 | for (i = 0, lun = (scsi_debug_no_lun_0 ? 1 : 0); |
1737 | ((i < lun_cnt) && ((unsigned char *)(one_lun + i) < max_addr)); | ||
1738 | i++, lun++) { | ||
1739 | upper = (lun >> 8) & 0x3f; | ||
965 | if (upper) | 1740 | if (upper) |
966 | one_lun[i].scsi_lun[0] = | 1741 | one_lun[i].scsi_lun[0] = |
967 | (upper | (SAM2_LUN_ADDRESS_METHOD << 6)); | 1742 | (upper | (SAM2_LUN_ADDRESS_METHOD << 6)); |
968 | one_lun[i].scsi_lun[1] = i & 0xff; | 1743 | one_lun[i].scsi_lun[1] = lun & 0xff; |
1744 | } | ||
1745 | if (wlun) { | ||
1746 | one_lun[i].scsi_lun[0] = (SAM2_WLUN_REPORT_LUNS >> 8) & 0xff; | ||
1747 | one_lun[i].scsi_lun[1] = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
1748 | i++; | ||
969 | } | 1749 | } |
1750 | alloc_len = (unsigned char *)(one_lun + i) - arr; | ||
970 | return fill_from_dev_buffer(scp, arr, | 1751 | return fill_from_dev_buffer(scp, arr, |
971 | min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); | 1752 | min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); |
972 | } | 1753 | } |
@@ -1002,7 +1783,8 @@ static void timer_intr_handler(unsigned long indx) | |||
1002 | static int scsi_debug_slave_alloc(struct scsi_device * sdp) | 1783 | static int scsi_debug_slave_alloc(struct scsi_device * sdp) |
1003 | { | 1784 | { |
1004 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1785 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1005 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_alloc\n"); | 1786 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", |
1787 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
1006 | return 0; | 1788 | return 0; |
1007 | } | 1789 | } |
1008 | 1790 | ||
@@ -1011,7 +1793,8 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
1011 | struct sdebug_dev_info * devip; | 1793 | struct sdebug_dev_info * devip; |
1012 | 1794 | ||
1013 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1795 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1014 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_configure\n"); | 1796 | printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n", |
1797 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
1015 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) | 1798 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) |
1016 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; | 1799 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; |
1017 | devip = devInfoReg(sdp); | 1800 | devip = devInfoReg(sdp); |
@@ -1019,6 +1802,7 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
1019 | if (sdp->host->cmd_per_lun) | 1802 | if (sdp->host->cmd_per_lun) |
1020 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, | 1803 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, |
1021 | sdp->host->cmd_per_lun); | 1804 | sdp->host->cmd_per_lun); |
1805 | blk_queue_max_segment_size(sdp->request_queue, 256 * 1024); | ||
1022 | return 0; | 1806 | return 0; |
1023 | } | 1807 | } |
1024 | 1808 | ||
@@ -1028,7 +1812,8 @@ static void scsi_debug_slave_destroy(struct scsi_device * sdp) | |||
1028 | (struct sdebug_dev_info *)sdp->hostdata; | 1812 | (struct sdebug_dev_info *)sdp->hostdata; |
1029 | 1813 | ||
1030 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1814 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
1031 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_destroy\n"); | 1815 | printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", |
1816 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
1032 | if (devip) { | 1817 | if (devip) { |
1033 | /* make this slot avaliable for re-use */ | 1818 | /* make this slot avaliable for re-use */ |
1034 | devip->used = 0; | 1819 | devip->used = 0; |
@@ -1085,6 +1870,8 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
1085 | open_devip->sense_buff[0] = 0x70; | 1870 | open_devip->sense_buff[0] = 0x70; |
1086 | open_devip->sense_buff[7] = 0xa; | 1871 | open_devip->sense_buff[7] = 0xa; |
1087 | } | 1872 | } |
1873 | if (sdev->lun == SAM2_WLUN_REPORT_LUNS) | ||
1874 | open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
1088 | return open_devip; | 1875 | return open_devip; |
1089 | } | 1876 | } |
1090 | return NULL; | 1877 | return NULL; |
@@ -1273,7 +2060,7 @@ static void __init sdebug_build_parts(unsigned char * ramp) | |||
1273 | printk(KERN_WARNING "scsi_debug:build_parts: reducing " | 2060 | printk(KERN_WARNING "scsi_debug:build_parts: reducing " |
1274 | "partitions to %d\n", SDEBUG_MAX_PARTS); | 2061 | "partitions to %d\n", SDEBUG_MAX_PARTS); |
1275 | } | 2062 | } |
1276 | num_sectors = (int)(sdebug_store_size / SECT_SIZE); | 2063 | num_sectors = (int)sdebug_store_sectors; |
1277 | sectors_per_part = (num_sectors - sdebug_sectors_per) | 2064 | sectors_per_part = (num_sectors - sdebug_sectors_per) |
1278 | / scsi_debug_num_parts; | 2065 | / scsi_debug_num_parts; |
1279 | heads_by_sects = sdebug_heads * sdebug_sectors_per; | 2066 | heads_by_sects = sdebug_heads * sdebug_sectors_per; |
@@ -1316,9 +2103,9 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
1316 | if (scsi_result) { | 2103 | if (scsi_result) { |
1317 | struct scsi_device * sdp = cmnd->device; | 2104 | struct scsi_device * sdp = cmnd->device; |
1318 | 2105 | ||
1319 | sdev_printk(KERN_INFO, sdp, | 2106 | printk(KERN_INFO "scsi_debug: <%u %u %u %u> " |
1320 | "non-zero result=0x%x\n", | 2107 | "non-zero result=0x%x\n", sdp->host->host_no, |
1321 | scsi_result); | 2108 | sdp->channel, sdp->id, sdp->lun, scsi_result); |
1322 | } | 2109 | } |
1323 | } | 2110 | } |
1324 | if (cmnd && devip) { | 2111 | if (cmnd && devip) { |
@@ -1365,21 +2152,19 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
1365 | } | 2152 | } |
1366 | } | 2153 | } |
1367 | 2154 | ||
1368 | /* Set 'perm' (4th argument) to 0 to disable module_param's definition | 2155 | module_param_named(add_host, scsi_debug_add_host, int, S_IRUGO | S_IWUSR); |
1369 | * of sysfs parameters (which module_param doesn't yet support). | 2156 | module_param_named(delay, scsi_debug_delay, int, S_IRUGO | S_IWUSR); |
1370 | * Sysfs parameters defined explicitly below. | 2157 | module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, S_IRUGO); |
1371 | */ | 2158 | module_param_named(dsense, scsi_debug_dsense, int, S_IRUGO | S_IWUSR); |
1372 | module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */ | 2159 | module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR); |
1373 | module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */ | 2160 | module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR); |
1374 | module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, 0); | 2161 | module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR); |
1375 | module_param_named(dsense, scsi_debug_dsense, int, 0); | 2162 | module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO); |
1376 | module_param_named(every_nth, scsi_debug_every_nth, int, 0); | 2163 | module_param_named(num_tgts, scsi_debug_num_tgts, int, S_IRUGO | S_IWUSR); |
1377 | module_param_named(max_luns, scsi_debug_max_luns, int, 0); | 2164 | module_param_named(opts, scsi_debug_opts, int, S_IRUGO | S_IWUSR); |
1378 | module_param_named(num_parts, scsi_debug_num_parts, int, 0); | 2165 | module_param_named(ptype, scsi_debug_ptype, int, S_IRUGO | S_IWUSR); |
1379 | module_param_named(num_tgts, scsi_debug_num_tgts, int, 0); | 2166 | module_param_named(scsi_level, scsi_debug_scsi_level, int, S_IRUGO); |
1380 | module_param_named(opts, scsi_debug_opts, int, 0); /* perm=0644 */ | 2167 | module_param_named(virtual_gb, scsi_debug_virtual_gb, int, S_IRUGO | S_IWUSR); |
1381 | module_param_named(ptype, scsi_debug_ptype, int, 0); | ||
1382 | module_param_named(scsi_level, scsi_debug_scsi_level, int, 0); | ||
1383 | 2168 | ||
1384 | MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); | 2169 | MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); |
1385 | MODULE_DESCRIPTION("SCSI debug adapter driver"); | 2170 | MODULE_DESCRIPTION("SCSI debug adapter driver"); |
@@ -1388,15 +2173,17 @@ MODULE_VERSION(SCSI_DEBUG_VERSION); | |||
1388 | 2173 | ||
1389 | MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); | 2174 | MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); |
1390 | MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); | 2175 | MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); |
1391 | MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs"); | 2176 | MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)"); |
1392 | MODULE_PARM_DESC(dsense, "use descriptor sense format(def: fixed)"); | 2177 | MODULE_PARM_DESC(dsense, "use descriptor sense format(def=0 -> fixed)"); |
1393 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)"); | 2178 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)"); |
1394 | MODULE_PARM_DESC(max_luns, "number of SCSI LUNs per target to simulate"); | 2179 | MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); |
2180 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); | ||
1395 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); | 2181 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); |
1396 | MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate"); | 2182 | MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); |
1397 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->..."); | 2183 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->... (def=0)"); |
1398 | MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); | 2184 | MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); |
1399 | MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); | 2185 | MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); |
2186 | MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); | ||
1400 | 2187 | ||
1401 | 2188 | ||
1402 | static char sdebug_info[256]; | 2189 | static char sdebug_info[256]; |
@@ -1548,6 +2335,24 @@ static ssize_t sdebug_dsense_store(struct device_driver * ddp, | |||
1548 | DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show, | 2335 | DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show, |
1549 | sdebug_dsense_store); | 2336 | sdebug_dsense_store); |
1550 | 2337 | ||
2338 | static ssize_t sdebug_no_lun_0_show(struct device_driver * ddp, char * buf) | ||
2339 | { | ||
2340 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_no_lun_0); | ||
2341 | } | ||
2342 | static ssize_t sdebug_no_lun_0_store(struct device_driver * ddp, | ||
2343 | const char * buf, size_t count) | ||
2344 | { | ||
2345 | int n; | ||
2346 | |||
2347 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | ||
2348 | scsi_debug_no_lun_0 = n; | ||
2349 | return count; | ||
2350 | } | ||
2351 | return -EINVAL; | ||
2352 | } | ||
2353 | DRIVER_ATTR(no_lun_0, S_IRUGO | S_IWUSR, sdebug_no_lun_0_show, | ||
2354 | sdebug_no_lun_0_store); | ||
2355 | |||
1551 | static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) | 2356 | static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) |
1552 | { | 2357 | { |
1553 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts); | 2358 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts); |
@@ -1623,6 +2428,29 @@ static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf) | |||
1623 | } | 2428 | } |
1624 | DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL); | 2429 | DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL); |
1625 | 2430 | ||
2431 | static ssize_t sdebug_virtual_gb_show(struct device_driver * ddp, char * buf) | ||
2432 | { | ||
2433 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_virtual_gb); | ||
2434 | } | ||
2435 | static ssize_t sdebug_virtual_gb_store(struct device_driver * ddp, | ||
2436 | const char * buf, size_t count) | ||
2437 | { | ||
2438 | int n; | ||
2439 | |||
2440 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | ||
2441 | scsi_debug_virtual_gb = n; | ||
2442 | if (scsi_debug_virtual_gb > 0) { | ||
2443 | sdebug_capacity = 2048 * 1024; | ||
2444 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
2445 | } else | ||
2446 | sdebug_capacity = sdebug_store_sectors; | ||
2447 | return count; | ||
2448 | } | ||
2449 | return -EINVAL; | ||
2450 | } | ||
2451 | DRIVER_ATTR(virtual_gb, S_IRUGO | S_IWUSR, sdebug_virtual_gb_show, | ||
2452 | sdebug_virtual_gb_store); | ||
2453 | |||
1626 | static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) | 2454 | static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) |
1627 | { | 2455 | { |
1628 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host); | 2456 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host); |
@@ -1692,14 +2520,19 @@ static void do_remove_driverfs_files(void) | |||
1692 | 2520 | ||
1693 | static int __init scsi_debug_init(void) | 2521 | static int __init scsi_debug_init(void) |
1694 | { | 2522 | { |
1695 | unsigned long sz; | 2523 | unsigned int sz; |
1696 | int host_to_add; | 2524 | int host_to_add; |
1697 | int k; | 2525 | int k; |
1698 | 2526 | ||
1699 | if (scsi_debug_dev_size_mb < 1) | 2527 | if (scsi_debug_dev_size_mb < 1) |
1700 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ | 2528 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ |
1701 | sdebug_store_size = (unsigned long)scsi_debug_dev_size_mb * 1048576; | 2529 | sdebug_store_size = (unsigned int)scsi_debug_dev_size_mb * 1048576; |
1702 | sdebug_capacity = sdebug_store_size / SECT_SIZE; | 2530 | sdebug_store_sectors = sdebug_store_size / SECT_SIZE; |
2531 | if (scsi_debug_virtual_gb > 0) { | ||
2532 | sdebug_capacity = 2048 * 1024; | ||
2533 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
2534 | } else | ||
2535 | sdebug_capacity = sdebug_store_sectors; | ||
1703 | 2536 | ||
1704 | /* play around with geometry, don't waste too much on track 0 */ | 2537 | /* play around with geometry, don't waste too much on track 0 */ |
1705 | sdebug_heads = 8; | 2538 | sdebug_heads = 8; |
@@ -1813,7 +2646,7 @@ static int sdebug_add_adapter(void) | |||
1813 | struct sdebug_dev_info *sdbg_devinfo; | 2646 | struct sdebug_dev_info *sdbg_devinfo; |
1814 | struct list_head *lh, *lh_sf; | 2647 | struct list_head *lh, *lh_sf; |
1815 | 2648 | ||
1816 | sdbg_host = kzalloc(sizeof(*sdbg_host), GFP_KERNEL); | 2649 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); |
1817 | 2650 | ||
1818 | if (NULL == sdbg_host) { | 2651 | if (NULL == sdbg_host) { |
1819 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2652 | printk(KERN_ERR "%s: out of memory at line %d\n", |
@@ -1825,7 +2658,7 @@ static int sdebug_add_adapter(void) | |||
1825 | 2658 | ||
1826 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; | 2659 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; |
1827 | for (k = 0; k < devs_per_host; k++) { | 2660 | for (k = 0; k < devs_per_host; k++) { |
1828 | sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo), GFP_KERNEL); | 2661 | sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo),GFP_KERNEL); |
1829 | if (NULL == sdbg_devinfo) { | 2662 | if (NULL == sdbg_devinfo) { |
1830 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2663 | printk(KERN_ERR "%s: out of memory at line %d\n", |
1831 | __FUNCTION__, __LINE__); | 2664 | __FUNCTION__, __LINE__); |
@@ -1906,7 +2739,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
1906 | hpnt->max_id = scsi_debug_num_tgts + 1; | 2739 | hpnt->max_id = scsi_debug_num_tgts + 1; |
1907 | else | 2740 | else |
1908 | hpnt->max_id = scsi_debug_num_tgts; | 2741 | hpnt->max_id = scsi_debug_num_tgts; |
1909 | hpnt->max_lun = scsi_debug_max_luns; | 2742 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* = scsi_debug_max_luns; */ |
1910 | 2743 | ||
1911 | error = scsi_add_host(hpnt, &sdbg_host->dev); | 2744 | error = scsi_add_host(hpnt, &sdbg_host->dev); |
1912 | if (error) { | 2745 | if (error) { |
@@ -1960,7 +2793,7 @@ static void sdebug_max_tgts_luns(void) | |||
1960 | hpnt->max_id = scsi_debug_num_tgts + 1; | 2793 | hpnt->max_id = scsi_debug_num_tgts + 1; |
1961 | else | 2794 | else |
1962 | hpnt->max_id = scsi_debug_num_tgts; | 2795 | hpnt->max_id = scsi_debug_num_tgts; |
1963 | hpnt->max_lun = scsi_debug_max_luns; | 2796 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* scsi_debug_max_luns; */ |
1964 | } | 2797 | } |
1965 | spin_unlock(&sdebug_host_list_lock); | 2798 | spin_unlock(&sdebug_host_list_lock); |
1966 | } | 2799 | } |
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index fb5cb4c9ac65..3d0429bc14ab 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
@@ -162,7 +162,7 @@ static struct { | |||
162 | {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, | 162 | {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, |
163 | {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, | 163 | {"HITACHI", "OPEN-E", "*", BLIST_ATTACH_PQ3 | BLIST_SPARSELUN | BLIST_LARGELUN}, |
164 | {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ | 164 | {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ |
165 | {"HP", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP XP Arrays */ | 165 | {"HP", "OPEN-", "*", BLIST_REPORTLUN2}, /* HP XP Arrays */ |
166 | {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, | 166 | {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, |
167 | {"HP", "HSV100", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, | 167 | {"HP", "HSV100", NULL, BLIST_REPORTLUN2 | BLIST_NOSTARTONADD}, |
168 | {"HP", "C1557A", NULL, BLIST_FORCELUN}, | 168 | {"HP", "C1557A", NULL, BLIST_FORCELUN}, |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 6a7a60fc0a4e..6683d596234a 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1672,7 +1672,9 @@ int | |||
1672 | scsi_reset_provider(struct scsi_device *dev, int flag) | 1672 | scsi_reset_provider(struct scsi_device *dev, int flag) |
1673 | { | 1673 | { |
1674 | struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL); | 1674 | struct scsi_cmnd *scmd = scsi_get_command(dev, GFP_KERNEL); |
1675 | struct Scsi_Host *shost = dev->host; | ||
1675 | struct request req; | 1676 | struct request req; |
1677 | unsigned long flags; | ||
1676 | int rtn; | 1678 | int rtn; |
1677 | 1679 | ||
1678 | scmd->request = &req; | 1680 | scmd->request = &req; |
@@ -1699,6 +1701,10 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1699 | */ | 1701 | */ |
1700 | scmd->pid = 0; | 1702 | scmd->pid = 0; |
1701 | 1703 | ||
1704 | spin_lock_irqsave(shost->host_lock, flags); | ||
1705 | shost->tmf_in_progress = 1; | ||
1706 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1707 | |||
1702 | switch (flag) { | 1708 | switch (flag) { |
1703 | case SCSI_TRY_RESET_DEVICE: | 1709 | case SCSI_TRY_RESET_DEVICE: |
1704 | rtn = scsi_try_bus_device_reset(scmd); | 1710 | rtn = scsi_try_bus_device_reset(scmd); |
@@ -1717,6 +1723,22 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1717 | rtn = FAILED; | 1723 | rtn = FAILED; |
1718 | } | 1724 | } |
1719 | 1725 | ||
1726 | spin_lock_irqsave(shost->host_lock, flags); | ||
1727 | shost->tmf_in_progress = 0; | ||
1728 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1729 | |||
1730 | /* | ||
1731 | * be sure to wake up anyone who was sleeping or had their queue | ||
1732 | * suspended while we performed the TMF. | ||
1733 | */ | ||
1734 | SCSI_LOG_ERROR_RECOVERY(3, | ||
1735 | printk("%s: waking up host to restart after TMF\n", | ||
1736 | __FUNCTION__)); | ||
1737 | |||
1738 | wake_up(&shost->host_wait); | ||
1739 | |||
1740 | scsi_run_host_queues(shost); | ||
1741 | |||
1720 | scsi_next_command(scmd); | 1742 | scsi_next_command(scmd); |
1721 | return rtn; | 1743 | return rtn; |
1722 | } | 1744 | } |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3d04a9f386ac..bf5191f6aaa1 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -855,8 +855,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd) | |||
855 | * b) We can just use scsi_requeue_command() here. This would | 855 | * b) We can just use scsi_requeue_command() here. This would |
856 | * be used if we just wanted to retry, for example. | 856 | * be used if we just wanted to retry, for example. |
857 | */ | 857 | */ |
858 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | 858 | void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) |
859 | unsigned int block_bytes) | ||
860 | { | 859 | { |
861 | int result = cmd->result; | 860 | int result = cmd->result; |
862 | int this_count = cmd->bufflen; | 861 | int this_count = cmd->bufflen; |
@@ -921,87 +920,72 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
921 | * Next deal with any sectors which we were able to correctly | 920 | * Next deal with any sectors which we were able to correctly |
922 | * handle. | 921 | * handle. |
923 | */ | 922 | */ |
924 | if (good_bytes >= 0) { | 923 | if (good_bytes > 0) { |
925 | SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, %d bytes done.\n", | 924 | SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, " |
925 | "%d bytes done.\n", | ||
926 | req->nr_sectors, good_bytes)); | 926 | req->nr_sectors, good_bytes)); |
927 | SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg)); | 927 | SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg)); |
928 | 928 | ||
929 | if (clear_errors) | 929 | if (clear_errors) |
930 | req->errors = 0; | 930 | req->errors = 0; |
931 | /* | ||
932 | * If multiple sectors are requested in one buffer, then | ||
933 | * they will have been finished off by the first command. | ||
934 | * If not, then we have a multi-buffer command. | ||
935 | * | ||
936 | * If block_bytes != 0, it means we had a medium error | ||
937 | * of some sort, and that we want to mark some number of | ||
938 | * sectors as not uptodate. Thus we want to inhibit | ||
939 | * requeueing right here - we will requeue down below | ||
940 | * when we handle the bad sectors. | ||
941 | */ | ||
942 | 931 | ||
943 | /* | 932 | /* A number of bytes were successfully read. If there |
944 | * If the command completed without error, then either | 933 | * is leftovers and there is some kind of error |
945 | * finish off the rest of the command, or start a new one. | 934 | * (result != 0), retry the rest. |
946 | */ | 935 | */ |
947 | if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL) | 936 | if (scsi_end_request(cmd, 1, good_bytes, !!result) == NULL) |
948 | return; | 937 | return; |
949 | } | 938 | } |
950 | /* | 939 | |
951 | * Now, if we were good little boys and girls, Santa left us a request | 940 | /* good_bytes = 0, or (inclusive) there were leftovers and |
952 | * sense buffer. We can extract information from this, so we | 941 | * result = 0, so scsi_end_request couldn't retry. |
953 | * can choose a block to remap, etc. | ||
954 | */ | 942 | */ |
955 | if (sense_valid && !sense_deferred) { | 943 | if (sense_valid && !sense_deferred) { |
956 | switch (sshdr.sense_key) { | 944 | switch (sshdr.sense_key) { |
957 | case UNIT_ATTENTION: | 945 | case UNIT_ATTENTION: |
958 | if (cmd->device->removable) { | 946 | if (cmd->device->removable) { |
959 | /* detected disc change. set a bit | 947 | /* Detected disc change. Set a bit |
960 | * and quietly refuse further access. | 948 | * and quietly refuse further access. |
961 | */ | 949 | */ |
962 | cmd->device->changed = 1; | 950 | cmd->device->changed = 1; |
963 | scsi_end_request(cmd, 0, | 951 | scsi_end_request(cmd, 0, this_count, 1); |
964 | this_count, 1); | ||
965 | return; | 952 | return; |
966 | } else { | 953 | } else { |
967 | /* | 954 | /* Must have been a power glitch, or a |
968 | * Must have been a power glitch, or a | 955 | * bus reset. Could not have been a |
969 | * bus reset. Could not have been a | 956 | * media change, so we just retry the |
970 | * media change, so we just retry the | 957 | * request and see what happens. |
971 | * request and see what happens. | 958 | */ |
972 | */ | ||
973 | scsi_requeue_command(q, cmd); | 959 | scsi_requeue_command(q, cmd); |
974 | return; | 960 | return; |
975 | } | 961 | } |
976 | break; | 962 | break; |
977 | case ILLEGAL_REQUEST: | 963 | case ILLEGAL_REQUEST: |
978 | /* | 964 | /* If we had an ILLEGAL REQUEST returned, then |
979 | * If we had an ILLEGAL REQUEST returned, then we may | 965 | * we may have performed an unsupported |
980 | * have performed an unsupported command. The only | 966 | * command. The only thing this should be |
981 | * thing this should be would be a ten byte read where | 967 | * would be a ten byte read where only a six |
982 | * only a six byte read was supported. Also, on a | 968 | * byte read was supported. Also, on a system |
983 | * system where READ CAPACITY failed, we may have read | 969 | * where READ CAPACITY failed, we may have |
984 | * past the end of the disk. | 970 | * read past the end of the disk. |
985 | */ | 971 | */ |
986 | if ((cmd->device->use_10_for_rw && | 972 | if ((cmd->device->use_10_for_rw && |
987 | sshdr.asc == 0x20 && sshdr.ascq == 0x00) && | 973 | sshdr.asc == 0x20 && sshdr.ascq == 0x00) && |
988 | (cmd->cmnd[0] == READ_10 || | 974 | (cmd->cmnd[0] == READ_10 || |
989 | cmd->cmnd[0] == WRITE_10)) { | 975 | cmd->cmnd[0] == WRITE_10)) { |
990 | cmd->device->use_10_for_rw = 0; | 976 | cmd->device->use_10_for_rw = 0; |
991 | /* | 977 | /* This will cause a retry with a |
992 | * This will cause a retry with a 6-byte | 978 | * 6-byte command. |
993 | * command. | ||
994 | */ | 979 | */ |
995 | scsi_requeue_command(q, cmd); | 980 | scsi_requeue_command(q, cmd); |
996 | result = 0; | 981 | return; |
997 | } else { | 982 | } else { |
998 | scsi_end_request(cmd, 0, this_count, 1); | 983 | scsi_end_request(cmd, 0, this_count, 1); |
999 | return; | 984 | return; |
1000 | } | 985 | } |
1001 | break; | 986 | break; |
1002 | case NOT_READY: | 987 | case NOT_READY: |
1003 | /* | 988 | /* If the device is in the process of becoming |
1004 | * If the device is in the process of becoming | ||
1005 | * ready, or has a temporary blockage, retry. | 989 | * ready, or has a temporary blockage, retry. |
1006 | */ | 990 | */ |
1007 | if (sshdr.asc == 0x04) { | 991 | if (sshdr.asc == 0x04) { |
@@ -1021,7 +1005,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
1021 | } | 1005 | } |
1022 | if (!(req->flags & REQ_QUIET)) { | 1006 | if (!(req->flags & REQ_QUIET)) { |
1023 | scmd_printk(KERN_INFO, cmd, | 1007 | scmd_printk(KERN_INFO, cmd, |
1024 | "Device not ready: "); | 1008 | "Device not ready: "); |
1025 | scsi_print_sense_hdr("", &sshdr); | 1009 | scsi_print_sense_hdr("", &sshdr); |
1026 | } | 1010 | } |
1027 | scsi_end_request(cmd, 0, this_count, 1); | 1011 | scsi_end_request(cmd, 0, this_count, 1); |
@@ -1029,21 +1013,21 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
1029 | case VOLUME_OVERFLOW: | 1013 | case VOLUME_OVERFLOW: |
1030 | if (!(req->flags & REQ_QUIET)) { | 1014 | if (!(req->flags & REQ_QUIET)) { |
1031 | scmd_printk(KERN_INFO, cmd, | 1015 | scmd_printk(KERN_INFO, cmd, |
1032 | "Volume overflow, CDB: "); | 1016 | "Volume overflow, CDB: "); |
1033 | __scsi_print_command(cmd->data_cmnd); | 1017 | __scsi_print_command(cmd->data_cmnd); |
1034 | scsi_print_sense("", cmd); | 1018 | scsi_print_sense("", cmd); |
1035 | } | 1019 | } |
1036 | scsi_end_request(cmd, 0, block_bytes, 1); | 1020 | /* See SSC3rXX or current. */ |
1021 | scsi_end_request(cmd, 0, this_count, 1); | ||
1037 | return; | 1022 | return; |
1038 | default: | 1023 | default: |
1039 | break; | 1024 | break; |
1040 | } | 1025 | } |
1041 | } /* driver byte != 0 */ | 1026 | } |
1042 | if (host_byte(result) == DID_RESET) { | 1027 | if (host_byte(result) == DID_RESET) { |
1043 | /* | 1028 | /* Third party bus reset or reset for error recovery |
1044 | * Third party bus reset or reset for error | 1029 | * reasons. Just retry the request and see what |
1045 | * recovery reasons. Just retry the request | 1030 | * happens. |
1046 | * and see what happens. | ||
1047 | */ | 1031 | */ |
1048 | scsi_requeue_command(q, cmd); | 1032 | scsi_requeue_command(q, cmd); |
1049 | return; | 1033 | return; |
@@ -1051,21 +1035,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
1051 | if (result) { | 1035 | if (result) { |
1052 | if (!(req->flags & REQ_QUIET)) { | 1036 | if (!(req->flags & REQ_QUIET)) { |
1053 | scmd_printk(KERN_INFO, cmd, | 1037 | scmd_printk(KERN_INFO, cmd, |
1054 | "SCSI error: return code = 0x%x\n", result); | 1038 | "SCSI error: return code = 0x%08x\n", |
1055 | 1039 | result); | |
1056 | if (driver_byte(result) & DRIVER_SENSE) | 1040 | if (driver_byte(result) & DRIVER_SENSE) |
1057 | scsi_print_sense("", cmd); | 1041 | scsi_print_sense("", cmd); |
1058 | } | 1042 | } |
1059 | /* | ||
1060 | * Mark a single buffer as not uptodate. Queue the remainder. | ||
1061 | * We sometimes get this cruft in the event that a medium error | ||
1062 | * isn't properly reported. | ||
1063 | */ | ||
1064 | block_bytes = req->hard_cur_sectors << 9; | ||
1065 | if (!block_bytes) | ||
1066 | block_bytes = req->data_len; | ||
1067 | scsi_end_request(cmd, 0, block_bytes, 1); | ||
1068 | } | 1043 | } |
1044 | scsi_end_request(cmd, 0, this_count, !result); | ||
1069 | } | 1045 | } |
1070 | EXPORT_SYMBOL(scsi_io_completion); | 1046 | EXPORT_SYMBOL(scsi_io_completion); |
1071 | 1047 | ||
@@ -1169,7 +1145,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | |||
1169 | * successfully. Since this is a REQ_BLOCK_PC command the | 1145 | * successfully. Since this is a REQ_BLOCK_PC command the |
1170 | * caller should check the request's errors value | 1146 | * caller should check the request's errors value |
1171 | */ | 1147 | */ |
1172 | scsi_io_completion(cmd, cmd->bufflen, 0); | 1148 | scsi_io_completion(cmd, cmd->bufflen); |
1173 | } | 1149 | } |
1174 | 1150 | ||
1175 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | 1151 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) |
@@ -2050,6 +2026,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
2050 | switch (oldstate) { | 2026 | switch (oldstate) { |
2051 | case SDEV_CREATED: | 2027 | case SDEV_CREATED: |
2052 | case SDEV_RUNNING: | 2028 | case SDEV_RUNNING: |
2029 | case SDEV_QUIESCE: | ||
2053 | case SDEV_OFFLINE: | 2030 | case SDEV_OFFLINE: |
2054 | case SDEV_BLOCK: | 2031 | case SDEV_BLOCK: |
2055 | break; | 2032 | break; |
@@ -2060,6 +2037,9 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
2060 | 2037 | ||
2061 | case SDEV_DEL: | 2038 | case SDEV_DEL: |
2062 | switch (oldstate) { | 2039 | switch (oldstate) { |
2040 | case SDEV_CREATED: | ||
2041 | case SDEV_RUNNING: | ||
2042 | case SDEV_OFFLINE: | ||
2063 | case SDEV_CANCEL: | 2043 | case SDEV_CANCEL: |
2064 | break; | 2044 | break; |
2065 | default: | 2045 | default: |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index a1727a0e1bdd..117c2336f333 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -117,7 +117,7 @@ extern struct bus_type scsi_bus_type; | |||
117 | * classes. | 117 | * classes. |
118 | */ | 118 | */ |
119 | 119 | ||
120 | #define SCSI_DEVICE_BLOCK_MAX_TIMEOUT (HZ*60) | 120 | #define SCSI_DEVICE_BLOCK_MAX_TIMEOUT 600 /* units in seconds */ |
121 | extern int scsi_internal_device_block(struct scsi_device *sdev); | 121 | extern int scsi_internal_device_block(struct scsi_device *sdev); |
122 | extern int scsi_internal_device_unblock(struct scsi_device *sdev); | 122 | extern int scsi_internal_device_unblock(struct scsi_device *sdev); |
123 | 123 | ||
diff --git a/drivers/scsi/scsi_sas_internal.h b/drivers/scsi/scsi_sas_internal.h index d76e6e3d8ca5..e1edab45a37b 100644 --- a/drivers/scsi/scsi_sas_internal.h +++ b/drivers/scsi/scsi_sas_internal.h | |||
@@ -2,7 +2,8 @@ | |||
2 | #define _SCSI_SAS_INTERNAL_H | 2 | #define _SCSI_SAS_INTERNAL_H |
3 | 3 | ||
4 | #define SAS_HOST_ATTRS 0 | 4 | #define SAS_HOST_ATTRS 0 |
5 | #define SAS_PORT_ATTRS 17 | 5 | #define SAS_PHY_ATTRS 17 |
6 | #define SAS_PORT_ATTRS 1 | ||
6 | #define SAS_RPORT_ATTRS 7 | 7 | #define SAS_RPORT_ATTRS 7 |
7 | #define SAS_END_DEV_ATTRS 3 | 8 | #define SAS_END_DEV_ATTRS 3 |
8 | #define SAS_EXPANDER_ATTRS 7 | 9 | #define SAS_EXPANDER_ATTRS 7 |
@@ -13,12 +14,14 @@ struct sas_internal { | |||
13 | struct sas_domain_function_template *dft; | 14 | struct sas_domain_function_template *dft; |
14 | 15 | ||
15 | struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS]; | 16 | struct class_device_attribute private_host_attrs[SAS_HOST_ATTRS]; |
16 | struct class_device_attribute private_phy_attrs[SAS_PORT_ATTRS]; | 17 | struct class_device_attribute private_phy_attrs[SAS_PHY_ATTRS]; |
18 | struct class_device_attribute private_port_attrs[SAS_PORT_ATTRS]; | ||
17 | struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS]; | 19 | struct class_device_attribute private_rphy_attrs[SAS_RPORT_ATTRS]; |
18 | struct class_device_attribute private_end_dev_attrs[SAS_END_DEV_ATTRS]; | 20 | struct class_device_attribute private_end_dev_attrs[SAS_END_DEV_ATTRS]; |
19 | struct class_device_attribute private_expander_attrs[SAS_EXPANDER_ATTRS]; | 21 | struct class_device_attribute private_expander_attrs[SAS_EXPANDER_ATTRS]; |
20 | 22 | ||
21 | struct transport_container phy_attr_cont; | 23 | struct transport_container phy_attr_cont; |
24 | struct transport_container port_attr_cont; | ||
22 | struct transport_container rphy_attr_cont; | 25 | struct transport_container rphy_attr_cont; |
23 | struct transport_container end_dev_attr_cont; | 26 | struct transport_container end_dev_attr_cont; |
24 | struct transport_container expander_attr_cont; | 27 | struct transport_container expander_attr_cont; |
@@ -28,7 +31,8 @@ struct sas_internal { | |||
28 | * needed by scsi_sysfs.c | 31 | * needed by scsi_sysfs.c |
29 | */ | 32 | */ |
30 | struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1]; | 33 | struct class_device_attribute *host_attrs[SAS_HOST_ATTRS + 1]; |
31 | struct class_device_attribute *phy_attrs[SAS_PORT_ATTRS + 1]; | 34 | struct class_device_attribute *phy_attrs[SAS_PHY_ATTRS + 1]; |
35 | struct class_device_attribute *port_attrs[SAS_PORT_ATTRS + 1]; | ||
32 | struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1]; | 36 | struct class_device_attribute *rphy_attrs[SAS_RPORT_ATTRS + 1]; |
33 | struct class_device_attribute *end_dev_attrs[SAS_END_DEV_ATTRS + 1]; | 37 | struct class_device_attribute *end_dev_attrs[SAS_END_DEV_ATTRS + 1]; |
34 | struct class_device_attribute *expander_attrs[SAS_EXPANDER_ATTRS + 1]; | 38 | struct class_device_attribute *expander_attrs[SAS_EXPANDER_ATTRS + 1]; |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 0f7e6f94d66b..4c31799e2711 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -810,6 +810,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) | |||
810 | 810 | ||
811 | static inline void scsi_destroy_sdev(struct scsi_device *sdev) | 811 | static inline void scsi_destroy_sdev(struct scsi_device *sdev) |
812 | { | 812 | { |
813 | scsi_device_set_state(sdev, SDEV_DEL); | ||
813 | if (sdev->host->hostt->slave_destroy) | 814 | if (sdev->host->hostt->slave_destroy) |
814 | sdev->host->hostt->slave_destroy(sdev); | 815 | sdev->host->hostt->slave_destroy(sdev); |
815 | transport_destroy_device(&sdev->sdev_gendev); | 816 | transport_destroy_device(&sdev->sdev_gendev); |
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index f2db7a41cf1d..b03aa85108e5 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -368,7 +368,7 @@ static DECLARE_TRANSPORT_CLASS(fc_rport_class, | |||
368 | * should insulate the loss of a remote port. | 368 | * should insulate the loss of a remote port. |
369 | * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT. | 369 | * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT. |
370 | */ | 370 | */ |
371 | static unsigned int fc_dev_loss_tmo = SCSI_DEVICE_BLOCK_MAX_TIMEOUT; | 371 | static unsigned int fc_dev_loss_tmo = 60; /* seconds */ |
372 | 372 | ||
373 | module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); | 373 | module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); |
374 | MODULE_PARM_DESC(dev_loss_tmo, | 374 | MODULE_PARM_DESC(dev_loss_tmo, |
@@ -1284,7 +1284,9 @@ EXPORT_SYMBOL(fc_release_transport); | |||
1284 | * @work: Work to queue for execution. | 1284 | * @work: Work to queue for execution. |
1285 | * | 1285 | * |
1286 | * Return value: | 1286 | * Return value: |
1287 | * 0 on success / != 0 for error | 1287 | * 1 - work queued for execution |
1288 | * 0 - work is already queued | ||
1289 | * -EINVAL - work queue doesn't exist | ||
1288 | **/ | 1290 | **/ |
1289 | static int | 1291 | static int |
1290 | fc_queue_work(struct Scsi_Host *shost, struct work_struct *work) | 1292 | fc_queue_work(struct Scsi_Host *shost, struct work_struct *work) |
@@ -1434,8 +1436,6 @@ fc_starget_delete(void *data) | |||
1434 | struct Scsi_Host *shost = rport_to_shost(rport); | 1436 | struct Scsi_Host *shost = rport_to_shost(rport); |
1435 | unsigned long flags; | 1437 | unsigned long flags; |
1436 | 1438 | ||
1437 | scsi_target_unblock(&rport->dev); | ||
1438 | |||
1439 | spin_lock_irqsave(shost->host_lock, flags); | 1439 | spin_lock_irqsave(shost->host_lock, flags); |
1440 | if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { | 1440 | if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { |
1441 | spin_unlock_irqrestore(shost->host_lock, flags); | 1441 | spin_unlock_irqrestore(shost->host_lock, flags); |
@@ -1476,7 +1476,8 @@ fc_rport_final_delete(void *data) | |||
1476 | transport_remove_device(dev); | 1476 | transport_remove_device(dev); |
1477 | device_del(dev); | 1477 | device_del(dev); |
1478 | transport_destroy_device(dev); | 1478 | transport_destroy_device(dev); |
1479 | put_device(&shost->shost_gendev); | 1479 | put_device(&shost->shost_gendev); /* for fc_host->rport list */ |
1480 | put_device(dev); /* for self-reference */ | ||
1480 | } | 1481 | } |
1481 | 1482 | ||
1482 | 1483 | ||
@@ -1537,13 +1538,13 @@ fc_rport_create(struct Scsi_Host *shost, int channel, | |||
1537 | else | 1538 | else |
1538 | rport->scsi_target_id = -1; | 1539 | rport->scsi_target_id = -1; |
1539 | list_add_tail(&rport->peers, &fc_host->rports); | 1540 | list_add_tail(&rport->peers, &fc_host->rports); |
1540 | get_device(&shost->shost_gendev); | 1541 | get_device(&shost->shost_gendev); /* for fc_host->rport list */ |
1541 | 1542 | ||
1542 | spin_unlock_irqrestore(shost->host_lock, flags); | 1543 | spin_unlock_irqrestore(shost->host_lock, flags); |
1543 | 1544 | ||
1544 | dev = &rport->dev; | 1545 | dev = &rport->dev; |
1545 | device_initialize(dev); | 1546 | device_initialize(dev); /* takes self reference */ |
1546 | dev->parent = get_device(&shost->shost_gendev); | 1547 | dev->parent = get_device(&shost->shost_gendev); /* parent reference */ |
1547 | dev->release = fc_rport_dev_release; | 1548 | dev->release = fc_rport_dev_release; |
1548 | sprintf(dev->bus_id, "rport-%d:%d-%d", | 1549 | sprintf(dev->bus_id, "rport-%d:%d-%d", |
1549 | shost->host_no, channel, rport->number); | 1550 | shost->host_no, channel, rport->number); |
@@ -1567,10 +1568,9 @@ fc_rport_create(struct Scsi_Host *shost, int channel, | |||
1567 | 1568 | ||
1568 | delete_rport: | 1569 | delete_rport: |
1569 | transport_destroy_device(dev); | 1570 | transport_destroy_device(dev); |
1570 | put_device(dev->parent); | ||
1571 | spin_lock_irqsave(shost->host_lock, flags); | 1571 | spin_lock_irqsave(shost->host_lock, flags); |
1572 | list_del(&rport->peers); | 1572 | list_del(&rport->peers); |
1573 | put_device(&shost->shost_gendev); | 1573 | put_device(&shost->shost_gendev); /* for fc_host->rport list */ |
1574 | spin_unlock_irqrestore(shost->host_lock, flags); | 1574 | spin_unlock_irqrestore(shost->host_lock, flags); |
1575 | put_device(dev->parent); | 1575 | put_device(dev->parent); |
1576 | kfree(rport); | 1576 | kfree(rport); |
@@ -1707,6 +1707,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, | |||
1707 | 1707 | ||
1708 | spin_unlock_irqrestore(shost->host_lock, flags); | 1708 | spin_unlock_irqrestore(shost->host_lock, flags); |
1709 | 1709 | ||
1710 | scsi_target_unblock(&rport->dev); | ||
1711 | |||
1710 | return rport; | 1712 | return rport; |
1711 | } | 1713 | } |
1712 | } | 1714 | } |
@@ -1762,9 +1764,10 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, | |||
1762 | /* initiate a scan of the target */ | 1764 | /* initiate a scan of the target */ |
1763 | rport->flags |= FC_RPORT_SCAN_PENDING; | 1765 | rport->flags |= FC_RPORT_SCAN_PENDING; |
1764 | scsi_queue_work(shost, &rport->scan_work); | 1766 | scsi_queue_work(shost, &rport->scan_work); |
1765 | } | 1767 | spin_unlock_irqrestore(shost->host_lock, flags); |
1766 | 1768 | scsi_target_unblock(&rport->dev); | |
1767 | spin_unlock_irqrestore(shost->host_lock, flags); | 1769 | } else |
1770 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1768 | 1771 | ||
1769 | return rport; | 1772 | return rport; |
1770 | } | 1773 | } |
@@ -1938,6 +1941,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) | |||
1938 | rport->flags |= FC_RPORT_SCAN_PENDING; | 1941 | rport->flags |= FC_RPORT_SCAN_PENDING; |
1939 | scsi_queue_work(shost, &rport->scan_work); | 1942 | scsi_queue_work(shost, &rport->scan_work); |
1940 | spin_unlock_irqrestore(shost->host_lock, flags); | 1943 | spin_unlock_irqrestore(shost->host_lock, flags); |
1944 | scsi_target_unblock(&rport->dev); | ||
1941 | } | 1945 | } |
1942 | } | 1946 | } |
1943 | EXPORT_SYMBOL(fc_remote_port_rolechg); | 1947 | EXPORT_SYMBOL(fc_remote_port_rolechg); |
@@ -1970,8 +1974,9 @@ fc_timeout_deleted_rport(void *data) | |||
1970 | dev_printk(KERN_ERR, &rport->dev, | 1974 | dev_printk(KERN_ERR, &rport->dev, |
1971 | "blocked FC remote port time out: no longer" | 1975 | "blocked FC remote port time out: no longer" |
1972 | " a FCP target, removing starget\n"); | 1976 | " a FCP target, removing starget\n"); |
1973 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
1974 | spin_unlock_irqrestore(shost->host_lock, flags); | 1977 | spin_unlock_irqrestore(shost->host_lock, flags); |
1978 | scsi_target_unblock(&rport->dev); | ||
1979 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
1975 | return; | 1980 | return; |
1976 | } | 1981 | } |
1977 | 1982 | ||
@@ -2035,17 +2040,15 @@ fc_timeout_deleted_rport(void *data) | |||
2035 | * went away and didn't come back - we'll remove | 2040 | * went away and didn't come back - we'll remove |
2036 | * all attached scsi devices. | 2041 | * all attached scsi devices. |
2037 | */ | 2042 | */ |
2038 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
2039 | |||
2040 | spin_unlock_irqrestore(shost->host_lock, flags); | 2043 | spin_unlock_irqrestore(shost->host_lock, flags); |
2044 | |||
2045 | scsi_target_unblock(&rport->dev); | ||
2046 | fc_queue_work(shost, &rport->stgt_delete_work); | ||
2041 | } | 2047 | } |
2042 | 2048 | ||
2043 | /** | 2049 | /** |
2044 | * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. | 2050 | * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. |
2045 | * | 2051 | * |
2046 | * Will unblock the target (in case it went away and has now come back), | ||
2047 | * then invoke a scan. | ||
2048 | * | ||
2049 | * @data: remote port to be scanned. | 2052 | * @data: remote port to be scanned. |
2050 | **/ | 2053 | **/ |
2051 | static void | 2054 | static void |
@@ -2057,7 +2060,6 @@ fc_scsi_scan_rport(void *data) | |||
2057 | 2060 | ||
2058 | if ((rport->port_state == FC_PORTSTATE_ONLINE) && | 2061 | if ((rport->port_state == FC_PORTSTATE_ONLINE) && |
2059 | (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { | 2062 | (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { |
2060 | scsi_target_unblock(&rport->dev); | ||
2061 | scsi_scan_target(&rport->dev, rport->channel, | 2063 | scsi_scan_target(&rport->dev, rport->channel, |
2062 | rport->scsi_target_id, SCAN_WILD_CARD, 1); | 2064 | rport->scsi_target_id, SCAN_WILD_CARD, 1); |
2063 | } | 2065 | } |
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 1fe6b2d01853..dd075627e605 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -174,12 +174,29 @@ static int sas_host_match(struct attribute_container *cont, | |||
174 | 174 | ||
175 | static int do_sas_phy_delete(struct device *dev, void *data) | 175 | static int do_sas_phy_delete(struct device *dev, void *data) |
176 | { | 176 | { |
177 | if (scsi_is_sas_phy(dev)) | 177 | int pass = (int)(unsigned long)data; |
178 | |||
179 | if (pass == 0 && scsi_is_sas_port(dev)) | ||
180 | sas_port_delete(dev_to_sas_port(dev)); | ||
181 | else if (pass == 1 && scsi_is_sas_phy(dev)) | ||
178 | sas_phy_delete(dev_to_phy(dev)); | 182 | sas_phy_delete(dev_to_phy(dev)); |
179 | return 0; | 183 | return 0; |
180 | } | 184 | } |
181 | 185 | ||
182 | /** | 186 | /** |
187 | * sas_remove_children -- tear down a devices SAS data structures | ||
188 | * @dev: device belonging to the sas object | ||
189 | * | ||
190 | * Removes all SAS PHYs and remote PHYs for a given object | ||
191 | */ | ||
192 | void sas_remove_children(struct device *dev) | ||
193 | { | ||
194 | device_for_each_child(dev, (void *)0, do_sas_phy_delete); | ||
195 | device_for_each_child(dev, (void *)1, do_sas_phy_delete); | ||
196 | } | ||
197 | EXPORT_SYMBOL(sas_remove_children); | ||
198 | |||
199 | /** | ||
183 | * sas_remove_host -- tear down a Scsi_Host's SAS data structures | 200 | * sas_remove_host -- tear down a Scsi_Host's SAS data structures |
184 | * @shost: Scsi Host that is torn down | 201 | * @shost: Scsi Host that is torn down |
185 | * | 202 | * |
@@ -188,13 +205,13 @@ static int do_sas_phy_delete(struct device *dev, void *data) | |||
188 | */ | 205 | */ |
189 | void sas_remove_host(struct Scsi_Host *shost) | 206 | void sas_remove_host(struct Scsi_Host *shost) |
190 | { | 207 | { |
191 | device_for_each_child(&shost->shost_gendev, NULL, do_sas_phy_delete); | 208 | sas_remove_children(&shost->shost_gendev); |
192 | } | 209 | } |
193 | EXPORT_SYMBOL(sas_remove_host); | 210 | EXPORT_SYMBOL(sas_remove_host); |
194 | 211 | ||
195 | 212 | ||
196 | /* | 213 | /* |
197 | * SAS Port attributes | 214 | * SAS Phy attributes |
198 | */ | 215 | */ |
199 | 216 | ||
200 | #define sas_phy_show_simple(field, name, format_string, cast) \ | 217 | #define sas_phy_show_simple(field, name, format_string, cast) \ |
@@ -310,7 +327,7 @@ sas_phy_protocol_attr(identify.target_port_protocols, | |||
310 | sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", | 327 | sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", |
311 | unsigned long long); | 328 | unsigned long long); |
312 | sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); | 329 | sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); |
313 | sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); | 330 | //sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); |
314 | sas_phy_linkspeed_attr(negotiated_linkrate); | 331 | sas_phy_linkspeed_attr(negotiated_linkrate); |
315 | sas_phy_linkspeed_attr(minimum_linkrate_hw); | 332 | sas_phy_linkspeed_attr(minimum_linkrate_hw); |
316 | sas_phy_linkspeed_attr(minimum_linkrate); | 333 | sas_phy_linkspeed_attr(minimum_linkrate); |
@@ -378,9 +395,10 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number) | |||
378 | device_initialize(&phy->dev); | 395 | device_initialize(&phy->dev); |
379 | phy->dev.parent = get_device(parent); | 396 | phy->dev.parent = get_device(parent); |
380 | phy->dev.release = sas_phy_release; | 397 | phy->dev.release = sas_phy_release; |
398 | INIT_LIST_HEAD(&phy->port_siblings); | ||
381 | if (scsi_is_sas_expander_device(parent)) { | 399 | if (scsi_is_sas_expander_device(parent)) { |
382 | struct sas_rphy *rphy = dev_to_rphy(parent); | 400 | struct sas_rphy *rphy = dev_to_rphy(parent); |
383 | sprintf(phy->dev.bus_id, "phy-%d-%d:%d", shost->host_no, | 401 | sprintf(phy->dev.bus_id, "phy-%d:%d:%d", shost->host_no, |
384 | rphy->scsi_target_id, number); | 402 | rphy->scsi_target_id, number); |
385 | } else | 403 | } else |
386 | sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number); | 404 | sprintf(phy->dev.bus_id, "phy-%d:%d", shost->host_no, number); |
@@ -440,8 +458,8 @@ sas_phy_delete(struct sas_phy *phy) | |||
440 | { | 458 | { |
441 | struct device *dev = &phy->dev; | 459 | struct device *dev = &phy->dev; |
442 | 460 | ||
443 | if (phy->rphy) | 461 | /* this happens if the phy is still part of a port when deleted */ |
444 | sas_rphy_delete(phy->rphy); | 462 | BUG_ON(!list_empty(&phy->port_siblings)); |
445 | 463 | ||
446 | transport_remove_device(dev); | 464 | transport_remove_device(dev); |
447 | device_del(dev); | 465 | device_del(dev); |
@@ -464,6 +482,258 @@ int scsi_is_sas_phy(const struct device *dev) | |||
464 | EXPORT_SYMBOL(scsi_is_sas_phy); | 482 | EXPORT_SYMBOL(scsi_is_sas_phy); |
465 | 483 | ||
466 | /* | 484 | /* |
485 | * SAS Port attributes | ||
486 | */ | ||
487 | #define sas_port_show_simple(field, name, format_string, cast) \ | ||
488 | static ssize_t \ | ||
489 | show_sas_port_##name(struct class_device *cdev, char *buf) \ | ||
490 | { \ | ||
491 | struct sas_port *port = transport_class_to_sas_port(cdev); \ | ||
492 | \ | ||
493 | return snprintf(buf, 20, format_string, cast port->field); \ | ||
494 | } | ||
495 | |||
496 | #define sas_port_simple_attr(field, name, format_string, type) \ | ||
497 | sas_port_show_simple(field, name, format_string, (type)) \ | ||
498 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_sas_port_##name, NULL) | ||
499 | |||
500 | sas_port_simple_attr(num_phys, num_phys, "%d\n", int); | ||
501 | |||
502 | static DECLARE_TRANSPORT_CLASS(sas_port_class, | ||
503 | "sas_port", NULL, NULL, NULL); | ||
504 | |||
505 | static int sas_port_match(struct attribute_container *cont, struct device *dev) | ||
506 | { | ||
507 | struct Scsi_Host *shost; | ||
508 | struct sas_internal *i; | ||
509 | |||
510 | if (!scsi_is_sas_port(dev)) | ||
511 | return 0; | ||
512 | shost = dev_to_shost(dev->parent); | ||
513 | |||
514 | if (!shost->transportt) | ||
515 | return 0; | ||
516 | if (shost->transportt->host_attrs.ac.class != | ||
517 | &sas_host_class.class) | ||
518 | return 0; | ||
519 | |||
520 | i = to_sas_internal(shost->transportt); | ||
521 | return &i->port_attr_cont.ac == cont; | ||
522 | } | ||
523 | |||
524 | |||
525 | static void sas_port_release(struct device *dev) | ||
526 | { | ||
527 | struct sas_port *port = dev_to_sas_port(dev); | ||
528 | |||
529 | BUG_ON(!list_empty(&port->phy_list)); | ||
530 | |||
531 | put_device(dev->parent); | ||
532 | kfree(port); | ||
533 | } | ||
534 | |||
535 | static void sas_port_create_link(struct sas_port *port, | ||
536 | struct sas_phy *phy) | ||
537 | { | ||
538 | sysfs_create_link(&port->dev.kobj, &phy->dev.kobj, phy->dev.bus_id); | ||
539 | sysfs_create_link(&phy->dev.kobj, &port->dev.kobj, "port"); | ||
540 | } | ||
541 | |||
542 | static void sas_port_delete_link(struct sas_port *port, | ||
543 | struct sas_phy *phy) | ||
544 | { | ||
545 | sysfs_remove_link(&port->dev.kobj, phy->dev.bus_id); | ||
546 | sysfs_remove_link(&phy->dev.kobj, "port"); | ||
547 | } | ||
548 | |||
549 | /** sas_port_alloc - allocate and initialize a SAS port structure | ||
550 | * | ||
551 | * @parent: parent device | ||
552 | * @port_id: port number | ||
553 | * | ||
554 | * Allocates a SAS port structure. It will be added to the device tree | ||
555 | * below the device specified by @parent which must be either a Scsi_Host | ||
556 | * or a sas_expander_device. | ||
557 | * | ||
558 | * Returns %NULL on error | ||
559 | */ | ||
560 | struct sas_port *sas_port_alloc(struct device *parent, int port_id) | ||
561 | { | ||
562 | struct Scsi_Host *shost = dev_to_shost(parent); | ||
563 | struct sas_port *port; | ||
564 | |||
565 | port = kzalloc(sizeof(*port), GFP_KERNEL); | ||
566 | if (!port) | ||
567 | return NULL; | ||
568 | |||
569 | port->port_identifier = port_id; | ||
570 | |||
571 | device_initialize(&port->dev); | ||
572 | |||
573 | port->dev.parent = get_device(parent); | ||
574 | port->dev.release = sas_port_release; | ||
575 | |||
576 | mutex_init(&port->phy_list_mutex); | ||
577 | INIT_LIST_HEAD(&port->phy_list); | ||
578 | |||
579 | if (scsi_is_sas_expander_device(parent)) { | ||
580 | struct sas_rphy *rphy = dev_to_rphy(parent); | ||
581 | sprintf(port->dev.bus_id, "port-%d:%d:%d", shost->host_no, | ||
582 | rphy->scsi_target_id, port->port_identifier); | ||
583 | } else | ||
584 | sprintf(port->dev.bus_id, "port-%d:%d", shost->host_no, | ||
585 | port->port_identifier); | ||
586 | |||
587 | transport_setup_device(&port->dev); | ||
588 | |||
589 | return port; | ||
590 | } | ||
591 | EXPORT_SYMBOL(sas_port_alloc); | ||
592 | |||
593 | /** | ||
594 | * sas_port_add - add a SAS port to the device hierarchy | ||
595 | * | ||
596 | * @port: port to be added | ||
597 | * | ||
598 | * publishes a port to the rest of the system | ||
599 | */ | ||
600 | int sas_port_add(struct sas_port *port) | ||
601 | { | ||
602 | int error; | ||
603 | |||
604 | /* No phys should be added until this is made visible */ | ||
605 | BUG_ON(!list_empty(&port->phy_list)); | ||
606 | |||
607 | error = device_add(&port->dev); | ||
608 | |||
609 | if (error) | ||
610 | return error; | ||
611 | |||
612 | transport_add_device(&port->dev); | ||
613 | transport_configure_device(&port->dev); | ||
614 | |||
615 | return 0; | ||
616 | } | ||
617 | EXPORT_SYMBOL(sas_port_add); | ||
618 | |||
619 | /** | ||
620 | * sas_port_free -- free a SAS PORT | ||
621 | * @port: SAS PORT to free | ||
622 | * | ||
623 | * Frees the specified SAS PORT. | ||
624 | * | ||
625 | * Note: | ||
626 | * This function must only be called on a PORT that has not | ||
627 | * sucessfully been added using sas_port_add(). | ||
628 | */ | ||
629 | void sas_port_free(struct sas_port *port) | ||
630 | { | ||
631 | transport_destroy_device(&port->dev); | ||
632 | put_device(&port->dev); | ||
633 | } | ||
634 | EXPORT_SYMBOL(sas_port_free); | ||
635 | |||
636 | /** | ||
637 | * sas_port_delete -- remove SAS PORT | ||
638 | * @port: SAS PORT to remove | ||
639 | * | ||
640 | * Removes the specified SAS PORT. If the SAS PORT has an | ||
641 | * associated phys, unlink them from the port as well. | ||
642 | */ | ||
643 | void sas_port_delete(struct sas_port *port) | ||
644 | { | ||
645 | struct device *dev = &port->dev; | ||
646 | struct sas_phy *phy, *tmp_phy; | ||
647 | |||
648 | if (port->rphy) { | ||
649 | sas_rphy_delete(port->rphy); | ||
650 | port->rphy = NULL; | ||
651 | } | ||
652 | |||
653 | mutex_lock(&port->phy_list_mutex); | ||
654 | list_for_each_entry_safe(phy, tmp_phy, &port->phy_list, | ||
655 | port_siblings) { | ||
656 | sas_port_delete_link(port, phy); | ||
657 | list_del_init(&phy->port_siblings); | ||
658 | } | ||
659 | mutex_unlock(&port->phy_list_mutex); | ||
660 | |||
661 | transport_remove_device(dev); | ||
662 | device_del(dev); | ||
663 | transport_destroy_device(dev); | ||
664 | put_device(dev); | ||
665 | } | ||
666 | EXPORT_SYMBOL(sas_port_delete); | ||
667 | |||
668 | /** | ||
669 | * scsi_is_sas_port -- check if a struct device represents a SAS port | ||
670 | * @dev: device to check | ||
671 | * | ||
672 | * Returns: | ||
673 | * %1 if the device represents a SAS Port, %0 else | ||
674 | */ | ||
675 | int scsi_is_sas_port(const struct device *dev) | ||
676 | { | ||
677 | return dev->release == sas_port_release; | ||
678 | } | ||
679 | EXPORT_SYMBOL(scsi_is_sas_port); | ||
680 | |||
681 | /** | ||
682 | * sas_port_add_phy - add another phy to a port to form a wide port | ||
683 | * @port: port to add the phy to | ||
684 | * @phy: phy to add | ||
685 | * | ||
686 | * When a port is initially created, it is empty (has no phys). All | ||
687 | * ports must have at least one phy to operated, and all wide ports | ||
688 | * must have at least two. The current code makes no difference | ||
689 | * between ports and wide ports, but the only object that can be | ||
690 | * connected to a remote device is a port, so ports must be formed on | ||
691 | * all devices with phys if they're connected to anything. | ||
692 | */ | ||
693 | void sas_port_add_phy(struct sas_port *port, struct sas_phy *phy) | ||
694 | { | ||
695 | mutex_lock(&port->phy_list_mutex); | ||
696 | if (unlikely(!list_empty(&phy->port_siblings))) { | ||
697 | /* make sure we're already on this port */ | ||
698 | struct sas_phy *tmp; | ||
699 | |||
700 | list_for_each_entry(tmp, &port->phy_list, port_siblings) | ||
701 | if (tmp == phy) | ||
702 | break; | ||
703 | /* If this trips, you added a phy that was already | ||
704 | * part of a different port */ | ||
705 | if (unlikely(tmp != phy)) { | ||
706 | dev_printk(KERN_ERR, &port->dev, "trying to add phy %s fails: it's already part of another port\n", phy->dev.bus_id); | ||
707 | BUG(); | ||
708 | } | ||
709 | } else { | ||
710 | sas_port_create_link(port, phy); | ||
711 | list_add_tail(&phy->port_siblings, &port->phy_list); | ||
712 | port->num_phys++; | ||
713 | } | ||
714 | mutex_unlock(&port->phy_list_mutex); | ||
715 | } | ||
716 | EXPORT_SYMBOL(sas_port_add_phy); | ||
717 | |||
718 | /** | ||
719 | * sas_port_delete_phy - remove a phy from a port or wide port | ||
720 | * @port: port to remove the phy from | ||
721 | * @phy: phy to remove | ||
722 | * | ||
723 | * This operation is used for tearing down ports again. It must be | ||
724 | * done to every port or wide port before calling sas_port_delete. | ||
725 | */ | ||
726 | void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy) | ||
727 | { | ||
728 | mutex_lock(&port->phy_list_mutex); | ||
729 | sas_port_delete_link(port, phy); | ||
730 | list_del_init(&phy->port_siblings); | ||
731 | port->num_phys--; | ||
732 | mutex_unlock(&port->phy_list_mutex); | ||
733 | } | ||
734 | EXPORT_SYMBOL(sas_port_delete_phy); | ||
735 | |||
736 | /* | ||
467 | * SAS remote PHY attributes. | 737 | * SAS remote PHY attributes. |
468 | */ | 738 | */ |
469 | 739 | ||
@@ -767,7 +1037,7 @@ static void sas_rphy_initialize(struct sas_rphy *rphy) | |||
767 | * Returns: | 1037 | * Returns: |
768 | * SAS PHY allocated or %NULL if the allocation failed. | 1038 | * SAS PHY allocated or %NULL if the allocation failed. |
769 | */ | 1039 | */ |
770 | struct sas_rphy *sas_end_device_alloc(struct sas_phy *parent) | 1040 | struct sas_rphy *sas_end_device_alloc(struct sas_port *parent) |
771 | { | 1041 | { |
772 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); | 1042 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); |
773 | struct sas_end_device *rdev; | 1043 | struct sas_end_device *rdev; |
@@ -780,8 +1050,13 @@ struct sas_rphy *sas_end_device_alloc(struct sas_phy *parent) | |||
780 | device_initialize(&rdev->rphy.dev); | 1050 | device_initialize(&rdev->rphy.dev); |
781 | rdev->rphy.dev.parent = get_device(&parent->dev); | 1051 | rdev->rphy.dev.parent = get_device(&parent->dev); |
782 | rdev->rphy.dev.release = sas_end_device_release; | 1052 | rdev->rphy.dev.release = sas_end_device_release; |
783 | sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d-%d", | 1053 | if (scsi_is_sas_expander_device(parent->dev.parent)) { |
784 | shost->host_no, parent->port_identifier, parent->number); | 1054 | struct sas_rphy *rphy = dev_to_rphy(parent->dev.parent); |
1055 | sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d:%d", | ||
1056 | shost->host_no, rphy->scsi_target_id, parent->port_identifier); | ||
1057 | } else | ||
1058 | sprintf(rdev->rphy.dev.bus_id, "end_device-%d:%d", | ||
1059 | shost->host_no, parent->port_identifier); | ||
785 | rdev->rphy.identify.device_type = SAS_END_DEVICE; | 1060 | rdev->rphy.identify.device_type = SAS_END_DEVICE; |
786 | sas_rphy_initialize(&rdev->rphy); | 1061 | sas_rphy_initialize(&rdev->rphy); |
787 | transport_setup_device(&rdev->rphy.dev); | 1062 | transport_setup_device(&rdev->rphy.dev); |
@@ -798,7 +1073,7 @@ EXPORT_SYMBOL(sas_end_device_alloc); | |||
798 | * Returns: | 1073 | * Returns: |
799 | * SAS PHY allocated or %NULL if the allocation failed. | 1074 | * SAS PHY allocated or %NULL if the allocation failed. |
800 | */ | 1075 | */ |
801 | struct sas_rphy *sas_expander_alloc(struct sas_phy *parent, | 1076 | struct sas_rphy *sas_expander_alloc(struct sas_port *parent, |
802 | enum sas_device_type type) | 1077 | enum sas_device_type type) |
803 | { | 1078 | { |
804 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); | 1079 | struct Scsi_Host *shost = dev_to_shost(&parent->dev); |
@@ -837,7 +1112,7 @@ EXPORT_SYMBOL(sas_expander_alloc); | |||
837 | */ | 1112 | */ |
838 | int sas_rphy_add(struct sas_rphy *rphy) | 1113 | int sas_rphy_add(struct sas_rphy *rphy) |
839 | { | 1114 | { |
840 | struct sas_phy *parent = dev_to_phy(rphy->dev.parent); | 1115 | struct sas_port *parent = dev_to_sas_port(rphy->dev.parent); |
841 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); | 1116 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); |
842 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); | 1117 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); |
843 | struct sas_identify *identify = &rphy->identify; | 1118 | struct sas_identify *identify = &rphy->identify; |
@@ -910,7 +1185,7 @@ void | |||
910 | sas_rphy_delete(struct sas_rphy *rphy) | 1185 | sas_rphy_delete(struct sas_rphy *rphy) |
911 | { | 1186 | { |
912 | struct device *dev = &rphy->dev; | 1187 | struct device *dev = &rphy->dev; |
913 | struct sas_phy *parent = dev_to_phy(dev->parent); | 1188 | struct sas_port *parent = dev_to_sas_port(dev->parent); |
914 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); | 1189 | struct Scsi_Host *shost = dev_to_shost(parent->dev.parent); |
915 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); | 1190 | struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); |
916 | 1191 | ||
@@ -920,7 +1195,7 @@ sas_rphy_delete(struct sas_rphy *rphy) | |||
920 | break; | 1195 | break; |
921 | case SAS_EDGE_EXPANDER_DEVICE: | 1196 | case SAS_EDGE_EXPANDER_DEVICE: |
922 | case SAS_FANOUT_EXPANDER_DEVICE: | 1197 | case SAS_FANOUT_EXPANDER_DEVICE: |
923 | device_for_each_child(dev, NULL, do_sas_phy_delete); | 1198 | sas_remove_children(dev); |
924 | break; | 1199 | break; |
925 | default: | 1200 | default: |
926 | break; | 1201 | break; |
@@ -967,7 +1242,7 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
967 | 1242 | ||
968 | mutex_lock(&sas_host->lock); | 1243 | mutex_lock(&sas_host->lock); |
969 | list_for_each_entry(rphy, &sas_host->rphy_list, list) { | 1244 | list_for_each_entry(rphy, &sas_host->rphy_list, list) { |
970 | struct sas_phy *parent = dev_to_phy(rphy->dev.parent); | 1245 | struct sas_port *parent = dev_to_sas_port(rphy->dev.parent); |
971 | 1246 | ||
972 | if (rphy->identify.device_type != SAS_END_DEVICE || | 1247 | if (rphy->identify.device_type != SAS_END_DEVICE || |
973 | rphy->scsi_target_id == -1) | 1248 | rphy->scsi_target_id == -1) |
@@ -1003,16 +1278,19 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
1003 | #define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func) \ | 1278 | #define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func) \ |
1004 | SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func) | 1279 | SETUP_TEMPLATE(rphy_attrs, field, S_IRUGO, i->f->func) |
1005 | 1280 | ||
1006 | #define SETUP_PORT_ATTRIBUTE(field) \ | 1281 | #define SETUP_PHY_ATTRIBUTE(field) \ |
1007 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1) | 1282 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, 1) |
1008 | 1283 | ||
1009 | #define SETUP_OPTIONAL_PORT_ATTRIBUTE(field, func) \ | 1284 | #define SETUP_PORT_ATTRIBUTE(field) \ |
1285 | SETUP_TEMPLATE(port_attrs, field, S_IRUGO, 1) | ||
1286 | |||
1287 | #define SETUP_OPTIONAL_PHY_ATTRIBUTE(field, func) \ | ||
1010 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func) | 1288 | SETUP_TEMPLATE(phy_attrs, field, S_IRUGO, i->f->func) |
1011 | 1289 | ||
1012 | #define SETUP_PORT_ATTRIBUTE_WRONLY(field) \ | 1290 | #define SETUP_PHY_ATTRIBUTE_WRONLY(field) \ |
1013 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, 1) | 1291 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, 1) |
1014 | 1292 | ||
1015 | #define SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(field, func) \ | 1293 | #define SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(field, func) \ |
1016 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, i->f->func) | 1294 | SETUP_TEMPLATE(phy_attrs, field, S_IWUGO, i->f->func) |
1017 | 1295 | ||
1018 | #define SETUP_END_DEV_ATTRIBUTE(field) \ | 1296 | #define SETUP_END_DEV_ATTRIBUTE(field) \ |
@@ -1048,6 +1326,11 @@ sas_attach_transport(struct sas_function_template *ft) | |||
1048 | i->phy_attr_cont.ac.match = sas_phy_match; | 1326 | i->phy_attr_cont.ac.match = sas_phy_match; |
1049 | transport_container_register(&i->phy_attr_cont); | 1327 | transport_container_register(&i->phy_attr_cont); |
1050 | 1328 | ||
1329 | i->port_attr_cont.ac.class = &sas_port_class.class; | ||
1330 | i->port_attr_cont.ac.attrs = &i->port_attrs[0]; | ||
1331 | i->port_attr_cont.ac.match = sas_port_match; | ||
1332 | transport_container_register(&i->port_attr_cont); | ||
1333 | |||
1051 | i->rphy_attr_cont.ac.class = &sas_rphy_class.class; | 1334 | i->rphy_attr_cont.ac.class = &sas_rphy_class.class; |
1052 | i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0]; | 1335 | i->rphy_attr_cont.ac.attrs = &i->rphy_attrs[0]; |
1053 | i->rphy_attr_cont.ac.match = sas_rphy_match; | 1336 | i->rphy_attr_cont.ac.match = sas_rphy_match; |
@@ -1066,30 +1349,35 @@ sas_attach_transport(struct sas_function_template *ft) | |||
1066 | i->f = ft; | 1349 | i->f = ft; |
1067 | 1350 | ||
1068 | count = 0; | 1351 | count = 0; |
1352 | SETUP_PORT_ATTRIBUTE(num_phys); | ||
1069 | i->host_attrs[count] = NULL; | 1353 | i->host_attrs[count] = NULL; |
1070 | 1354 | ||
1071 | count = 0; | 1355 | count = 0; |
1072 | SETUP_PORT_ATTRIBUTE(initiator_port_protocols); | 1356 | SETUP_PHY_ATTRIBUTE(initiator_port_protocols); |
1073 | SETUP_PORT_ATTRIBUTE(target_port_protocols); | 1357 | SETUP_PHY_ATTRIBUTE(target_port_protocols); |
1074 | SETUP_PORT_ATTRIBUTE(device_type); | 1358 | SETUP_PHY_ATTRIBUTE(device_type); |
1075 | SETUP_PORT_ATTRIBUTE(sas_address); | 1359 | SETUP_PHY_ATTRIBUTE(sas_address); |
1076 | SETUP_PORT_ATTRIBUTE(phy_identifier); | 1360 | SETUP_PHY_ATTRIBUTE(phy_identifier); |
1077 | SETUP_PORT_ATTRIBUTE(port_identifier); | 1361 | //SETUP_PHY_ATTRIBUTE(port_identifier); |
1078 | SETUP_PORT_ATTRIBUTE(negotiated_linkrate); | 1362 | SETUP_PHY_ATTRIBUTE(negotiated_linkrate); |
1079 | SETUP_PORT_ATTRIBUTE(minimum_linkrate_hw); | 1363 | SETUP_PHY_ATTRIBUTE(minimum_linkrate_hw); |
1080 | SETUP_PORT_ATTRIBUTE(minimum_linkrate); | 1364 | SETUP_PHY_ATTRIBUTE(minimum_linkrate); |
1081 | SETUP_PORT_ATTRIBUTE(maximum_linkrate_hw); | 1365 | SETUP_PHY_ATTRIBUTE(maximum_linkrate_hw); |
1082 | SETUP_PORT_ATTRIBUTE(maximum_linkrate); | 1366 | SETUP_PHY_ATTRIBUTE(maximum_linkrate); |
1083 | 1367 | ||
1084 | SETUP_PORT_ATTRIBUTE(invalid_dword_count); | 1368 | SETUP_PHY_ATTRIBUTE(invalid_dword_count); |
1085 | SETUP_PORT_ATTRIBUTE(running_disparity_error_count); | 1369 | SETUP_PHY_ATTRIBUTE(running_disparity_error_count); |
1086 | SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count); | 1370 | SETUP_PHY_ATTRIBUTE(loss_of_dword_sync_count); |
1087 | SETUP_PORT_ATTRIBUTE(phy_reset_problem_count); | 1371 | SETUP_PHY_ATTRIBUTE(phy_reset_problem_count); |
1088 | SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(link_reset, phy_reset); | 1372 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(link_reset, phy_reset); |
1089 | SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(hard_reset, phy_reset); | 1373 | SETUP_OPTIONAL_PHY_ATTRIBUTE_WRONLY(hard_reset, phy_reset); |
1090 | i->phy_attrs[count] = NULL; | 1374 | i->phy_attrs[count] = NULL; |
1091 | 1375 | ||
1092 | count = 0; | 1376 | count = 0; |
1377 | SETUP_PORT_ATTRIBUTE(num_phys); | ||
1378 | i->port_attrs[count] = NULL; | ||
1379 | |||
1380 | count = 0; | ||
1093 | SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols); | 1381 | SETUP_RPORT_ATTRIBUTE(rphy_initiator_port_protocols); |
1094 | SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols); | 1382 | SETUP_RPORT_ATTRIBUTE(rphy_target_port_protocols); |
1095 | SETUP_RPORT_ATTRIBUTE(rphy_device_type); | 1383 | SETUP_RPORT_ATTRIBUTE(rphy_device_type); |
@@ -1131,6 +1419,7 @@ void sas_release_transport(struct scsi_transport_template *t) | |||
1131 | 1419 | ||
1132 | transport_container_unregister(&i->t.host_attrs); | 1420 | transport_container_unregister(&i->t.host_attrs); |
1133 | transport_container_unregister(&i->phy_attr_cont); | 1421 | transport_container_unregister(&i->phy_attr_cont); |
1422 | transport_container_unregister(&i->port_attr_cont); | ||
1134 | transport_container_unregister(&i->rphy_attr_cont); | 1423 | transport_container_unregister(&i->rphy_attr_cont); |
1135 | transport_container_unregister(&i->end_dev_attr_cont); | 1424 | transport_container_unregister(&i->end_dev_attr_cont); |
1136 | transport_container_unregister(&i->expander_attr_cont); | 1425 | transport_container_unregister(&i->expander_attr_cont); |
@@ -1149,9 +1438,12 @@ static __init int sas_transport_init(void) | |||
1149 | error = transport_class_register(&sas_phy_class); | 1438 | error = transport_class_register(&sas_phy_class); |
1150 | if (error) | 1439 | if (error) |
1151 | goto out_unregister_transport; | 1440 | goto out_unregister_transport; |
1152 | error = transport_class_register(&sas_rphy_class); | 1441 | error = transport_class_register(&sas_port_class); |
1153 | if (error) | 1442 | if (error) |
1154 | goto out_unregister_phy; | 1443 | goto out_unregister_phy; |
1444 | error = transport_class_register(&sas_rphy_class); | ||
1445 | if (error) | ||
1446 | goto out_unregister_port; | ||
1155 | error = transport_class_register(&sas_end_dev_class); | 1447 | error = transport_class_register(&sas_end_dev_class); |
1156 | if (error) | 1448 | if (error) |
1157 | goto out_unregister_rphy; | 1449 | goto out_unregister_rphy; |
@@ -1165,6 +1457,8 @@ static __init int sas_transport_init(void) | |||
1165 | transport_class_unregister(&sas_end_dev_class); | 1457 | transport_class_unregister(&sas_end_dev_class); |
1166 | out_unregister_rphy: | 1458 | out_unregister_rphy: |
1167 | transport_class_unregister(&sas_rphy_class); | 1459 | transport_class_unregister(&sas_rphy_class); |
1460 | out_unregister_port: | ||
1461 | transport_class_unregister(&sas_port_class); | ||
1168 | out_unregister_phy: | 1462 | out_unregister_phy: |
1169 | transport_class_unregister(&sas_phy_class); | 1463 | transport_class_unregister(&sas_phy_class); |
1170 | out_unregister_transport: | 1464 | out_unregister_transport: |
@@ -1178,6 +1472,7 @@ static void __exit sas_transport_exit(void) | |||
1178 | { | 1472 | { |
1179 | transport_class_unregister(&sas_host_class); | 1473 | transport_class_unregister(&sas_host_class); |
1180 | transport_class_unregister(&sas_phy_class); | 1474 | transport_class_unregister(&sas_phy_class); |
1475 | transport_class_unregister(&sas_port_class); | ||
1181 | transport_class_unregister(&sas_rphy_class); | 1476 | transport_class_unregister(&sas_rphy_class); |
1182 | transport_class_unregister(&sas_end_dev_class); | 1477 | transport_class_unregister(&sas_end_dev_class); |
1183 | transport_class_unregister(&sas_expander_class); | 1478 | transport_class_unregister(&sas_expander_class); |
diff --git a/drivers/scsi/scsicam.c b/drivers/scsi/scsicam.c index b78354fc4b17..cd68a66c7bb3 100644 --- a/drivers/scsi/scsicam.c +++ b/drivers/scsi/scsicam.c | |||
@@ -57,6 +57,7 @@ EXPORT_SYMBOL(scsi_bios_ptable); | |||
57 | int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip) | 57 | int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip) |
58 | { | 58 | { |
59 | unsigned char *p; | 59 | unsigned char *p; |
60 | u64 capacity64 = capacity; /* Suppress gcc warning */ | ||
60 | int ret; | 61 | int ret; |
61 | 62 | ||
62 | p = scsi_bios_ptable(bdev); | 63 | p = scsi_bios_ptable(bdev); |
@@ -68,7 +69,7 @@ int scsicam_bios_param(struct block_device *bdev, sector_t capacity, int *ip) | |||
68 | (unsigned int *)ip + 0, (unsigned int *)ip + 1); | 69 | (unsigned int *)ip + 0, (unsigned int *)ip + 1); |
69 | kfree(p); | 70 | kfree(p); |
70 | 71 | ||
71 | if (ret == -1) { | 72 | if (ret == -1 && capacity64 < (1ULL << 32)) { |
72 | /* pick some standard mapping with at most 1024 cylinders, | 73 | /* pick some standard mapping with at most 1024 cylinders, |
73 | and at most 62 sectors per track - this works up to | 74 | and at most 62 sectors per track - this works up to |
74 | 7905 MB */ | 75 | 7905 MB */ |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 354199011246..2e96c3d8f7e2 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -208,6 +208,23 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf, | |||
208 | return count; | 208 | return count; |
209 | } | 209 | } |
210 | 210 | ||
211 | static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf, | ||
212 | size_t count) | ||
213 | { | ||
214 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | ||
215 | struct scsi_device *sdp = sdkp->device; | ||
216 | |||
217 | if (!capable(CAP_SYS_ADMIN)) | ||
218 | return -EACCES; | ||
219 | |||
220 | if (sdp->type != TYPE_DISK) | ||
221 | return -EINVAL; | ||
222 | |||
223 | sdp->allow_restart = simple_strtoul(buf, NULL, 10); | ||
224 | |||
225 | return count; | ||
226 | } | ||
227 | |||
211 | static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf) | 228 | static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf) |
212 | { | 229 | { |
213 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | 230 | struct scsi_disk *sdkp = to_scsi_disk(cdev); |
@@ -223,10 +240,19 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf) | |||
223 | return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); | 240 | return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); |
224 | } | 241 | } |
225 | 242 | ||
243 | static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf) | ||
244 | { | ||
245 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | ||
246 | |||
247 | return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); | ||
248 | } | ||
249 | |||
226 | static struct class_device_attribute sd_disk_attrs[] = { | 250 | static struct class_device_attribute sd_disk_attrs[] = { |
227 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, | 251 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, |
228 | sd_store_cache_type), | 252 | sd_store_cache_type), |
229 | __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), | 253 | __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), |
254 | __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, | ||
255 | sd_store_allow_restart), | ||
230 | __ATTR_NULL, | 256 | __ATTR_NULL, |
231 | }; | 257 | }; |
232 | 258 | ||
@@ -891,11 +917,10 @@ static struct block_device_operations sd_fops = { | |||
891 | static void sd_rw_intr(struct scsi_cmnd * SCpnt) | 917 | static void sd_rw_intr(struct scsi_cmnd * SCpnt) |
892 | { | 918 | { |
893 | int result = SCpnt->result; | 919 | int result = SCpnt->result; |
894 | int this_count = SCpnt->request_bufflen; | 920 | unsigned int xfer_size = SCpnt->request_bufflen; |
895 | int good_bytes = (result == 0 ? this_count : 0); | 921 | unsigned int good_bytes = result ? 0 : xfer_size; |
896 | sector_t block_sectors = 1; | 922 | u64 start_lba = SCpnt->request->sector; |
897 | u64 first_err_block; | 923 | u64 bad_lba; |
898 | sector_t error_sector; | ||
899 | struct scsi_sense_hdr sshdr; | 924 | struct scsi_sense_hdr sshdr; |
900 | int sense_valid = 0; | 925 | int sense_valid = 0; |
901 | int sense_deferred = 0; | 926 | int sense_deferred = 0; |
@@ -906,7 +931,6 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
906 | if (sense_valid) | 931 | if (sense_valid) |
907 | sense_deferred = scsi_sense_is_deferred(&sshdr); | 932 | sense_deferred = scsi_sense_is_deferred(&sshdr); |
908 | } | 933 | } |
909 | |||
910 | #ifdef CONFIG_SCSI_LOGGING | 934 | #ifdef CONFIG_SCSI_LOGGING |
911 | SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", | 935 | SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", |
912 | SCpnt->request->rq_disk->disk_name, result)); | 936 | SCpnt->request->rq_disk->disk_name, result)); |
@@ -916,89 +940,72 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
916 | sshdr.sense_key, sshdr.asc, sshdr.ascq)); | 940 | sshdr.sense_key, sshdr.asc, sshdr.ascq)); |
917 | } | 941 | } |
918 | #endif | 942 | #endif |
919 | /* | 943 | if (driver_byte(result) != DRIVER_SENSE && |
920 | Handle MEDIUM ERRORs that indicate partial success. Since this is a | 944 | (!sense_valid || sense_deferred)) |
921 | relatively rare error condition, no care is taken to avoid | 945 | goto out; |
922 | unnecessary additional work such as memcpy's that could be avoided. | ||
923 | */ | ||
924 | if (driver_byte(result) != 0 && | ||
925 | sense_valid && !sense_deferred) { | ||
926 | switch (sshdr.sense_key) { | ||
927 | case MEDIUM_ERROR: | ||
928 | if (!blk_fs_request(SCpnt->request)) | ||
929 | break; | ||
930 | info_valid = scsi_get_sense_info_fld( | ||
931 | SCpnt->sense_buffer, SCSI_SENSE_BUFFERSIZE, | ||
932 | &first_err_block); | ||
933 | /* | ||
934 | * May want to warn and skip if following cast results | ||
935 | * in actual truncation (if sector_t < 64 bits) | ||
936 | */ | ||
937 | error_sector = (sector_t)first_err_block; | ||
938 | if (SCpnt->request->bio != NULL) | ||
939 | block_sectors = bio_sectors(SCpnt->request->bio); | ||
940 | switch (SCpnt->device->sector_size) { | ||
941 | case 1024: | ||
942 | error_sector <<= 1; | ||
943 | if (block_sectors < 2) | ||
944 | block_sectors = 2; | ||
945 | break; | ||
946 | case 2048: | ||
947 | error_sector <<= 2; | ||
948 | if (block_sectors < 4) | ||
949 | block_sectors = 4; | ||
950 | break; | ||
951 | case 4096: | ||
952 | error_sector <<=3; | ||
953 | if (block_sectors < 8) | ||
954 | block_sectors = 8; | ||
955 | break; | ||
956 | case 256: | ||
957 | error_sector >>= 1; | ||
958 | break; | ||
959 | default: | ||
960 | break; | ||
961 | } | ||
962 | 946 | ||
963 | error_sector &= ~(block_sectors - 1); | 947 | switch (sshdr.sense_key) { |
964 | good_bytes = (error_sector - SCpnt->request->sector) << 9; | 948 | case HARDWARE_ERROR: |
965 | if (good_bytes < 0 || good_bytes >= this_count) | 949 | case MEDIUM_ERROR: |
966 | good_bytes = 0; | 950 | if (!blk_fs_request(SCpnt->request)) |
951 | goto out; | ||
952 | info_valid = scsi_get_sense_info_fld(SCpnt->sense_buffer, | ||
953 | SCSI_SENSE_BUFFERSIZE, | ||
954 | &bad_lba); | ||
955 | if (!info_valid) | ||
956 | goto out; | ||
957 | if (xfer_size <= SCpnt->device->sector_size) | ||
958 | goto out; | ||
959 | switch (SCpnt->device->sector_size) { | ||
960 | case 256: | ||
961 | start_lba <<= 1; | ||
967 | break; | 962 | break; |
968 | 963 | case 512: | |
969 | case RECOVERED_ERROR: /* an error occurred, but it recovered */ | ||
970 | case NO_SENSE: /* LLDD got sense data */ | ||
971 | /* | ||
972 | * Inform the user, but make sure that it's not treated | ||
973 | * as a hard error. | ||
974 | */ | ||
975 | scsi_print_sense("sd", SCpnt); | ||
976 | SCpnt->result = 0; | ||
977 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | ||
978 | good_bytes = this_count; | ||
979 | break; | 964 | break; |
980 | 965 | case 1024: | |
981 | case ILLEGAL_REQUEST: | 966 | start_lba >>= 1; |
982 | if (SCpnt->device->use_10_for_rw && | 967 | break; |
983 | (SCpnt->cmnd[0] == READ_10 || | 968 | case 2048: |
984 | SCpnt->cmnd[0] == WRITE_10)) | 969 | start_lba >>= 2; |
985 | SCpnt->device->use_10_for_rw = 0; | 970 | break; |
986 | if (SCpnt->device->use_10_for_ms && | 971 | case 4096: |
987 | (SCpnt->cmnd[0] == MODE_SENSE_10 || | 972 | start_lba >>= 3; |
988 | SCpnt->cmnd[0] == MODE_SELECT_10)) | ||
989 | SCpnt->device->use_10_for_ms = 0; | ||
990 | break; | 973 | break; |
991 | |||
992 | default: | 974 | default: |
975 | /* Print something here with limiting frequency. */ | ||
976 | goto out; | ||
993 | break; | 977 | break; |
994 | } | 978 | } |
979 | /* This computation should always be done in terms of | ||
980 | * the resolution of the device's medium. | ||
981 | */ | ||
982 | good_bytes = (bad_lba - start_lba)*SCpnt->device->sector_size; | ||
983 | break; | ||
984 | case RECOVERED_ERROR: | ||
985 | case NO_SENSE: | ||
986 | /* Inform the user, but make sure that it's not treated | ||
987 | * as a hard error. | ||
988 | */ | ||
989 | scsi_print_sense("sd", SCpnt); | ||
990 | SCpnt->result = 0; | ||
991 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | ||
992 | good_bytes = xfer_size; | ||
993 | break; | ||
994 | case ILLEGAL_REQUEST: | ||
995 | if (SCpnt->device->use_10_for_rw && | ||
996 | (SCpnt->cmnd[0] == READ_10 || | ||
997 | SCpnt->cmnd[0] == WRITE_10)) | ||
998 | SCpnt->device->use_10_for_rw = 0; | ||
999 | if (SCpnt->device->use_10_for_ms && | ||
1000 | (SCpnt->cmnd[0] == MODE_SENSE_10 || | ||
1001 | SCpnt->cmnd[0] == MODE_SELECT_10)) | ||
1002 | SCpnt->device->use_10_for_ms = 0; | ||
1003 | break; | ||
1004 | default: | ||
1005 | break; | ||
995 | } | 1006 | } |
996 | /* | 1007 | out: |
997 | * This calls the generic completion function, now that we know | 1008 | scsi_io_completion(SCpnt, good_bytes); |
998 | * how many actual sectors finished, and how many sectors we need | ||
999 | * to say have failed. | ||
1000 | */ | ||
1001 | scsi_io_completion(SCpnt, good_bytes, block_sectors << 9); | ||
1002 | } | 1009 | } |
1003 | 1010 | ||
1004 | static int media_not_present(struct scsi_disk *sdkp, | 1011 | static int media_not_present(struct scsi_disk *sdkp, |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index ebf6579ed698..fd94408577e5 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -292,7 +292,7 @@ static void rw_intr(struct scsi_cmnd * SCpnt) | |||
292 | * how many actual sectors finished, and how many sectors we need | 292 | * how many actual sectors finished, and how many sectors we need |
293 | * to say have failed. | 293 | * to say have failed. |
294 | */ | 294 | */ |
295 | scsi_io_completion(SCpnt, good_bytes, block_sectors << 9); | 295 | scsi_io_completion(SCpnt, good_bytes); |
296 | } | 296 | } |
297 | 297 | ||
298 | static int sr_init_command(struct scsi_cmnd * SCpnt) | 298 | static int sr_init_command(struct scsi_cmnd * SCpnt) |