diff options
Diffstat (limited to 'drivers/scsi')
52 files changed, 3158 insertions, 2223 deletions
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index eb7a6a4ded75..657a3ab75399 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c | |||
| @@ -173,6 +173,7 @@ STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt); | |||
| 173 | STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt); | 173 | STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt); |
| 174 | STATIC void NCR_700_chip_setup(struct Scsi_Host *host); | 174 | STATIC void NCR_700_chip_setup(struct Scsi_Host *host); |
| 175 | STATIC void NCR_700_chip_reset(struct Scsi_Host *host); | 175 | STATIC void NCR_700_chip_reset(struct Scsi_Host *host); |
| 176 | STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt); | ||
| 176 | STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); | 177 | STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt); |
| 177 | STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); | 178 | STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt); |
| 178 | static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); | 179 | static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth); |
| @@ -182,10 +183,6 @@ STATIC struct device_attribute *NCR_700_dev_attrs[]; | |||
| 182 | 183 | ||
| 183 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; | 184 | STATIC struct scsi_transport_template *NCR_700_transport_template = NULL; |
| 184 | 185 | ||
| 185 | struct NCR_700_sense { | ||
| 186 | unsigned char cmnd[MAX_COMMAND_SIZE]; | ||
| 187 | }; | ||
| 188 | |||
| 189 | static char *NCR_700_phase[] = { | 186 | static char *NCR_700_phase[] = { |
| 190 | "", | 187 | "", |
| 191 | "after selection", | 188 | "after selection", |
| @@ -333,6 +330,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, | |||
| 333 | tpnt->use_clustering = ENABLE_CLUSTERING; | 330 | tpnt->use_clustering = ENABLE_CLUSTERING; |
| 334 | tpnt->slave_configure = NCR_700_slave_configure; | 331 | tpnt->slave_configure = NCR_700_slave_configure; |
| 335 | tpnt->slave_destroy = NCR_700_slave_destroy; | 332 | tpnt->slave_destroy = NCR_700_slave_destroy; |
| 333 | tpnt->slave_alloc = NCR_700_slave_alloc; | ||
| 336 | tpnt->change_queue_depth = NCR_700_change_queue_depth; | 334 | tpnt->change_queue_depth = NCR_700_change_queue_depth; |
| 337 | tpnt->change_queue_type = NCR_700_change_queue_type; | 335 | tpnt->change_queue_type = NCR_700_change_queue_type; |
| 338 | 336 | ||
| @@ -611,9 +609,10 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
| 611 | struct NCR_700_command_slot *slot = | 609 | struct NCR_700_command_slot *slot = |
| 612 | (struct NCR_700_command_slot *)SCp->host_scribble; | 610 | (struct NCR_700_command_slot *)SCp->host_scribble; |
| 613 | 611 | ||
| 614 | NCR_700_unmap(hostdata, SCp, slot); | 612 | dma_unmap_single(hostdata->dev, slot->pCmd, |
| 613 | sizeof(SCp->cmnd), DMA_TO_DEVICE); | ||
| 615 | if (slot->flags == NCR_700_FLAG_AUTOSENSE) { | 614 | if (slot->flags == NCR_700_FLAG_AUTOSENSE) { |
| 616 | struct NCR_700_sense *sense = SCp->device->hostdata; | 615 | char *cmnd = NCR_700_get_sense_cmnd(SCp->device); |
| 617 | #ifdef NCR_700_DEBUG | 616 | #ifdef NCR_700_DEBUG |
| 618 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", | 617 | printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n", |
| 619 | SCp, SCp->cmnd[7], result); | 618 | SCp, SCp->cmnd[7], result); |
| @@ -624,10 +623,9 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
| 624 | /* restore the old result if the request sense was | 623 | /* restore the old result if the request sense was |
| 625 | * successful */ | 624 | * successful */ |
| 626 | if(result == 0) | 625 | if(result == 0) |
| 627 | result = sense->cmnd[7]; | 626 | result = cmnd[7]; |
| 628 | } else | 627 | } else |
| 629 | dma_unmap_single(hostdata->dev, slot->pCmd, | 628 | NCR_700_unmap(hostdata, SCp, slot); |
| 630 | sizeof(SCp->cmnd), DMA_TO_DEVICE); | ||
| 631 | 629 | ||
| 632 | free_slot(slot, hostdata); | 630 | free_slot(slot, hostdata); |
| 633 | #ifdef NCR_700_DEBUG | 631 | #ifdef NCR_700_DEBUG |
| @@ -969,14 +967,15 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
| 969 | status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { | 967 | status_byte(hostdata->status[0]) == COMMAND_TERMINATED) { |
| 970 | struct NCR_700_command_slot *slot = | 968 | struct NCR_700_command_slot *slot = |
| 971 | (struct NCR_700_command_slot *)SCp->host_scribble; | 969 | (struct NCR_700_command_slot *)SCp->host_scribble; |
| 972 | if(SCp->cmnd[0] == REQUEST_SENSE) { | 970 | if(slot->flags == NCR_700_FLAG_AUTOSENSE) { |
| 973 | /* OOPS: bad device, returning another | 971 | /* OOPS: bad device, returning another |
| 974 | * contingent allegiance condition */ | 972 | * contingent allegiance condition */ |
| 975 | scmd_printk(KERN_ERR, SCp, | 973 | scmd_printk(KERN_ERR, SCp, |
| 976 | "broken device is looping in contingent allegiance: ignoring\n"); | 974 | "broken device is looping in contingent allegiance: ignoring\n"); |
| 977 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); | 975 | NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]); |
| 978 | } else { | 976 | } else { |
| 979 | struct NCR_700_sense *sense = SCp->device->hostdata; | 977 | char *cmnd = |
| 978 | NCR_700_get_sense_cmnd(SCp->device); | ||
| 980 | #ifdef NCR_DEBUG | 979 | #ifdef NCR_DEBUG |
| 981 | scsi_print_command(SCp); | 980 | scsi_print_command(SCp); |
| 982 | printk(" cmd %p has status %d, requesting sense\n", | 981 | printk(" cmd %p has status %d, requesting sense\n", |
| @@ -994,21 +993,21 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
| 994 | sizeof(SCp->cmnd), | 993 | sizeof(SCp->cmnd), |
| 995 | DMA_TO_DEVICE); | 994 | DMA_TO_DEVICE); |
| 996 | 995 | ||
| 997 | sense->cmnd[0] = REQUEST_SENSE; | 996 | cmnd[0] = REQUEST_SENSE; |
| 998 | sense->cmnd[1] = (SCp->device->lun & 0x7) << 5; | 997 | cmnd[1] = (SCp->device->lun & 0x7) << 5; |
| 999 | sense->cmnd[2] = 0; | 998 | cmnd[2] = 0; |
| 1000 | sense->cmnd[3] = 0; | 999 | cmnd[3] = 0; |
| 1001 | sense->cmnd[4] = sizeof(SCp->sense_buffer); | 1000 | cmnd[4] = sizeof(SCp->sense_buffer); |
| 1002 | sense->cmnd[5] = 0; | 1001 | cmnd[5] = 0; |
| 1003 | /* Here's a quiet hack: the | 1002 | /* Here's a quiet hack: the |
| 1004 | * REQUEST_SENSE command is six bytes, | 1003 | * REQUEST_SENSE command is six bytes, |
| 1005 | * so store a flag indicating that | 1004 | * so store a flag indicating that |
| 1006 | * this was an internal sense request | 1005 | * this was an internal sense request |
| 1007 | * and the original status at the end | 1006 | * and the original status at the end |
| 1008 | * of the command */ | 1007 | * of the command */ |
| 1009 | sense->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; | 1008 | cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; |
| 1010 | sense->cmnd[7] = hostdata->status[0]; | 1009 | cmnd[7] = hostdata->status[0]; |
| 1011 | slot->pCmd = dma_map_single(hostdata->dev, sense->cmnd, sizeof(sense->cmnd), DMA_TO_DEVICE); | 1010 | slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE); |
| 1012 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); | 1011 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); |
| 1013 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); | 1012 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); |
| 1014 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); | 1013 | slot->SG[0].pAddr = bS_to_host(slot->dma_handle); |
| @@ -1530,7 +1529,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
| 1530 | 1529 | ||
| 1531 | /* clear all the negotiated parameters */ | 1530 | /* clear all the negotiated parameters */ |
| 1532 | __shost_for_each_device(SDp, host) | 1531 | __shost_for_each_device(SDp, host) |
| 1533 | SDp->hostdata = NULL; | 1532 | NCR_700_clear_flag(SDp, ~0); |
| 1534 | 1533 | ||
| 1535 | /* clear all the slots and their pending commands */ | 1534 | /* clear all the slots and their pending commands */ |
| 1536 | for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) { | 1535 | for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) { |
| @@ -2035,7 +2034,17 @@ NCR_700_set_offset(struct scsi_target *STp, int offset) | |||
| 2035 | spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; | 2034 | spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; |
| 2036 | } | 2035 | } |
| 2037 | 2036 | ||
| 2037 | STATIC int | ||
| 2038 | NCR_700_slave_alloc(struct scsi_device *SDp) | ||
| 2039 | { | ||
| 2040 | SDp->hostdata = kzalloc(sizeof(struct NCR_700_Device_Parameters), | ||
| 2041 | GFP_KERNEL); | ||
| 2038 | 2042 | ||
| 2043 | if (!SDp->hostdata) | ||
| 2044 | return -ENOMEM; | ||
| 2045 | |||
| 2046 | return 0; | ||
| 2047 | } | ||
| 2039 | 2048 | ||
| 2040 | STATIC int | 2049 | STATIC int |
| 2041 | NCR_700_slave_configure(struct scsi_device *SDp) | 2050 | NCR_700_slave_configure(struct scsi_device *SDp) |
| @@ -2043,11 +2052,6 @@ NCR_700_slave_configure(struct scsi_device *SDp) | |||
| 2043 | struct NCR_700_Host_Parameters *hostdata = | 2052 | struct NCR_700_Host_Parameters *hostdata = |
| 2044 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; | 2053 | (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; |
| 2045 | 2054 | ||
| 2046 | SDp->hostdata = kmalloc(GFP_KERNEL, sizeof(struct NCR_700_sense)); | ||
| 2047 | |||
| 2048 | if (!SDp->hostdata) | ||
| 2049 | return -ENOMEM; | ||
| 2050 | |||
| 2051 | /* to do here: allocate memory; build a queue_full list */ | 2055 | /* to do here: allocate memory; build a queue_full list */ |
| 2052 | if(SDp->tagged_supported) { | 2056 | if(SDp->tagged_supported) { |
| 2053 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); | 2057 | scsi_set_tag_type(SDp, MSG_ORDERED_TAG); |
diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h index 7f22a06fe5ec..97ebe71b701b 100644 --- a/drivers/scsi/53c700.h +++ b/drivers/scsi/53c700.h | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <asm/io.h> | 12 | #include <asm/io.h> |
| 13 | 13 | ||
| 14 | #include <scsi/scsi_device.h> | 14 | #include <scsi/scsi_device.h> |
| 15 | 15 | #include <scsi/scsi_cmnd.h> | |
| 16 | 16 | ||
| 17 | /* Turn on for general debugging---too verbose for normal use */ | 17 | /* Turn on for general debugging---too verbose for normal use */ |
| 18 | #undef NCR_700_DEBUG | 18 | #undef NCR_700_DEBUG |
| @@ -76,11 +76,16 @@ struct NCR_700_SG_List { | |||
| 76 | #define SCRIPT_RETURN 0x90080000 | 76 | #define SCRIPT_RETURN 0x90080000 |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | /* We use device->hostdata to store negotiated parameters. This is | 79 | struct NCR_700_Device_Parameters { |
| 80 | * supposed to be a pointer to a device private area, but we cannot | 80 | /* space for creating a request sense command. Really, except |
| 81 | * really use it as such since it will never be freed, so just use the | 81 | * for the annoying SCSI-2 requirement for LUN information in |
| 82 | * 32 bits to cram the information. The SYNC negotiation sequence looks | 82 | * cmnd[1], this could be in static storage */ |
| 83 | * like: | 83 | unsigned char cmnd[MAX_COMMAND_SIZE]; |
| 84 | __u8 depth; | ||
| 85 | }; | ||
| 86 | |||
| 87 | |||
| 88 | /* The SYNC negotiation sequence looks like: | ||
| 84 | * | 89 | * |
| 85 | * If DEV_NEGOTIATED_SYNC not set, tack and SDTR message on to the | 90 | * If DEV_NEGOTIATED_SYNC not set, tack and SDTR message on to the |
| 86 | * initial identify for the device and set DEV_BEGIN_SYNC_NEGOTATION | 91 | * initial identify for the device and set DEV_BEGIN_SYNC_NEGOTATION |
| @@ -98,19 +103,26 @@ struct NCR_700_SG_List { | |||
| 98 | #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION (1<<17) | 103 | #define NCR_700_DEV_BEGIN_SYNC_NEGOTIATION (1<<17) |
| 99 | #define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19) | 104 | #define NCR_700_DEV_PRINT_SYNC_NEGOTIATION (1<<19) |
| 100 | 105 | ||
| 106 | static inline char *NCR_700_get_sense_cmnd(struct scsi_device *SDp) | ||
| 107 | { | ||
| 108 | struct NCR_700_Device_Parameters *hostdata = SDp->hostdata; | ||
| 109 | |||
| 110 | return hostdata->cmnd; | ||
| 111 | } | ||
| 112 | |||
| 101 | static inline void | 113 | static inline void |
| 102 | NCR_700_set_depth(struct scsi_device *SDp, __u8 depth) | 114 | NCR_700_set_depth(struct scsi_device *SDp, __u8 depth) |
| 103 | { | 115 | { |
| 104 | long l = (long)SDp->hostdata; | 116 | struct NCR_700_Device_Parameters *hostdata = SDp->hostdata; |
| 105 | 117 | ||
| 106 | l &= 0xffff00ff; | 118 | hostdata->depth = depth; |
| 107 | l |= 0xff00 & (depth << 8); | ||
| 108 | SDp->hostdata = (void *)l; | ||
| 109 | } | 119 | } |
| 110 | static inline __u8 | 120 | static inline __u8 |
| 111 | NCR_700_get_depth(struct scsi_device *SDp) | 121 | NCR_700_get_depth(struct scsi_device *SDp) |
| 112 | { | 122 | { |
| 113 | return ((((unsigned long)SDp->hostdata) & 0xff00)>>8); | 123 | struct NCR_700_Device_Parameters *hostdata = SDp->hostdata; |
| 124 | |||
| 125 | return hostdata->depth; | ||
| 114 | } | 126 | } |
| 115 | static inline int | 127 | static inline int |
| 116 | NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag) | 128 | NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag) |
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 92c6154575e7..9e871de23835 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h | |||
| @@ -262,7 +262,6 @@ typedef enum { | |||
| 262 | AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ | 262 | AHD_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ |
| 263 | } ahd_linux_dev_flags; | 263 | } ahd_linux_dev_flags; |
| 264 | 264 | ||
| 265 | struct ahd_linux_target; | ||
| 266 | struct ahd_linux_device { | 265 | struct ahd_linux_device { |
| 267 | TAILQ_ENTRY(ahd_linux_device) links; | 266 | TAILQ_ENTRY(ahd_linux_device) links; |
| 268 | 267 | ||
| @@ -342,12 +341,6 @@ struct ahd_linux_device { | |||
| 342 | #define AHD_OTAG_THRESH 500 | 341 | #define AHD_OTAG_THRESH 500 |
| 343 | }; | 342 | }; |
| 344 | 343 | ||
| 345 | struct ahd_linux_target { | ||
| 346 | struct scsi_device *sdev[AHD_NUM_LUNS]; | ||
| 347 | struct ahd_transinfo last_tinfo; | ||
| 348 | struct ahd_softc *ahd; | ||
| 349 | }; | ||
| 350 | |||
| 351 | /********************* Definitions Required by the Core ***********************/ | 344 | /********************* Definitions Required by the Core ***********************/ |
| 352 | /* | 345 | /* |
| 353 | * Number of SG segments we require. So long as the S/G segments for | 346 | * Number of SG segments we require. So long as the S/G segments for |
| @@ -864,7 +857,7 @@ ahd_freeze_scb(struct scb *scb) | |||
| 864 | } | 857 | } |
| 865 | } | 858 | } |
| 866 | 859 | ||
| 867 | void ahd_platform_set_tags(struct ahd_softc *ahd, | 860 | void ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev, |
| 868 | struct ahd_devinfo *devinfo, ahd_queue_alg); | 861 | struct ahd_devinfo *devinfo, ahd_queue_alg); |
| 869 | int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, | 862 | int ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, |
| 870 | char channel, int lun, u_int tag, | 863 | char channel, int lun, u_int tag, |
| @@ -873,7 +866,7 @@ irqreturn_t | |||
| 873 | ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); | 866 | ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs); |
| 874 | void ahd_done(struct ahd_softc*, struct scb*); | 867 | void ahd_done(struct ahd_softc*, struct scb*); |
| 875 | void ahd_send_async(struct ahd_softc *, char channel, | 868 | void ahd_send_async(struct ahd_softc *, char channel, |
| 876 | u_int target, u_int lun, ac_code, void *); | 869 | u_int target, u_int lun, ac_code); |
| 877 | void ahd_print_path(struct ahd_softc *, struct scb *); | 870 | void ahd_print_path(struct ahd_softc *, struct scb *); |
| 878 | 871 | ||
| 879 | #ifdef CONFIG_PCI | 872 | #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 412f8301b757..0ec41f34f462 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/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index b4743a9ecc80..848fb2aa4ca3 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
| @@ -2130,19 +2130,21 @@ iscsi_r2tpool_free(struct iscsi_session *session) | |||
| 2130 | 2130 | ||
| 2131 | static int | 2131 | static int |
| 2132 | iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | 2132 | iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, |
| 2133 | uint32_t value) | 2133 | char *buf, int buflen) |
| 2134 | { | 2134 | { |
| 2135 | struct iscsi_conn *conn = cls_conn->dd_data; | 2135 | struct iscsi_conn *conn = cls_conn->dd_data; |
| 2136 | struct iscsi_session *session = conn->session; | 2136 | struct iscsi_session *session = conn->session; |
| 2137 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 2137 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
| 2138 | int value; | ||
| 2138 | 2139 | ||
| 2139 | switch(param) { | 2140 | switch(param) { |
| 2140 | case ISCSI_PARAM_MAX_RECV_DLENGTH: { | 2141 | case ISCSI_PARAM_MAX_RECV_DLENGTH: { |
| 2141 | char *saveptr = tcp_conn->data; | 2142 | char *saveptr = tcp_conn->data; |
| 2142 | gfp_t flags = GFP_KERNEL; | 2143 | gfp_t flags = GFP_KERNEL; |
| 2143 | 2144 | ||
| 2145 | sscanf(buf, "%d", &value); | ||
| 2144 | if (tcp_conn->data_size >= value) { | 2146 | if (tcp_conn->data_size >= value) { |
| 2145 | conn->max_recv_dlength = value; | 2147 | iscsi_set_param(cls_conn, param, buf, buflen); |
| 2146 | break; | 2148 | break; |
| 2147 | } | 2149 | } |
| 2148 | 2150 | ||
| @@ -2165,15 +2167,12 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
| 2165 | else | 2167 | else |
| 2166 | free_pages((unsigned long)saveptr, | 2168 | free_pages((unsigned long)saveptr, |
| 2167 | get_order(tcp_conn->data_size)); | 2169 | get_order(tcp_conn->data_size)); |
| 2168 | conn->max_recv_dlength = value; | 2170 | iscsi_set_param(cls_conn, param, buf, buflen); |
| 2169 | tcp_conn->data_size = value; | 2171 | tcp_conn->data_size = value; |
| 2170 | } | ||
| 2171 | break; | ||
| 2172 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
| 2173 | conn->max_xmit_dlength = value; | ||
| 2174 | break; | 2172 | break; |
| 2173 | } | ||
| 2175 | case ISCSI_PARAM_HDRDGST_EN: | 2174 | case ISCSI_PARAM_HDRDGST_EN: |
| 2176 | conn->hdrdgst_en = value; | 2175 | iscsi_set_param(cls_conn, param, buf, buflen); |
| 2177 | tcp_conn->hdr_size = sizeof(struct iscsi_hdr); | 2176 | tcp_conn->hdr_size = sizeof(struct iscsi_hdr); |
| 2178 | if (conn->hdrdgst_en) { | 2177 | if (conn->hdrdgst_en) { |
| 2179 | tcp_conn->hdr_size += sizeof(__u32); | 2178 | tcp_conn->hdr_size += sizeof(__u32); |
| @@ -2197,7 +2196,7 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
| 2197 | } | 2196 | } |
| 2198 | break; | 2197 | break; |
| 2199 | case ISCSI_PARAM_DATADGST_EN: | 2198 | case ISCSI_PARAM_DATADGST_EN: |
| 2200 | conn->datadgst_en = value; | 2199 | iscsi_set_param(cls_conn, param, buf, buflen); |
| 2201 | if (conn->datadgst_en) { | 2200 | if (conn->datadgst_en) { |
| 2202 | if (!tcp_conn->data_tx_tfm) | 2201 | if (!tcp_conn->data_tx_tfm) |
| 2203 | tcp_conn->data_tx_tfm = | 2202 | tcp_conn->data_tx_tfm = |
| @@ -2220,121 +2219,36 @@ iscsi_conn_set_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, | |||
| 2220 | tcp_conn->sendpage = conn->datadgst_en ? | 2219 | tcp_conn->sendpage = conn->datadgst_en ? |
| 2221 | sock_no_sendpage : tcp_conn->sock->ops->sendpage; | 2220 | sock_no_sendpage : tcp_conn->sock->ops->sendpage; |
| 2222 | break; | 2221 | break; |
| 2223 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
| 2224 | session->initial_r2t_en = value; | ||
| 2225 | break; | ||
| 2226 | case ISCSI_PARAM_MAX_R2T: | 2222 | case ISCSI_PARAM_MAX_R2T: |
| 2223 | sscanf(buf, "%d", &value); | ||
| 2227 | if (session->max_r2t == roundup_pow_of_two(value)) | 2224 | if (session->max_r2t == roundup_pow_of_two(value)) |
| 2228 | break; | 2225 | break; |
| 2229 | iscsi_r2tpool_free(session); | 2226 | iscsi_r2tpool_free(session); |
| 2230 | session->max_r2t = value; | 2227 | iscsi_set_param(cls_conn, param, buf, buflen); |
| 2231 | if (session->max_r2t & (session->max_r2t - 1)) | 2228 | if (session->max_r2t & (session->max_r2t - 1)) |
| 2232 | session->max_r2t = roundup_pow_of_two(session->max_r2t); | 2229 | session->max_r2t = roundup_pow_of_two(session->max_r2t); |
| 2233 | if (iscsi_r2tpool_alloc(session)) | 2230 | if (iscsi_r2tpool_alloc(session)) |
| 2234 | return -ENOMEM; | 2231 | return -ENOMEM; |
| 2235 | break; | 2232 | break; |
| 2236 | case ISCSI_PARAM_IMM_DATA_EN: | ||
| 2237 | session->imm_data_en = value; | ||
| 2238 | break; | ||
| 2239 | case ISCSI_PARAM_FIRST_BURST: | ||
| 2240 | session->first_burst = value; | ||
| 2241 | break; | ||
| 2242 | case ISCSI_PARAM_MAX_BURST: | ||
| 2243 | session->max_burst = value; | ||
| 2244 | break; | ||
| 2245 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
| 2246 | session->pdu_inorder_en = value; | ||
| 2247 | break; | ||
| 2248 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
| 2249 | session->dataseq_inorder_en = value; | ||
| 2250 | break; | ||
| 2251 | case ISCSI_PARAM_ERL: | ||
| 2252 | session->erl = value; | ||
| 2253 | break; | ||
| 2254 | case ISCSI_PARAM_IFMARKER_EN: | ||
| 2255 | BUG_ON(value); | ||
| 2256 | session->ifmarker_en = value; | ||
| 2257 | break; | ||
| 2258 | case ISCSI_PARAM_OFMARKER_EN: | ||
| 2259 | BUG_ON(value); | ||
| 2260 | session->ofmarker_en = value; | ||
| 2261 | break; | ||
| 2262 | case ISCSI_PARAM_EXP_STATSN: | ||
| 2263 | conn->exp_statsn = value; | ||
| 2264 | break; | ||
| 2265 | default: | ||
| 2266 | break; | ||
| 2267 | } | ||
| 2268 | |||
| 2269 | return 0; | ||
| 2270 | } | ||
| 2271 | |||
| 2272 | static int | ||
| 2273 | iscsi_session_get_param(struct iscsi_cls_session *cls_session, | ||
| 2274 | enum iscsi_param param, uint32_t *value) | ||
| 2275 | { | ||
| 2276 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
| 2277 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | ||
| 2278 | |||
| 2279 | switch(param) { | ||
| 2280 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
| 2281 | *value = session->initial_r2t_en; | ||
| 2282 | break; | ||
| 2283 | case ISCSI_PARAM_MAX_R2T: | ||
| 2284 | *value = session->max_r2t; | ||
| 2285 | break; | ||
| 2286 | case ISCSI_PARAM_IMM_DATA_EN: | ||
| 2287 | *value = session->imm_data_en; | ||
| 2288 | break; | ||
| 2289 | case ISCSI_PARAM_FIRST_BURST: | ||
| 2290 | *value = session->first_burst; | ||
| 2291 | break; | ||
| 2292 | case ISCSI_PARAM_MAX_BURST: | ||
| 2293 | *value = session->max_burst; | ||
| 2294 | break; | ||
| 2295 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
| 2296 | *value = session->pdu_inorder_en; | ||
| 2297 | break; | ||
| 2298 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
| 2299 | *value = session->dataseq_inorder_en; | ||
| 2300 | break; | ||
| 2301 | case ISCSI_PARAM_ERL: | ||
| 2302 | *value = session->erl; | ||
| 2303 | break; | ||
| 2304 | case ISCSI_PARAM_IFMARKER_EN: | ||
| 2305 | *value = session->ifmarker_en; | ||
| 2306 | break; | ||
| 2307 | case ISCSI_PARAM_OFMARKER_EN: | ||
| 2308 | *value = session->ofmarker_en; | ||
| 2309 | break; | ||
| 2310 | default: | 2233 | default: |
| 2311 | return -EINVAL; | 2234 | return iscsi_set_param(cls_conn, param, buf, buflen); |
| 2312 | } | 2235 | } |
| 2313 | 2236 | ||
| 2314 | return 0; | 2237 | return 0; |
| 2315 | } | 2238 | } |
| 2316 | 2239 | ||
| 2317 | static int | 2240 | static int |
| 2318 | iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | 2241 | iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, |
| 2319 | enum iscsi_param param, uint32_t *value) | 2242 | enum iscsi_param param, char *buf) |
| 2320 | { | 2243 | { |
| 2321 | struct iscsi_conn *conn = cls_conn->dd_data; | 2244 | struct iscsi_conn *conn = cls_conn->dd_data; |
| 2322 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 2245 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
| 2323 | struct inet_sock *inet; | 2246 | struct inet_sock *inet; |
| 2247 | struct ipv6_pinfo *np; | ||
| 2248 | struct sock *sk; | ||
| 2249 | int len; | ||
| 2324 | 2250 | ||
| 2325 | switch(param) { | 2251 | switch(param) { |
| 2326 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
| 2327 | *value = conn->max_recv_dlength; | ||
| 2328 | break; | ||
| 2329 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
| 2330 | *value = conn->max_xmit_dlength; | ||
| 2331 | break; | ||
| 2332 | case ISCSI_PARAM_HDRDGST_EN: | ||
| 2333 | *value = conn->hdrdgst_en; | ||
| 2334 | break; | ||
| 2335 | case ISCSI_PARAM_DATADGST_EN: | ||
| 2336 | *value = conn->datadgst_en; | ||
| 2337 | break; | ||
| 2338 | case ISCSI_PARAM_CONN_PORT: | 2252 | case ISCSI_PARAM_CONN_PORT: |
| 2339 | mutex_lock(&conn->xmitmutex); | 2253 | mutex_lock(&conn->xmitmutex); |
| 2340 | if (!tcp_conn->sock) { | 2254 | if (!tcp_conn->sock) { |
| @@ -2343,30 +2257,9 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
| 2343 | } | 2257 | } |
| 2344 | 2258 | ||
| 2345 | inet = inet_sk(tcp_conn->sock->sk); | 2259 | inet = inet_sk(tcp_conn->sock->sk); |
| 2346 | *value = be16_to_cpu(inet->dport); | 2260 | len = sprintf(buf, "%hu\n", be16_to_cpu(inet->dport)); |
| 2347 | mutex_unlock(&conn->xmitmutex); | 2261 | mutex_unlock(&conn->xmitmutex); |
| 2348 | case ISCSI_PARAM_EXP_STATSN: | ||
| 2349 | *value = conn->exp_statsn; | ||
| 2350 | break; | 2262 | break; |
| 2351 | default: | ||
| 2352 | return -EINVAL; | ||
| 2353 | } | ||
| 2354 | |||
| 2355 | return 0; | ||
| 2356 | } | ||
| 2357 | |||
| 2358 | static int | ||
| 2359 | iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn, | ||
| 2360 | enum iscsi_param param, char *buf) | ||
| 2361 | { | ||
| 2362 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
| 2363 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | ||
| 2364 | struct sock *sk; | ||
| 2365 | struct inet_sock *inet; | ||
| 2366 | struct ipv6_pinfo *np; | ||
| 2367 | int len = 0; | ||
| 2368 | |||
| 2369 | switch (param) { | ||
| 2370 | case ISCSI_PARAM_CONN_ADDRESS: | 2263 | case ISCSI_PARAM_CONN_ADDRESS: |
| 2371 | mutex_lock(&conn->xmitmutex); | 2264 | mutex_lock(&conn->xmitmutex); |
| 2372 | if (!tcp_conn->sock) { | 2265 | if (!tcp_conn->sock) { |
| @@ -2388,7 +2281,7 @@ iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn, | |||
| 2388 | mutex_unlock(&conn->xmitmutex); | 2281 | mutex_unlock(&conn->xmitmutex); |
| 2389 | break; | 2282 | break; |
| 2390 | default: | 2283 | default: |
| 2391 | return -EINVAL; | 2284 | return iscsi_conn_get_param(cls_conn, param, buf); |
| 2392 | } | 2285 | } |
| 2393 | 2286 | ||
| 2394 | return len; | 2287 | return len; |
| @@ -2501,7 +2394,11 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
| 2501 | ISCSI_ERL | | 2394 | ISCSI_ERL | |
| 2502 | ISCSI_CONN_PORT | | 2395 | ISCSI_CONN_PORT | |
| 2503 | ISCSI_CONN_ADDRESS | | 2396 | ISCSI_CONN_ADDRESS | |
| 2504 | ISCSI_EXP_STATSN, | 2397 | ISCSI_EXP_STATSN | |
| 2398 | ISCSI_PERSISTENT_PORT | | ||
| 2399 | ISCSI_PERSISTENT_ADDRESS | | ||
| 2400 | ISCSI_TARGET_NAME | | ||
| 2401 | ISCSI_TPGT, | ||
| 2505 | .host_template = &iscsi_sht, | 2402 | .host_template = &iscsi_sht, |
| 2506 | .conndata_size = sizeof(struct iscsi_conn), | 2403 | .conndata_size = sizeof(struct iscsi_conn), |
| 2507 | .max_conn = 1, | 2404 | .max_conn = 1, |
| @@ -2514,8 +2411,7 @@ static struct iscsi_transport iscsi_tcp_transport = { | |||
| 2514 | .bind_conn = iscsi_tcp_conn_bind, | 2411 | .bind_conn = iscsi_tcp_conn_bind, |
| 2515 | .destroy_conn = iscsi_tcp_conn_destroy, | 2412 | .destroy_conn = iscsi_tcp_conn_destroy, |
| 2516 | .set_param = iscsi_conn_set_param, | 2413 | .set_param = iscsi_conn_set_param, |
| 2517 | .get_conn_param = iscsi_conn_get_param, | 2414 | .get_conn_param = iscsi_tcp_conn_get_param, |
| 2518 | .get_conn_str_param = iscsi_conn_get_str_param, | ||
| 2519 | .get_session_param = iscsi_session_get_param, | 2415 | .get_session_param = iscsi_session_get_param, |
| 2520 | .start_conn = iscsi_conn_start, | 2416 | .start_conn = iscsi_conn_start, |
| 2521 | .stop_conn = iscsi_conn_stop, | 2417 | .stop_conn = iscsi_conn_stop, |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 82caba464291..1c960ac1617f 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
| @@ -1001,7 +1001,7 @@ unsigned ata_exec_internal(struct ata_device *dev, | |||
| 1001 | struct ata_queued_cmd *qc; | 1001 | struct ata_queued_cmd *qc; |
| 1002 | unsigned int tag, preempted_tag; | 1002 | unsigned int tag, preempted_tag; |
| 1003 | u32 preempted_sactive, preempted_qc_active; | 1003 | u32 preempted_sactive, preempted_qc_active; |
| 1004 | DECLARE_COMPLETION(wait); | 1004 | DECLARE_COMPLETION_ONSTACK(wait); |
| 1005 | unsigned long flags; | 1005 | unsigned long flags; |
| 1006 | unsigned int err_mask; | 1006 | unsigned int err_mask; |
| 1007 | int rc; | 1007 | int rc; |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 2673a11a9495..7e6e031cc41b 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -1287,13 +1287,18 @@ iscsi_session_setup(struct iscsi_transport *iscsit, | |||
| 1287 | if (scsi_add_host(shost, NULL)) | 1287 | if (scsi_add_host(shost, NULL)) |
| 1288 | goto add_host_fail; | 1288 | goto add_host_fail; |
| 1289 | 1289 | ||
| 1290 | if (!try_module_get(iscsit->owner)) | ||
| 1291 | goto cls_session_fail; | ||
| 1292 | |||
| 1290 | cls_session = iscsi_create_session(shost, iscsit, 0); | 1293 | cls_session = iscsi_create_session(shost, iscsit, 0); |
| 1291 | if (!cls_session) | 1294 | if (!cls_session) |
| 1292 | goto cls_session_fail; | 1295 | goto module_put; |
| 1293 | *(unsigned long*)shost->hostdata = (unsigned long)cls_session; | 1296 | *(unsigned long*)shost->hostdata = (unsigned long)cls_session; |
| 1294 | 1297 | ||
| 1295 | return cls_session; | 1298 | return cls_session; |
| 1296 | 1299 | ||
| 1300 | module_put: | ||
| 1301 | module_put(iscsit->owner); | ||
| 1297 | cls_session_fail: | 1302 | cls_session_fail: |
| 1298 | scsi_remove_host(shost); | 1303 | scsi_remove_host(shost); |
| 1299 | add_host_fail: | 1304 | add_host_fail: |
| @@ -1325,6 +1330,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) | |||
| 1325 | 1330 | ||
| 1326 | iscsi_destroy_session(cls_session); | 1331 | iscsi_destroy_session(cls_session); |
| 1327 | scsi_host_put(shost); | 1332 | scsi_host_put(shost); |
| 1333 | module_put(cls_session->transport->owner); | ||
| 1328 | } | 1334 | } |
| 1329 | EXPORT_SYMBOL_GPL(iscsi_session_teardown); | 1335 | EXPORT_SYMBOL_GPL(iscsi_session_teardown); |
| 1330 | 1336 | ||
| @@ -1697,6 +1703,185 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session, | |||
| 1697 | } | 1703 | } |
| 1698 | EXPORT_SYMBOL_GPL(iscsi_conn_bind); | 1704 | EXPORT_SYMBOL_GPL(iscsi_conn_bind); |
| 1699 | 1705 | ||
| 1706 | |||
| 1707 | int iscsi_set_param(struct iscsi_cls_conn *cls_conn, | ||
| 1708 | enum iscsi_param param, char *buf, int buflen) | ||
| 1709 | { | ||
| 1710 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
| 1711 | struct iscsi_session *session = conn->session; | ||
| 1712 | uint32_t value; | ||
| 1713 | |||
| 1714 | switch(param) { | ||
| 1715 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
| 1716 | sscanf(buf, "%d", &conn->max_recv_dlength); | ||
| 1717 | break; | ||
| 1718 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
| 1719 | sscanf(buf, "%d", &conn->max_xmit_dlength); | ||
| 1720 | break; | ||
| 1721 | case ISCSI_PARAM_HDRDGST_EN: | ||
| 1722 | sscanf(buf, "%d", &conn->hdrdgst_en); | ||
| 1723 | break; | ||
| 1724 | case ISCSI_PARAM_DATADGST_EN: | ||
| 1725 | sscanf(buf, "%d", &conn->datadgst_en); | ||
| 1726 | break; | ||
| 1727 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
| 1728 | sscanf(buf, "%d", &session->initial_r2t_en); | ||
| 1729 | break; | ||
| 1730 | case ISCSI_PARAM_MAX_R2T: | ||
| 1731 | sscanf(buf, "%d", &session->max_r2t); | ||
| 1732 | break; | ||
| 1733 | case ISCSI_PARAM_IMM_DATA_EN: | ||
| 1734 | sscanf(buf, "%d", &session->imm_data_en); | ||
| 1735 | break; | ||
| 1736 | case ISCSI_PARAM_FIRST_BURST: | ||
| 1737 | sscanf(buf, "%d", &session->first_burst); | ||
| 1738 | break; | ||
| 1739 | case ISCSI_PARAM_MAX_BURST: | ||
| 1740 | sscanf(buf, "%d", &session->max_burst); | ||
| 1741 | break; | ||
| 1742 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
| 1743 | sscanf(buf, "%d", &session->pdu_inorder_en); | ||
| 1744 | break; | ||
| 1745 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
| 1746 | sscanf(buf, "%d", &session->dataseq_inorder_en); | ||
| 1747 | break; | ||
| 1748 | case ISCSI_PARAM_ERL: | ||
| 1749 | sscanf(buf, "%d", &session->erl); | ||
| 1750 | break; | ||
| 1751 | case ISCSI_PARAM_IFMARKER_EN: | ||
| 1752 | sscanf(buf, "%d", &value); | ||
| 1753 | BUG_ON(value); | ||
| 1754 | break; | ||
| 1755 | case ISCSI_PARAM_OFMARKER_EN: | ||
| 1756 | sscanf(buf, "%d", &value); | ||
| 1757 | BUG_ON(value); | ||
| 1758 | break; | ||
| 1759 | case ISCSI_PARAM_EXP_STATSN: | ||
| 1760 | sscanf(buf, "%u", &conn->exp_statsn); | ||
| 1761 | break; | ||
| 1762 | case ISCSI_PARAM_TARGET_NAME: | ||
| 1763 | /* this should not change between logins */ | ||
| 1764 | if (session->targetname) | ||
| 1765 | break; | ||
| 1766 | |||
| 1767 | session->targetname = kstrdup(buf, GFP_KERNEL); | ||
| 1768 | if (!session->targetname) | ||
| 1769 | return -ENOMEM; | ||
| 1770 | break; | ||
| 1771 | case ISCSI_PARAM_TPGT: | ||
| 1772 | sscanf(buf, "%d", &session->tpgt); | ||
| 1773 | break; | ||
| 1774 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
| 1775 | sscanf(buf, "%d", &conn->persistent_port); | ||
| 1776 | break; | ||
| 1777 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
| 1778 | /* | ||
| 1779 | * this is the address returned in discovery so it should | ||
| 1780 | * not change between logins. | ||
| 1781 | */ | ||
| 1782 | if (conn->persistent_address) | ||
| 1783 | break; | ||
| 1784 | |||
| 1785 | conn->persistent_address = kstrdup(buf, GFP_KERNEL); | ||
| 1786 | if (!conn->persistent_address) | ||
| 1787 | return -ENOMEM; | ||
| 1788 | break; | ||
| 1789 | default: | ||
| 1790 | return -ENOSYS; | ||
| 1791 | } | ||
| 1792 | |||
| 1793 | return 0; | ||
| 1794 | } | ||
| 1795 | EXPORT_SYMBOL_GPL(iscsi_set_param); | ||
| 1796 | |||
| 1797 | int iscsi_session_get_param(struct iscsi_cls_session *cls_session, | ||
| 1798 | enum iscsi_param param, char *buf) | ||
| 1799 | { | ||
| 1800 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
| 1801 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | ||
| 1802 | int len; | ||
| 1803 | |||
| 1804 | switch(param) { | ||
| 1805 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
| 1806 | len = sprintf(buf, "%d\n", session->initial_r2t_en); | ||
| 1807 | break; | ||
| 1808 | case ISCSI_PARAM_MAX_R2T: | ||
| 1809 | len = sprintf(buf, "%hu\n", session->max_r2t); | ||
| 1810 | break; | ||
| 1811 | case ISCSI_PARAM_IMM_DATA_EN: | ||
| 1812 | len = sprintf(buf, "%d\n", session->imm_data_en); | ||
| 1813 | break; | ||
| 1814 | case ISCSI_PARAM_FIRST_BURST: | ||
| 1815 | len = sprintf(buf, "%u\n", session->first_burst); | ||
| 1816 | break; | ||
| 1817 | case ISCSI_PARAM_MAX_BURST: | ||
| 1818 | len = sprintf(buf, "%u\n", session->max_burst); | ||
| 1819 | break; | ||
| 1820 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
| 1821 | len = sprintf(buf, "%d\n", session->pdu_inorder_en); | ||
| 1822 | break; | ||
| 1823 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
| 1824 | len = sprintf(buf, "%d\n", session->dataseq_inorder_en); | ||
| 1825 | break; | ||
| 1826 | case ISCSI_PARAM_ERL: | ||
| 1827 | len = sprintf(buf, "%d\n", session->erl); | ||
| 1828 | break; | ||
| 1829 | case ISCSI_PARAM_TARGET_NAME: | ||
| 1830 | len = sprintf(buf, "%s\n", session->targetname); | ||
| 1831 | break; | ||
| 1832 | case ISCSI_PARAM_TPGT: | ||
| 1833 | len = sprintf(buf, "%d\n", session->tpgt); | ||
| 1834 | break; | ||
| 1835 | default: | ||
| 1836 | return -ENOSYS; | ||
| 1837 | } | ||
| 1838 | |||
| 1839 | return len; | ||
| 1840 | } | ||
| 1841 | EXPORT_SYMBOL_GPL(iscsi_session_get_param); | ||
| 1842 | |||
| 1843 | int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | ||
| 1844 | enum iscsi_param param, char *buf) | ||
| 1845 | { | ||
| 1846 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
| 1847 | int len; | ||
| 1848 | |||
| 1849 | switch(param) { | ||
| 1850 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
| 1851 | len = sprintf(buf, "%u\n", conn->max_recv_dlength); | ||
| 1852 | break; | ||
| 1853 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
| 1854 | len = sprintf(buf, "%u\n", conn->max_xmit_dlength); | ||
| 1855 | break; | ||
| 1856 | case ISCSI_PARAM_HDRDGST_EN: | ||
| 1857 | len = sprintf(buf, "%d\n", conn->hdrdgst_en); | ||
| 1858 | break; | ||
| 1859 | case ISCSI_PARAM_DATADGST_EN: | ||
| 1860 | len = sprintf(buf, "%d\n", conn->datadgst_en); | ||
| 1861 | break; | ||
| 1862 | case ISCSI_PARAM_IFMARKER_EN: | ||
| 1863 | len = sprintf(buf, "%d\n", conn->ifmarker_en); | ||
| 1864 | break; | ||
| 1865 | case ISCSI_PARAM_OFMARKER_EN: | ||
| 1866 | len = sprintf(buf, "%d\n", conn->ofmarker_en); | ||
| 1867 | break; | ||
| 1868 | case ISCSI_PARAM_EXP_STATSN: | ||
| 1869 | len = sprintf(buf, "%u\n", conn->exp_statsn); | ||
| 1870 | break; | ||
| 1871 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
| 1872 | len = sprintf(buf, "%d\n", conn->persistent_port); | ||
| 1873 | break; | ||
| 1874 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
| 1875 | len = sprintf(buf, "%s\n", conn->persistent_address); | ||
| 1876 | break; | ||
| 1877 | default: | ||
| 1878 | return -ENOSYS; | ||
| 1879 | } | ||
| 1880 | |||
| 1881 | return len; | ||
| 1882 | } | ||
| 1883 | EXPORT_SYMBOL_GPL(iscsi_conn_get_param); | ||
| 1884 | |||
| 1700 | MODULE_AUTHOR("Mike Christie"); | 1885 | MODULE_AUTHOR("Mike Christie"); |
| 1701 | MODULE_DESCRIPTION("iSCSI library functions"); | 1886 | MODULE_DESCRIPTION("iSCSI library functions"); |
| 1702 | MODULE_LICENSE("GPL"); | 1887 | MODULE_LICENSE("GPL"); |
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 5a28d9bf8e4d..81755a3f7c68 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 e5c017ccda59..a8c9627a15c4 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 bd337a914298..bfb4f49e125d 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, IRQF_SHARED, "nsp32", data); |
| 2870 | IRQF_SHARED | IRQF_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 7ff5851c040b..0d4c04e1f3de 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 |= (IRQF_SHARED | IRQF_SAMPLE_RANDOM); | 1626 | link->irq.Attributes |= IRQF_SHARED; |
| 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/qla1280.c b/drivers/scsi/qla1280.c index b818b9bfe678..8953991462d7 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
| @@ -4209,7 +4209,7 @@ qla1280_setup(char *s) | |||
| 4209 | } | 4209 | } |
| 4210 | 4210 | ||
| 4211 | 4211 | ||
| 4212 | static int | 4212 | static int __init |
| 4213 | qla1280_get_token(char *str) | 4213 | qla1280_get_token(char *str) |
| 4214 | { | 4214 | { |
| 4215 | char *sep; | 4215 | char *sep; |
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 6734453ea28a..139ea0e27fd7 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..8311ac2b93a8 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
| @@ -31,13 +31,9 @@ extern void qla2x00_update_fw_options(struct scsi_qla_host *); | |||
| 31 | extern void qla24xx_update_fw_options(scsi_qla_host_t *); | 31 | extern void qla24xx_update_fw_options(scsi_qla_host_t *); |
| 32 | extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *); | 32 | extern int qla2x00_load_risc(struct scsi_qla_host *, uint32_t *); |
| 33 | extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *); | 33 | extern int qla24xx_load_risc(scsi_qla_host_t *, uint32_t *); |
| 34 | extern int qla24xx_load_risc_flash(scsi_qla_host_t *, uint32_t *); | ||
| 35 | |||
| 36 | extern fc_port_t *qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t); | ||
| 37 | 34 | ||
| 38 | extern int qla2x00_loop_resync(scsi_qla_host_t *); | 35 | extern int qla2x00_loop_resync(scsi_qla_host_t *); |
| 39 | 36 | ||
| 40 | extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *); | ||
| 41 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); | 37 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); |
| 42 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); | 38 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); |
| 43 | 39 | ||
| @@ -51,6 +47,8 @@ extern int qla2x00_abort_isp(scsi_qla_host_t *); | |||
| 51 | extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | 47 | 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 *); | 48 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); |
| 53 | 49 | ||
| 50 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); | ||
| 51 | |||
| 54 | /* | 52 | /* |
| 55 | * Global Data in qla_os.c source file. | 53 | * Global Data in qla_os.c source file. |
| 56 | */ | 54 | */ |
| @@ -61,6 +59,8 @@ extern int qlport_down_retry; | |||
| 61 | extern int ql2xplogiabsentdevice; | 59 | extern int ql2xplogiabsentdevice; |
| 62 | extern int ql2xloginretrycount; | 60 | extern int ql2xloginretrycount; |
| 63 | extern int ql2xfdmienable; | 61 | extern int ql2xfdmienable; |
| 62 | extern int ql2xallocfwdump; | ||
| 63 | extern int extended_error_logging; | ||
| 64 | 64 | ||
| 65 | extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); | 65 | extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *); |
| 66 | 66 | ||
| @@ -80,8 +80,6 @@ extern void qla2xxx_wake_dpc(scsi_qla_host_t *); | |||
| 80 | /* | 80 | /* |
| 81 | * Global Function Prototypes in qla_iocb.c source file. | 81 | * Global Function Prototypes in qla_iocb.c source file. |
| 82 | */ | 82 | */ |
| 83 | extern void qla2x00_isp_cmd(scsi_qla_host_t *); | ||
| 84 | |||
| 85 | extern uint16_t qla2x00_calc_iocbs_32(uint16_t); | 83 | extern uint16_t qla2x00_calc_iocbs_32(uint16_t); |
| 86 | extern uint16_t qla2x00_calc_iocbs_64(uint16_t); | 84 | extern uint16_t qla2x00_calc_iocbs_64(uint16_t); |
| 87 | extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); | 85 | extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); |
| @@ -204,6 +202,12 @@ qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | |||
| 204 | extern int | 202 | extern int |
| 205 | qla2x00_stop_firmware(scsi_qla_host_t *); | 203 | qla2x00_stop_firmware(scsi_qla_host_t *); |
| 206 | 204 | ||
| 205 | extern int | ||
| 206 | qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t); | ||
| 207 | |||
| 208 | extern int | ||
| 209 | qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); | ||
| 210 | |||
| 207 | /* | 211 | /* |
| 208 | * Global Function Prototypes in qla_isr.c source file. | 212 | * Global Function Prototypes in qla_isr.c source file. |
| 209 | */ | 213 | */ |
| @@ -254,9 +258,6 @@ extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, | |||
| 254 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); | 258 | extern void qla2100_fw_dump(scsi_qla_host_t *, int); |
| 255 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); | 259 | extern void qla2300_fw_dump(scsi_qla_host_t *, int); |
| 256 | extern void qla24xx_fw_dump(scsi_qla_host_t *, int); | 260 | 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 *); | 261 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
| 261 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 262 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
| 262 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); | 263 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); |
| @@ -280,13 +281,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 *); | 281 | extern int qla2x00_fdmi_register(scsi_qla_host_t *); |
| 281 | 282 | ||
| 282 | /* | 283 | /* |
| 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. | 284 | * Global Function Prototypes in qla_attr.c source file. |
| 291 | */ | 285 | */ |
| 292 | struct class_device_attribute; | 286 | struct class_device_attribute; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 3d4487eac9b7..9758dba95542 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -39,6 +39,8 @@ static int qla2x00_fabric_dev_login(scsi_qla_host_t *, fc_port_t *, | |||
| 39 | 39 | ||
| 40 | static int qla2x00_restart_isp(scsi_qla_host_t *); | 40 | static int qla2x00_restart_isp(scsi_qla_host_t *); |
| 41 | 41 | ||
| 42 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); | ||
| 43 | |||
| 42 | /****************************************************************************/ | 44 | /****************************************************************************/ |
| 43 | /* QLogic ISP2x00 Hardware Support Functions. */ | 45 | /* QLogic ISP2x00 Hardware Support Functions. */ |
| 44 | /****************************************************************************/ | 46 | /****************************************************************************/ |
| @@ -89,6 +91,17 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
| 89 | 91 | ||
| 90 | ha->isp_ops.nvram_config(ha); | 92 | ha->isp_ops.nvram_config(ha); |
| 91 | 93 | ||
| 94 | if (ha->flags.disable_serdes) { | ||
| 95 | /* Mask HBA via NVRAM settings? */ | ||
| 96 | qla_printk(KERN_INFO, ha, "Masking HBA WWPN " | ||
| 97 | "%02x%02x%02x%02x%02x%02x%02x%02x (via NVRAM).\n", | ||
| 98 | ha->port_name[0], ha->port_name[1], | ||
| 99 | ha->port_name[2], ha->port_name[3], | ||
| 100 | ha->port_name[4], ha->port_name[5], | ||
| 101 | ha->port_name[6], ha->port_name[7]); | ||
| 102 | return QLA_FUNCTION_FAILED; | ||
| 103 | } | ||
| 104 | |||
| 92 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); | 105 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); |
| 93 | 106 | ||
| 94 | retry = 10; | 107 | retry = 10; |
| @@ -770,29 +783,104 @@ qla24xx_chip_diag(scsi_qla_host_t *ha) | |||
| 770 | return rval; | 783 | return rval; |
| 771 | } | 784 | } |
| 772 | 785 | ||
| 773 | static void | 786 | void |
| 774 | qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | 787 | qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) |
| 775 | { | 788 | { |
| 776 | uint32_t dump_size = 0; | 789 | int rval; |
| 790 | uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size, | ||
| 791 | eft_size; | ||
| 792 | dma_addr_t eft_dma; | ||
| 793 | void *eft; | ||
| 794 | |||
| 795 | if (ha->fw_dump) { | ||
| 796 | qla_printk(KERN_WARNING, ha, | ||
| 797 | "Firmware dump previously allocated.\n"); | ||
| 798 | return; | ||
| 799 | } | ||
| 777 | 800 | ||
| 778 | ha->fw_dumped = 0; | 801 | ha->fw_dumped = 0; |
| 802 | fixed_size = mem_size = eft_size = 0; | ||
| 779 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | 803 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { |
| 780 | dump_size = sizeof(struct qla2100_fw_dump); | 804 | fixed_size = sizeof(struct qla2100_fw_dump); |
| 781 | } else if (IS_QLA23XX(ha)) { | 805 | } else if (IS_QLA23XX(ha)) { |
| 782 | dump_size = sizeof(struct qla2300_fw_dump); | 806 | fixed_size = offsetof(struct qla2300_fw_dump, data_ram); |
| 783 | dump_size += (ha->fw_memory_size - 0x11000) * sizeof(uint16_t); | 807 | mem_size = (ha->fw_memory_size - 0x11000 + 1) * |
| 784 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 808 | sizeof(uint16_t); |
| 785 | dump_size = sizeof(struct qla24xx_fw_dump); | 809 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { |
| 786 | dump_size += (ha->fw_memory_size - 0x100000) * sizeof(uint32_t); | 810 | fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem); |
| 811 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | ||
| 812 | sizeof(uint32_t); | ||
| 813 | |||
| 814 | /* Allocate memory for Extended Trace Buffer. */ | ||
| 815 | eft = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &eft_dma, | ||
| 816 | GFP_KERNEL); | ||
| 817 | if (!eft) { | ||
| 818 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | ||
| 819 | "(%d KB) for EFT.\n", EFT_SIZE / 1024); | ||
| 820 | goto cont_alloc; | ||
| 821 | } | ||
| 822 | |||
| 823 | rval = qla2x00_trace_control(ha, TC_ENABLE, eft_dma, | ||
| 824 | EFT_NUM_BUFFERS); | ||
| 825 | if (rval) { | ||
| 826 | qla_printk(KERN_WARNING, ha, "Unable to initialize " | ||
| 827 | "EFT (%d).\n", rval); | ||
| 828 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, eft, | ||
| 829 | eft_dma); | ||
| 830 | goto cont_alloc; | ||
| 831 | } | ||
| 832 | |||
| 833 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n", | ||
| 834 | EFT_SIZE / 1024); | ||
| 835 | |||
| 836 | eft_size = EFT_SIZE; | ||
| 837 | memset(eft, 0, eft_size); | ||
| 838 | ha->eft_dma = eft_dma; | ||
| 839 | ha->eft = eft; | ||
| 787 | } | 840 | } |
| 841 | cont_alloc: | ||
| 842 | req_q_size = ha->request_q_length * sizeof(request_t); | ||
| 843 | rsp_q_size = ha->response_q_length * sizeof(response_t); | ||
| 844 | |||
| 845 | dump_size = offsetof(struct qla2xxx_fw_dump, isp); | ||
| 846 | dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + | ||
| 847 | eft_size; | ||
| 788 | 848 | ||
| 789 | ha->fw_dump = vmalloc(dump_size); | 849 | ha->fw_dump = vmalloc(dump_size); |
| 790 | if (ha->fw_dump) | 850 | 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 " | 851 | qla_printk(KERN_WARNING, ha, "Unable to allocate (%d KB) for " |
| 795 | "firmware dump!!!\n", dump_size / 1024); | 852 | "firmware dump!!!\n", dump_size / 1024); |
| 853 | |||
| 854 | if (ha->eft) { | ||
| 855 | dma_free_coherent(&ha->pdev->dev, eft_size, ha->eft, | ||
| 856 | ha->eft_dma); | ||
| 857 | ha->eft = NULL; | ||
| 858 | ha->eft_dma = 0; | ||
| 859 | } | ||
| 860 | return; | ||
| 861 | } | ||
| 862 | |||
| 863 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for firmware dump...\n", | ||
| 864 | dump_size / 1024); | ||
| 865 | |||
| 866 | ha->fw_dump_len = dump_size; | ||
| 867 | ha->fw_dump->signature[0] = 'Q'; | ||
| 868 | ha->fw_dump->signature[1] = 'L'; | ||
| 869 | ha->fw_dump->signature[2] = 'G'; | ||
| 870 | ha->fw_dump->signature[3] = 'C'; | ||
| 871 | ha->fw_dump->version = __constant_htonl(1); | ||
| 872 | |||
| 873 | ha->fw_dump->fixed_size = htonl(fixed_size); | ||
| 874 | ha->fw_dump->mem_size = htonl(mem_size); | ||
| 875 | ha->fw_dump->req_q_size = htonl(req_q_size); | ||
| 876 | ha->fw_dump->rsp_q_size = htonl(rsp_q_size); | ||
| 877 | |||
| 878 | ha->fw_dump->eft_size = htonl(eft_size); | ||
| 879 | ha->fw_dump->eft_addr_l = htonl(LSD(ha->eft_dma)); | ||
| 880 | ha->fw_dump->eft_addr_h = htonl(MSD(ha->eft_dma)); | ||
| 881 | |||
| 882 | ha->fw_dump->header_size = | ||
| 883 | htonl(offsetof(struct qla2xxx_fw_dump, isp)); | ||
| 796 | } | 884 | } |
| 797 | 885 | ||
| 798 | /** | 886 | /** |
| @@ -810,8 +898,6 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha) | |||
| 810 | dma_addr_t request_dma; | 898 | dma_addr_t request_dma; |
| 811 | request_t *request_ring; | 899 | request_t *request_ring; |
| 812 | 900 | ||
| 813 | qla2x00_alloc_fw_dump(ha); | ||
| 814 | |||
| 815 | /* Valid only on recent ISPs. */ | 901 | /* Valid only on recent ISPs. */ |
| 816 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) | 902 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) |
| 817 | return; | 903 | return; |
| @@ -883,6 +969,9 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) | |||
| 883 | &ha->fw_subminor_version, | 969 | &ha->fw_subminor_version, |
| 884 | &ha->fw_attributes, &ha->fw_memory_size); | 970 | &ha->fw_attributes, &ha->fw_memory_size); |
| 885 | qla2x00_resize_request_q(ha); | 971 | qla2x00_resize_request_q(ha); |
| 972 | |||
| 973 | if (ql2xallocfwdump) | ||
| 974 | qla2x00_alloc_fw_dump(ha); | ||
| 886 | } | 975 | } |
| 887 | } else { | 976 | } else { |
| 888 | DEBUG2(printk(KERN_INFO | 977 | DEBUG2(printk(KERN_INFO |
| @@ -1186,8 +1275,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
| 1186 | rval = QLA_FUNCTION_FAILED; | 1275 | rval = QLA_FUNCTION_FAILED; |
| 1187 | 1276 | ||
| 1188 | if (atomic_read(&ha->loop_down_timer) && | 1277 | if (atomic_read(&ha->loop_down_timer) && |
| 1189 | (fw_state >= FSTATE_LOSS_OF_SYNC || | 1278 | fw_state != FSTATE_READY) { |
| 1190 | fw_state == FSTATE_WAIT_AL_PA)) { | ||
| 1191 | /* Loop down. Timeout on min_wait for states | 1279 | /* Loop down. Timeout on min_wait for states |
| 1192 | * other than Wait for Login. | 1280 | * other than Wait for Login. |
| 1193 | */ | 1281 | */ |
| @@ -1555,6 +1643,8 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
| 1555 | /* | 1643 | /* |
| 1556 | * Set host adapter parameters. | 1644 | * Set host adapter parameters. |
| 1557 | */ | 1645 | */ |
| 1646 | if (nv->host_p[0] & BIT_7) | ||
| 1647 | extended_error_logging = 1; | ||
| 1558 | ha->flags.disable_risc_code_load = ((nv->host_p[0] & BIT_4) ? 1 : 0); | 1648 | 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. */ | 1649 | /* Always load RISC code on non ISP2[12]00 chips. */ |
| 1560 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) | 1650 | if (!IS_QLA2100(ha) && !IS_QLA2200(ha)) |
| @@ -1563,6 +1653,7 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
| 1563 | ha->flags.enable_lip_full_login = ((nv->host_p[1] & BIT_2) ? 1 : 0); | 1653 | 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); | 1654 | 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; | 1655 | ha->flags.enable_led_scheme = (nv->special_options[1] & BIT_4) ? 1 : 0; |
| 1656 | ha->flags.disable_serdes = 0; | ||
| 1566 | 1657 | ||
| 1567 | ha->operating_mode = | 1658 | ha->operating_mode = |
| 1568 | (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4; | 1659 | (icb->add_firmware_options[0] & (BIT_6 | BIT_5 | BIT_4)) >> 4; |
| @@ -1701,7 +1792,7 @@ qla2x00_rport_del(void *data) | |||
| 1701 | * | 1792 | * |
| 1702 | * Returns a pointer to the allocated fcport, or NULL, if none available. | 1793 | * Returns a pointer to the allocated fcport, or NULL, if none available. |
| 1703 | */ | 1794 | */ |
| 1704 | fc_port_t * | 1795 | static fc_port_t * |
| 1705 | qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) | 1796 | qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) |
| 1706 | { | 1797 | { |
| 1707 | fc_port_t *fcport; | 1798 | fc_port_t *fcport; |
| @@ -2497,7 +2588,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
| 2497 | * Context: | 2588 | * Context: |
| 2498 | * Kernel context. | 2589 | * Kernel context. |
| 2499 | */ | 2590 | */ |
| 2500 | int | 2591 | static int |
| 2501 | qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev) | 2592 | qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev) |
| 2502 | { | 2593 | { |
| 2503 | int rval; | 2594 | int rval; |
| @@ -3048,14 +3139,14 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
| 3048 | ha->isp_abort_cnt--; | 3139 | ha->isp_abort_cnt--; |
| 3049 | DEBUG(printk("qla%ld: ISP abort - " | 3140 | DEBUG(printk("qla%ld: ISP abort - " |
| 3050 | "retry remaining %d\n", | 3141 | "retry remaining %d\n", |
| 3051 | ha->host_no, ha->isp_abort_cnt);) | 3142 | ha->host_no, ha->isp_abort_cnt)); |
| 3052 | status = 1; | 3143 | status = 1; |
| 3053 | } | 3144 | } |
| 3054 | } else { | 3145 | } else { |
| 3055 | ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT; | 3146 | ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT; |
| 3056 | DEBUG(printk("qla2x00(%ld): ISP error recovery " | 3147 | DEBUG(printk("qla2x00(%ld): ISP error recovery " |
| 3057 | "- retrying (%d) more times\n", | 3148 | "- retrying (%d) more times\n", |
| 3058 | ha->host_no, ha->isp_abort_cnt);) | 3149 | ha->host_no, ha->isp_abort_cnt)); |
| 3059 | set_bit(ISP_ABORT_RETRY, &ha->dpc_flags); | 3150 | set_bit(ISP_ABORT_RETRY, &ha->dpc_flags); |
| 3060 | status = 1; | 3151 | status = 1; |
| 3061 | } | 3152 | } |
| @@ -3069,7 +3160,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
| 3069 | } else { | 3160 | } else { |
| 3070 | DEBUG(printk(KERN_INFO | 3161 | DEBUG(printk(KERN_INFO |
| 3071 | "qla2x00_abort_isp(%ld): exiting.\n", | 3162 | "qla2x00_abort_isp(%ld): exiting.\n", |
| 3072 | ha->host_no);) | 3163 | ha->host_no)); |
| 3073 | } | 3164 | } |
| 3074 | 3165 | ||
| 3075 | return(status); | 3166 | return(status); |
| @@ -3145,7 +3236,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) | |||
| 3145 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 3236 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
| 3146 | if (!(status = qla2x00_fw_ready(ha))) { | 3237 | if (!(status = qla2x00_fw_ready(ha))) { |
| 3147 | DEBUG(printk("%s(): Start configure loop, " | 3238 | DEBUG(printk("%s(): Start configure loop, " |
| 3148 | "status = %d\n", __func__, status);) | 3239 | "status = %d\n", __func__, status)); |
| 3149 | 3240 | ||
| 3150 | /* Issue a marker after FW becomes ready. */ | 3241 | /* Issue a marker after FW becomes ready. */ |
| 3151 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | 3242 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); |
| @@ -3169,7 +3260,7 @@ qla2x00_restart_isp(scsi_qla_host_t *ha) | |||
| 3169 | 3260 | ||
| 3170 | DEBUG(printk("%s(): Configure loop done, status = 0x%x\n", | 3261 | DEBUG(printk("%s(): Configure loop done, status = 0x%x\n", |
| 3171 | __func__, | 3262 | __func__, |
| 3172 | status);) | 3263 | status)); |
| 3173 | } | 3264 | } |
| 3174 | return (status); | 3265 | return (status); |
| 3175 | } | 3266 | } |
| @@ -3289,7 +3380,6 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
| 3289 | nv->node_name[6] = 0x55; | 3380 | nv->node_name[6] = 0x55; |
| 3290 | nv->node_name[7] = 0x86; | 3381 | nv->node_name[7] = 0x86; |
| 3291 | nv->login_retry_count = __constant_cpu_to_le16(8); | 3382 | 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); | 3383 | nv->interrupt_delay_timer = __constant_cpu_to_le16(0); |
| 3294 | nv->login_timeout = __constant_cpu_to_le16(0); | 3384 | nv->login_timeout = __constant_cpu_to_le16(0); |
| 3295 | nv->firmware_options_1 = | 3385 | nv->firmware_options_1 = |
| @@ -3318,7 +3408,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
| 3318 | *dptr1++ = *dptr2++; | 3408 | *dptr1++ = *dptr2++; |
| 3319 | 3409 | ||
| 3320 | icb->login_retry_count = nv->login_retry_count; | 3410 | icb->login_retry_count = nv->login_retry_count; |
| 3321 | icb->link_down_timeout = nv->link_down_timeout; | 3411 | icb->link_down_on_nos = nv->link_down_on_nos; |
| 3322 | 3412 | ||
| 3323 | /* Copy 2nd segment. */ | 3413 | /* Copy 2nd segment. */ |
| 3324 | dptr1 = (uint8_t *)&icb->interrupt_delay_timer; | 3414 | dptr1 = (uint8_t *)&icb->interrupt_delay_timer; |
| @@ -3373,6 +3463,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
| 3373 | ha->flags.enable_lip_full_login = 1; | 3463 | ha->flags.enable_lip_full_login = 1; |
| 3374 | ha->flags.enable_target_reset = 1; | 3464 | ha->flags.enable_target_reset = 1; |
| 3375 | ha->flags.enable_led_scheme = 0; | 3465 | ha->flags.enable_led_scheme = 0; |
| 3466 | ha->flags.disable_serdes = le32_to_cpu(nv->host_p) & BIT_5 ? 1: 0; | ||
| 3376 | 3467 | ||
| 3377 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & | 3468 | ha->operating_mode = (le32_to_cpu(icb->firmware_options_2) & |
| 3378 | (BIT_6 | BIT_5 | BIT_4)) >> 4; | 3469 | (BIT_6 | BIT_5 | BIT_4)) >> 4; |
| @@ -3472,7 +3563,7 @@ qla24xx_nvram_config(scsi_qla_host_t *ha) | |||
| 3472 | return (rval); | 3563 | return (rval); |
| 3473 | } | 3564 | } |
| 3474 | 3565 | ||
| 3475 | int | 3566 | static int |
| 3476 | qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) | 3567 | qla24xx_load_risc_flash(scsi_qla_host_t *ha, uint32_t *srisc_addr) |
| 3477 | { | 3568 | { |
| 3478 | int rval; | 3569 | int rval; |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 8c769cfaa14c..2b60a27eff0b 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
| @@ -15,6 +15,7 @@ static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd); | |||
| 15 | static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *); | 15 | static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *); |
| 16 | static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *); | 16 | static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *); |
| 17 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); | 17 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); |
| 18 | static void qla2x00_isp_cmd(scsi_qla_host_t *ha); | ||
| 18 | 19 | ||
| 19 | /** | 20 | /** |
| 20 | * qla2x00_get_cmd_direction() - Determine control_flag data direction. | 21 | * qla2x00_get_cmd_direction() - Determine control_flag data direction. |
| @@ -574,7 +575,7 @@ qla2x00_req_pkt(scsi_qla_host_t *ha) | |||
| 574 | * | 575 | * |
| 575 | * Note: The caller must hold the hardware lock before calling this routine. | 576 | * Note: The caller must hold the hardware lock before calling this routine. |
| 576 | */ | 577 | */ |
| 577 | void | 578 | static void |
| 578 | qla2x00_isp_cmd(scsi_qla_host_t *ha) | 579 | qla2x00_isp_cmd(scsi_qla_host_t *ha) |
| 579 | { | 580 | { |
| 580 | device_reg_t __iomem *reg = ha->iobase; | 581 | device_reg_t __iomem *reg = ha->iobase; |
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 93062593ebe7..ec7ebb6037e6 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -39,14 +39,14 @@ MODULE_PARM_DESC(ql2xlogintimeout, | |||
| 39 | int qlport_down_retry = 30; | 39 | int qlport_down_retry = 30; |
| 40 | module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR); | 40 | module_param(qlport_down_retry, int, S_IRUGO|S_IRUSR); |
| 41 | MODULE_PARM_DESC(qlport_down_retry, | 41 | MODULE_PARM_DESC(qlport_down_retry, |
| 42 | "Maximum number of command retries to a port that returns" | 42 | "Maximum number of command retries to a port that returns " |
| 43 | "a PORT-DOWN status."); | 43 | "a PORT-DOWN status."); |
| 44 | 44 | ||
| 45 | int ql2xplogiabsentdevice; | 45 | int ql2xplogiabsentdevice; |
| 46 | module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR); | 46 | module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR); |
| 47 | MODULE_PARM_DESC(ql2xplogiabsentdevice, | 47 | MODULE_PARM_DESC(ql2xplogiabsentdevice, |
| 48 | "Option to enable PLOGI to devices that are not present after " | 48 | "Option to enable PLOGI to devices that are not present after " |
| 49 | "a Fabric scan. This is needed for several broken switches." | 49 | "a Fabric scan. This is needed for several broken switches. " |
| 50 | "Default is 0 - no PLOGI. 1 - perfom PLOGI."); | 50 | "Default is 0 - no PLOGI. 1 - perfom PLOGI."); |
| 51 | 51 | ||
| 52 | int ql2xloginretrycount = 0; | 52 | int ql2xloginretrycount = 0; |
| @@ -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 e1168860045c..9c63b00773c4 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
| @@ -50,18 +50,22 @@ | |||
| 50 | #include "scsi_logging.h" | 50 | #include "scsi_logging.h" |
| 51 | #include "scsi_debug.h" | 51 | #include "scsi_debug.h" |
| 52 | 52 | ||
| 53 | #define SCSI_DEBUG_VERSION "1.75" | 53 | #define SCSI_DEBUG_VERSION "1.79" |
| 54 | static const char * scsi_debug_version_date = "20050113"; | 54 | static const char * scsi_debug_version_date = "20060604"; |
| 55 | 55 | ||
| 56 | /* Additional Sense Code (ASC) used */ | 56 | /* Additional Sense Code (ASC) used */ |
| 57 | #define NO_ADDED_SENSE 0x0 | 57 | #define NO_ADDITIONAL_SENSE 0x0 |
| 58 | #define LOGICAL_UNIT_NOT_READY 0x4 | ||
| 58 | #define UNRECOVERED_READ_ERR 0x11 | 59 | #define UNRECOVERED_READ_ERR 0x11 |
| 60 | #define PARAMETER_LIST_LENGTH_ERR 0x1a | ||
| 59 | #define INVALID_OPCODE 0x20 | 61 | #define INVALID_OPCODE 0x20 |
| 60 | #define ADDR_OUT_OF_RANGE 0x21 | 62 | #define ADDR_OUT_OF_RANGE 0x21 |
| 61 | #define INVALID_FIELD_IN_CDB 0x24 | 63 | #define INVALID_FIELD_IN_CDB 0x24 |
| 64 | #define INVALID_FIELD_IN_PARAM_LIST 0x26 | ||
| 62 | #define POWERON_RESET 0x29 | 65 | #define POWERON_RESET 0x29 |
| 63 | #define SAVING_PARAMS_UNSUP 0x39 | 66 | #define SAVING_PARAMS_UNSUP 0x39 |
| 64 | #define THRESHHOLD_EXCEEDED 0x5d | 67 | #define THRESHOLD_EXCEEDED 0x5d |
| 68 | #define LOW_POWER_COND_ON 0x5e | ||
| 65 | 69 | ||
| 66 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ | 70 | #define SDEBUG_TAGGED_QUEUING 0 /* 0 | MSG_SIMPLE_TAG | MSG_ORDERED_TAG */ |
| 67 | 71 | ||
| @@ -80,6 +84,8 @@ static const char * scsi_debug_version_date = "20050113"; | |||
| 80 | #define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */ | 84 | #define DEF_SCSI_LEVEL 5 /* INQUIRY, byte2 [5->SPC-3] */ |
| 81 | #define DEF_PTYPE 0 | 85 | #define DEF_PTYPE 0 |
| 82 | #define DEF_D_SENSE 0 | 86 | #define DEF_D_SENSE 0 |
| 87 | #define DEF_NO_LUN_0 0 | ||
| 88 | #define DEF_VIRTUAL_GB 0 | ||
| 83 | 89 | ||
| 84 | /* bit mask values for scsi_debug_opts */ | 90 | /* bit mask values for scsi_debug_opts */ |
| 85 | #define SCSI_DEBUG_OPT_NOISE 1 | 91 | #define SCSI_DEBUG_OPT_NOISE 1 |
| @@ -106,6 +112,7 @@ static const char * scsi_debug_version_date = "20050113"; | |||
| 106 | /* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) | 112 | /* If REPORT LUNS has luns >= 256 it can choose "flat space" (value 1) |
| 107 | * or "peripheral device" addressing (value 0) */ | 113 | * or "peripheral device" addressing (value 0) */ |
| 108 | #define SAM2_LUN_ADDRESS_METHOD 0 | 114 | #define SAM2_LUN_ADDRESS_METHOD 0 |
| 115 | #define SAM2_WLUN_REPORT_LUNS 0xc101 | ||
| 109 | 116 | ||
| 110 | static int scsi_debug_add_host = DEF_NUM_HOST; | 117 | static int scsi_debug_add_host = DEF_NUM_HOST; |
| 111 | static int scsi_debug_delay = DEF_DELAY; | 118 | static int scsi_debug_delay = DEF_DELAY; |
| @@ -118,13 +125,16 @@ static int scsi_debug_opts = DEF_OPTS; | |||
| 118 | static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; | 125 | static int scsi_debug_scsi_level = DEF_SCSI_LEVEL; |
| 119 | static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */ | 126 | static int scsi_debug_ptype = DEF_PTYPE; /* SCSI peripheral type (0==disk) */ |
| 120 | static int scsi_debug_dsense = DEF_D_SENSE; | 127 | static int scsi_debug_dsense = DEF_D_SENSE; |
| 128 | static int scsi_debug_no_lun_0 = DEF_NO_LUN_0; | ||
| 129 | static int scsi_debug_virtual_gb = DEF_VIRTUAL_GB; | ||
| 121 | 130 | ||
| 122 | static int scsi_debug_cmnd_count = 0; | 131 | static int scsi_debug_cmnd_count = 0; |
| 123 | 132 | ||
| 124 | #define DEV_READONLY(TGT) (0) | 133 | #define DEV_READONLY(TGT) (0) |
| 125 | #define DEV_REMOVEABLE(TGT) (0) | 134 | #define DEV_REMOVEABLE(TGT) (0) |
| 126 | 135 | ||
| 127 | static unsigned long sdebug_store_size; /* in bytes */ | 136 | static unsigned int sdebug_store_size; /* in bytes */ |
| 137 | static unsigned int sdebug_store_sectors; | ||
| 128 | static sector_t sdebug_capacity; /* in sectors */ | 138 | static sector_t sdebug_capacity; /* in sectors */ |
| 129 | 139 | ||
| 130 | /* old BIOS stuff, kernel may get rid of them but some mode sense pages | 140 | /* old BIOS stuff, kernel may get rid of them but some mode sense pages |
| @@ -149,7 +159,9 @@ struct sdebug_dev_info { | |||
| 149 | unsigned int target; | 159 | unsigned int target; |
| 150 | unsigned int lun; | 160 | unsigned int lun; |
| 151 | struct sdebug_host_info *sdbg_host; | 161 | struct sdebug_host_info *sdbg_host; |
| 162 | unsigned int wlun; | ||
| 152 | char reset; | 163 | char reset; |
| 164 | char stopped; | ||
| 153 | char used; | 165 | char used; |
| 154 | }; | 166 | }; |
| 155 | 167 | ||
| @@ -193,11 +205,11 @@ static struct scsi_host_template sdebug_driver_template = { | |||
| 193 | .bios_param = scsi_debug_biosparam, | 205 | .bios_param = scsi_debug_biosparam, |
| 194 | .can_queue = SCSI_DEBUG_CANQUEUE, | 206 | .can_queue = SCSI_DEBUG_CANQUEUE, |
| 195 | .this_id = 7, | 207 | .this_id = 7, |
| 196 | .sg_tablesize = 64, | 208 | .sg_tablesize = 256, |
| 197 | .cmd_per_lun = 3, | 209 | .cmd_per_lun = 16, |
| 198 | .max_sectors = 4096, | 210 | .max_sectors = 0xffff, |
| 199 | .unchecked_isa_dma = 0, | 211 | .unchecked_isa_dma = 0, |
| 200 | .use_clustering = DISABLE_CLUSTERING, | 212 | .use_clustering = ENABLE_CLUSTERING, |
| 201 | .module = THIS_MODULE, | 213 | .module = THIS_MODULE, |
| 202 | }; | 214 | }; |
| 203 | 215 | ||
| @@ -225,19 +237,32 @@ static struct device_driver sdebug_driverfs_driver = { | |||
| 225 | static const int check_condition_result = | 237 | static const int check_condition_result = |
| 226 | (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | 238 | (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; |
| 227 | 239 | ||
| 240 | static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | ||
| 241 | 0, 0, 0x2, 0x4b}; | ||
| 242 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | ||
| 243 | 0, 0, 0x0, 0x0}; | ||
| 244 | |||
| 228 | /* function declarations */ | 245 | /* function declarations */ |
| 229 | static int resp_inquiry(struct scsi_cmnd * SCpnt, int target, | 246 | static int resp_inquiry(struct scsi_cmnd * SCpnt, int target, |
| 230 | struct sdebug_dev_info * devip); | 247 | struct sdebug_dev_info * devip); |
| 231 | static int resp_requests(struct scsi_cmnd * SCpnt, | 248 | static int resp_requests(struct scsi_cmnd * SCpnt, |
| 232 | struct sdebug_dev_info * devip); | 249 | struct sdebug_dev_info * devip); |
| 250 | static int resp_start_stop(struct scsi_cmnd * scp, | ||
| 251 | struct sdebug_dev_info * devip); | ||
| 233 | static int resp_readcap(struct scsi_cmnd * SCpnt, | 252 | static int resp_readcap(struct scsi_cmnd * SCpnt, |
| 234 | struct sdebug_dev_info * devip); | 253 | struct sdebug_dev_info * devip); |
| 235 | static int resp_mode_sense(struct scsi_cmnd * SCpnt, int target, | 254 | static int resp_readcap16(struct scsi_cmnd * SCpnt, |
| 255 | struct sdebug_dev_info * devip); | ||
| 256 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, | ||
| 236 | struct sdebug_dev_info * devip); | 257 | struct sdebug_dev_info * devip); |
| 237 | static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 258 | static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, |
| 238 | int num, struct sdebug_dev_info * devip); | 259 | struct sdebug_dev_info * devip); |
| 239 | static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 260 | static int resp_log_sense(struct scsi_cmnd * scp, |
| 240 | int num, struct sdebug_dev_info * devip); | 261 | struct sdebug_dev_info * devip); |
| 262 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
| 263 | unsigned int num, struct sdebug_dev_info * devip); | ||
| 264 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
| 265 | unsigned int num, struct sdebug_dev_info * devip); | ||
| 241 | static int resp_report_luns(struct scsi_cmnd * SCpnt, | 266 | static int resp_report_luns(struct scsi_cmnd * SCpnt, |
| 242 | struct sdebug_dev_info * devip); | 267 | struct sdebug_dev_info * devip); |
| 243 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | 268 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, |
| @@ -248,8 +273,8 @@ static void timer_intr_handler(unsigned long); | |||
| 248 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); | 273 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); |
| 249 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, | 274 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, |
| 250 | int asc, int asq); | 275 | int asc, int asq); |
| 251 | static int check_reset(struct scsi_cmnd * SCpnt, | 276 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, |
| 252 | struct sdebug_dev_info * devip); | 277 | struct sdebug_dev_info * devip); |
| 253 | static int schedule_resp(struct scsi_cmnd * cmnd, | 278 | static int schedule_resp(struct scsi_cmnd * cmnd, |
| 254 | struct sdebug_dev_info * devip, | 279 | struct sdebug_dev_info * devip, |
| 255 | done_funct_t done, int scsi_result, int delta_jiff); | 280 | done_funct_t done, int scsi_result, int delta_jiff); |
| @@ -257,8 +282,10 @@ static void __init sdebug_build_parts(unsigned char * ramp); | |||
| 257 | static void __init init_all_queued(void); | 282 | static void __init init_all_queued(void); |
| 258 | static void stop_all_queued(void); | 283 | static void stop_all_queued(void); |
| 259 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); | 284 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); |
| 260 | static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | 285 | static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, |
| 261 | const char * dev_id_str, int dev_id_str_len); | 286 | int dev_id_num, const char * dev_id_str, |
| 287 | int dev_id_str_len); | ||
| 288 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); | ||
| 262 | static void do_create_driverfs_files(void); | 289 | static void do_create_driverfs_files(void); |
| 263 | static void do_remove_driverfs_files(void); | 290 | static void do_remove_driverfs_files(void); |
| 264 | 291 | ||
| @@ -274,18 +301,22 @@ static | |||
| 274 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | 301 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) |
| 275 | { | 302 | { |
| 276 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; | 303 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; |
| 277 | int block, upper_blk, num, k; | 304 | int len, k, j; |
| 305 | unsigned int num; | ||
| 306 | unsigned long long lba; | ||
| 278 | int errsts = 0; | 307 | int errsts = 0; |
| 279 | int target = scmd_id(SCpnt); | 308 | int target = SCpnt->device->id; |
| 280 | struct sdebug_dev_info * devip = NULL; | 309 | struct sdebug_dev_info * devip = NULL; |
| 281 | int inj_recovered = 0; | 310 | int inj_recovered = 0; |
| 311 | int delay_override = 0; | ||
| 282 | 312 | ||
| 283 | if (done == NULL) | 313 | if (done == NULL) |
| 284 | return 0; /* assume mid level reprocessing command */ | 314 | return 0; /* assume mid level reprocessing command */ |
| 285 | 315 | ||
| 316 | SCpnt->resid = 0; | ||
| 286 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { | 317 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { |
| 287 | printk(KERN_INFO "scsi_debug: cmd "); | 318 | printk(KERN_INFO "scsi_debug: cmd "); |
| 288 | for (k = 0, num = SCpnt->cmd_len; k < num; ++k) | 319 | for (k = 0, len = SCpnt->cmd_len; k < len; ++k) |
| 289 | printk("%02x ", (int)cmd[k]); | 320 | printk("%02x ", (int)cmd[k]); |
| 290 | printk("\n"); | 321 | printk("\n"); |
| 291 | } | 322 | } |
| @@ -296,7 +327,8 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
| 296 | DID_NO_CONNECT << 16, 0); | 327 | DID_NO_CONNECT << 16, 0); |
| 297 | } | 328 | } |
| 298 | 329 | ||
| 299 | if (SCpnt->device->lun >= scsi_debug_max_luns) | 330 | if ((SCpnt->device->lun >= scsi_debug_max_luns) && |
| 331 | (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) | ||
| 300 | return schedule_resp(SCpnt, NULL, done, | 332 | return schedule_resp(SCpnt, NULL, done, |
| 301 | DID_NO_CONNECT << 16, 0); | 333 | DID_NO_CONNECT << 16, 0); |
| 302 | devip = devInfoReg(SCpnt->device); | 334 | devip = devInfoReg(SCpnt->device); |
| @@ -315,118 +347,150 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
| 315 | inj_recovered = 1; /* to reads and writes below */ | 347 | inj_recovered = 1; /* to reads and writes below */ |
| 316 | } | 348 | } |
| 317 | 349 | ||
| 350 | if (devip->wlun) { | ||
| 351 | switch (*cmd) { | ||
| 352 | case INQUIRY: | ||
| 353 | case REQUEST_SENSE: | ||
| 354 | case TEST_UNIT_READY: | ||
| 355 | case REPORT_LUNS: | ||
| 356 | break; /* only allowable wlun commands */ | ||
| 357 | default: | ||
| 358 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
| 359 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x " | ||
| 360 | "not supported for wlun\n", *cmd); | ||
| 361 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 362 | INVALID_OPCODE, 0); | ||
| 363 | errsts = check_condition_result; | ||
| 364 | return schedule_resp(SCpnt, devip, done, errsts, | ||
| 365 | 0); | ||
| 366 | } | ||
| 367 | } | ||
| 368 | |||
| 318 | switch (*cmd) { | 369 | switch (*cmd) { |
| 319 | case INQUIRY: /* mandatory, ignore unit attention */ | 370 | case INQUIRY: /* mandatory, ignore unit attention */ |
| 371 | delay_override = 1; | ||
| 320 | errsts = resp_inquiry(SCpnt, target, devip); | 372 | errsts = resp_inquiry(SCpnt, target, devip); |
| 321 | break; | 373 | break; |
| 322 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ | 374 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ |
| 375 | delay_override = 1; | ||
| 323 | errsts = resp_requests(SCpnt, devip); | 376 | errsts = resp_requests(SCpnt, devip); |
| 324 | break; | 377 | break; |
| 325 | case REZERO_UNIT: /* actually this is REWIND for SSC */ | 378 | case REZERO_UNIT: /* actually this is REWIND for SSC */ |
| 326 | case START_STOP: | 379 | case START_STOP: |
| 327 | errsts = check_reset(SCpnt, devip); | 380 | errsts = resp_start_stop(SCpnt, devip); |
| 328 | break; | 381 | break; |
| 329 | case ALLOW_MEDIUM_REMOVAL: | 382 | case ALLOW_MEDIUM_REMOVAL: |
| 330 | if ((errsts = check_reset(SCpnt, devip))) | 383 | if ((errsts = check_readiness(SCpnt, 1, devip))) |
| 331 | break; | 384 | break; |
| 332 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 385 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
| 333 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", | 386 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", |
| 334 | cmd[4] ? "inhibited" : "enabled"); | 387 | cmd[4] ? "inhibited" : "enabled"); |
| 335 | break; | 388 | break; |
| 336 | case SEND_DIAGNOSTIC: /* mandatory */ | 389 | case SEND_DIAGNOSTIC: /* mandatory */ |
| 337 | errsts = check_reset(SCpnt, devip); | 390 | errsts = check_readiness(SCpnt, 1, devip); |
| 338 | break; | 391 | break; |
| 339 | case TEST_UNIT_READY: /* mandatory */ | 392 | case TEST_UNIT_READY: /* mandatory */ |
| 340 | errsts = check_reset(SCpnt, devip); | 393 | delay_override = 1; |
| 394 | errsts = check_readiness(SCpnt, 0, devip); | ||
| 341 | break; | 395 | break; |
| 342 | case RESERVE: | 396 | case RESERVE: |
| 343 | errsts = check_reset(SCpnt, devip); | 397 | errsts = check_readiness(SCpnt, 1, devip); |
| 344 | break; | 398 | break; |
| 345 | case RESERVE_10: | 399 | case RESERVE_10: |
| 346 | errsts = check_reset(SCpnt, devip); | 400 | errsts = check_readiness(SCpnt, 1, devip); |
| 347 | break; | 401 | break; |
| 348 | case RELEASE: | 402 | case RELEASE: |
| 349 | errsts = check_reset(SCpnt, devip); | 403 | errsts = check_readiness(SCpnt, 1, devip); |
| 350 | break; | 404 | break; |
| 351 | case RELEASE_10: | 405 | case RELEASE_10: |
| 352 | errsts = check_reset(SCpnt, devip); | 406 | errsts = check_readiness(SCpnt, 1, devip); |
| 353 | break; | 407 | break; |
| 354 | case READ_CAPACITY: | 408 | case READ_CAPACITY: |
| 355 | errsts = resp_readcap(SCpnt, devip); | 409 | errsts = resp_readcap(SCpnt, devip); |
| 356 | break; | 410 | break; |
| 411 | case SERVICE_ACTION_IN: | ||
| 412 | if (SAI_READ_CAPACITY_16 != cmd[1]) { | ||
| 413 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 414 | INVALID_OPCODE, 0); | ||
| 415 | errsts = check_condition_result; | ||
| 416 | break; | ||
| 417 | } | ||
| 418 | errsts = resp_readcap16(SCpnt, devip); | ||
| 419 | break; | ||
| 357 | case READ_16: | 420 | case READ_16: |
| 358 | case READ_12: | 421 | case READ_12: |
| 359 | case READ_10: | 422 | case READ_10: |
| 360 | case READ_6: | 423 | case READ_6: |
| 361 | if ((errsts = check_reset(SCpnt, devip))) | 424 | if ((errsts = check_readiness(SCpnt, 0, devip))) |
| 362 | break; | 425 | break; |
| 363 | upper_blk = 0; | ||
| 364 | if ((*cmd) == READ_16) { | 426 | if ((*cmd) == READ_16) { |
| 365 | upper_blk = cmd[5] + (cmd[4] << 8) + | 427 | for (lba = 0, j = 0; j < 8; ++j) { |
| 366 | (cmd[3] << 16) + (cmd[2] << 24); | 428 | if (j > 0) |
| 367 | block = cmd[9] + (cmd[8] << 8) + | 429 | lba <<= 8; |
| 368 | (cmd[7] << 16) + (cmd[6] << 24); | 430 | lba += cmd[2 + j]; |
| 431 | } | ||
| 369 | num = cmd[13] + (cmd[12] << 8) + | 432 | num = cmd[13] + (cmd[12] << 8) + |
| 370 | (cmd[11] << 16) + (cmd[10] << 24); | 433 | (cmd[11] << 16) + (cmd[10] << 24); |
| 371 | } else if ((*cmd) == READ_12) { | 434 | } else if ((*cmd) == READ_12) { |
| 372 | block = cmd[5] + (cmd[4] << 8) + | 435 | lba = cmd[5] + (cmd[4] << 8) + |
| 373 | (cmd[3] << 16) + (cmd[2] << 24); | 436 | (cmd[3] << 16) + (cmd[2] << 24); |
| 374 | num = cmd[9] + (cmd[8] << 8) + | 437 | num = cmd[9] + (cmd[8] << 8) + |
| 375 | (cmd[7] << 16) + (cmd[6] << 24); | 438 | (cmd[7] << 16) + (cmd[6] << 24); |
| 376 | } else if ((*cmd) == READ_10) { | 439 | } else if ((*cmd) == READ_10) { |
| 377 | block = cmd[5] + (cmd[4] << 8) + | 440 | lba = cmd[5] + (cmd[4] << 8) + |
| 378 | (cmd[3] << 16) + (cmd[2] << 24); | 441 | (cmd[3] << 16) + (cmd[2] << 24); |
| 379 | num = cmd[8] + (cmd[7] << 8); | 442 | num = cmd[8] + (cmd[7] << 8); |
| 380 | } else { | 443 | } else { /* READ (6) */ |
| 381 | block = cmd[3] + (cmd[2] << 8) + | 444 | lba = cmd[3] + (cmd[2] << 8) + |
| 382 | ((cmd[1] & 0x1f) << 16); | 445 | ((cmd[1] & 0x1f) << 16); |
| 383 | num = cmd[4]; | 446 | num = (0 == cmd[4]) ? 256 : cmd[4]; |
| 384 | } | 447 | } |
| 385 | errsts = resp_read(SCpnt, upper_blk, block, num, devip); | 448 | errsts = resp_read(SCpnt, lba, num, devip); |
| 386 | if (inj_recovered && (0 == errsts)) { | 449 | if (inj_recovered && (0 == errsts)) { |
| 387 | mk_sense_buffer(devip, RECOVERED_ERROR, | 450 | mk_sense_buffer(devip, RECOVERED_ERROR, |
| 388 | THRESHHOLD_EXCEEDED, 0); | 451 | THRESHOLD_EXCEEDED, 0); |
| 389 | errsts = check_condition_result; | 452 | errsts = check_condition_result; |
| 390 | } | 453 | } |
| 391 | break; | 454 | break; |
| 392 | case REPORT_LUNS: /* mandatory, ignore unit attention */ | 455 | case REPORT_LUNS: /* mandatory, ignore unit attention */ |
| 456 | delay_override = 1; | ||
| 393 | errsts = resp_report_luns(SCpnt, devip); | 457 | errsts = resp_report_luns(SCpnt, devip); |
| 394 | break; | 458 | break; |
| 395 | case VERIFY: /* 10 byte SBC-2 command */ | 459 | case VERIFY: /* 10 byte SBC-2 command */ |
| 396 | errsts = check_reset(SCpnt, devip); | 460 | errsts = check_readiness(SCpnt, 0, devip); |
| 397 | break; | 461 | break; |
| 398 | case WRITE_16: | 462 | case WRITE_16: |
| 399 | case WRITE_12: | 463 | case WRITE_12: |
| 400 | case WRITE_10: | 464 | case WRITE_10: |
| 401 | case WRITE_6: | 465 | case WRITE_6: |
| 402 | if ((errsts = check_reset(SCpnt, devip))) | 466 | if ((errsts = check_readiness(SCpnt, 0, devip))) |
| 403 | break; | 467 | break; |
| 404 | upper_blk = 0; | ||
| 405 | if ((*cmd) == WRITE_16) { | 468 | if ((*cmd) == WRITE_16) { |
| 406 | upper_blk = cmd[5] + (cmd[4] << 8) + | 469 | for (lba = 0, j = 0; j < 8; ++j) { |
| 407 | (cmd[3] << 16) + (cmd[2] << 24); | 470 | if (j > 0) |
| 408 | block = cmd[9] + (cmd[8] << 8) + | 471 | lba <<= 8; |
| 409 | (cmd[7] << 16) + (cmd[6] << 24); | 472 | lba += cmd[2 + j]; |
| 473 | } | ||
| 410 | num = cmd[13] + (cmd[12] << 8) + | 474 | num = cmd[13] + (cmd[12] << 8) + |
| 411 | (cmd[11] << 16) + (cmd[10] << 24); | 475 | (cmd[11] << 16) + (cmd[10] << 24); |
| 412 | } else if ((*cmd) == WRITE_12) { | 476 | } else if ((*cmd) == WRITE_12) { |
| 413 | block = cmd[5] + (cmd[4] << 8) + | 477 | lba = cmd[5] + (cmd[4] << 8) + |
| 414 | (cmd[3] << 16) + (cmd[2] << 24); | 478 | (cmd[3] << 16) + (cmd[2] << 24); |
| 415 | num = cmd[9] + (cmd[8] << 8) + | 479 | num = cmd[9] + (cmd[8] << 8) + |
| 416 | (cmd[7] << 16) + (cmd[6] << 24); | 480 | (cmd[7] << 16) + (cmd[6] << 24); |
| 417 | } else if ((*cmd) == WRITE_10) { | 481 | } else if ((*cmd) == WRITE_10) { |
| 418 | block = cmd[5] + (cmd[4] << 8) + | 482 | lba = cmd[5] + (cmd[4] << 8) + |
| 419 | (cmd[3] << 16) + (cmd[2] << 24); | 483 | (cmd[3] << 16) + (cmd[2] << 24); |
| 420 | num = cmd[8] + (cmd[7] << 8); | 484 | num = cmd[8] + (cmd[7] << 8); |
| 421 | } else { | 485 | } else { /* WRITE (6) */ |
| 422 | block = cmd[3] + (cmd[2] << 8) + | 486 | lba = cmd[3] + (cmd[2] << 8) + |
| 423 | ((cmd[1] & 0x1f) << 16); | 487 | ((cmd[1] & 0x1f) << 16); |
| 424 | num = cmd[4]; | 488 | num = (0 == cmd[4]) ? 256 : cmd[4]; |
| 425 | } | 489 | } |
| 426 | errsts = resp_write(SCpnt, upper_blk, block, num, devip); | 490 | errsts = resp_write(SCpnt, lba, num, devip); |
| 427 | if (inj_recovered && (0 == errsts)) { | 491 | if (inj_recovered && (0 == errsts)) { |
| 428 | mk_sense_buffer(devip, RECOVERED_ERROR, | 492 | mk_sense_buffer(devip, RECOVERED_ERROR, |
| 429 | THRESHHOLD_EXCEEDED, 0); | 493 | THRESHOLD_EXCEEDED, 0); |
| 430 | errsts = check_condition_result; | 494 | errsts = check_condition_result; |
| 431 | } | 495 | } |
| 432 | break; | 496 | break; |
| @@ -434,20 +498,31 @@ int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | |||
| 434 | case MODE_SENSE_10: | 498 | case MODE_SENSE_10: |
| 435 | errsts = resp_mode_sense(SCpnt, target, devip); | 499 | errsts = resp_mode_sense(SCpnt, target, devip); |
| 436 | break; | 500 | break; |
| 501 | case MODE_SELECT: | ||
| 502 | errsts = resp_mode_select(SCpnt, 1, devip); | ||
| 503 | break; | ||
| 504 | case MODE_SELECT_10: | ||
| 505 | errsts = resp_mode_select(SCpnt, 0, devip); | ||
| 506 | break; | ||
| 507 | case LOG_SENSE: | ||
| 508 | errsts = resp_log_sense(SCpnt, devip); | ||
| 509 | break; | ||
| 437 | case SYNCHRONIZE_CACHE: | 510 | case SYNCHRONIZE_CACHE: |
| 438 | errsts = check_reset(SCpnt, devip); | 511 | delay_override = 1; |
| 512 | errsts = check_readiness(SCpnt, 0, devip); | ||
| 439 | break; | 513 | break; |
| 440 | default: | 514 | default: |
| 441 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 515 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
| 442 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | 516 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " |
| 443 | "supported\n", *cmd); | 517 | "supported\n", *cmd); |
| 444 | if ((errsts = check_reset(SCpnt, devip))) | 518 | if ((errsts = check_readiness(SCpnt, 1, devip))) |
| 445 | break; /* Unit attention takes precedence */ | 519 | break; /* Unit attention takes precedence */ |
| 446 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); | 520 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); |
| 447 | errsts = check_condition_result; | 521 | errsts = check_condition_result; |
| 448 | break; | 522 | break; |
| 449 | } | 523 | } |
| 450 | return schedule_resp(SCpnt, devip, done, errsts, scsi_debug_delay); | 524 | return schedule_resp(SCpnt, devip, done, errsts, |
| 525 | (delay_override ? 0 : scsi_debug_delay)); | ||
| 451 | } | 526 | } |
| 452 | 527 | ||
| 453 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | 528 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) |
| @@ -459,7 +534,8 @@ static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | |||
| 459 | /* return -ENOTTY; // correct return but upsets fdisk */ | 534 | /* return -ENOTTY; // correct return but upsets fdisk */ |
| 460 | } | 535 | } |
| 461 | 536 | ||
| 462 | static int check_reset(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip) | 537 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, |
| 538 | struct sdebug_dev_info * devip) | ||
| 463 | { | 539 | { |
| 464 | if (devip->reset) { | 540 | if (devip->reset) { |
| 465 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 541 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
| @@ -469,6 +545,14 @@ static int check_reset(struct scsi_cmnd * SCpnt, struct sdebug_dev_info * devip) | |||
| 469 | mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0); | 545 | mk_sense_buffer(devip, UNIT_ATTENTION, POWERON_RESET, 0); |
| 470 | return check_condition_result; | 546 | return check_condition_result; |
| 471 | } | 547 | } |
| 548 | if ((0 == reset_only) && devip->stopped) { | ||
| 549 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
| 550 | printk(KERN_INFO "scsi_debug: Reporting Not " | ||
| 551 | "ready: initializing command required\n"); | ||
| 552 | mk_sense_buffer(devip, NOT_READY, LOGICAL_UNIT_NOT_READY, | ||
| 553 | 0x2); | ||
| 554 | return check_condition_result; | ||
| 555 | } | ||
| 472 | return 0; | 556 | return 0; |
| 473 | } | 557 | } |
| 474 | 558 | ||
| @@ -492,7 +576,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | |||
| 492 | req_len = scp->request_bufflen; | 576 | req_len = scp->request_bufflen; |
| 493 | act_len = (req_len < arr_len) ? req_len : arr_len; | 577 | act_len = (req_len < arr_len) ? req_len : arr_len; |
| 494 | memcpy(scp->request_buffer, arr, act_len); | 578 | memcpy(scp->request_buffer, arr, act_len); |
| 495 | scp->resid = req_len - act_len; | 579 | if (scp->resid) |
| 580 | scp->resid -= act_len; | ||
| 581 | else | ||
| 582 | scp->resid = req_len - act_len; | ||
| 496 | return 0; | 583 | return 0; |
| 497 | } | 584 | } |
| 498 | sgpnt = (struct scatterlist *)scp->request_buffer; | 585 | sgpnt = (struct scatterlist *)scp->request_buffer; |
| @@ -515,7 +602,10 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | |||
| 515 | } | 602 | } |
| 516 | req_len += sgpnt->length; | 603 | req_len += sgpnt->length; |
| 517 | } | 604 | } |
| 518 | scp->resid = req_len - act_len; | 605 | if (scp->resid) |
| 606 | scp->resid -= act_len; | ||
| 607 | else | ||
| 608 | scp->resid = req_len - act_len; | ||
| 519 | return 0; | 609 | return 0; |
| 520 | } | 610 | } |
| 521 | 611 | ||
| @@ -566,12 +656,14 @@ static const char * inq_vendor_id = "Linux "; | |||
| 566 | static const char * inq_product_id = "scsi_debug "; | 656 | static const char * inq_product_id = "scsi_debug "; |
| 567 | static const char * inq_product_rev = "0004"; | 657 | static const char * inq_product_rev = "0004"; |
| 568 | 658 | ||
| 569 | static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | 659 | static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, |
| 570 | const char * dev_id_str, int dev_id_str_len) | 660 | int dev_id_num, const char * dev_id_str, |
| 661 | int dev_id_str_len) | ||
| 571 | { | 662 | { |
| 572 | int num; | 663 | int num, port_a; |
| 664 | char b[32]; | ||
| 573 | 665 | ||
| 574 | /* Two identification descriptors: */ | 666 | port_a = target_dev_id + 1; |
| 575 | /* T10 vendor identifier field format (faked) */ | 667 | /* T10 vendor identifier field format (faked) */ |
| 576 | arr[0] = 0x2; /* ASCII */ | 668 | arr[0] = 0x2; /* ASCII */ |
| 577 | arr[1] = 0x1; | 669 | arr[1] = 0x1; |
| @@ -582,25 +674,246 @@ static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, | |||
| 582 | num = 8 + 16 + dev_id_str_len; | 674 | num = 8 + 16 + dev_id_str_len; |
| 583 | arr[3] = num; | 675 | arr[3] = num; |
| 584 | num += 4; | 676 | num += 4; |
| 585 | /* NAA IEEE registered identifier (faked) */ | 677 | if (dev_id_num >= 0) { |
| 586 | arr[num] = 0x1; /* binary */ | 678 | /* NAA-5, Logical unit identifier (binary) */ |
| 587 | arr[num + 1] = 0x3; | 679 | arr[num++] = 0x1; /* binary (not necessarily sas) */ |
| 588 | arr[num + 2] = 0x0; | 680 | arr[num++] = 0x3; /* PIV=0, lu, naa */ |
| 589 | arr[num + 3] = 0x8; | 681 | arr[num++] = 0x0; |
| 590 | arr[num + 4] = 0x51; /* ieee company id=0x123456 (faked) */ | 682 | arr[num++] = 0x8; |
| 591 | arr[num + 5] = 0x23; | 683 | arr[num++] = 0x53; /* naa-5 ieee company id=0x333333 (fake) */ |
| 592 | arr[num + 6] = 0x45; | 684 | arr[num++] = 0x33; |
| 593 | arr[num + 7] = 0x60; | 685 | arr[num++] = 0x33; |
| 594 | arr[num + 8] = (dev_id_num >> 24); | 686 | arr[num++] = 0x30; |
| 595 | arr[num + 9] = (dev_id_num >> 16) & 0xff; | 687 | arr[num++] = (dev_id_num >> 24); |
| 596 | arr[num + 10] = (dev_id_num >> 8) & 0xff; | 688 | arr[num++] = (dev_id_num >> 16) & 0xff; |
| 597 | arr[num + 11] = dev_id_num & 0xff; | 689 | arr[num++] = (dev_id_num >> 8) & 0xff; |
| 598 | return num + 12; | 690 | arr[num++] = dev_id_num & 0xff; |
| 691 | /* Target relative port number */ | ||
| 692 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
| 693 | arr[num++] = 0x94; /* PIV=1, target port, rel port */ | ||
| 694 | arr[num++] = 0x0; /* reserved */ | ||
| 695 | arr[num++] = 0x4; /* length */ | ||
| 696 | arr[num++] = 0x0; /* reserved */ | ||
| 697 | arr[num++] = 0x0; /* reserved */ | ||
| 698 | arr[num++] = 0x0; | ||
| 699 | arr[num++] = 0x1; /* relative port A */ | ||
| 700 | } | ||
| 701 | /* NAA-5, Target port identifier */ | ||
| 702 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
| 703 | arr[num++] = 0x93; /* piv=1, target port, naa */ | ||
| 704 | arr[num++] = 0x0; | ||
| 705 | arr[num++] = 0x8; | ||
| 706 | arr[num++] = 0x52; /* naa-5, company id=0x222222 (fake) */ | ||
| 707 | arr[num++] = 0x22; | ||
| 708 | arr[num++] = 0x22; | ||
| 709 | arr[num++] = 0x20; | ||
| 710 | arr[num++] = (port_a >> 24); | ||
| 711 | arr[num++] = (port_a >> 16) & 0xff; | ||
| 712 | arr[num++] = (port_a >> 8) & 0xff; | ||
| 713 | arr[num++] = port_a & 0xff; | ||
| 714 | /* NAA-5, Target device identifier */ | ||
| 715 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
| 716 | arr[num++] = 0xa3; /* piv=1, target device, naa */ | ||
| 717 | arr[num++] = 0x0; | ||
| 718 | arr[num++] = 0x8; | ||
| 719 | arr[num++] = 0x52; /* naa-5, company id=0x222222 (fake) */ | ||
| 720 | arr[num++] = 0x22; | ||
| 721 | arr[num++] = 0x22; | ||
| 722 | arr[num++] = 0x20; | ||
| 723 | arr[num++] = (target_dev_id >> 24); | ||
| 724 | arr[num++] = (target_dev_id >> 16) & 0xff; | ||
| 725 | arr[num++] = (target_dev_id >> 8) & 0xff; | ||
| 726 | arr[num++] = target_dev_id & 0xff; | ||
| 727 | /* SCSI name string: Target device identifier */ | ||
| 728 | arr[num++] = 0x63; /* proto=sas, UTF-8 */ | ||
| 729 | arr[num++] = 0xa8; /* piv=1, target device, SCSI name string */ | ||
| 730 | arr[num++] = 0x0; | ||
| 731 | arr[num++] = 24; | ||
| 732 | memcpy(arr + num, "naa.52222220", 12); | ||
| 733 | num += 12; | ||
| 734 | snprintf(b, sizeof(b), "%08X", target_dev_id); | ||
| 735 | memcpy(arr + num, b, 8); | ||
| 736 | num += 8; | ||
| 737 | memset(arr + num, 0, 4); | ||
| 738 | num += 4; | ||
| 739 | return num; | ||
| 740 | } | ||
| 741 | |||
| 742 | |||
| 743 | static unsigned char vpd84_data[] = { | ||
| 744 | /* from 4th byte */ 0x22,0x22,0x22,0x0,0xbb,0x0, | ||
| 745 | 0x22,0x22,0x22,0x0,0xbb,0x1, | ||
| 746 | 0x22,0x22,0x22,0x0,0xbb,0x2, | ||
| 747 | }; | ||
| 748 | |||
| 749 | static int inquiry_evpd_84(unsigned char * arr) | ||
| 750 | { | ||
| 751 | memcpy(arr, vpd84_data, sizeof(vpd84_data)); | ||
| 752 | return sizeof(vpd84_data); | ||
| 753 | } | ||
| 754 | |||
| 755 | static int inquiry_evpd_85(unsigned char * arr) | ||
| 756 | { | ||
| 757 | int num = 0; | ||
| 758 | const char * na1 = "https://www.kernel.org/config"; | ||
| 759 | const char * na2 = "http://www.kernel.org/log"; | ||
| 760 | int plen, olen; | ||
| 761 | |||
| 762 | arr[num++] = 0x1; /* lu, storage config */ | ||
| 763 | arr[num++] = 0x0; /* reserved */ | ||
| 764 | arr[num++] = 0x0; | ||
| 765 | olen = strlen(na1); | ||
| 766 | plen = olen + 1; | ||
| 767 | if (plen % 4) | ||
| 768 | plen = ((plen / 4) + 1) * 4; | ||
| 769 | arr[num++] = plen; /* length, null termianted, padded */ | ||
| 770 | memcpy(arr + num, na1, olen); | ||
| 771 | memset(arr + num + olen, 0, plen - olen); | ||
| 772 | num += plen; | ||
| 773 | |||
| 774 | arr[num++] = 0x4; /* lu, logging */ | ||
| 775 | arr[num++] = 0x0; /* reserved */ | ||
| 776 | arr[num++] = 0x0; | ||
| 777 | olen = strlen(na2); | ||
| 778 | plen = olen + 1; | ||
| 779 | if (plen % 4) | ||
| 780 | plen = ((plen / 4) + 1) * 4; | ||
| 781 | arr[num++] = plen; /* length, null terminated, padded */ | ||
| 782 | memcpy(arr + num, na2, olen); | ||
| 783 | memset(arr + num + olen, 0, plen - olen); | ||
| 784 | num += plen; | ||
| 785 | |||
| 786 | return num; | ||
| 787 | } | ||
| 788 | |||
| 789 | /* SCSI ports VPD page */ | ||
| 790 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id) | ||
| 791 | { | ||
| 792 | int num = 0; | ||
| 793 | int port_a, port_b; | ||
| 794 | |||
| 795 | port_a = target_dev_id + 1; | ||
| 796 | port_b = port_a + 1; | ||
| 797 | arr[num++] = 0x0; /* reserved */ | ||
| 798 | arr[num++] = 0x0; /* reserved */ | ||
| 799 | arr[num++] = 0x0; | ||
| 800 | arr[num++] = 0x1; /* relative port 1 (primary) */ | ||
| 801 | memset(arr + num, 0, 6); | ||
| 802 | num += 6; | ||
| 803 | arr[num++] = 0x0; | ||
| 804 | arr[num++] = 12; /* length tp descriptor */ | ||
| 805 | /* naa-5 target port identifier (A) */ | ||
| 806 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
| 807 | arr[num++] = 0x93; /* PIV=1, target port, NAA */ | ||
| 808 | arr[num++] = 0x0; /* reserved */ | ||
| 809 | arr[num++] = 0x8; /* length */ | ||
| 810 | arr[num++] = 0x52; /* NAA-5, company_id=0x222222 (fake) */ | ||
| 811 | arr[num++] = 0x22; | ||
| 812 | arr[num++] = 0x22; | ||
| 813 | arr[num++] = 0x20; | ||
| 814 | arr[num++] = (port_a >> 24); | ||
| 815 | arr[num++] = (port_a >> 16) & 0xff; | ||
| 816 | arr[num++] = (port_a >> 8) & 0xff; | ||
| 817 | arr[num++] = port_a & 0xff; | ||
| 818 | |||
| 819 | arr[num++] = 0x0; /* reserved */ | ||
| 820 | arr[num++] = 0x0; /* reserved */ | ||
| 821 | arr[num++] = 0x0; | ||
| 822 | arr[num++] = 0x2; /* relative port 2 (secondary) */ | ||
| 823 | memset(arr + num, 0, 6); | ||
| 824 | num += 6; | ||
| 825 | arr[num++] = 0x0; | ||
| 826 | arr[num++] = 12; /* length tp descriptor */ | ||
| 827 | /* naa-5 target port identifier (B) */ | ||
| 828 | arr[num++] = 0x61; /* proto=sas, binary */ | ||
| 829 | arr[num++] = 0x93; /* PIV=1, target port, NAA */ | ||
| 830 | arr[num++] = 0x0; /* reserved */ | ||
| 831 | arr[num++] = 0x8; /* length */ | ||
| 832 | arr[num++] = 0x52; /* NAA-5, company_id=0x222222 (fake) */ | ||
| 833 | arr[num++] = 0x22; | ||
| 834 | arr[num++] = 0x22; | ||
| 835 | arr[num++] = 0x20; | ||
| 836 | arr[num++] = (port_b >> 24); | ||
| 837 | arr[num++] = (port_b >> 16) & 0xff; | ||
| 838 | arr[num++] = (port_b >> 8) & 0xff; | ||
| 839 | arr[num++] = port_b & 0xff; | ||
| 840 | |||
| 841 | return num; | ||
| 842 | } | ||
| 843 | |||
| 844 | |||
| 845 | static unsigned char vpd89_data[] = { | ||
| 846 | /* from 4th byte */ 0,0,0,0, | ||
| 847 | 'l','i','n','u','x',' ',' ',' ', | ||
| 848 | 'S','A','T',' ','s','c','s','i','_','d','e','b','u','g',' ',' ', | ||
| 849 | '1','2','3','4', | ||
| 850 | 0x34,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, | ||
| 851 | 0xec,0,0,0, | ||
| 852 | 0x5a,0xc,0xff,0x3f,0x37,0xc8,0x10,0,0,0,0,0,0x3f,0,0,0, | ||
| 853 | 0,0,0,0,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x58,0x20,0x20,0x20,0x20, | ||
| 854 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0,0,0,0x40,0x4,0,0x2e,0x33, | ||
| 855 | 0x38,0x31,0x20,0x20,0x20,0x20,0x54,0x53,0x38,0x33,0x30,0x30,0x33,0x31, | ||
| 856 | 0x53,0x41, | ||
| 857 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, | ||
| 858 | 0x20,0x20, | ||
| 859 | 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, | ||
| 860 | 0x10,0x80, | ||
| 861 | 0,0,0,0x2f,0,0,0,0x2,0,0x2,0x7,0,0xff,0xff,0x1,0, | ||
| 862 | 0x3f,0,0xc1,0xff,0x3e,0,0x10,0x1,0xb0,0xf8,0x50,0x9,0,0,0x7,0, | ||
| 863 | 0x3,0,0x78,0,0x78,0,0xf0,0,0x78,0,0,0,0,0,0,0, | ||
| 864 | 0,0,0,0,0,0,0,0,0x2,0,0,0,0,0,0,0, | ||
| 865 | 0x7e,0,0x1b,0,0x6b,0x34,0x1,0x7d,0x3,0x40,0x69,0x34,0x1,0x3c,0x3,0x40, | ||
| 866 | 0x7f,0x40,0,0,0,0,0xfe,0xfe,0,0,0,0,0,0xfe,0,0, | ||
| 867 | 0,0,0,0,0,0,0,0,0xb0,0xf8,0x50,0x9,0,0,0,0, | ||
| 868 | 0,0,0,0,0,0,0,0,0,0,0,0,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 | 0x1,0,0xb0,0xf8,0x50,0x9,0xb0,0xf8,0x50,0x9,0x20,0x20,0x2,0,0xb6,0x42, | ||
| 872 | 0,0x80,0x8a,0,0x6,0x3c,0xa,0x3c,0xff,0xff,0xc6,0x7,0,0x1,0,0x8, | ||
| 873 | 0xf0,0xf,0,0x10,0x2,0,0x30,0,0,0,0,0,0,0,0x6,0xfe, | ||
| 874 | 0,0,0x2,0,0x50,0,0x8a,0,0x4f,0x95,0,0,0x21,0,0xb,0, | ||
| 875 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,0xa5,0x51, | ||
| 887 | }; | ||
| 888 | |||
| 889 | static int inquiry_evpd_89(unsigned char * arr) | ||
| 890 | { | ||
| 891 | memcpy(arr, vpd89_data, sizeof(vpd89_data)); | ||
| 892 | return sizeof(vpd89_data); | ||
| 893 | } | ||
| 894 | |||
| 895 | |||
| 896 | static unsigned char vpdb0_data[] = { | ||
| 897 | /* from 4th byte */ 0,0,0,4, | ||
| 898 | 0,0,0x4,0, | ||
| 899 | 0,0,0,64, | ||
| 900 | }; | ||
| 901 | |||
| 902 | static int inquiry_evpd_b0(unsigned char * arr) | ||
| 903 | { | ||
| 904 | memcpy(arr, vpdb0_data, sizeof(vpdb0_data)); | ||
| 905 | if (sdebug_store_sectors > 0x400) { | ||
| 906 | arr[4] = (sdebug_store_sectors >> 24) & 0xff; | ||
| 907 | arr[5] = (sdebug_store_sectors >> 16) & 0xff; | ||
| 908 | arr[6] = (sdebug_store_sectors >> 8) & 0xff; | ||
| 909 | arr[7] = sdebug_store_sectors & 0xff; | ||
| 910 | } | ||
| 911 | return sizeof(vpdb0_data); | ||
| 599 | } | 912 | } |
| 600 | 913 | ||
| 601 | 914 | ||
| 602 | #define SDEBUG_LONG_INQ_SZ 96 | 915 | #define SDEBUG_LONG_INQ_SZ 96 |
| 603 | #define SDEBUG_MAX_INQ_ARR_SZ 128 | 916 | #define SDEBUG_MAX_INQ_ARR_SZ 584 |
| 604 | 917 | ||
| 605 | static int resp_inquiry(struct scsi_cmnd * scp, int target, | 918 | static int resp_inquiry(struct scsi_cmnd * scp, int target, |
| 606 | struct sdebug_dev_info * devip) | 919 | struct sdebug_dev_info * devip) |
| @@ -608,64 +921,113 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target, | |||
| 608 | unsigned char pq_pdt; | 921 | unsigned char pq_pdt; |
| 609 | unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; | 922 | unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; |
| 610 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 923 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
| 611 | int alloc_len; | 924 | int alloc_len, n; |
| 612 | 925 | ||
| 613 | alloc_len = (cmd[3] << 8) + cmd[4]; | 926 | alloc_len = (cmd[3] << 8) + cmd[4]; |
| 614 | memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); | 927 | memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); |
| 615 | pq_pdt = (scsi_debug_ptype & 0x1f); | 928 | if (devip->wlun) |
| 929 | pq_pdt = 0x1e; /* present, wlun */ | ||
| 930 | else if (scsi_debug_no_lun_0 && (0 == devip->lun)) | ||
| 931 | pq_pdt = 0x7f; /* not present, no device type */ | ||
| 932 | else | ||
| 933 | pq_pdt = (scsi_debug_ptype & 0x1f); | ||
| 616 | arr[0] = pq_pdt; | 934 | arr[0] = pq_pdt; |
| 617 | if (0x2 & cmd[1]) { /* CMDDT bit set */ | 935 | if (0x2 & cmd[1]) { /* CMDDT bit set */ |
| 618 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 936 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
| 619 | 0); | 937 | 0); |
| 620 | return check_condition_result; | 938 | return check_condition_result; |
| 621 | } else if (0x1 & cmd[1]) { /* EVPD bit set */ | 939 | } else if (0x1 & cmd[1]) { /* EVPD bit set */ |
| 622 | int dev_id_num, len; | 940 | int lu_id_num, target_dev_id, len; |
| 623 | char dev_id_str[6]; | 941 | char lu_id_str[6]; |
| 942 | int host_no = devip->sdbg_host->shost->host_no; | ||
| 624 | 943 | ||
| 625 | dev_id_num = ((devip->sdbg_host->shost->host_no + 1) * 2000) + | 944 | lu_id_num = devip->wlun ? -1 : (((host_no + 1) * 2000) + |
| 626 | (devip->target * 1000) + devip->lun; | 945 | (devip->target * 1000) + devip->lun); |
| 627 | len = scnprintf(dev_id_str, 6, "%d", dev_id_num); | 946 | target_dev_id = ((host_no + 1) * 2000) + |
| 947 | (devip->target * 1000) - 3; | ||
| 948 | len = scnprintf(lu_id_str, 6, "%d", lu_id_num); | ||
| 628 | if (0 == cmd[2]) { /* supported vital product data pages */ | 949 | if (0 == cmd[2]) { /* supported vital product data pages */ |
| 629 | arr[3] = 3; | 950 | arr[1] = cmd[2]; /*sanity */ |
| 630 | arr[4] = 0x0; /* this page */ | 951 | n = 4; |
| 631 | arr[5] = 0x80; /* unit serial number */ | 952 | arr[n++] = 0x0; /* this page */ |
| 632 | arr[6] = 0x83; /* device identification */ | 953 | arr[n++] = 0x80; /* unit serial number */ |
| 954 | arr[n++] = 0x83; /* device identification */ | ||
| 955 | arr[n++] = 0x84; /* software interface ident. */ | ||
| 956 | arr[n++] = 0x85; /* management network addresses */ | ||
| 957 | arr[n++] = 0x86; /* extended inquiry */ | ||
| 958 | arr[n++] = 0x87; /* mode page policy */ | ||
| 959 | arr[n++] = 0x88; /* SCSI ports */ | ||
| 960 | arr[n++] = 0x89; /* ATA information */ | ||
| 961 | arr[n++] = 0xb0; /* Block limits (SBC) */ | ||
| 962 | arr[3] = n - 4; /* number of supported VPD pages */ | ||
| 633 | } else if (0x80 == cmd[2]) { /* unit serial number */ | 963 | } else if (0x80 == cmd[2]) { /* unit serial number */ |
| 634 | arr[1] = 0x80; | 964 | arr[1] = cmd[2]; /*sanity */ |
| 635 | arr[3] = len; | 965 | arr[3] = len; |
| 636 | memcpy(&arr[4], dev_id_str, len); | 966 | memcpy(&arr[4], lu_id_str, len); |
| 637 | } else if (0x83 == cmd[2]) { /* device identification */ | 967 | } else if (0x83 == cmd[2]) { /* device identification */ |
| 638 | arr[1] = 0x83; | 968 | arr[1] = cmd[2]; /*sanity */ |
| 639 | arr[3] = inquiry_evpd_83(&arr[4], dev_id_num, | 969 | arr[3] = inquiry_evpd_83(&arr[4], target_dev_id, |
| 640 | dev_id_str, len); | 970 | lu_id_num, lu_id_str, len); |
| 971 | } else if (0x84 == cmd[2]) { /* Software interface ident. */ | ||
| 972 | arr[1] = cmd[2]; /*sanity */ | ||
| 973 | arr[3] = inquiry_evpd_84(&arr[4]); | ||
| 974 | } else if (0x85 == cmd[2]) { /* Management network addresses */ | ||
| 975 | arr[1] = cmd[2]; /*sanity */ | ||
| 976 | arr[3] = inquiry_evpd_85(&arr[4]); | ||
| 977 | } else if (0x86 == cmd[2]) { /* extended inquiry */ | ||
| 978 | arr[1] = cmd[2]; /*sanity */ | ||
| 979 | arr[3] = 0x3c; /* number of following entries */ | ||
| 980 | arr[4] = 0x0; /* no protection stuff */ | ||
| 981 | arr[5] = 0x7; /* head of q, ordered + simple q's */ | ||
| 982 | } else if (0x87 == cmd[2]) { /* mode page policy */ | ||
| 983 | arr[1] = cmd[2]; /*sanity */ | ||
| 984 | arr[3] = 0x8; /* number of following entries */ | ||
| 985 | arr[4] = 0x2; /* disconnect-reconnect mp */ | ||
| 986 | arr[6] = 0x80; /* mlus, shared */ | ||
| 987 | arr[8] = 0x18; /* protocol specific lu */ | ||
| 988 | arr[10] = 0x82; /* mlus, per initiator port */ | ||
| 989 | } else if (0x88 == cmd[2]) { /* SCSI Ports */ | ||
| 990 | arr[1] = cmd[2]; /*sanity */ | ||
| 991 | arr[3] = inquiry_evpd_88(&arr[4], target_dev_id); | ||
| 992 | } else if (0x89 == cmd[2]) { /* ATA information */ | ||
| 993 | arr[1] = cmd[2]; /*sanity */ | ||
| 994 | n = inquiry_evpd_89(&arr[4]); | ||
| 995 | arr[2] = (n >> 8); | ||
| 996 | arr[3] = (n & 0xff); | ||
| 997 | } else if (0xb0 == cmd[2]) { /* Block limits (SBC) */ | ||
| 998 | arr[1] = cmd[2]; /*sanity */ | ||
| 999 | arr[3] = inquiry_evpd_b0(&arr[4]); | ||
| 641 | } else { | 1000 | } else { |
| 642 | /* Illegal request, invalid field in cdb */ | 1001 | /* Illegal request, invalid field in cdb */ |
| 643 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | 1002 | mk_sense_buffer(devip, ILLEGAL_REQUEST, |
| 644 | INVALID_FIELD_IN_CDB, 0); | 1003 | INVALID_FIELD_IN_CDB, 0); |
| 645 | return check_condition_result; | 1004 | return check_condition_result; |
| 646 | } | 1005 | } |
| 1006 | len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); | ||
| 647 | return fill_from_dev_buffer(scp, arr, | 1007 | return fill_from_dev_buffer(scp, arr, |
| 648 | min(alloc_len, SDEBUG_MAX_INQ_ARR_SZ)); | 1008 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); |
| 649 | } | 1009 | } |
| 650 | /* drops through here for a standard inquiry */ | 1010 | /* drops through here for a standard inquiry */ |
| 651 | arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ | 1011 | arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ |
| 652 | arr[2] = scsi_debug_scsi_level; | 1012 | arr[2] = scsi_debug_scsi_level; |
| 653 | arr[3] = 2; /* response_data_format==2 */ | 1013 | arr[3] = 2; /* response_data_format==2 */ |
| 654 | arr[4] = SDEBUG_LONG_INQ_SZ - 5; | 1014 | arr[4] = SDEBUG_LONG_INQ_SZ - 5; |
| 655 | arr[6] = 0x1; /* claim: ADDR16 */ | 1015 | arr[6] = 0x10; /* claim: MultiP */ |
| 656 | /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ | 1016 | /* arr[6] |= 0x40; ... claim: EncServ (enclosure services) */ |
| 657 | arr[7] = 0x3a; /* claim: WBUS16, SYNC, LINKED + CMDQUE */ | 1017 | arr[7] = 0xa; /* claim: LINKED + CMDQUE */ |
| 658 | memcpy(&arr[8], inq_vendor_id, 8); | 1018 | memcpy(&arr[8], inq_vendor_id, 8); |
| 659 | memcpy(&arr[16], inq_product_id, 16); | 1019 | memcpy(&arr[16], inq_product_id, 16); |
| 660 | memcpy(&arr[32], inq_product_rev, 4); | 1020 | memcpy(&arr[32], inq_product_rev, 4); |
| 661 | /* version descriptors (2 bytes each) follow */ | 1021 | /* version descriptors (2 bytes each) follow */ |
| 662 | arr[58] = 0x0; arr[59] = 0x40; /* SAM-2 */ | 1022 | arr[58] = 0x0; arr[59] = 0x77; /* SAM-3 ANSI */ |
| 663 | arr[60] = 0x3; arr[61] = 0x0; /* SPC-3 */ | 1023 | arr[60] = 0x3; arr[61] = 0x14; /* SPC-3 ANSI */ |
| 1024 | n = 62; | ||
| 664 | if (scsi_debug_ptype == 0) { | 1025 | if (scsi_debug_ptype == 0) { |
| 665 | arr[62] = 0x1; arr[63] = 0x80; /* SBC */ | 1026 | arr[n++] = 0x3; arr[n++] = 0x3d; /* SBC-2 ANSI */ |
| 666 | } else if (scsi_debug_ptype == 1) { | 1027 | } else if (scsi_debug_ptype == 1) { |
| 667 | arr[62] = 0x2; arr[63] = 0x00; /* SSC */ | 1028 | arr[n++] = 0x3; arr[n++] = 0x60; /* SSC-2 no version */ |
| 668 | } | 1029 | } |
| 1030 | arr[n++] = 0xc; arr[n++] = 0xf; /* SAS-1.1 rev 10 */ | ||
| 669 | return fill_from_dev_buffer(scp, arr, | 1031 | return fill_from_dev_buffer(scp, arr, |
| 670 | min(alloc_len, SDEBUG_LONG_INQ_SZ)); | 1032 | min(alloc_len, SDEBUG_LONG_INQ_SZ)); |
| 671 | } | 1033 | } |
| @@ -676,46 +1038,141 @@ static int resp_requests(struct scsi_cmnd * scp, | |||
| 676 | unsigned char * sbuff; | 1038 | unsigned char * sbuff; |
| 677 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1039 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
| 678 | unsigned char arr[SDEBUG_SENSE_LEN]; | 1040 | unsigned char arr[SDEBUG_SENSE_LEN]; |
| 1041 | int want_dsense; | ||
| 679 | int len = 18; | 1042 | int len = 18; |
| 680 | 1043 | ||
| 681 | memset(arr, 0, SDEBUG_SENSE_LEN); | 1044 | memset(arr, 0, sizeof(arr)); |
| 682 | if (devip->reset == 1) | 1045 | if (devip->reset == 1) |
| 683 | mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0); | 1046 | mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0); |
| 1047 | want_dsense = !!(cmd[1] & 1) || scsi_debug_dsense; | ||
| 684 | sbuff = devip->sense_buff; | 1048 | sbuff = devip->sense_buff; |
| 685 | if ((cmd[1] & 1) && (! scsi_debug_dsense)) { | 1049 | if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) { |
| 686 | /* DESC bit set and sense_buff in fixed format */ | 1050 | if (want_dsense) { |
| 687 | arr[0] = 0x72; | 1051 | arr[0] = 0x72; |
| 688 | arr[1] = sbuff[2]; /* sense key */ | 1052 | arr[1] = 0x0; /* NO_SENSE in sense_key */ |
| 689 | arr[2] = sbuff[12]; /* asc */ | 1053 | arr[2] = THRESHOLD_EXCEEDED; |
| 690 | arr[3] = sbuff[13]; /* ascq */ | 1054 | arr[3] = 0xff; /* TEST set and MRIE==6 */ |
| 691 | len = 8; | 1055 | } else { |
| 692 | } else | 1056 | arr[0] = 0x70; |
| 1057 | arr[2] = 0x0; /* NO_SENSE in sense_key */ | ||
| 1058 | arr[7] = 0xa; /* 18 byte sense buffer */ | ||
| 1059 | arr[12] = THRESHOLD_EXCEEDED; | ||
| 1060 | arr[13] = 0xff; /* TEST set and MRIE==6 */ | ||
| 1061 | } | ||
| 1062 | } else if (devip->stopped) { | ||
| 1063 | if (want_dsense) { | ||
| 1064 | arr[0] = 0x72; | ||
| 1065 | arr[1] = 0x0; /* NO_SENSE in sense_key */ | ||
| 1066 | arr[2] = LOW_POWER_COND_ON; | ||
| 1067 | arr[3] = 0x0; /* TEST set and MRIE==6 */ | ||
| 1068 | } else { | ||
| 1069 | arr[0] = 0x70; | ||
| 1070 | arr[2] = 0x0; /* NO_SENSE in sense_key */ | ||
| 1071 | arr[7] = 0xa; /* 18 byte sense buffer */ | ||
| 1072 | arr[12] = LOW_POWER_COND_ON; | ||
| 1073 | arr[13] = 0x0; /* TEST set and MRIE==6 */ | ||
| 1074 | } | ||
| 1075 | } else { | ||
| 693 | memcpy(arr, sbuff, SDEBUG_SENSE_LEN); | 1076 | memcpy(arr, sbuff, SDEBUG_SENSE_LEN); |
| 694 | mk_sense_buffer(devip, 0, NO_ADDED_SENSE, 0); | 1077 | if ((cmd[1] & 1) && (! scsi_debug_dsense)) { |
| 1078 | /* DESC bit set and sense_buff in fixed format */ | ||
| 1079 | memset(arr, 0, sizeof(arr)); | ||
| 1080 | arr[0] = 0x72; | ||
| 1081 | arr[1] = sbuff[2]; /* sense key */ | ||
| 1082 | arr[2] = sbuff[12]; /* asc */ | ||
| 1083 | arr[3] = sbuff[13]; /* ascq */ | ||
| 1084 | len = 8; | ||
| 1085 | } | ||
| 1086 | } | ||
| 1087 | mk_sense_buffer(devip, 0, NO_ADDITIONAL_SENSE, 0); | ||
| 695 | return fill_from_dev_buffer(scp, arr, len); | 1088 | return fill_from_dev_buffer(scp, arr, len); |
| 696 | } | 1089 | } |
| 697 | 1090 | ||
| 1091 | static int resp_start_stop(struct scsi_cmnd * scp, | ||
| 1092 | struct sdebug_dev_info * devip) | ||
| 1093 | { | ||
| 1094 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
| 1095 | int power_cond, errsts, start; | ||
| 1096 | |||
| 1097 | if ((errsts = check_readiness(scp, 1, devip))) | ||
| 1098 | return errsts; | ||
| 1099 | power_cond = (cmd[4] & 0xf0) >> 4; | ||
| 1100 | if (power_cond) { | ||
| 1101 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
| 1102 | 0); | ||
| 1103 | return check_condition_result; | ||
| 1104 | } | ||
| 1105 | start = cmd[4] & 1; | ||
| 1106 | if (start == devip->stopped) | ||
| 1107 | devip->stopped = !start; | ||
| 1108 | return 0; | ||
| 1109 | } | ||
| 1110 | |||
| 698 | #define SDEBUG_READCAP_ARR_SZ 8 | 1111 | #define SDEBUG_READCAP_ARR_SZ 8 |
| 699 | static int resp_readcap(struct scsi_cmnd * scp, | 1112 | static int resp_readcap(struct scsi_cmnd * scp, |
| 700 | struct sdebug_dev_info * devip) | 1113 | struct sdebug_dev_info * devip) |
| 701 | { | 1114 | { |
| 702 | unsigned char arr[SDEBUG_READCAP_ARR_SZ]; | 1115 | unsigned char arr[SDEBUG_READCAP_ARR_SZ]; |
| 703 | unsigned long capac; | 1116 | unsigned int capac; |
| 704 | int errsts; | 1117 | int errsts; |
| 705 | 1118 | ||
| 706 | if ((errsts = check_reset(scp, devip))) | 1119 | if ((errsts = check_readiness(scp, 1, devip))) |
| 707 | return errsts; | 1120 | return errsts; |
| 1121 | /* following just in case virtual_gb changed */ | ||
| 1122 | if (scsi_debug_virtual_gb > 0) { | ||
| 1123 | sdebug_capacity = 2048 * 1024; | ||
| 1124 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
| 1125 | } else | ||
| 1126 | sdebug_capacity = sdebug_store_sectors; | ||
| 708 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); | 1127 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); |
| 709 | capac = (unsigned long)sdebug_capacity - 1; | 1128 | if (sdebug_capacity < 0xffffffff) { |
| 710 | arr[0] = (capac >> 24); | 1129 | capac = (unsigned int)sdebug_capacity - 1; |
| 711 | arr[1] = (capac >> 16) & 0xff; | 1130 | arr[0] = (capac >> 24); |
| 712 | arr[2] = (capac >> 8) & 0xff; | 1131 | arr[1] = (capac >> 16) & 0xff; |
| 713 | arr[3] = capac & 0xff; | 1132 | arr[2] = (capac >> 8) & 0xff; |
| 1133 | arr[3] = capac & 0xff; | ||
| 1134 | } else { | ||
| 1135 | arr[0] = 0xff; | ||
| 1136 | arr[1] = 0xff; | ||
| 1137 | arr[2] = 0xff; | ||
| 1138 | arr[3] = 0xff; | ||
| 1139 | } | ||
| 714 | arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; | 1140 | arr[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; |
| 715 | arr[7] = SECT_SIZE_PER(target) & 0xff; | 1141 | arr[7] = SECT_SIZE_PER(target) & 0xff; |
| 716 | return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ); | 1142 | return fill_from_dev_buffer(scp, arr, SDEBUG_READCAP_ARR_SZ); |
| 717 | } | 1143 | } |
| 718 | 1144 | ||
| 1145 | #define SDEBUG_READCAP16_ARR_SZ 32 | ||
| 1146 | static int resp_readcap16(struct scsi_cmnd * scp, | ||
| 1147 | struct sdebug_dev_info * devip) | ||
| 1148 | { | ||
| 1149 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
| 1150 | unsigned char arr[SDEBUG_READCAP16_ARR_SZ]; | ||
| 1151 | unsigned long long capac; | ||
| 1152 | int errsts, k, alloc_len; | ||
| 1153 | |||
| 1154 | if ((errsts = check_readiness(scp, 1, devip))) | ||
| 1155 | return errsts; | ||
| 1156 | alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) | ||
| 1157 | + cmd[13]); | ||
| 1158 | /* following just in case virtual_gb changed */ | ||
| 1159 | if (scsi_debug_virtual_gb > 0) { | ||
| 1160 | sdebug_capacity = 2048 * 1024; | ||
| 1161 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
| 1162 | } else | ||
| 1163 | sdebug_capacity = sdebug_store_sectors; | ||
| 1164 | memset(arr, 0, SDEBUG_READCAP16_ARR_SZ); | ||
| 1165 | capac = sdebug_capacity - 1; | ||
| 1166 | for (k = 0; k < 8; ++k, capac >>= 8) | ||
| 1167 | arr[7 - k] = capac & 0xff; | ||
| 1168 | arr[8] = (SECT_SIZE_PER(target) >> 24) & 0xff; | ||
| 1169 | arr[9] = (SECT_SIZE_PER(target) >> 16) & 0xff; | ||
| 1170 | arr[10] = (SECT_SIZE_PER(target) >> 8) & 0xff; | ||
| 1171 | arr[11] = SECT_SIZE_PER(target) & 0xff; | ||
| 1172 | return fill_from_dev_buffer(scp, arr, | ||
| 1173 | min(alloc_len, SDEBUG_READCAP16_ARR_SZ)); | ||
| 1174 | } | ||
| 1175 | |||
| 719 | /* <<Following mode page info copied from ST318451LW>> */ | 1176 | /* <<Following mode page info copied from ST318451LW>> */ |
| 720 | 1177 | ||
| 721 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) | 1178 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) |
| @@ -771,27 +1228,98 @@ static int resp_caching_pg(unsigned char * p, int pcontrol, int target) | |||
| 771 | 1228 | ||
| 772 | static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) | 1229 | static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) |
| 773 | { /* Control mode page for mode_sense */ | 1230 | { /* Control mode page for mode_sense */ |
| 774 | unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | 1231 | unsigned char ch_ctrl_m_pg[] = {/* 0xa, 10, */ 0x6, 0, 0, 0, 0, 0, |
| 1232 | 0, 0, 0, 0}; | ||
| 1233 | unsigned char d_ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | ||
| 775 | 0, 0, 0x2, 0x4b}; | 1234 | 0, 0, 0x2, 0x4b}; |
| 776 | 1235 | ||
| 777 | if (scsi_debug_dsense) | 1236 | if (scsi_debug_dsense) |
| 778 | ctrl_m_pg[2] |= 0x4; | 1237 | ctrl_m_pg[2] |= 0x4; |
| 1238 | else | ||
| 1239 | ctrl_m_pg[2] &= ~0x4; | ||
| 779 | memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); | 1240 | memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); |
| 780 | if (1 == pcontrol) | 1241 | if (1 == pcontrol) |
| 781 | memset(p + 2, 0, sizeof(ctrl_m_pg) - 2); | 1242 | memcpy(p + 2, ch_ctrl_m_pg, sizeof(ch_ctrl_m_pg)); |
| 1243 | else if (2 == pcontrol) | ||
| 1244 | memcpy(p, d_ctrl_m_pg, sizeof(d_ctrl_m_pg)); | ||
| 782 | return sizeof(ctrl_m_pg); | 1245 | return sizeof(ctrl_m_pg); |
| 783 | } | 1246 | } |
| 784 | 1247 | ||
| 1248 | |||
| 785 | static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target) | 1249 | static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target) |
| 786 | { /* Informational Exceptions control mode page for mode_sense */ | 1250 | { /* Informational Exceptions control mode page for mode_sense */ |
| 787 | unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | 1251 | unsigned char ch_iec_m_pg[] = {/* 0x1c, 0xa, */ 0x4, 0xf, 0, 0, 0, 0, |
| 788 | 0, 0, 0x0, 0x0}; | 1252 | 0, 0, 0x0, 0x0}; |
| 1253 | unsigned char d_iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | ||
| 1254 | 0, 0, 0x0, 0x0}; | ||
| 1255 | |||
| 789 | memcpy(p, iec_m_pg, sizeof(iec_m_pg)); | 1256 | memcpy(p, iec_m_pg, sizeof(iec_m_pg)); |
| 790 | if (1 == pcontrol) | 1257 | if (1 == pcontrol) |
| 791 | memset(p + 2, 0, sizeof(iec_m_pg) - 2); | 1258 | memcpy(p + 2, ch_iec_m_pg, sizeof(ch_iec_m_pg)); |
| 1259 | else if (2 == pcontrol) | ||
| 1260 | memcpy(p, d_iec_m_pg, sizeof(d_iec_m_pg)); | ||
| 792 | return sizeof(iec_m_pg); | 1261 | return sizeof(iec_m_pg); |
| 793 | } | 1262 | } |
| 794 | 1263 | ||
| 1264 | static int resp_sas_sf_m_pg(unsigned char * p, int pcontrol, int target) | ||
| 1265 | { /* SAS SSP mode page - short format for mode_sense */ | ||
| 1266 | unsigned char sas_sf_m_pg[] = {0x19, 0x6, | ||
| 1267 | 0x6, 0x0, 0x7, 0xd0, 0x0, 0x0}; | ||
| 1268 | |||
| 1269 | memcpy(p, sas_sf_m_pg, sizeof(sas_sf_m_pg)); | ||
| 1270 | if (1 == pcontrol) | ||
| 1271 | memset(p + 2, 0, sizeof(sas_sf_m_pg) - 2); | ||
| 1272 | return sizeof(sas_sf_m_pg); | ||
| 1273 | } | ||
| 1274 | |||
| 1275 | |||
| 1276 | static int resp_sas_pcd_m_spg(unsigned char * p, int pcontrol, int target, | ||
| 1277 | int target_dev_id) | ||
| 1278 | { /* SAS phy control and discover mode page for mode_sense */ | ||
| 1279 | unsigned char sas_pcd_m_pg[] = {0x59, 0x1, 0, 0x64, 0, 0x6, 0, 2, | ||
| 1280 | 0, 0, 0, 0, 0x10, 0x9, 0x8, 0x0, | ||
| 1281 | 0x52, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x0, | ||
| 1282 | 0x51, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1, | ||
| 1283 | 0x2, 0, 0, 0, 0, 0, 0, 0, | ||
| 1284 | 0x88, 0x99, 0, 0, 0, 0, 0, 0, | ||
| 1285 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 1286 | 0, 1, 0, 0, 0x10, 0x9, 0x8, 0x0, | ||
| 1287 | 0x52, 0x22, 0x22, 0x20, 0x0, 0x0, 0x0, 0x0, | ||
| 1288 | 0x51, 0x11, 0x11, 0x10, 0x0, 0x0, 0x0, 0x1, | ||
| 1289 | 0x3, 0, 0, 0, 0, 0, 0, 0, | ||
| 1290 | 0x88, 0x99, 0, 0, 0, 0, 0, 0, | ||
| 1291 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 1292 | }; | ||
| 1293 | int port_a, port_b; | ||
| 1294 | |||
| 1295 | port_a = target_dev_id + 1; | ||
| 1296 | port_b = port_a + 1; | ||
| 1297 | memcpy(p, sas_pcd_m_pg, sizeof(sas_pcd_m_pg)); | ||
| 1298 | p[20] = (port_a >> 24); | ||
| 1299 | p[21] = (port_a >> 16) & 0xff; | ||
| 1300 | p[22] = (port_a >> 8) & 0xff; | ||
| 1301 | p[23] = port_a & 0xff; | ||
| 1302 | p[48 + 20] = (port_b >> 24); | ||
| 1303 | p[48 + 21] = (port_b >> 16) & 0xff; | ||
| 1304 | p[48 + 22] = (port_b >> 8) & 0xff; | ||
| 1305 | p[48 + 23] = port_b & 0xff; | ||
| 1306 | if (1 == pcontrol) | ||
| 1307 | memset(p + 4, 0, sizeof(sas_pcd_m_pg) - 4); | ||
| 1308 | return sizeof(sas_pcd_m_pg); | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | static int resp_sas_sha_m_spg(unsigned char * p, int pcontrol) | ||
| 1312 | { /* SAS SSP shared protocol specific port mode subpage */ | ||
| 1313 | unsigned char sas_sha_m_pg[] = {0x59, 0x2, 0, 0xc, 0, 0x6, 0x10, 0, | ||
| 1314 | 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 1315 | }; | ||
| 1316 | |||
| 1317 | memcpy(p, sas_sha_m_pg, sizeof(sas_sha_m_pg)); | ||
| 1318 | if (1 == pcontrol) | ||
| 1319 | memset(p + 4, 0, sizeof(sas_sha_m_pg) - 4); | ||
| 1320 | return sizeof(sas_sha_m_pg); | ||
| 1321 | } | ||
| 1322 | |||
| 795 | #define SDEBUG_MAX_MSENSE_SZ 256 | 1323 | #define SDEBUG_MAX_MSENSE_SZ 256 |
| 796 | 1324 | ||
| 797 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, | 1325 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, |
| @@ -800,12 +1328,12 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
| 800 | unsigned char dbd; | 1328 | unsigned char dbd; |
| 801 | int pcontrol, pcode, subpcode; | 1329 | int pcontrol, pcode, subpcode; |
| 802 | unsigned char dev_spec; | 1330 | unsigned char dev_spec; |
| 803 | int alloc_len, msense_6, offset, len, errsts; | 1331 | int alloc_len, msense_6, offset, len, errsts, target_dev_id; |
| 804 | unsigned char * ap; | 1332 | unsigned char * ap; |
| 805 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; | 1333 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; |
| 806 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1334 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
| 807 | 1335 | ||
| 808 | if ((errsts = check_reset(scp, devip))) | 1336 | if ((errsts = check_readiness(scp, 1, devip))) |
| 809 | return errsts; | 1337 | return errsts; |
| 810 | dbd = cmd[1] & 0x8; | 1338 | dbd = cmd[1] & 0x8; |
| 811 | pcontrol = (cmd[2] & 0xc0) >> 6; | 1339 | pcontrol = (cmd[2] & 0xc0) >> 6; |
| @@ -819,6 +1347,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
| 819 | 0); | 1347 | 0); |
| 820 | return check_condition_result; | 1348 | return check_condition_result; |
| 821 | } | 1349 | } |
| 1350 | target_dev_id = ((devip->sdbg_host->shost->host_no + 1) * 2000) + | ||
| 1351 | (devip->target * 1000) - 3; | ||
| 822 | dev_spec = DEV_READONLY(target) ? 0x80 : 0x0; | 1352 | dev_spec = DEV_READONLY(target) ? 0x80 : 0x0; |
| 823 | if (msense_6) { | 1353 | if (msense_6) { |
| 824 | arr[2] = dev_spec; | 1354 | arr[2] = dev_spec; |
| @@ -829,7 +1359,8 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
| 829 | } | 1359 | } |
| 830 | ap = arr + offset; | 1360 | ap = arr + offset; |
| 831 | 1361 | ||
| 832 | if (0 != subpcode) { /* TODO: Control Extension page */ | 1362 | if ((subpcode > 0x0) && (subpcode < 0xff) && (0x19 != pcode)) { |
| 1363 | /* TODO: Control Extension page */ | ||
| 833 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1364 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
| 834 | 0); | 1365 | 0); |
| 835 | return check_condition_result; | 1366 | return check_condition_result; |
| @@ -855,17 +1386,45 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
| 855 | len = resp_ctrl_m_pg(ap, pcontrol, target); | 1386 | len = resp_ctrl_m_pg(ap, pcontrol, target); |
| 856 | offset += len; | 1387 | offset += len; |
| 857 | break; | 1388 | break; |
| 1389 | case 0x19: /* if spc==1 then sas phy, control+discover */ | ||
| 1390 | if ((subpcode > 0x2) && (subpcode < 0xff)) { | ||
| 1391 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 1392 | INVALID_FIELD_IN_CDB, 0); | ||
| 1393 | return check_condition_result; | ||
| 1394 | } | ||
| 1395 | len = 0; | ||
| 1396 | if ((0x0 == subpcode) || (0xff == subpcode)) | ||
| 1397 | len += resp_sas_sf_m_pg(ap + len, pcontrol, target); | ||
| 1398 | if ((0x1 == subpcode) || (0xff == subpcode)) | ||
| 1399 | len += resp_sas_pcd_m_spg(ap + len, pcontrol, target, | ||
| 1400 | target_dev_id); | ||
| 1401 | if ((0x2 == subpcode) || (0xff == subpcode)) | ||
| 1402 | len += resp_sas_sha_m_spg(ap + len, pcontrol); | ||
| 1403 | offset += len; | ||
| 1404 | break; | ||
| 858 | case 0x1c: /* Informational Exceptions Mode page, all devices */ | 1405 | case 0x1c: /* Informational Exceptions Mode page, all devices */ |
| 859 | len = resp_iec_m_pg(ap, pcontrol, target); | 1406 | len = resp_iec_m_pg(ap, pcontrol, target); |
| 860 | offset += len; | 1407 | offset += len; |
| 861 | break; | 1408 | break; |
| 862 | case 0x3f: /* Read all Mode pages */ | 1409 | case 0x3f: /* Read all Mode pages */ |
| 863 | len = resp_err_recov_pg(ap, pcontrol, target); | 1410 | if ((0 == subpcode) || (0xff == subpcode)) { |
| 864 | len += resp_disconnect_pg(ap + len, pcontrol, target); | 1411 | len = resp_err_recov_pg(ap, pcontrol, target); |
| 865 | len += resp_format_pg(ap + len, pcontrol, target); | 1412 | len += resp_disconnect_pg(ap + len, pcontrol, target); |
| 866 | len += resp_caching_pg(ap + len, pcontrol, target); | 1413 | len += resp_format_pg(ap + len, pcontrol, target); |
| 867 | len += resp_ctrl_m_pg(ap + len, pcontrol, target); | 1414 | len += resp_caching_pg(ap + len, pcontrol, target); |
| 868 | len += resp_iec_m_pg(ap + len, pcontrol, target); | 1415 | len += resp_ctrl_m_pg(ap + len, pcontrol, target); |
| 1416 | len += resp_sas_sf_m_pg(ap + len, pcontrol, target); | ||
| 1417 | if (0xff == subpcode) { | ||
| 1418 | len += resp_sas_pcd_m_spg(ap + len, pcontrol, | ||
| 1419 | target, target_dev_id); | ||
| 1420 | len += resp_sas_sha_m_spg(ap + len, pcontrol); | ||
| 1421 | } | ||
| 1422 | len += resp_iec_m_pg(ap + len, pcontrol, target); | ||
| 1423 | } else { | ||
| 1424 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 1425 | INVALID_FIELD_IN_CDB, 0); | ||
| 1426 | return check_condition_result; | ||
| 1427 | } | ||
| 869 | offset += len; | 1428 | offset += len; |
| 870 | break; | 1429 | break; |
| 871 | default: | 1430 | default: |
| @@ -882,71 +1441,274 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
| 882 | return fill_from_dev_buffer(scp, arr, min(alloc_len, offset)); | 1441 | return fill_from_dev_buffer(scp, arr, min(alloc_len, offset)); |
| 883 | } | 1442 | } |
| 884 | 1443 | ||
| 885 | static int resp_read(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 1444 | #define SDEBUG_MAX_MSELECT_SZ 512 |
| 886 | int num, struct sdebug_dev_info * devip) | 1445 | |
| 1446 | static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, | ||
| 1447 | struct sdebug_dev_info * devip) | ||
| 1448 | { | ||
| 1449 | int pf, sp, ps, md_len, bd_len, off, spf, pg_len; | ||
| 1450 | int param_len, res, errsts, mpage; | ||
| 1451 | unsigned char arr[SDEBUG_MAX_MSELECT_SZ]; | ||
| 1452 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
| 1453 | |||
| 1454 | if ((errsts = check_readiness(scp, 1, devip))) | ||
| 1455 | return errsts; | ||
| 1456 | memset(arr, 0, sizeof(arr)); | ||
| 1457 | pf = cmd[1] & 0x10; | ||
| 1458 | sp = cmd[1] & 0x1; | ||
| 1459 | param_len = mselect6 ? cmd[4] : ((cmd[7] << 8) + cmd[8]); | ||
| 1460 | if ((0 == pf) || sp || (param_len > SDEBUG_MAX_MSELECT_SZ)) { | ||
| 1461 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 1462 | INVALID_FIELD_IN_CDB, 0); | ||
| 1463 | return check_condition_result; | ||
| 1464 | } | ||
| 1465 | res = fetch_to_dev_buffer(scp, arr, param_len); | ||
| 1466 | if (-1 == res) | ||
| 1467 | return (DID_ERROR << 16); | ||
| 1468 | else if ((res < param_len) && | ||
| 1469 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | ||
| 1470 | printk(KERN_INFO "scsi_debug: mode_select: cdb indicated=%d, " | ||
| 1471 | " IO sent=%d bytes\n", param_len, res); | ||
| 1472 | md_len = mselect6 ? (arr[0] + 1) : ((arr[0] << 8) + arr[1] + 2); | ||
| 1473 | bd_len = mselect6 ? arr[3] : ((arr[6] << 8) + arr[7]); | ||
| 1474 | if ((md_len > 2) || (0 != bd_len)) { | ||
| 1475 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 1476 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
| 1477 | return check_condition_result; | ||
| 1478 | } | ||
| 1479 | off = bd_len + (mselect6 ? 4 : 8); | ||
| 1480 | mpage = arr[off] & 0x3f; | ||
| 1481 | ps = !!(arr[off] & 0x80); | ||
| 1482 | if (ps) { | ||
| 1483 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 1484 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
| 1485 | return check_condition_result; | ||
| 1486 | } | ||
| 1487 | spf = !!(arr[off] & 0x40); | ||
| 1488 | pg_len = spf ? ((arr[off + 2] << 8) + arr[off + 3] + 4) : | ||
| 1489 | (arr[off + 1] + 2); | ||
| 1490 | if ((pg_len + off) > param_len) { | ||
| 1491 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 1492 | PARAMETER_LIST_LENGTH_ERR, 0); | ||
| 1493 | return check_condition_result; | ||
| 1494 | } | ||
| 1495 | switch (mpage) { | ||
| 1496 | case 0xa: /* Control Mode page */ | ||
| 1497 | if (ctrl_m_pg[1] == arr[off + 1]) { | ||
| 1498 | memcpy(ctrl_m_pg + 2, arr + off + 2, | ||
| 1499 | sizeof(ctrl_m_pg) - 2); | ||
| 1500 | scsi_debug_dsense = !!(ctrl_m_pg[2] & 0x4); | ||
| 1501 | return 0; | ||
| 1502 | } | ||
| 1503 | break; | ||
| 1504 | case 0x1c: /* Informational Exceptions Mode page */ | ||
| 1505 | if (iec_m_pg[1] == arr[off + 1]) { | ||
| 1506 | memcpy(iec_m_pg + 2, arr + off + 2, | ||
| 1507 | sizeof(iec_m_pg) - 2); | ||
| 1508 | return 0; | ||
| 1509 | } | ||
| 1510 | break; | ||
| 1511 | default: | ||
| 1512 | break; | ||
| 1513 | } | ||
| 1514 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 1515 | INVALID_FIELD_IN_PARAM_LIST, 0); | ||
| 1516 | return check_condition_result; | ||
| 1517 | } | ||
| 1518 | |||
| 1519 | static int resp_temp_l_pg(unsigned char * arr) | ||
| 1520 | { | ||
| 1521 | unsigned char temp_l_pg[] = {0x0, 0x0, 0x3, 0x2, 0x0, 38, | ||
| 1522 | 0x0, 0x1, 0x3, 0x2, 0x0, 65, | ||
| 1523 | }; | ||
| 1524 | |||
| 1525 | memcpy(arr, temp_l_pg, sizeof(temp_l_pg)); | ||
| 1526 | return sizeof(temp_l_pg); | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | static int resp_ie_l_pg(unsigned char * arr) | ||
| 1530 | { | ||
| 1531 | unsigned char ie_l_pg[] = {0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 38, | ||
| 1532 | }; | ||
| 1533 | |||
| 1534 | memcpy(arr, ie_l_pg, sizeof(ie_l_pg)); | ||
| 1535 | if (iec_m_pg[2] & 0x4) { /* TEST bit set */ | ||
| 1536 | arr[4] = THRESHOLD_EXCEEDED; | ||
| 1537 | arr[5] = 0xff; | ||
| 1538 | } | ||
| 1539 | return sizeof(ie_l_pg); | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | #define SDEBUG_MAX_LSENSE_SZ 512 | ||
| 1543 | |||
| 1544 | static int resp_log_sense(struct scsi_cmnd * scp, | ||
| 1545 | struct sdebug_dev_info * devip) | ||
| 1546 | { | ||
| 1547 | int ppc, sp, pcontrol, pcode, alloc_len, errsts, len, n; | ||
| 1548 | unsigned char arr[SDEBUG_MAX_LSENSE_SZ]; | ||
| 1549 | unsigned char *cmd = (unsigned char *)scp->cmnd; | ||
| 1550 | |||
| 1551 | if ((errsts = check_readiness(scp, 1, devip))) | ||
| 1552 | return errsts; | ||
| 1553 | memset(arr, 0, sizeof(arr)); | ||
| 1554 | ppc = cmd[1] & 0x2; | ||
| 1555 | sp = cmd[1] & 0x1; | ||
| 1556 | if (ppc || sp) { | ||
| 1557 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 1558 | INVALID_FIELD_IN_CDB, 0); | ||
| 1559 | return check_condition_result; | ||
| 1560 | } | ||
| 1561 | pcontrol = (cmd[2] & 0xc0) >> 6; | ||
| 1562 | pcode = cmd[2] & 0x3f; | ||
| 1563 | alloc_len = (cmd[7] << 8) + cmd[8]; | ||
| 1564 | arr[0] = pcode; | ||
| 1565 | switch (pcode) { | ||
| 1566 | case 0x0: /* Supported log pages log page */ | ||
| 1567 | n = 4; | ||
| 1568 | arr[n++] = 0x0; /* this page */ | ||
| 1569 | arr[n++] = 0xd; /* Temperature */ | ||
| 1570 | arr[n++] = 0x2f; /* Informational exceptions */ | ||
| 1571 | arr[3] = n - 4; | ||
| 1572 | break; | ||
| 1573 | case 0xd: /* Temperature log page */ | ||
| 1574 | arr[3] = resp_temp_l_pg(arr + 4); | ||
| 1575 | break; | ||
| 1576 | case 0x2f: /* Informational exceptions log page */ | ||
| 1577 | arr[3] = resp_ie_l_pg(arr + 4); | ||
| 1578 | break; | ||
| 1579 | default: | ||
| 1580 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
| 1581 | INVALID_FIELD_IN_CDB, 0); | ||
| 1582 | return check_condition_result; | ||
| 1583 | } | ||
| 1584 | len = min(((arr[2] << 8) + arr[3]) + 4, alloc_len); | ||
| 1585 | return fill_from_dev_buffer(scp, arr, | ||
| 1586 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); | ||
| 1587 | } | ||
| 1588 | |||
| 1589 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
| 1590 | unsigned int num, struct sdebug_dev_info * devip) | ||
| 887 | { | 1591 | { |
| 888 | unsigned long iflags; | 1592 | unsigned long iflags; |
| 1593 | unsigned int block, from_bottom; | ||
| 1594 | unsigned long long u; | ||
| 889 | int ret; | 1595 | int ret; |
| 890 | 1596 | ||
| 891 | if (upper_blk || (block + num > sdebug_capacity)) { | 1597 | if (lba + num > sdebug_capacity) { |
| 892 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1598 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, |
| 893 | 0); | 1599 | 0); |
| 894 | return check_condition_result; | 1600 | return check_condition_result; |
| 895 | } | 1601 | } |
| 1602 | /* transfer length excessive (tie in to block limits VPD page) */ | ||
| 1603 | if (num > sdebug_store_sectors) { | ||
| 1604 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
| 1605 | 0); | ||
| 1606 | return check_condition_result; | ||
| 1607 | } | ||
| 896 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && | 1608 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && |
| 897 | (block <= OPT_MEDIUM_ERR_ADDR) && | 1609 | (lba <= OPT_MEDIUM_ERR_ADDR) && |
| 898 | ((block + num) > OPT_MEDIUM_ERR_ADDR)) { | 1610 | ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { |
| 1611 | /* claim unrecoverable read error */ | ||
| 899 | mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, | 1612 | mk_sense_buffer(devip, MEDIUM_ERROR, UNRECOVERED_READ_ERR, |
| 900 | 0); | 1613 | 0); |
| 901 | /* claim unrecoverable read error */ | 1614 | /* set info field and valid bit for fixed descriptor */ |
| 1615 | if (0x70 == (devip->sense_buff[0] & 0x7f)) { | ||
| 1616 | devip->sense_buff[0] |= 0x80; /* Valid bit */ | ||
| 1617 | ret = OPT_MEDIUM_ERR_ADDR; | ||
| 1618 | devip->sense_buff[3] = (ret >> 24) & 0xff; | ||
| 1619 | devip->sense_buff[4] = (ret >> 16) & 0xff; | ||
| 1620 | devip->sense_buff[5] = (ret >> 8) & 0xff; | ||
| 1621 | devip->sense_buff[6] = ret & 0xff; | ||
| 1622 | } | ||
| 902 | return check_condition_result; | 1623 | return check_condition_result; |
| 903 | } | 1624 | } |
| 904 | read_lock_irqsave(&atomic_rw, iflags); | 1625 | read_lock_irqsave(&atomic_rw, iflags); |
| 905 | ret = fill_from_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE), | 1626 | if ((lba + num) <= sdebug_store_sectors) |
| 906 | num * SECT_SIZE); | 1627 | ret = fill_from_dev_buffer(SCpnt, |
| 1628 | fake_storep + (lba * SECT_SIZE), | ||
| 1629 | num * SECT_SIZE); | ||
| 1630 | else { | ||
| 1631 | /* modulo when one arg is 64 bits needs do_div() */ | ||
| 1632 | u = lba; | ||
| 1633 | block = do_div(u, sdebug_store_sectors); | ||
| 1634 | from_bottom = 0; | ||
| 1635 | if ((block + num) > sdebug_store_sectors) | ||
| 1636 | from_bottom = (block + num) - sdebug_store_sectors; | ||
| 1637 | ret = fill_from_dev_buffer(SCpnt, | ||
| 1638 | fake_storep + (block * SECT_SIZE), | ||
| 1639 | (num - from_bottom) * SECT_SIZE); | ||
| 1640 | if ((0 == ret) && (from_bottom > 0)) | ||
| 1641 | ret = fill_from_dev_buffer(SCpnt, fake_storep, | ||
| 1642 | from_bottom * SECT_SIZE); | ||
| 1643 | } | ||
| 907 | read_unlock_irqrestore(&atomic_rw, iflags); | 1644 | read_unlock_irqrestore(&atomic_rw, iflags); |
| 908 | return ret; | 1645 | return ret; |
| 909 | } | 1646 | } |
| 910 | 1647 | ||
| 911 | static int resp_write(struct scsi_cmnd * SCpnt, int upper_blk, int block, | 1648 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, |
| 912 | int num, struct sdebug_dev_info * devip) | 1649 | unsigned int num, struct sdebug_dev_info * devip) |
| 913 | { | 1650 | { |
| 914 | unsigned long iflags; | 1651 | unsigned long iflags; |
| 1652 | unsigned int block, to_bottom; | ||
| 1653 | unsigned long long u; | ||
| 915 | int res; | 1654 | int res; |
| 916 | 1655 | ||
| 917 | if (upper_blk || (block + num > sdebug_capacity)) { | 1656 | if (lba + num > sdebug_capacity) { |
| 918 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1657 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, |
| 919 | 0); | 1658 | 0); |
| 920 | return check_condition_result; | 1659 | return check_condition_result; |
| 921 | } | 1660 | } |
| 1661 | /* transfer length excessive (tie in to block limits VPD page) */ | ||
| 1662 | if (num > sdebug_store_sectors) { | ||
| 1663 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
| 1664 | 0); | ||
| 1665 | return check_condition_result; | ||
| 1666 | } | ||
| 922 | 1667 | ||
| 923 | write_lock_irqsave(&atomic_rw, iflags); | 1668 | write_lock_irqsave(&atomic_rw, iflags); |
| 924 | res = fetch_to_dev_buffer(SCpnt, fake_storep + (block * SECT_SIZE), | 1669 | if ((lba + num) <= sdebug_store_sectors) |
| 925 | num * SECT_SIZE); | 1670 | res = fetch_to_dev_buffer(SCpnt, |
| 1671 | fake_storep + (lba * SECT_SIZE), | ||
| 1672 | num * SECT_SIZE); | ||
| 1673 | else { | ||
| 1674 | /* modulo when one arg is 64 bits needs do_div() */ | ||
| 1675 | u = lba; | ||
| 1676 | block = do_div(u, sdebug_store_sectors); | ||
| 1677 | to_bottom = 0; | ||
| 1678 | if ((block + num) > sdebug_store_sectors) | ||
| 1679 | to_bottom = (block + num) - sdebug_store_sectors; | ||
| 1680 | res = fetch_to_dev_buffer(SCpnt, | ||
| 1681 | fake_storep + (block * SECT_SIZE), | ||
| 1682 | (num - to_bottom) * SECT_SIZE); | ||
| 1683 | if ((0 == res) && (to_bottom > 0)) | ||
| 1684 | res = fetch_to_dev_buffer(SCpnt, fake_storep, | ||
| 1685 | to_bottom * SECT_SIZE); | ||
| 1686 | } | ||
| 926 | write_unlock_irqrestore(&atomic_rw, iflags); | 1687 | write_unlock_irqrestore(&atomic_rw, iflags); |
| 927 | if (-1 == res) | 1688 | if (-1 == res) |
| 928 | return (DID_ERROR << 16); | 1689 | return (DID_ERROR << 16); |
| 929 | else if ((res < (num * SECT_SIZE)) && | 1690 | else if ((res < (num * SECT_SIZE)) && |
| 930 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 1691 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
| 931 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%d, " | 1692 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, " |
| 932 | " IO sent=%d bytes\n", num * SECT_SIZE, res); | 1693 | " IO sent=%d bytes\n", num * SECT_SIZE, res); |
| 933 | return 0; | 1694 | return 0; |
| 934 | } | 1695 | } |
| 935 | 1696 | ||
| 936 | #define SDEBUG_RLUN_ARR_SZ 128 | 1697 | #define SDEBUG_RLUN_ARR_SZ 256 |
| 937 | 1698 | ||
| 938 | static int resp_report_luns(struct scsi_cmnd * scp, | 1699 | static int resp_report_luns(struct scsi_cmnd * scp, |
| 939 | struct sdebug_dev_info * devip) | 1700 | struct sdebug_dev_info * devip) |
| 940 | { | 1701 | { |
| 941 | unsigned int alloc_len; | 1702 | unsigned int alloc_len; |
| 942 | int lun_cnt, i, upper; | 1703 | int lun_cnt, i, upper, num, n, wlun, lun; |
| 943 | unsigned char *cmd = (unsigned char *)scp->cmnd; | 1704 | unsigned char *cmd = (unsigned char *)scp->cmnd; |
| 944 | int select_report = (int)cmd[2]; | 1705 | int select_report = (int)cmd[2]; |
| 945 | struct scsi_lun *one_lun; | 1706 | struct scsi_lun *one_lun; |
| 946 | unsigned char arr[SDEBUG_RLUN_ARR_SZ]; | 1707 | unsigned char arr[SDEBUG_RLUN_ARR_SZ]; |
| 1708 | unsigned char * max_addr; | ||
| 947 | 1709 | ||
| 948 | alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); | 1710 | alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); |
| 949 | if ((alloc_len < 16) || (select_report > 2)) { | 1711 | if ((alloc_len < 4) || (select_report > 2)) { |
| 950 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1712 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, |
| 951 | 0); | 1713 | 0); |
| 952 | return check_condition_result; | 1714 | return check_condition_result; |
| @@ -954,18 +1716,37 @@ static int resp_report_luns(struct scsi_cmnd * scp, | |||
| 954 | /* can produce response with up to 16k luns (lun 0 to lun 16383) */ | 1716 | /* can produce response with up to 16k luns (lun 0 to lun 16383) */ |
| 955 | memset(arr, 0, SDEBUG_RLUN_ARR_SZ); | 1717 | memset(arr, 0, SDEBUG_RLUN_ARR_SZ); |
| 956 | lun_cnt = scsi_debug_max_luns; | 1718 | lun_cnt = scsi_debug_max_luns; |
| 957 | arr[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff; | 1719 | if (1 == select_report) |
| 958 | arr[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff; | 1720 | lun_cnt = 0; |
| 959 | lun_cnt = min((int)((SDEBUG_RLUN_ARR_SZ - 8) / | 1721 | else if (scsi_debug_no_lun_0 && (lun_cnt > 0)) |
| 960 | sizeof(struct scsi_lun)), lun_cnt); | 1722 | --lun_cnt; |
| 1723 | wlun = (select_report > 0) ? 1 : 0; | ||
| 1724 | num = lun_cnt + wlun; | ||
| 1725 | arr[2] = ((sizeof(struct scsi_lun) * num) >> 8) & 0xff; | ||
| 1726 | arr[3] = (sizeof(struct scsi_lun) * num) & 0xff; | ||
| 1727 | n = min((int)((SDEBUG_RLUN_ARR_SZ - 8) / | ||
| 1728 | sizeof(struct scsi_lun)), num); | ||
| 1729 | if (n < num) { | ||
| 1730 | wlun = 0; | ||
| 1731 | lun_cnt = n; | ||
| 1732 | } | ||
| 961 | one_lun = (struct scsi_lun *) &arr[8]; | 1733 | one_lun = (struct scsi_lun *) &arr[8]; |
| 962 | for (i = 0; i < lun_cnt; i++) { | 1734 | max_addr = arr + SDEBUG_RLUN_ARR_SZ; |
| 963 | upper = (i >> 8) & 0x3f; | 1735 | for (i = 0, lun = (scsi_debug_no_lun_0 ? 1 : 0); |
| 1736 | ((i < lun_cnt) && ((unsigned char *)(one_lun + i) < max_addr)); | ||
| 1737 | i++, lun++) { | ||
| 1738 | upper = (lun >> 8) & 0x3f; | ||
| 964 | if (upper) | 1739 | if (upper) |
| 965 | one_lun[i].scsi_lun[0] = | 1740 | one_lun[i].scsi_lun[0] = |
| 966 | (upper | (SAM2_LUN_ADDRESS_METHOD << 6)); | 1741 | (upper | (SAM2_LUN_ADDRESS_METHOD << 6)); |
| 967 | one_lun[i].scsi_lun[1] = i & 0xff; | 1742 | one_lun[i].scsi_lun[1] = lun & 0xff; |
| 1743 | } | ||
| 1744 | if (wlun) { | ||
| 1745 | one_lun[i].scsi_lun[0] = (SAM2_WLUN_REPORT_LUNS >> 8) & 0xff; | ||
| 1746 | one_lun[i].scsi_lun[1] = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
| 1747 | i++; | ||
| 968 | } | 1748 | } |
| 1749 | alloc_len = (unsigned char *)(one_lun + i) - arr; | ||
| 969 | return fill_from_dev_buffer(scp, arr, | 1750 | return fill_from_dev_buffer(scp, arr, |
| 970 | min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); | 1751 | min((int)alloc_len, SDEBUG_RLUN_ARR_SZ)); |
| 971 | } | 1752 | } |
| @@ -1001,7 +1782,8 @@ static void timer_intr_handler(unsigned long indx) | |||
| 1001 | static int scsi_debug_slave_alloc(struct scsi_device * sdp) | 1782 | static int scsi_debug_slave_alloc(struct scsi_device * sdp) |
| 1002 | { | 1783 | { |
| 1003 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1784 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
| 1004 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_alloc\n"); | 1785 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", |
| 1786 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
| 1005 | return 0; | 1787 | return 0; |
| 1006 | } | 1788 | } |
| 1007 | 1789 | ||
| @@ -1010,7 +1792,8 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
| 1010 | struct sdebug_dev_info * devip; | 1792 | struct sdebug_dev_info * devip; |
| 1011 | 1793 | ||
| 1012 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1794 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
| 1013 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_configure\n"); | 1795 | printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n", |
| 1796 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
| 1014 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) | 1797 | if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) |
| 1015 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; | 1798 | sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; |
| 1016 | devip = devInfoReg(sdp); | 1799 | devip = devInfoReg(sdp); |
| @@ -1018,6 +1801,7 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
| 1018 | if (sdp->host->cmd_per_lun) | 1801 | if (sdp->host->cmd_per_lun) |
| 1019 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, | 1802 | scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING, |
| 1020 | sdp->host->cmd_per_lun); | 1803 | sdp->host->cmd_per_lun); |
| 1804 | blk_queue_max_segment_size(sdp->request_queue, 256 * 1024); | ||
| 1021 | return 0; | 1805 | return 0; |
| 1022 | } | 1806 | } |
| 1023 | 1807 | ||
| @@ -1027,7 +1811,8 @@ static void scsi_debug_slave_destroy(struct scsi_device * sdp) | |||
| 1027 | (struct sdebug_dev_info *)sdp->hostdata; | 1811 | (struct sdebug_dev_info *)sdp->hostdata; |
| 1028 | 1812 | ||
| 1029 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1813 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
| 1030 | sdev_printk(KERN_INFO, sdp, "scsi_debug: slave_destroy\n"); | 1814 | printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", |
| 1815 | sdp->host->host_no, sdp->channel, sdp->id, sdp->lun); | ||
| 1031 | if (devip) { | 1816 | if (devip) { |
| 1032 | /* make this slot avaliable for re-use */ | 1817 | /* make this slot avaliable for re-use */ |
| 1033 | devip->used = 0; | 1818 | devip->used = 0; |
| @@ -1084,6 +1869,8 @@ static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | |||
| 1084 | open_devip->sense_buff[0] = 0x70; | 1869 | open_devip->sense_buff[0] = 0x70; |
| 1085 | open_devip->sense_buff[7] = 0xa; | 1870 | open_devip->sense_buff[7] = 0xa; |
| 1086 | } | 1871 | } |
| 1872 | if (sdev->lun == SAM2_WLUN_REPORT_LUNS) | ||
| 1873 | open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
| 1087 | return open_devip; | 1874 | return open_devip; |
| 1088 | } | 1875 | } |
| 1089 | return NULL; | 1876 | return NULL; |
| @@ -1272,7 +2059,7 @@ static void __init sdebug_build_parts(unsigned char * ramp) | |||
| 1272 | printk(KERN_WARNING "scsi_debug:build_parts: reducing " | 2059 | printk(KERN_WARNING "scsi_debug:build_parts: reducing " |
| 1273 | "partitions to %d\n", SDEBUG_MAX_PARTS); | 2060 | "partitions to %d\n", SDEBUG_MAX_PARTS); |
| 1274 | } | 2061 | } |
| 1275 | num_sectors = (int)(sdebug_store_size / SECT_SIZE); | 2062 | num_sectors = (int)sdebug_store_sectors; |
| 1276 | sectors_per_part = (num_sectors - sdebug_sectors_per) | 2063 | sectors_per_part = (num_sectors - sdebug_sectors_per) |
| 1277 | / scsi_debug_num_parts; | 2064 | / scsi_debug_num_parts; |
| 1278 | heads_by_sects = sdebug_heads * sdebug_sectors_per; | 2065 | heads_by_sects = sdebug_heads * sdebug_sectors_per; |
| @@ -1315,9 +2102,9 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
| 1315 | if (scsi_result) { | 2102 | if (scsi_result) { |
| 1316 | struct scsi_device * sdp = cmnd->device; | 2103 | struct scsi_device * sdp = cmnd->device; |
| 1317 | 2104 | ||
| 1318 | sdev_printk(KERN_INFO, sdp, | 2105 | printk(KERN_INFO "scsi_debug: <%u %u %u %u> " |
| 1319 | "non-zero result=0x%x\n", | 2106 | "non-zero result=0x%x\n", sdp->host->host_no, |
| 1320 | scsi_result); | 2107 | sdp->channel, sdp->id, sdp->lun, scsi_result); |
| 1321 | } | 2108 | } |
| 1322 | } | 2109 | } |
| 1323 | if (cmnd && devip) { | 2110 | if (cmnd && devip) { |
| @@ -1364,21 +2151,19 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
| 1364 | } | 2151 | } |
| 1365 | } | 2152 | } |
| 1366 | 2153 | ||
| 1367 | /* Set 'perm' (4th argument) to 0 to disable module_param's definition | 2154 | module_param_named(add_host, scsi_debug_add_host, int, S_IRUGO | S_IWUSR); |
| 1368 | * of sysfs parameters (which module_param doesn't yet support). | 2155 | module_param_named(delay, scsi_debug_delay, int, S_IRUGO | S_IWUSR); |
| 1369 | * Sysfs parameters defined explicitly below. | 2156 | module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, S_IRUGO); |
| 1370 | */ | 2157 | module_param_named(dsense, scsi_debug_dsense, int, S_IRUGO | S_IWUSR); |
| 1371 | module_param_named(add_host, scsi_debug_add_host, int, 0); /* perm=0644 */ | 2158 | module_param_named(every_nth, scsi_debug_every_nth, int, S_IRUGO | S_IWUSR); |
| 1372 | module_param_named(delay, scsi_debug_delay, int, 0); /* perm=0644 */ | 2159 | module_param_named(max_luns, scsi_debug_max_luns, int, S_IRUGO | S_IWUSR); |
| 1373 | module_param_named(dev_size_mb, scsi_debug_dev_size_mb, int, 0); | 2160 | module_param_named(no_lun_0, scsi_debug_no_lun_0, int, S_IRUGO | S_IWUSR); |
| 1374 | module_param_named(dsense, scsi_debug_dsense, int, 0); | 2161 | module_param_named(num_parts, scsi_debug_num_parts, int, S_IRUGO); |
| 1375 | module_param_named(every_nth, scsi_debug_every_nth, int, 0); | 2162 | module_param_named(num_tgts, scsi_debug_num_tgts, int, S_IRUGO | S_IWUSR); |
| 1376 | module_param_named(max_luns, scsi_debug_max_luns, int, 0); | 2163 | module_param_named(opts, scsi_debug_opts, int, S_IRUGO | S_IWUSR); |
| 1377 | module_param_named(num_parts, scsi_debug_num_parts, int, 0); | 2164 | module_param_named(ptype, scsi_debug_ptype, int, S_IRUGO | S_IWUSR); |
| 1378 | module_param_named(num_tgts, scsi_debug_num_tgts, int, 0); | 2165 | module_param_named(scsi_level, scsi_debug_scsi_level, int, S_IRUGO); |
| 1379 | module_param_named(opts, scsi_debug_opts, int, 0); /* perm=0644 */ | 2166 | module_param_named(virtual_gb, scsi_debug_virtual_gb, int, S_IRUGO | S_IWUSR); |
| 1380 | module_param_named(ptype, scsi_debug_ptype, int, 0); | ||
| 1381 | module_param_named(scsi_level, scsi_debug_scsi_level, int, 0); | ||
| 1382 | 2167 | ||
| 1383 | MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); | 2168 | MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); |
| 1384 | MODULE_DESCRIPTION("SCSI debug adapter driver"); | 2169 | MODULE_DESCRIPTION("SCSI debug adapter driver"); |
| @@ -1387,15 +2172,17 @@ MODULE_VERSION(SCSI_DEBUG_VERSION); | |||
| 1387 | 2172 | ||
| 1388 | MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); | 2173 | MODULE_PARM_DESC(add_host, "0..127 hosts allowed(def=1)"); |
| 1389 | MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); | 2174 | MODULE_PARM_DESC(delay, "# of jiffies to delay response(def=1)"); |
| 1390 | MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs"); | 2175 | MODULE_PARM_DESC(dev_size_mb, "size in MB of ram shared by devs(def=8)"); |
| 1391 | MODULE_PARM_DESC(dsense, "use descriptor sense format(def: fixed)"); | 2176 | MODULE_PARM_DESC(dsense, "use descriptor sense format(def=0 -> fixed)"); |
| 1392 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)"); | 2177 | MODULE_PARM_DESC(every_nth, "timeout every nth command(def=100)"); |
| 1393 | MODULE_PARM_DESC(max_luns, "number of SCSI LUNs per target to simulate"); | 2178 | MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); |
| 2179 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); | ||
| 1394 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); | 2180 | MODULE_PARM_DESC(num_parts, "number of partitions(def=0)"); |
| 1395 | MODULE_PARM_DESC(num_tgts, "number of SCSI targets per host to simulate"); | 2181 | MODULE_PARM_DESC(num_tgts, "number of targets per host to simulate(def=1)"); |
| 1396 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->..."); | 2182 | MODULE_PARM_DESC(opts, "1->noise, 2->medium_error, 4->... (def=0)"); |
| 1397 | MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); | 2183 | MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])"); |
| 1398 | MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); | 2184 | MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=5[SPC-3])"); |
| 2185 | MODULE_PARM_DESC(virtual_gb, "virtual gigabyte size (def=0 -> use dev_size_mb)"); | ||
| 1399 | 2186 | ||
| 1400 | 2187 | ||
| 1401 | static char sdebug_info[256]; | 2188 | static char sdebug_info[256]; |
| @@ -1547,6 +2334,24 @@ static ssize_t sdebug_dsense_store(struct device_driver * ddp, | |||
| 1547 | DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show, | 2334 | DRIVER_ATTR(dsense, S_IRUGO | S_IWUSR, sdebug_dsense_show, |
| 1548 | sdebug_dsense_store); | 2335 | sdebug_dsense_store); |
| 1549 | 2336 | ||
| 2337 | static ssize_t sdebug_no_lun_0_show(struct device_driver * ddp, char * buf) | ||
| 2338 | { | ||
| 2339 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_no_lun_0); | ||
| 2340 | } | ||
| 2341 | static ssize_t sdebug_no_lun_0_store(struct device_driver * ddp, | ||
| 2342 | const char * buf, size_t count) | ||
| 2343 | { | ||
| 2344 | int n; | ||
| 2345 | |||
| 2346 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | ||
| 2347 | scsi_debug_no_lun_0 = n; | ||
| 2348 | return count; | ||
| 2349 | } | ||
| 2350 | return -EINVAL; | ||
| 2351 | } | ||
| 2352 | DRIVER_ATTR(no_lun_0, S_IRUGO | S_IWUSR, sdebug_no_lun_0_show, | ||
| 2353 | sdebug_no_lun_0_store); | ||
| 2354 | |||
| 1550 | static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) | 2355 | static ssize_t sdebug_num_tgts_show(struct device_driver * ddp, char * buf) |
| 1551 | { | 2356 | { |
| 1552 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts); | 2357 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_num_tgts); |
| @@ -1622,6 +2427,29 @@ static ssize_t sdebug_scsi_level_show(struct device_driver * ddp, char * buf) | |||
| 1622 | } | 2427 | } |
| 1623 | DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL); | 2428 | DRIVER_ATTR(scsi_level, S_IRUGO, sdebug_scsi_level_show, NULL); |
| 1624 | 2429 | ||
| 2430 | static ssize_t sdebug_virtual_gb_show(struct device_driver * ddp, char * buf) | ||
| 2431 | { | ||
| 2432 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_virtual_gb); | ||
| 2433 | } | ||
| 2434 | static ssize_t sdebug_virtual_gb_store(struct device_driver * ddp, | ||
| 2435 | const char * buf, size_t count) | ||
| 2436 | { | ||
| 2437 | int n; | ||
| 2438 | |||
| 2439 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | ||
| 2440 | scsi_debug_virtual_gb = n; | ||
| 2441 | if (scsi_debug_virtual_gb > 0) { | ||
| 2442 | sdebug_capacity = 2048 * 1024; | ||
| 2443 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
| 2444 | } else | ||
| 2445 | sdebug_capacity = sdebug_store_sectors; | ||
| 2446 | return count; | ||
| 2447 | } | ||
| 2448 | return -EINVAL; | ||
| 2449 | } | ||
| 2450 | DRIVER_ATTR(virtual_gb, S_IRUGO | S_IWUSR, sdebug_virtual_gb_show, | ||
| 2451 | sdebug_virtual_gb_store); | ||
| 2452 | |||
| 1625 | static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) | 2453 | static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) |
| 1626 | { | 2454 | { |
| 1627 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host); | 2455 | return scnprintf(buf, PAGE_SIZE, "%d\n", scsi_debug_add_host); |
| @@ -1691,14 +2519,19 @@ static void do_remove_driverfs_files(void) | |||
| 1691 | 2519 | ||
| 1692 | static int __init scsi_debug_init(void) | 2520 | static int __init scsi_debug_init(void) |
| 1693 | { | 2521 | { |
| 1694 | unsigned long sz; | 2522 | unsigned int sz; |
| 1695 | int host_to_add; | 2523 | int host_to_add; |
| 1696 | int k; | 2524 | int k; |
| 1697 | 2525 | ||
| 1698 | if (scsi_debug_dev_size_mb < 1) | 2526 | if (scsi_debug_dev_size_mb < 1) |
| 1699 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ | 2527 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ |
| 1700 | sdebug_store_size = (unsigned long)scsi_debug_dev_size_mb * 1048576; | 2528 | sdebug_store_size = (unsigned int)scsi_debug_dev_size_mb * 1048576; |
| 1701 | sdebug_capacity = sdebug_store_size / SECT_SIZE; | 2529 | sdebug_store_sectors = sdebug_store_size / SECT_SIZE; |
| 2530 | if (scsi_debug_virtual_gb > 0) { | ||
| 2531 | sdebug_capacity = 2048 * 1024; | ||
| 2532 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
| 2533 | } else | ||
| 2534 | sdebug_capacity = sdebug_store_sectors; | ||
| 1702 | 2535 | ||
| 1703 | /* play around with geometry, don't waste too much on track 0 */ | 2536 | /* play around with geometry, don't waste too much on track 0 */ |
| 1704 | sdebug_heads = 8; | 2537 | sdebug_heads = 8; |
| @@ -1812,7 +2645,7 @@ static int sdebug_add_adapter(void) | |||
| 1812 | struct sdebug_dev_info *sdbg_devinfo; | 2645 | struct sdebug_dev_info *sdbg_devinfo; |
| 1813 | struct list_head *lh, *lh_sf; | 2646 | struct list_head *lh, *lh_sf; |
| 1814 | 2647 | ||
| 1815 | sdbg_host = kzalloc(sizeof(*sdbg_host), GFP_KERNEL); | 2648 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); |
| 1816 | 2649 | ||
| 1817 | if (NULL == sdbg_host) { | 2650 | if (NULL == sdbg_host) { |
| 1818 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2651 | printk(KERN_ERR "%s: out of memory at line %d\n", |
| @@ -1824,7 +2657,7 @@ static int sdebug_add_adapter(void) | |||
| 1824 | 2657 | ||
| 1825 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; | 2658 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; |
| 1826 | for (k = 0; k < devs_per_host; k++) { | 2659 | for (k = 0; k < devs_per_host; k++) { |
| 1827 | sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo), GFP_KERNEL); | 2660 | sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo),GFP_KERNEL); |
| 1828 | if (NULL == sdbg_devinfo) { | 2661 | if (NULL == sdbg_devinfo) { |
| 1829 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2662 | printk(KERN_ERR "%s: out of memory at line %d\n", |
| 1830 | __FUNCTION__, __LINE__); | 2663 | __FUNCTION__, __LINE__); |
| @@ -1905,7 +2738,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
| 1905 | hpnt->max_id = scsi_debug_num_tgts + 1; | 2738 | hpnt->max_id = scsi_debug_num_tgts + 1; |
| 1906 | else | 2739 | else |
| 1907 | hpnt->max_id = scsi_debug_num_tgts; | 2740 | hpnt->max_id = scsi_debug_num_tgts; |
| 1908 | hpnt->max_lun = scsi_debug_max_luns; | 2741 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* = scsi_debug_max_luns; */ |
| 1909 | 2742 | ||
| 1910 | error = scsi_add_host(hpnt, &sdbg_host->dev); | 2743 | error = scsi_add_host(hpnt, &sdbg_host->dev); |
| 1911 | if (error) { | 2744 | if (error) { |
| @@ -1959,7 +2792,7 @@ static void sdebug_max_tgts_luns(void) | |||
| 1959 | hpnt->max_id = scsi_debug_num_tgts + 1; | 2792 | hpnt->max_id = scsi_debug_num_tgts + 1; |
| 1960 | else | 2793 | else |
| 1961 | hpnt->max_id = scsi_debug_num_tgts; | 2794 | hpnt->max_id = scsi_debug_num_tgts; |
| 1962 | hpnt->max_lun = scsi_debug_max_luns; | 2795 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* scsi_debug_max_luns; */ |
| 1963 | } | 2796 | } |
| 1964 | spin_unlock(&sdebug_host_list_lock); | 2797 | spin_unlock(&sdebug_host_list_lock); |
| 1965 | } | 2798 | } |
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..08af9aae7df3 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,70 @@ 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 | SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, " |
| 925 | SCSI_LOG_HLCOMPLETE(1, printk("%ld sectors total, %d bytes done.\n", | 924 | "%d bytes done.\n", |
| 926 | req->nr_sectors, good_bytes)); | 925 | req->nr_sectors, good_bytes)); |
| 927 | SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg)); | 926 | SCSI_LOG_HLCOMPLETE(1, printk("use_sg is %d\n", cmd->use_sg)); |
| 928 | 927 | ||
| 929 | if (clear_errors) | 928 | if (clear_errors) |
| 930 | req->errors = 0; | 929 | 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 | 930 | ||
| 943 | /* | 931 | /* A number of bytes were successfully read. If there |
| 944 | * If the command completed without error, then either | 932 | * are leftovers and there is some kind of error |
| 945 | * finish off the rest of the command, or start a new one. | 933 | * (result != 0), retry the rest. |
| 946 | */ | 934 | */ |
| 947 | if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL) | 935 | if (scsi_end_request(cmd, 1, good_bytes, result == 0) == NULL) |
| 948 | return; | 936 | return; |
| 949 | } | 937 | |
| 950 | /* | 938 | /* good_bytes = 0, or (inclusive) there were leftovers and |
| 951 | * Now, if we were good little boys and girls, Santa left us a request | 939 | * result = 0, so scsi_end_request couldn't retry. |
| 952 | * sense buffer. We can extract information from this, so we | ||
| 953 | * can choose a block to remap, etc. | ||
| 954 | */ | 940 | */ |
| 955 | if (sense_valid && !sense_deferred) { | 941 | if (sense_valid && !sense_deferred) { |
| 956 | switch (sshdr.sense_key) { | 942 | switch (sshdr.sense_key) { |
| 957 | case UNIT_ATTENTION: | 943 | case UNIT_ATTENTION: |
| 958 | if (cmd->device->removable) { | 944 | if (cmd->device->removable) { |
| 959 | /* detected disc change. set a bit | 945 | /* Detected disc change. Set a bit |
| 960 | * and quietly refuse further access. | 946 | * and quietly refuse further access. |
| 961 | */ | 947 | */ |
| 962 | cmd->device->changed = 1; | 948 | cmd->device->changed = 1; |
| 963 | scsi_end_request(cmd, 0, | 949 | scsi_end_request(cmd, 0, this_count, 1); |
| 964 | this_count, 1); | ||
| 965 | return; | 950 | return; |
| 966 | } else { | 951 | } else { |
| 967 | /* | 952 | /* Must have been a power glitch, or a |
| 968 | * Must have been a power glitch, or a | 953 | * bus reset. Could not have been a |
| 969 | * bus reset. Could not have been a | 954 | * media change, so we just retry the |
| 970 | * media change, so we just retry the | 955 | * request and see what happens. |
| 971 | * request and see what happens. | 956 | */ |
| 972 | */ | ||
| 973 | scsi_requeue_command(q, cmd); | 957 | scsi_requeue_command(q, cmd); |
| 974 | return; | 958 | return; |
| 975 | } | 959 | } |
| 976 | break; | 960 | break; |
| 977 | case ILLEGAL_REQUEST: | 961 | case ILLEGAL_REQUEST: |
| 978 | /* | 962 | /* If we had an ILLEGAL REQUEST returned, then |
| 979 | * If we had an ILLEGAL REQUEST returned, then we may | 963 | * we may have performed an unsupported |
| 980 | * have performed an unsupported command. The only | 964 | * command. The only thing this should be |
| 981 | * thing this should be would be a ten byte read where | 965 | * would be a ten byte read where only a six |
| 982 | * only a six byte read was supported. Also, on a | 966 | * byte read was supported. Also, on a system |
| 983 | * system where READ CAPACITY failed, we may have read | 967 | * where READ CAPACITY failed, we may have |
| 984 | * past the end of the disk. | 968 | * read past the end of the disk. |
| 985 | */ | 969 | */ |
| 986 | if ((cmd->device->use_10_for_rw && | 970 | if ((cmd->device->use_10_for_rw && |
| 987 | sshdr.asc == 0x20 && sshdr.ascq == 0x00) && | 971 | sshdr.asc == 0x20 && sshdr.ascq == 0x00) && |
| 988 | (cmd->cmnd[0] == READ_10 || | 972 | (cmd->cmnd[0] == READ_10 || |
| 989 | cmd->cmnd[0] == WRITE_10)) { | 973 | cmd->cmnd[0] == WRITE_10)) { |
| 990 | cmd->device->use_10_for_rw = 0; | 974 | cmd->device->use_10_for_rw = 0; |
| 991 | /* | 975 | /* This will cause a retry with a |
| 992 | * This will cause a retry with a 6-byte | 976 | * 6-byte command. |
| 993 | * command. | ||
| 994 | */ | 977 | */ |
| 995 | scsi_requeue_command(q, cmd); | 978 | scsi_requeue_command(q, cmd); |
| 996 | result = 0; | 979 | return; |
| 997 | } else { | 980 | } else { |
| 998 | scsi_end_request(cmd, 0, this_count, 1); | 981 | scsi_end_request(cmd, 0, this_count, 1); |
| 999 | return; | 982 | return; |
| 1000 | } | 983 | } |
| 1001 | break; | 984 | break; |
| 1002 | case NOT_READY: | 985 | case NOT_READY: |
| 1003 | /* | 986 | /* 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. | 987 | * ready, or has a temporary blockage, retry. |
| 1006 | */ | 988 | */ |
| 1007 | if (sshdr.asc == 0x04) { | 989 | if (sshdr.asc == 0x04) { |
| @@ -1021,7 +1003,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
| 1021 | } | 1003 | } |
| 1022 | if (!(req->flags & REQ_QUIET)) { | 1004 | if (!(req->flags & REQ_QUIET)) { |
| 1023 | scmd_printk(KERN_INFO, cmd, | 1005 | scmd_printk(KERN_INFO, cmd, |
| 1024 | "Device not ready: "); | 1006 | "Device not ready: "); |
| 1025 | scsi_print_sense_hdr("", &sshdr); | 1007 | scsi_print_sense_hdr("", &sshdr); |
| 1026 | } | 1008 | } |
| 1027 | scsi_end_request(cmd, 0, this_count, 1); | 1009 | scsi_end_request(cmd, 0, this_count, 1); |
| @@ -1029,21 +1011,21 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
| 1029 | case VOLUME_OVERFLOW: | 1011 | case VOLUME_OVERFLOW: |
| 1030 | if (!(req->flags & REQ_QUIET)) { | 1012 | if (!(req->flags & REQ_QUIET)) { |
| 1031 | scmd_printk(KERN_INFO, cmd, | 1013 | scmd_printk(KERN_INFO, cmd, |
| 1032 | "Volume overflow, CDB: "); | 1014 | "Volume overflow, CDB: "); |
| 1033 | __scsi_print_command(cmd->data_cmnd); | 1015 | __scsi_print_command(cmd->data_cmnd); |
| 1034 | scsi_print_sense("", cmd); | 1016 | scsi_print_sense("", cmd); |
| 1035 | } | 1017 | } |
| 1036 | scsi_end_request(cmd, 0, block_bytes, 1); | 1018 | /* See SSC3rXX or current. */ |
| 1019 | scsi_end_request(cmd, 0, this_count, 1); | ||
| 1037 | return; | 1020 | return; |
| 1038 | default: | 1021 | default: |
| 1039 | break; | 1022 | break; |
| 1040 | } | 1023 | } |
| 1041 | } /* driver byte != 0 */ | 1024 | } |
| 1042 | if (host_byte(result) == DID_RESET) { | 1025 | if (host_byte(result) == DID_RESET) { |
| 1043 | /* | 1026 | /* Third party bus reset or reset for error recovery |
| 1044 | * Third party bus reset or reset for error | 1027 | * reasons. Just retry the request and see what |
| 1045 | * recovery reasons. Just retry the request | 1028 | * happens. |
| 1046 | * and see what happens. | ||
| 1047 | */ | 1029 | */ |
| 1048 | scsi_requeue_command(q, cmd); | 1030 | scsi_requeue_command(q, cmd); |
| 1049 | return; | 1031 | return; |
| @@ -1051,21 +1033,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes, | |||
| 1051 | if (result) { | 1033 | if (result) { |
| 1052 | if (!(req->flags & REQ_QUIET)) { | 1034 | if (!(req->flags & REQ_QUIET)) { |
| 1053 | scmd_printk(KERN_INFO, cmd, | 1035 | scmd_printk(KERN_INFO, cmd, |
| 1054 | "SCSI error: return code = 0x%x\n", result); | 1036 | "SCSI error: return code = 0x%08x\n", |
| 1055 | 1037 | result); | |
| 1056 | if (driver_byte(result) & DRIVER_SENSE) | 1038 | if (driver_byte(result) & DRIVER_SENSE) |
| 1057 | scsi_print_sense("", cmd); | 1039 | scsi_print_sense("", cmd); |
| 1058 | } | 1040 | } |
| 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 | } | 1041 | } |
| 1042 | scsi_end_request(cmd, 0, this_count, !result); | ||
| 1069 | } | 1043 | } |
| 1070 | EXPORT_SYMBOL(scsi_io_completion); | 1044 | EXPORT_SYMBOL(scsi_io_completion); |
| 1071 | 1045 | ||
| @@ -1169,7 +1143,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | |||
| 1169 | * successfully. Since this is a REQ_BLOCK_PC command the | 1143 | * successfully. Since this is a REQ_BLOCK_PC command the |
| 1170 | * caller should check the request's errors value | 1144 | * caller should check the request's errors value |
| 1171 | */ | 1145 | */ |
| 1172 | scsi_io_completion(cmd, cmd->bufflen, 0); | 1146 | scsi_io_completion(cmd, cmd->bufflen); |
| 1173 | } | 1147 | } |
| 1174 | 1148 | ||
| 1175 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | 1149 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) |
| @@ -2050,6 +2024,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
| 2050 | switch (oldstate) { | 2024 | switch (oldstate) { |
| 2051 | case SDEV_CREATED: | 2025 | case SDEV_CREATED: |
| 2052 | case SDEV_RUNNING: | 2026 | case SDEV_RUNNING: |
| 2027 | case SDEV_QUIESCE: | ||
| 2053 | case SDEV_OFFLINE: | 2028 | case SDEV_OFFLINE: |
| 2054 | case SDEV_BLOCK: | 2029 | case SDEV_BLOCK: |
| 2055 | break; | 2030 | break; |
| @@ -2060,6 +2035,9 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) | |||
| 2060 | 2035 | ||
| 2061 | case SDEV_DEL: | 2036 | case SDEV_DEL: |
| 2062 | switch (oldstate) { | 2037 | switch (oldstate) { |
| 2038 | case SDEV_CREATED: | ||
| 2039 | case SDEV_RUNNING: | ||
| 2040 | case SDEV_OFFLINE: | ||
| 2063 | case SDEV_CANCEL: | 2041 | case SDEV_CANCEL: |
| 2064 | break; | 2042 | break; |
| 2065 | default: | 2043 | default: |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 015c90cf3abc..e2fbe9a9d5a9 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
| @@ -116,7 +116,7 @@ extern struct bus_type scsi_bus_type; | |||
| 116 | * classes. | 116 | * classes. |
| 117 | */ | 117 | */ |
| 118 | 118 | ||
| 119 | #define SCSI_DEVICE_BLOCK_MAX_TIMEOUT (HZ*60) | 119 | #define SCSI_DEVICE_BLOCK_MAX_TIMEOUT 600 /* units in seconds */ |
| 120 | extern int scsi_internal_device_block(struct scsi_device *sdev); | 120 | extern int scsi_internal_device_block(struct scsi_device *sdev); |
| 121 | extern int scsi_internal_device_unblock(struct scsi_device *sdev); | 121 | extern int scsi_internal_device_unblock(struct scsi_device *sdev); |
| 122 | 122 | ||
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 1341608e9e3b..1bd92b9b46d9 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
| @@ -809,6 +809,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) | |||
| 809 | 809 | ||
| 810 | static inline void scsi_destroy_sdev(struct scsi_device *sdev) | 810 | static inline void scsi_destroy_sdev(struct scsi_device *sdev) |
| 811 | { | 811 | { |
| 812 | scsi_device_set_state(sdev, SDEV_DEL); | ||
| 812 | if (sdev->host->hostt->slave_destroy) | 813 | if (sdev->host->hostt->slave_destroy) |
| 813 | sdev->host->hostt->slave_destroy(sdev); | 814 | sdev->host->hostt->slave_destroy(sdev); |
| 814 | transport_destroy_device(&sdev->sdev_gendev); | 815 | 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_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 5569fdcfd621..7b9e8fa1a4e0 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
| @@ -228,14 +228,11 @@ static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid) | |||
| 228 | static void iscsi_session_release(struct device *dev) | 228 | static void iscsi_session_release(struct device *dev) |
| 229 | { | 229 | { |
| 230 | struct iscsi_cls_session *session = iscsi_dev_to_session(dev); | 230 | struct iscsi_cls_session *session = iscsi_dev_to_session(dev); |
| 231 | struct iscsi_transport *transport = session->transport; | ||
| 232 | struct Scsi_Host *shost; | 231 | struct Scsi_Host *shost; |
| 233 | 232 | ||
| 234 | shost = iscsi_session_to_shost(session); | 233 | shost = iscsi_session_to_shost(session); |
| 235 | scsi_host_put(shost); | 234 | scsi_host_put(shost); |
| 236 | kfree(session->targetname); | ||
| 237 | kfree(session); | 235 | kfree(session); |
| 238 | module_put(transport->owner); | ||
| 239 | } | 236 | } |
| 240 | 237 | ||
| 241 | static int iscsi_is_session_dev(const struct device *dev) | 238 | static int iscsi_is_session_dev(const struct device *dev) |
| @@ -251,10 +248,9 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, | |||
| 251 | 248 | ||
| 252 | mutex_lock(&ihost->mutex); | 249 | mutex_lock(&ihost->mutex); |
| 253 | list_for_each_entry(session, &ihost->sessions, host_list) { | 250 | list_for_each_entry(session, &ihost->sessions, host_list) { |
| 254 | if ((channel == SCAN_WILD_CARD || | 251 | if ((channel == SCAN_WILD_CARD || channel == 0) && |
| 255 | channel == session->channel) && | ||
| 256 | (id == SCAN_WILD_CARD || id == session->target_id)) | 252 | (id == SCAN_WILD_CARD || id == session->target_id)) |
| 257 | scsi_scan_target(&session->dev, session->channel, | 253 | scsi_scan_target(&session->dev, 0, |
| 258 | session->target_id, lun, 1); | 254 | session->target_id, lun, 1); |
| 259 | } | 255 | } |
| 260 | mutex_unlock(&ihost->mutex); | 256 | mutex_unlock(&ihost->mutex); |
| @@ -291,80 +287,92 @@ void iscsi_block_session(struct iscsi_cls_session *session) | |||
| 291 | } | 287 | } |
| 292 | EXPORT_SYMBOL_GPL(iscsi_block_session); | 288 | EXPORT_SYMBOL_GPL(iscsi_block_session); |
| 293 | 289 | ||
| 294 | /** | ||
| 295 | * iscsi_create_session - create iscsi class session | ||
| 296 | * @shost: scsi host | ||
| 297 | * @transport: iscsi transport | ||
| 298 | * | ||
| 299 | * This can be called from a LLD or iscsi_transport. | ||
| 300 | **/ | ||
| 301 | struct iscsi_cls_session * | 290 | struct iscsi_cls_session * |
| 302 | iscsi_create_session(struct Scsi_Host *shost, | 291 | iscsi_alloc_session(struct Scsi_Host *shost, |
| 303 | struct iscsi_transport *transport, int channel) | 292 | struct iscsi_transport *transport) |
| 304 | { | 293 | { |
| 305 | struct iscsi_host *ihost; | ||
| 306 | struct iscsi_cls_session *session; | 294 | struct iscsi_cls_session *session; |
| 307 | int err; | ||
| 308 | |||
| 309 | if (!try_module_get(transport->owner)) | ||
| 310 | return NULL; | ||
| 311 | 295 | ||
| 312 | session = kzalloc(sizeof(*session) + transport->sessiondata_size, | 296 | session = kzalloc(sizeof(*session) + transport->sessiondata_size, |
| 313 | GFP_KERNEL); | 297 | GFP_KERNEL); |
| 314 | if (!session) | 298 | if (!session) |
| 315 | goto module_put; | 299 | return NULL; |
| 300 | |||
| 316 | session->transport = transport; | 301 | session->transport = transport; |
| 317 | session->recovery_tmo = 120; | 302 | session->recovery_tmo = 120; |
| 318 | INIT_WORK(&session->recovery_work, session_recovery_timedout, session); | 303 | INIT_WORK(&session->recovery_work, session_recovery_timedout, session); |
| 319 | INIT_LIST_HEAD(&session->host_list); | 304 | INIT_LIST_HEAD(&session->host_list); |
| 320 | INIT_LIST_HEAD(&session->sess_list); | 305 | INIT_LIST_HEAD(&session->sess_list); |
| 321 | 306 | ||
| 307 | /* this is released in the dev's release function */ | ||
| 308 | scsi_host_get(shost); | ||
| 309 | session->dev.parent = &shost->shost_gendev; | ||
| 310 | session->dev.release = iscsi_session_release; | ||
| 311 | device_initialize(&session->dev); | ||
| 322 | if (transport->sessiondata_size) | 312 | if (transport->sessiondata_size) |
| 323 | session->dd_data = &session[1]; | 313 | session->dd_data = &session[1]; |
| 314 | return session; | ||
| 315 | } | ||
| 316 | EXPORT_SYMBOL_GPL(iscsi_alloc_session); | ||
| 324 | 317 | ||
| 325 | /* this is released in the dev's release function */ | 318 | int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) |
| 326 | scsi_host_get(shost); | 319 | { |
| 327 | ihost = shost->shost_data; | 320 | struct Scsi_Host *shost = iscsi_session_to_shost(session); |
| 321 | struct iscsi_host *ihost; | ||
| 322 | int err; | ||
| 328 | 323 | ||
| 324 | ihost = shost->shost_data; | ||
| 329 | session->sid = iscsi_session_nr++; | 325 | session->sid = iscsi_session_nr++; |
| 330 | session->channel = channel; | 326 | session->target_id = target_id; |
| 331 | session->target_id = ihost->next_target_id++; | ||
| 332 | 327 | ||
| 333 | snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", | 328 | snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u", |
| 334 | session->sid); | 329 | session->sid); |
| 335 | session->dev.parent = &shost->shost_gendev; | 330 | err = device_add(&session->dev); |
| 336 | session->dev.release = iscsi_session_release; | ||
| 337 | err = device_register(&session->dev); | ||
| 338 | if (err) { | 331 | if (err) { |
| 339 | dev_printk(KERN_ERR, &session->dev, "iscsi: could not " | 332 | dev_printk(KERN_ERR, &session->dev, "iscsi: could not " |
| 340 | "register session's dev\n"); | 333 | "register session's dev\n"); |
| 341 | goto free_session; | 334 | goto release_host; |
| 342 | } | 335 | } |
| 343 | transport_register_device(&session->dev); | 336 | transport_register_device(&session->dev); |
| 344 | 337 | ||
| 345 | mutex_lock(&ihost->mutex); | 338 | mutex_lock(&ihost->mutex); |
| 346 | list_add(&session->host_list, &ihost->sessions); | 339 | list_add(&session->host_list, &ihost->sessions); |
| 347 | mutex_unlock(&ihost->mutex); | 340 | mutex_unlock(&ihost->mutex); |
| 341 | return 0; | ||
| 348 | 342 | ||
| 349 | return session; | 343 | release_host: |
| 350 | 344 | scsi_host_put(shost); | |
| 351 | free_session: | 345 | return err; |
| 352 | kfree(session); | ||
| 353 | module_put: | ||
| 354 | module_put(transport->owner); | ||
| 355 | return NULL; | ||
| 356 | } | 346 | } |
| 357 | 347 | EXPORT_SYMBOL_GPL(iscsi_add_session); | |
| 358 | EXPORT_SYMBOL_GPL(iscsi_create_session); | ||
| 359 | 348 | ||
| 360 | /** | 349 | /** |
| 361 | * iscsi_destroy_session - destroy iscsi session | 350 | * iscsi_create_session - create iscsi class session |
| 362 | * @session: iscsi_session | 351 | * @shost: scsi host |
| 352 | * @transport: iscsi transport | ||
| 363 | * | 353 | * |
| 364 | * Can be called by a LLD or iscsi_transport. There must not be | 354 | * This can be called from a LLD or iscsi_transport. |
| 365 | * any running connections. | ||
| 366 | **/ | 355 | **/ |
| 367 | int iscsi_destroy_session(struct iscsi_cls_session *session) | 356 | struct iscsi_cls_session * |
| 357 | iscsi_create_session(struct Scsi_Host *shost, | ||
| 358 | struct iscsi_transport *transport, | ||
| 359 | unsigned int target_id) | ||
| 360 | { | ||
| 361 | struct iscsi_cls_session *session; | ||
| 362 | |||
| 363 | session = iscsi_alloc_session(shost, transport); | ||
| 364 | if (!session) | ||
| 365 | return NULL; | ||
| 366 | |||
| 367 | if (iscsi_add_session(session, target_id)) { | ||
| 368 | iscsi_free_session(session); | ||
| 369 | return NULL; | ||
| 370 | } | ||
| 371 | return session; | ||
| 372 | } | ||
| 373 | EXPORT_SYMBOL_GPL(iscsi_create_session); | ||
| 374 | |||
| 375 | void iscsi_remove_session(struct iscsi_cls_session *session) | ||
| 368 | { | 376 | { |
| 369 | struct Scsi_Host *shost = iscsi_session_to_shost(session); | 377 | struct Scsi_Host *shost = iscsi_session_to_shost(session); |
| 370 | struct iscsi_host *ihost = shost->shost_data; | 378 | struct iscsi_host *ihost = shost->shost_data; |
| @@ -376,19 +384,88 @@ int iscsi_destroy_session(struct iscsi_cls_session *session) | |||
| 376 | list_del(&session->host_list); | 384 | list_del(&session->host_list); |
| 377 | mutex_unlock(&ihost->mutex); | 385 | mutex_unlock(&ihost->mutex); |
| 378 | 386 | ||
| 387 | scsi_remove_target(&session->dev); | ||
| 388 | |||
| 379 | transport_unregister_device(&session->dev); | 389 | transport_unregister_device(&session->dev); |
| 380 | device_unregister(&session->dev); | 390 | device_del(&session->dev); |
| 381 | return 0; | 391 | } |
| 392 | EXPORT_SYMBOL_GPL(iscsi_remove_session); | ||
| 393 | |||
| 394 | void iscsi_free_session(struct iscsi_cls_session *session) | ||
| 395 | { | ||
| 396 | put_device(&session->dev); | ||
| 382 | } | 397 | } |
| 383 | 398 | ||
| 399 | EXPORT_SYMBOL_GPL(iscsi_free_session); | ||
| 400 | |||
| 401 | /** | ||
| 402 | * iscsi_destroy_session - destroy iscsi session | ||
| 403 | * @session: iscsi_session | ||
| 404 | * | ||
| 405 | * Can be called by a LLD or iscsi_transport. There must not be | ||
| 406 | * any running connections. | ||
| 407 | **/ | ||
| 408 | int iscsi_destroy_session(struct iscsi_cls_session *session) | ||
| 409 | { | ||
| 410 | iscsi_remove_session(session); | ||
| 411 | iscsi_free_session(session); | ||
| 412 | return 0; | ||
| 413 | } | ||
| 384 | EXPORT_SYMBOL_GPL(iscsi_destroy_session); | 414 | EXPORT_SYMBOL_GPL(iscsi_destroy_session); |
| 385 | 415 | ||
| 416 | static void mempool_zone_destroy(struct mempool_zone *zp) | ||
| 417 | { | ||
| 418 | mempool_destroy(zp->pool); | ||
| 419 | kfree(zp); | ||
| 420 | } | ||
| 421 | |||
| 422 | static void* | ||
| 423 | mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) | ||
| 424 | { | ||
| 425 | struct mempool_zone *zone = pool_data; | ||
| 426 | |||
| 427 | return alloc_skb(zone->size, gfp_mask); | ||
| 428 | } | ||
| 429 | |||
| 430 | static void | ||
| 431 | mempool_zone_free_skb(void *element, void *pool_data) | ||
| 432 | { | ||
| 433 | kfree_skb(element); | ||
| 434 | } | ||
| 435 | |||
| 436 | static struct mempool_zone * | ||
| 437 | mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) | ||
| 438 | { | ||
| 439 | struct mempool_zone *zp; | ||
| 440 | |||
| 441 | zp = kzalloc(sizeof(*zp), GFP_KERNEL); | ||
| 442 | if (!zp) | ||
| 443 | return NULL; | ||
| 444 | |||
| 445 | zp->size = size; | ||
| 446 | zp->hiwat = hiwat; | ||
| 447 | INIT_LIST_HEAD(&zp->freequeue); | ||
| 448 | spin_lock_init(&zp->freelock); | ||
| 449 | atomic_set(&zp->allocated, 0); | ||
| 450 | |||
| 451 | zp->pool = mempool_create(max, mempool_zone_alloc_skb, | ||
| 452 | mempool_zone_free_skb, zp); | ||
| 453 | if (!zp->pool) { | ||
| 454 | kfree(zp); | ||
| 455 | return NULL; | ||
| 456 | } | ||
| 457 | |||
| 458 | return zp; | ||
| 459 | } | ||
| 460 | |||
| 386 | static void iscsi_conn_release(struct device *dev) | 461 | static void iscsi_conn_release(struct device *dev) |
| 387 | { | 462 | { |
| 388 | struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); | 463 | struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); |
| 389 | struct device *parent = conn->dev.parent; | 464 | struct device *parent = conn->dev.parent; |
| 390 | 465 | ||
| 391 | kfree(conn->persistent_address); | 466 | mempool_zone_destroy(conn->z_pdu); |
| 467 | mempool_zone_destroy(conn->z_error); | ||
| 468 | |||
| 392 | kfree(conn); | 469 | kfree(conn); |
| 393 | put_device(parent); | 470 | put_device(parent); |
| 394 | } | 471 | } |
| @@ -398,6 +475,31 @@ static int iscsi_is_conn_dev(const struct device *dev) | |||
| 398 | return dev->release == iscsi_conn_release; | 475 | return dev->release == iscsi_conn_release; |
| 399 | } | 476 | } |
| 400 | 477 | ||
| 478 | static int iscsi_create_event_pools(struct iscsi_cls_conn *conn) | ||
| 479 | { | ||
| 480 | conn->z_pdu = mempool_zone_init(Z_MAX_PDU, | ||
| 481 | NLMSG_SPACE(sizeof(struct iscsi_uevent) + | ||
| 482 | sizeof(struct iscsi_hdr) + | ||
| 483 | DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH), | ||
| 484 | Z_HIWAT_PDU); | ||
| 485 | if (!conn->z_pdu) { | ||
| 486 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
| 487 | "pdu zone for new conn\n"); | ||
| 488 | return -ENOMEM; | ||
| 489 | } | ||
| 490 | |||
| 491 | conn->z_error = mempool_zone_init(Z_MAX_ERROR, | ||
| 492 | NLMSG_SPACE(sizeof(struct iscsi_uevent)), | ||
| 493 | Z_HIWAT_ERROR); | ||
| 494 | if (!conn->z_error) { | ||
| 495 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
| 496 | "error zone for new conn\n"); | ||
| 497 | mempool_zone_destroy(conn->z_pdu); | ||
| 498 | return -ENOMEM; | ||
| 499 | } | ||
| 500 | return 0; | ||
| 501 | } | ||
| 502 | |||
| 401 | /** | 503 | /** |
| 402 | * iscsi_create_conn - create iscsi class connection | 504 | * iscsi_create_conn - create iscsi class connection |
| 403 | * @session: iscsi cls session | 505 | * @session: iscsi cls session |
| @@ -430,9 +532,12 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) | |||
| 430 | conn->transport = transport; | 532 | conn->transport = transport; |
| 431 | conn->cid = cid; | 533 | conn->cid = cid; |
| 432 | 534 | ||
| 535 | if (iscsi_create_event_pools(conn)) | ||
| 536 | goto free_conn; | ||
| 537 | |||
| 433 | /* this is released in the dev's release function */ | 538 | /* this is released in the dev's release function */ |
| 434 | if (!get_device(&session->dev)) | 539 | if (!get_device(&session->dev)) |
| 435 | goto free_conn; | 540 | goto free_conn_pools; |
| 436 | 541 | ||
| 437 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", | 542 | snprintf(conn->dev.bus_id, BUS_ID_SIZE, "connection%d:%u", |
| 438 | session->sid, cid); | 543 | session->sid, cid); |
| @@ -449,6 +554,8 @@ iscsi_create_conn(struct iscsi_cls_session *session, uint32_t cid) | |||
| 449 | 554 | ||
| 450 | release_parent_ref: | 555 | release_parent_ref: |
| 451 | put_device(&session->dev); | 556 | put_device(&session->dev); |
| 557 | free_conn_pools: | ||
| 558 | |||
| 452 | free_conn: | 559 | free_conn: |
| 453 | kfree(conn); | 560 | kfree(conn); |
| 454 | return NULL; | 561 | return NULL; |
| @@ -496,20 +603,6 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb) | |||
| 496 | return (struct list_head *)&skb->cb; | 603 | return (struct list_head *)&skb->cb; |
| 497 | } | 604 | } |
| 498 | 605 | ||
| 499 | static void* | ||
| 500 | mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) | ||
| 501 | { | ||
| 502 | struct mempool_zone *zone = pool_data; | ||
| 503 | |||
| 504 | return alloc_skb(zone->size, gfp_mask); | ||
| 505 | } | ||
| 506 | |||
| 507 | static void | ||
| 508 | mempool_zone_free_skb(void *element, void *pool_data) | ||
| 509 | { | ||
| 510 | kfree_skb(element); | ||
| 511 | } | ||
| 512 | |||
| 513 | static void | 606 | static void |
| 514 | mempool_zone_complete(struct mempool_zone *zone) | 607 | mempool_zone_complete(struct mempool_zone *zone) |
| 515 | { | 608 | { |
| @@ -529,37 +622,6 @@ mempool_zone_complete(struct mempool_zone *zone) | |||
| 529 | spin_unlock_irqrestore(&zone->freelock, flags); | 622 | spin_unlock_irqrestore(&zone->freelock, flags); |
| 530 | } | 623 | } |
| 531 | 624 | ||
| 532 | static struct mempool_zone * | ||
| 533 | mempool_zone_init(unsigned max, unsigned size, unsigned hiwat) | ||
| 534 | { | ||
| 535 | struct mempool_zone *zp; | ||
| 536 | |||
| 537 | zp = kzalloc(sizeof(*zp), GFP_KERNEL); | ||
| 538 | if (!zp) | ||
| 539 | return NULL; | ||
| 540 | |||
| 541 | zp->size = size; | ||
| 542 | zp->hiwat = hiwat; | ||
| 543 | INIT_LIST_HEAD(&zp->freequeue); | ||
| 544 | spin_lock_init(&zp->freelock); | ||
| 545 | atomic_set(&zp->allocated, 0); | ||
| 546 | |||
| 547 | zp->pool = mempool_create(max, mempool_zone_alloc_skb, | ||
| 548 | mempool_zone_free_skb, zp); | ||
| 549 | if (!zp->pool) { | ||
| 550 | kfree(zp); | ||
| 551 | return NULL; | ||
| 552 | } | ||
| 553 | |||
| 554 | return zp; | ||
| 555 | } | ||
| 556 | |||
| 557 | static void mempool_zone_destroy(struct mempool_zone *zp) | ||
| 558 | { | ||
| 559 | mempool_destroy(zp->pool); | ||
| 560 | kfree(zp); | ||
| 561 | } | ||
| 562 | |||
| 563 | static struct sk_buff* | 625 | static struct sk_buff* |
| 564 | mempool_zone_get_skb(struct mempool_zone *zone) | 626 | mempool_zone_get_skb(struct mempool_zone *zone) |
| 565 | { | 627 | { |
| @@ -572,6 +634,27 @@ mempool_zone_get_skb(struct mempool_zone *zone) | |||
| 572 | } | 634 | } |
| 573 | 635 | ||
| 574 | static int | 636 | static int |
| 637 | iscsi_broadcast_skb(struct mempool_zone *zone, struct sk_buff *skb) | ||
| 638 | { | ||
| 639 | unsigned long flags; | ||
| 640 | int rc; | ||
| 641 | |||
| 642 | skb_get(skb); | ||
| 643 | rc = netlink_broadcast(nls, skb, 0, 1, GFP_KERNEL); | ||
| 644 | if (rc < 0) { | ||
| 645 | mempool_free(skb, zone->pool); | ||
| 646 | printk(KERN_ERR "iscsi: can not broadcast skb (%d)\n", rc); | ||
| 647 | return rc; | ||
| 648 | } | ||
| 649 | |||
| 650 | spin_lock_irqsave(&zone->freelock, flags); | ||
| 651 | INIT_LIST_HEAD(skb_to_lh(skb)); | ||
| 652 | list_add(skb_to_lh(skb), &zone->freequeue); | ||
| 653 | spin_unlock_irqrestore(&zone->freelock, flags); | ||
| 654 | return 0; | ||
| 655 | } | ||
| 656 | |||
| 657 | static int | ||
| 575 | iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) | 658 | iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid) |
| 576 | { | 659 | { |
| 577 | unsigned long flags; | 660 | unsigned long flags; |
| @@ -666,7 +749,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error) | |||
| 666 | ev->r.connerror.cid = conn->cid; | 749 | ev->r.connerror.cid = conn->cid; |
| 667 | ev->r.connerror.sid = iscsi_conn_get_sid(conn); | 750 | ev->r.connerror.sid = iscsi_conn_get_sid(conn); |
| 668 | 751 | ||
| 669 | iscsi_unicast_skb(conn->z_error, skb, priv->daemon_pid); | 752 | iscsi_broadcast_skb(conn->z_error, skb); |
| 670 | 753 | ||
| 671 | dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", | 754 | dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n", |
| 672 | error); | 755 | error); |
| @@ -767,6 +850,131 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) | |||
| 767 | return err; | 850 | return err; |
| 768 | } | 851 | } |
| 769 | 852 | ||
| 853 | /** | ||
| 854 | * iscsi_if_destroy_session_done - send session destr. completion event | ||
| 855 | * @conn: last connection for session | ||
| 856 | * | ||
| 857 | * This is called by HW iscsi LLDs to notify userpsace that its HW has | ||
| 858 | * removed a session. | ||
| 859 | **/ | ||
| 860 | int iscsi_if_destroy_session_done(struct iscsi_cls_conn *conn) | ||
| 861 | { | ||
| 862 | struct iscsi_internal *priv; | ||
| 863 | struct iscsi_cls_session *session; | ||
| 864 | struct Scsi_Host *shost; | ||
| 865 | struct iscsi_uevent *ev; | ||
| 866 | struct sk_buff *skb; | ||
| 867 | struct nlmsghdr *nlh; | ||
| 868 | unsigned long flags; | ||
| 869 | int rc, len = NLMSG_SPACE(sizeof(*ev)); | ||
| 870 | |||
| 871 | priv = iscsi_if_transport_lookup(conn->transport); | ||
| 872 | if (!priv) | ||
| 873 | return -EINVAL; | ||
| 874 | |||
| 875 | session = iscsi_dev_to_session(conn->dev.parent); | ||
| 876 | shost = iscsi_session_to_shost(session); | ||
| 877 | |||
| 878 | mempool_zone_complete(conn->z_pdu); | ||
| 879 | |||
| 880 | skb = mempool_zone_get_skb(conn->z_pdu); | ||
| 881 | if (!skb) { | ||
| 882 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
| 883 | "session creation event\n"); | ||
| 884 | return -ENOMEM; | ||
| 885 | } | ||
| 886 | |||
| 887 | nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); | ||
| 888 | ev = NLMSG_DATA(nlh); | ||
| 889 | ev->transport_handle = iscsi_handle(conn->transport); | ||
| 890 | ev->type = ISCSI_KEVENT_DESTROY_SESSION; | ||
| 891 | ev->r.d_session.host_no = shost->host_no; | ||
| 892 | ev->r.d_session.sid = session->sid; | ||
| 893 | |||
| 894 | /* | ||
| 895 | * this will occur if the daemon is not up, so we just warn | ||
| 896 | * the user and when the daemon is restarted it will handle it | ||
| 897 | */ | ||
| 898 | rc = iscsi_broadcast_skb(conn->z_pdu, skb); | ||
| 899 | if (rc < 0) | ||
| 900 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
| 901 | "session destruction event. Check iscsi daemon\n"); | ||
| 902 | |||
| 903 | spin_lock_irqsave(&sesslock, flags); | ||
| 904 | list_del(&session->sess_list); | ||
| 905 | spin_unlock_irqrestore(&sesslock, flags); | ||
| 906 | |||
| 907 | spin_lock_irqsave(&connlock, flags); | ||
| 908 | conn->active = 0; | ||
| 909 | list_del(&conn->conn_list); | ||
| 910 | spin_unlock_irqrestore(&connlock, flags); | ||
| 911 | |||
| 912 | return rc; | ||
| 913 | } | ||
| 914 | EXPORT_SYMBOL_GPL(iscsi_if_destroy_session_done); | ||
| 915 | |||
| 916 | /** | ||
| 917 | * iscsi_if_create_session_done - send session creation completion event | ||
| 918 | * @conn: leading connection for session | ||
| 919 | * | ||
| 920 | * This is called by HW iscsi LLDs to notify userpsace that its HW has | ||
| 921 | * created a session or a existing session is back in the logged in state. | ||
| 922 | **/ | ||
| 923 | int iscsi_if_create_session_done(struct iscsi_cls_conn *conn) | ||
| 924 | { | ||
| 925 | struct iscsi_internal *priv; | ||
| 926 | struct iscsi_cls_session *session; | ||
| 927 | struct Scsi_Host *shost; | ||
| 928 | struct iscsi_uevent *ev; | ||
| 929 | struct sk_buff *skb; | ||
| 930 | struct nlmsghdr *nlh; | ||
| 931 | unsigned long flags; | ||
| 932 | int rc, len = NLMSG_SPACE(sizeof(*ev)); | ||
| 933 | |||
| 934 | priv = iscsi_if_transport_lookup(conn->transport); | ||
| 935 | if (!priv) | ||
| 936 | return -EINVAL; | ||
| 937 | |||
| 938 | session = iscsi_dev_to_session(conn->dev.parent); | ||
| 939 | shost = iscsi_session_to_shost(session); | ||
| 940 | |||
| 941 | mempool_zone_complete(conn->z_pdu); | ||
| 942 | |||
| 943 | skb = mempool_zone_get_skb(conn->z_pdu); | ||
| 944 | if (!skb) { | ||
| 945 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
| 946 | "session creation event\n"); | ||
| 947 | return -ENOMEM; | ||
| 948 | } | ||
| 949 | |||
| 950 | nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0); | ||
| 951 | ev = NLMSG_DATA(nlh); | ||
| 952 | ev->transport_handle = iscsi_handle(conn->transport); | ||
| 953 | ev->type = ISCSI_UEVENT_CREATE_SESSION; | ||
| 954 | ev->r.c_session_ret.host_no = shost->host_no; | ||
| 955 | ev->r.c_session_ret.sid = session->sid; | ||
| 956 | |||
| 957 | /* | ||
| 958 | * this will occur if the daemon is not up, so we just warn | ||
| 959 | * the user and when the daemon is restarted it will handle it | ||
| 960 | */ | ||
| 961 | rc = iscsi_broadcast_skb(conn->z_pdu, skb); | ||
| 962 | if (rc < 0) | ||
| 963 | dev_printk(KERN_ERR, &conn->dev, "Cannot notify userspace of " | ||
| 964 | "session creation event. Check iscsi daemon\n"); | ||
| 965 | |||
| 966 | spin_lock_irqsave(&sesslock, flags); | ||
| 967 | list_add(&session->sess_list, &sesslist); | ||
| 968 | spin_unlock_irqrestore(&sesslock, flags); | ||
| 969 | |||
| 970 | spin_lock_irqsave(&connlock, flags); | ||
| 971 | list_add(&conn->conn_list, &connlist); | ||
| 972 | conn->active = 1; | ||
| 973 | spin_unlock_irqrestore(&connlock, flags); | ||
| 974 | return rc; | ||
| 975 | } | ||
| 976 | EXPORT_SYMBOL_GPL(iscsi_if_create_session_done); | ||
| 977 | |||
| 770 | static int | 978 | static int |
| 771 | iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) | 979 | iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) |
| 772 | { | 980 | { |
| @@ -812,26 +1020,6 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
| 812 | return -ENOMEM; | 1020 | return -ENOMEM; |
| 813 | } | 1021 | } |
| 814 | 1022 | ||
| 815 | conn->z_pdu = mempool_zone_init(Z_MAX_PDU, | ||
| 816 | NLMSG_SPACE(sizeof(struct iscsi_uevent) + | ||
| 817 | sizeof(struct iscsi_hdr) + | ||
| 818 | DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH), | ||
| 819 | Z_HIWAT_PDU); | ||
| 820 | if (!conn->z_pdu) { | ||
| 821 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
| 822 | "pdu zone for new conn\n"); | ||
| 823 | goto destroy_conn; | ||
| 824 | } | ||
| 825 | |||
| 826 | conn->z_error = mempool_zone_init(Z_MAX_ERROR, | ||
| 827 | NLMSG_SPACE(sizeof(struct iscsi_uevent)), | ||
| 828 | Z_HIWAT_ERROR); | ||
| 829 | if (!conn->z_error) { | ||
| 830 | dev_printk(KERN_ERR, &conn->dev, "iscsi: can not allocate " | ||
| 831 | "error zone for new conn\n"); | ||
| 832 | goto free_pdu_pool; | ||
| 833 | } | ||
| 834 | |||
| 835 | ev->r.c_conn_ret.sid = session->sid; | 1023 | ev->r.c_conn_ret.sid = session->sid; |
| 836 | ev->r.c_conn_ret.cid = conn->cid; | 1024 | ev->r.c_conn_ret.cid = conn->cid; |
| 837 | 1025 | ||
| @@ -841,13 +1029,6 @@ iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
| 841 | spin_unlock_irqrestore(&connlock, flags); | 1029 | spin_unlock_irqrestore(&connlock, flags); |
| 842 | 1030 | ||
| 843 | return 0; | 1031 | return 0; |
| 844 | |||
| 845 | free_pdu_pool: | ||
| 846 | mempool_zone_destroy(conn->z_pdu); | ||
| 847 | destroy_conn: | ||
| 848 | if (transport->destroy_conn) | ||
| 849 | transport->destroy_conn(conn->dd_data); | ||
| 850 | return -ENOMEM; | ||
| 851 | } | 1032 | } |
| 852 | 1033 | ||
| 853 | static int | 1034 | static int |
| @@ -855,7 +1036,6 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev | |||
| 855 | { | 1036 | { |
| 856 | unsigned long flags; | 1037 | unsigned long flags; |
| 857 | struct iscsi_cls_conn *conn; | 1038 | struct iscsi_cls_conn *conn; |
| 858 | struct mempool_zone *z_error, *z_pdu; | ||
| 859 | 1039 | ||
| 860 | conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid); | 1040 | conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid); |
| 861 | if (!conn) | 1041 | if (!conn) |
| @@ -865,35 +1045,18 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev | |||
| 865 | list_del(&conn->conn_list); | 1045 | list_del(&conn->conn_list); |
| 866 | spin_unlock_irqrestore(&connlock, flags); | 1046 | spin_unlock_irqrestore(&connlock, flags); |
| 867 | 1047 | ||
| 868 | z_pdu = conn->z_pdu; | ||
| 869 | z_error = conn->z_error; | ||
| 870 | |||
| 871 | if (transport->destroy_conn) | 1048 | if (transport->destroy_conn) |
| 872 | transport->destroy_conn(conn); | 1049 | transport->destroy_conn(conn); |
| 873 | |||
| 874 | mempool_zone_destroy(z_pdu); | ||
| 875 | mempool_zone_destroy(z_error); | ||
| 876 | |||
| 877 | return 0; | 1050 | return 0; |
| 878 | } | 1051 | } |
| 879 | 1052 | ||
| 880 | static void | ||
| 881 | iscsi_copy_param(struct iscsi_uevent *ev, uint32_t *value, char *data) | ||
| 882 | { | ||
| 883 | if (ev->u.set_param.len != sizeof(uint32_t)) | ||
| 884 | BUG(); | ||
| 885 | memcpy(value, data, min_t(uint32_t, sizeof(uint32_t), | ||
| 886 | ev->u.set_param.len)); | ||
| 887 | } | ||
| 888 | |||
| 889 | static int | 1053 | static int |
| 890 | iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) | 1054 | iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) |
| 891 | { | 1055 | { |
| 892 | char *data = (char*)ev + sizeof(*ev); | 1056 | char *data = (char*)ev + sizeof(*ev); |
| 893 | struct iscsi_cls_conn *conn; | 1057 | struct iscsi_cls_conn *conn; |
| 894 | struct iscsi_cls_session *session; | 1058 | struct iscsi_cls_session *session; |
| 895 | int err = 0; | 1059 | int err = 0, value = 0; |
| 896 | uint32_t value = 0; | ||
| 897 | 1060 | ||
| 898 | session = iscsi_session_lookup(ev->u.set_param.sid); | 1061 | session = iscsi_session_lookup(ev->u.set_param.sid); |
| 899 | conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); | 1062 | conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); |
| @@ -902,42 +1065,13 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
| 902 | 1065 | ||
| 903 | switch (ev->u.set_param.param) { | 1066 | switch (ev->u.set_param.param) { |
| 904 | case ISCSI_PARAM_SESS_RECOVERY_TMO: | 1067 | case ISCSI_PARAM_SESS_RECOVERY_TMO: |
| 905 | iscsi_copy_param(ev, &value, data); | 1068 | sscanf(data, "%d", &value); |
| 906 | if (value != 0) | 1069 | if (value != 0) |
| 907 | session->recovery_tmo = value; | 1070 | session->recovery_tmo = value; |
| 908 | break; | 1071 | break; |
| 909 | case ISCSI_PARAM_TARGET_NAME: | ||
| 910 | /* this should not change between logins */ | ||
| 911 | if (session->targetname) | ||
| 912 | return 0; | ||
| 913 | |||
| 914 | session->targetname = kstrdup(data, GFP_KERNEL); | ||
| 915 | if (!session->targetname) | ||
| 916 | return -ENOMEM; | ||
| 917 | break; | ||
| 918 | case ISCSI_PARAM_TPGT: | ||
| 919 | iscsi_copy_param(ev, &value, data); | ||
| 920 | session->tpgt = value; | ||
| 921 | break; | ||
| 922 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
| 923 | iscsi_copy_param(ev, &value, data); | ||
| 924 | conn->persistent_port = value; | ||
| 925 | break; | ||
| 926 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
| 927 | /* | ||
| 928 | * this is the address returned in discovery so it should | ||
| 929 | * not change between logins. | ||
| 930 | */ | ||
| 931 | if (conn->persistent_address) | ||
| 932 | return 0; | ||
| 933 | |||
| 934 | conn->persistent_address = kstrdup(data, GFP_KERNEL); | ||
| 935 | if (!conn->persistent_address) | ||
| 936 | return -ENOMEM; | ||
| 937 | break; | ||
| 938 | default: | 1072 | default: |
| 939 | iscsi_copy_param(ev, &value, data); | 1073 | err = transport->set_param(conn, ev->u.set_param.param, |
| 940 | err = transport->set_param(conn, ev->u.set_param.param, value); | 1074 | data, ev->u.set_param.len); |
| 941 | } | 1075 | } |
| 942 | 1076 | ||
| 943 | return err; | 1077 | return err; |
| @@ -978,6 +1112,21 @@ iscsi_if_transport_ep(struct iscsi_transport *transport, | |||
| 978 | } | 1112 | } |
| 979 | 1113 | ||
| 980 | static int | 1114 | static int |
| 1115 | iscsi_tgt_dscvr(struct iscsi_transport *transport, | ||
| 1116 | struct iscsi_uevent *ev) | ||
| 1117 | { | ||
| 1118 | struct sockaddr *dst_addr; | ||
| 1119 | |||
| 1120 | if (!transport->tgt_dscvr) | ||
| 1121 | return -EINVAL; | ||
| 1122 | |||
| 1123 | dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev)); | ||
| 1124 | return transport->tgt_dscvr(ev->u.tgt_dscvr.type, | ||
| 1125 | ev->u.tgt_dscvr.host_no, | ||
| 1126 | ev->u.tgt_dscvr.enable, dst_addr); | ||
| 1127 | } | ||
| 1128 | |||
| 1129 | static int | ||
| 981 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 1130 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) |
| 982 | { | 1131 | { |
| 983 | int err = 0; | 1132 | int err = 0; |
| @@ -1065,6 +1214,9 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 1065 | case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: | 1214 | case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: |
| 1066 | err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); | 1215 | err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); |
| 1067 | break; | 1216 | break; |
| 1217 | case ISCSI_UEVENT_TGT_DSCVR: | ||
| 1218 | err = iscsi_tgt_dscvr(transport, ev); | ||
| 1219 | break; | ||
| 1068 | default: | 1220 | default: |
| 1069 | err = -EINVAL; | 1221 | err = -EINVAL; |
| 1070 | break; | 1222 | break; |
| @@ -1147,49 +1299,31 @@ struct class_device_attribute class_device_attr_##_prefix##_##_name = \ | |||
| 1147 | /* | 1299 | /* |
| 1148 | * iSCSI connection attrs | 1300 | * iSCSI connection attrs |
| 1149 | */ | 1301 | */ |
| 1150 | #define iscsi_conn_int_attr_show(param, format) \ | 1302 | #define iscsi_conn_attr_show(param) \ |
| 1151 | static ssize_t \ | ||
| 1152 | show_conn_int_param_##param(struct class_device *cdev, char *buf) \ | ||
| 1153 | { \ | ||
| 1154 | uint32_t value = 0; \ | ||
| 1155 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | ||
| 1156 | struct iscsi_transport *t = conn->transport; \ | ||
| 1157 | \ | ||
| 1158 | t->get_conn_param(conn, param, &value); \ | ||
| 1159 | return snprintf(buf, 20, format"\n", value); \ | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | #define iscsi_conn_int_attr(field, param, format) \ | ||
| 1163 | iscsi_conn_int_attr_show(param, format) \ | ||
| 1164 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_int_param_##param, \ | ||
| 1165 | NULL); | ||
| 1166 | |||
| 1167 | iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u"); | ||
| 1168 | iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u"); | ||
| 1169 | iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d"); | ||
| 1170 | iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d"); | ||
| 1171 | iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); | ||
| 1172 | iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); | ||
| 1173 | iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d"); | ||
| 1174 | iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d"); | ||
| 1175 | iscsi_conn_int_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN, "%u"); | ||
| 1176 | |||
| 1177 | #define iscsi_conn_str_attr_show(param) \ | ||
| 1178 | static ssize_t \ | 1303 | static ssize_t \ |
| 1179 | show_conn_str_param_##param(struct class_device *cdev, char *buf) \ | 1304 | show_conn_param_##param(struct class_device *cdev, char *buf) \ |
| 1180 | { \ | 1305 | { \ |
| 1181 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | 1306 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ |
| 1182 | struct iscsi_transport *t = conn->transport; \ | 1307 | struct iscsi_transport *t = conn->transport; \ |
| 1183 | return t->get_conn_str_param(conn, param, buf); \ | 1308 | return t->get_conn_param(conn, param, buf); \ |
| 1184 | } | 1309 | } |
| 1185 | 1310 | ||
| 1186 | #define iscsi_conn_str_attr(field, param) \ | 1311 | #define iscsi_conn_attr(field, param) \ |
| 1187 | iscsi_conn_str_attr_show(param) \ | 1312 | iscsi_conn_attr_show(param) \ |
| 1188 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_str_param_##param, \ | 1313 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_param_##param, \ |
| 1189 | NULL); | 1314 | NULL); |
| 1190 | 1315 | ||
| 1191 | iscsi_conn_str_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); | 1316 | iscsi_conn_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH); |
| 1192 | iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS); | 1317 | iscsi_conn_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH); |
| 1318 | iscsi_conn_attr(header_digest, ISCSI_PARAM_HDRDGST_EN); | ||
| 1319 | iscsi_conn_attr(data_digest, ISCSI_PARAM_DATADGST_EN); | ||
| 1320 | iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN); | ||
| 1321 | iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN); | ||
| 1322 | iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT); | ||
| 1323 | iscsi_conn_attr(port, ISCSI_PARAM_CONN_PORT); | ||
| 1324 | iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN); | ||
| 1325 | iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); | ||
| 1326 | iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS); | ||
| 1193 | 1327 | ||
| 1194 | #define iscsi_cdev_to_session(_cdev) \ | 1328 | #define iscsi_cdev_to_session(_cdev) \ |
| 1195 | iscsi_dev_to_session(_cdev->dev) | 1329 | iscsi_dev_to_session(_cdev->dev) |
| @@ -1197,61 +1331,36 @@ iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS); | |||
| 1197 | /* | 1331 | /* |
| 1198 | * iSCSI session attrs | 1332 | * iSCSI session attrs |
| 1199 | */ | 1333 | */ |
| 1200 | #define iscsi_session_int_attr_show(param, format) \ | 1334 | #define iscsi_session_attr_show(param) \ |
| 1201 | static ssize_t \ | ||
| 1202 | show_session_int_param_##param(struct class_device *cdev, char *buf) \ | ||
| 1203 | { \ | ||
| 1204 | uint32_t value = 0; \ | ||
| 1205 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | ||
| 1206 | struct iscsi_transport *t = session->transport; \ | ||
| 1207 | \ | ||
| 1208 | t->get_session_param(session, param, &value); \ | ||
| 1209 | return snprintf(buf, 20, format"\n", value); \ | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | #define iscsi_session_int_attr(field, param, format) \ | ||
| 1213 | iscsi_session_int_attr_show(param, format) \ | ||
| 1214 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_int_param_##param, \ | ||
| 1215 | NULL); | ||
| 1216 | |||
| 1217 | iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d"); | ||
| 1218 | iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu"); | ||
| 1219 | iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d"); | ||
| 1220 | iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u"); | ||
| 1221 | iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u"); | ||
| 1222 | iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d"); | ||
| 1223 | iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d"); | ||
| 1224 | iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d"); | ||
| 1225 | iscsi_session_int_attr(tpgt, ISCSI_PARAM_TPGT, "%d"); | ||
| 1226 | |||
| 1227 | #define iscsi_session_str_attr_show(param) \ | ||
| 1228 | static ssize_t \ | 1335 | static ssize_t \ |
| 1229 | show_session_str_param_##param(struct class_device *cdev, char *buf) \ | 1336 | show_session_param_##param(struct class_device *cdev, char *buf) \ |
| 1230 | { \ | 1337 | { \ |
| 1231 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | 1338 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ |
| 1232 | struct iscsi_transport *t = session->transport; \ | 1339 | struct iscsi_transport *t = session->transport; \ |
| 1233 | return t->get_session_str_param(session, param, buf); \ | 1340 | return t->get_session_param(session, param, buf); \ |
| 1234 | } | 1341 | } |
| 1235 | 1342 | ||
| 1236 | #define iscsi_session_str_attr(field, param) \ | 1343 | #define iscsi_session_attr(field, param) \ |
| 1237 | iscsi_session_str_attr_show(param) \ | 1344 | iscsi_session_attr_show(param) \ |
| 1238 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \ | 1345 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_param_##param, \ |
| 1239 | NULL); | 1346 | NULL); |
| 1240 | 1347 | ||
| 1241 | iscsi_session_str_attr(targetname, ISCSI_PARAM_TARGET_NAME); | 1348 | iscsi_session_attr(targetname, ISCSI_PARAM_TARGET_NAME); |
| 1349 | iscsi_session_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN); | ||
| 1350 | iscsi_session_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T); | ||
| 1351 | iscsi_session_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN); | ||
| 1352 | iscsi_session_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST); | ||
| 1353 | iscsi_session_attr(max_burst_len, ISCSI_PARAM_MAX_BURST); | ||
| 1354 | iscsi_session_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN); | ||
| 1355 | iscsi_session_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN); | ||
| 1356 | iscsi_session_attr(erl, ISCSI_PARAM_ERL); | ||
| 1357 | iscsi_session_attr(tpgt, ISCSI_PARAM_TPGT); | ||
| 1242 | 1358 | ||
| 1243 | /* | ||
| 1244 | * Private session and conn attrs. userspace uses several iscsi values | ||
| 1245 | * to identify each session between reboots. Some of these values may not | ||
| 1246 | * be present in the iscsi_transport/LLD driver becuase userspace handles | ||
| 1247 | * login (and failback for login redirect) so for these type of drivers | ||
| 1248 | * the class manages the attrs and values for the iscsi_transport/LLD | ||
| 1249 | */ | ||
| 1250 | #define iscsi_priv_session_attr_show(field, format) \ | 1359 | #define iscsi_priv_session_attr_show(field, format) \ |
| 1251 | static ssize_t \ | 1360 | static ssize_t \ |
| 1252 | show_priv_session_##field(struct class_device *cdev, char *buf) \ | 1361 | show_priv_session_##field(struct class_device *cdev, char *buf) \ |
| 1253 | { \ | 1362 | { \ |
| 1254 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | 1363 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\ |
| 1255 | return sprintf(buf, format"\n", session->field); \ | 1364 | return sprintf(buf, format"\n", session->field); \ |
| 1256 | } | 1365 | } |
| 1257 | 1366 | ||
| @@ -1259,31 +1368,15 @@ show_priv_session_##field(struct class_device *cdev, char *buf) \ | |||
| 1259 | iscsi_priv_session_attr_show(field, format) \ | 1368 | iscsi_priv_session_attr_show(field, format) \ |
| 1260 | static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ | 1369 | static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ |
| 1261 | NULL) | 1370 | NULL) |
| 1262 | iscsi_priv_session_attr(targetname, "%s"); | ||
| 1263 | iscsi_priv_session_attr(tpgt, "%d"); | ||
| 1264 | iscsi_priv_session_attr(recovery_tmo, "%d"); | 1371 | iscsi_priv_session_attr(recovery_tmo, "%d"); |
| 1265 | 1372 | ||
| 1266 | #define iscsi_priv_conn_attr_show(field, format) \ | ||
| 1267 | static ssize_t \ | ||
| 1268 | show_priv_conn_##field(struct class_device *cdev, char *buf) \ | ||
| 1269 | { \ | ||
| 1270 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | ||
| 1271 | return sprintf(buf, format"\n", conn->field); \ | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | #define iscsi_priv_conn_attr(field, format) \ | ||
| 1275 | iscsi_priv_conn_attr_show(field, format) \ | ||
| 1276 | static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \ | ||
| 1277 | NULL) | ||
| 1278 | iscsi_priv_conn_attr(persistent_address, "%s"); | ||
| 1279 | iscsi_priv_conn_attr(persistent_port, "%d"); | ||
| 1280 | |||
| 1281 | #define SETUP_PRIV_SESSION_RD_ATTR(field) \ | 1373 | #define SETUP_PRIV_SESSION_RD_ATTR(field) \ |
| 1282 | do { \ | 1374 | do { \ |
| 1283 | priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ | 1375 | priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ |
| 1284 | count++; \ | 1376 | count++; \ |
| 1285 | } while (0) | 1377 | } while (0) |
| 1286 | 1378 | ||
| 1379 | |||
| 1287 | #define SETUP_SESSION_RD_ATTR(field, param_flag) \ | 1380 | #define SETUP_SESSION_RD_ATTR(field, param_flag) \ |
| 1288 | do { \ | 1381 | do { \ |
| 1289 | if (tt->param_mask & param_flag) { \ | 1382 | if (tt->param_mask & param_flag) { \ |
| @@ -1292,12 +1385,6 @@ do { \ | |||
| 1292 | } \ | 1385 | } \ |
| 1293 | } while (0) | 1386 | } while (0) |
| 1294 | 1387 | ||
| 1295 | #define SETUP_PRIV_CONN_RD_ATTR(field) \ | ||
| 1296 | do { \ | ||
| 1297 | priv->conn_attrs[count] = &class_device_attr_priv_conn_##field; \ | ||
| 1298 | count++; \ | ||
| 1299 | } while (0) | ||
| 1300 | |||
| 1301 | #define SETUP_CONN_RD_ATTR(field, param_flag) \ | 1388 | #define SETUP_CONN_RD_ATTR(field, param_flag) \ |
| 1302 | do { \ | 1389 | do { \ |
| 1303 | if (tt->param_mask & param_flag) { \ | 1390 | if (tt->param_mask & param_flag) { \ |
| @@ -1388,6 +1475,7 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
| 1388 | if (!priv) | 1475 | if (!priv) |
| 1389 | return NULL; | 1476 | return NULL; |
| 1390 | INIT_LIST_HEAD(&priv->list); | 1477 | INIT_LIST_HEAD(&priv->list); |
| 1478 | priv->daemon_pid = -1; | ||
| 1391 | priv->iscsi_transport = tt; | 1479 | priv->iscsi_transport = tt; |
| 1392 | priv->t.user_scan = iscsi_user_scan; | 1480 | priv->t.user_scan = iscsi_user_scan; |
| 1393 | 1481 | ||
| @@ -1424,16 +1512,8 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
| 1424 | SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); | 1512 | SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); |
| 1425 | SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); | 1513 | SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); |
| 1426 | SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); | 1514 | SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); |
| 1427 | 1515 | SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); | |
| 1428 | if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS) | 1516 | SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); |
| 1429 | SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); | ||
| 1430 | else | ||
| 1431 | SETUP_PRIV_CONN_RD_ATTR(persistent_address); | ||
| 1432 | |||
| 1433 | if (tt->param_mask & ISCSI_PERSISTENT_PORT) | ||
| 1434 | SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); | ||
| 1435 | else | ||
| 1436 | SETUP_PRIV_CONN_RD_ATTR(persistent_port); | ||
| 1437 | 1517 | ||
| 1438 | BUG_ON(count > ISCSI_CONN_ATTRS); | 1518 | BUG_ON(count > ISCSI_CONN_ATTRS); |
| 1439 | priv->conn_attrs[count] = NULL; | 1519 | priv->conn_attrs[count] = NULL; |
| @@ -1453,18 +1533,10 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
| 1453 | SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); | 1533 | SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); |
| 1454 | SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); | 1534 | SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); |
| 1455 | SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); | 1535 | SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); |
| 1536 | SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); | ||
| 1537 | SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); | ||
| 1456 | SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); | 1538 | SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); |
| 1457 | 1539 | ||
| 1458 | if (tt->param_mask & ISCSI_TARGET_NAME) | ||
| 1459 | SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); | ||
| 1460 | else | ||
| 1461 | SETUP_PRIV_SESSION_RD_ATTR(targetname); | ||
| 1462 | |||
| 1463 | if (tt->param_mask & ISCSI_TPGT) | ||
| 1464 | SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); | ||
| 1465 | else | ||
| 1466 | SETUP_PRIV_SESSION_RD_ATTR(tpgt); | ||
| 1467 | |||
| 1468 | BUG_ON(count > ISCSI_SESSION_ATTRS); | 1540 | BUG_ON(count > ISCSI_SESSION_ATTRS); |
| 1469 | priv->session_attrs[count] = NULL; | 1541 | priv->session_attrs[count] = NULL; |
| 1470 | 1542 | ||
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 ea38757d12e5..3225d31449e1 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -207,6 +207,23 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf, | |||
| 207 | return count; | 207 | return count; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf, | ||
| 211 | size_t count) | ||
| 212 | { | ||
| 213 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | ||
| 214 | struct scsi_device *sdp = sdkp->device; | ||
| 215 | |||
| 216 | if (!capable(CAP_SYS_ADMIN)) | ||
| 217 | return -EACCES; | ||
| 218 | |||
| 219 | if (sdp->type != TYPE_DISK) | ||
| 220 | return -EINVAL; | ||
| 221 | |||
| 222 | sdp->allow_restart = simple_strtoul(buf, NULL, 10); | ||
| 223 | |||
| 224 | return count; | ||
| 225 | } | ||
| 226 | |||
| 210 | static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf) | 227 | static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf) |
| 211 | { | 228 | { |
| 212 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | 229 | struct scsi_disk *sdkp = to_scsi_disk(cdev); |
| @@ -222,10 +239,19 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf) | |||
| 222 | return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); | 239 | return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); |
| 223 | } | 240 | } |
| 224 | 241 | ||
| 242 | static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf) | ||
| 243 | { | ||
| 244 | struct scsi_disk *sdkp = to_scsi_disk(cdev); | ||
| 245 | |||
| 246 | return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); | ||
| 247 | } | ||
| 248 | |||
| 225 | static struct class_device_attribute sd_disk_attrs[] = { | 249 | static struct class_device_attribute sd_disk_attrs[] = { |
| 226 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, | 250 | __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, |
| 227 | sd_store_cache_type), | 251 | sd_store_cache_type), |
| 228 | __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), | 252 | __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), |
| 253 | __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, | ||
| 254 | sd_store_allow_restart), | ||
| 229 | __ATTR_NULL, | 255 | __ATTR_NULL, |
| 230 | }; | 256 | }; |
| 231 | 257 | ||
| @@ -890,11 +916,10 @@ static struct block_device_operations sd_fops = { | |||
| 890 | static void sd_rw_intr(struct scsi_cmnd * SCpnt) | 916 | static void sd_rw_intr(struct scsi_cmnd * SCpnt) |
| 891 | { | 917 | { |
| 892 | int result = SCpnt->result; | 918 | int result = SCpnt->result; |
| 893 | int this_count = SCpnt->request_bufflen; | 919 | unsigned int xfer_size = SCpnt->request_bufflen; |
| 894 | int good_bytes = (result == 0 ? this_count : 0); | 920 | unsigned int good_bytes = result ? 0 : xfer_size; |
| 895 | sector_t block_sectors = 1; | 921 | u64 start_lba = SCpnt->request->sector; |
| 896 | u64 first_err_block; | 922 | u64 bad_lba; |
| 897 | sector_t error_sector; | ||
| 898 | struct scsi_sense_hdr sshdr; | 923 | struct scsi_sense_hdr sshdr; |
| 899 | int sense_valid = 0; | 924 | int sense_valid = 0; |
| 900 | int sense_deferred = 0; | 925 | int sense_deferred = 0; |
| @@ -905,7 +930,6 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
| 905 | if (sense_valid) | 930 | if (sense_valid) |
| 906 | sense_deferred = scsi_sense_is_deferred(&sshdr); | 931 | sense_deferred = scsi_sense_is_deferred(&sshdr); |
| 907 | } | 932 | } |
| 908 | |||
| 909 | #ifdef CONFIG_SCSI_LOGGING | 933 | #ifdef CONFIG_SCSI_LOGGING |
| 910 | SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", | 934 | SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", |
| 911 | SCpnt->request->rq_disk->disk_name, result)); | 935 | SCpnt->request->rq_disk->disk_name, result)); |
| @@ -915,89 +939,72 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
| 915 | sshdr.sense_key, sshdr.asc, sshdr.ascq)); | 939 | sshdr.sense_key, sshdr.asc, sshdr.ascq)); |
| 916 | } | 940 | } |
| 917 | #endif | 941 | #endif |
| 918 | /* | 942 | if (driver_byte(result) != DRIVER_SENSE && |
| 919 | Handle MEDIUM ERRORs that indicate partial success. Since this is a | 943 | (!sense_valid || sense_deferred)) |
| 920 | relatively rare error condition, no care is taken to avoid | 944 | goto out; |
| 921 | unnecessary additional work such as memcpy's that could be avoided. | ||
| 922 | */ | ||
| 923 | if (driver_byte(result) != 0 && | ||
| 924 | sense_valid && !sense_deferred) { | ||
| 925 | switch (sshdr.sense_key) { | ||
| 926 | case MEDIUM_ERROR: | ||
| 927 | if (!blk_fs_request(SCpnt->request)) | ||
| 928 | break; | ||
| 929 | info_valid = scsi_get_sense_info_fld( | ||
| 930 | SCpnt->sense_buffer, SCSI_SENSE_BUFFERSIZE, | ||
| 931 | &first_err_block); | ||
| 932 | /* | ||
| 933 | * May want to warn and skip if following cast results | ||
| 934 | * in actual truncation (if sector_t < 64 bits) | ||
| 935 | */ | ||
| 936 | error_sector = (sector_t)first_err_block; | ||
| 937 | if (SCpnt->request->bio != NULL) | ||
| 938 | block_sectors = bio_sectors(SCpnt->request->bio); | ||
| 939 | switch (SCpnt->device->sector_size) { | ||
| 940 | case 1024: | ||
| 941 | error_sector <<= 1; | ||
| 942 | if (block_sectors < 2) | ||
| 943 | block_sectors = 2; | ||
| 944 | break; | ||
| 945 | case 2048: | ||
| 946 | error_sector <<= 2; | ||
| 947 | if (block_sectors < 4) | ||
| 948 | block_sectors = 4; | ||
| 949 | break; | ||
| 950 | case 4096: | ||
| 951 | error_sector <<=3; | ||
| 952 | if (block_sectors < 8) | ||
| 953 | block_sectors = 8; | ||
| 954 | break; | ||
| 955 | case 256: | ||
| 956 | error_sector >>= 1; | ||
| 957 | break; | ||
| 958 | default: | ||
| 959 | break; | ||
| 960 | } | ||
| 961 | 945 | ||
| 962 | error_sector &= ~(block_sectors - 1); | 946 | switch (sshdr.sense_key) { |
| 963 | good_bytes = (error_sector - SCpnt->request->sector) << 9; | 947 | case HARDWARE_ERROR: |
| 964 | if (good_bytes < 0 || good_bytes >= this_count) | 948 | case MEDIUM_ERROR: |
| 965 | good_bytes = 0; | 949 | if (!blk_fs_request(SCpnt->request)) |
| 950 | goto out; | ||
| 951 | info_valid = scsi_get_sense_info_fld(SCpnt->sense_buffer, | ||
| 952 | SCSI_SENSE_BUFFERSIZE, | ||
| 953 | &bad_lba); | ||
| 954 | if (!info_valid) | ||
| 955 | goto out; | ||
| 956 | if (xfer_size <= SCpnt->device->sector_size) | ||
| 957 | goto out; | ||
| 958 | switch (SCpnt->device->sector_size) { | ||
| 959 | case 256: | ||
| 960 | start_lba <<= 1; | ||
| 966 | break; | 961 | break; |
| 967 | 962 | case 512: | |
| 968 | case RECOVERED_ERROR: /* an error occurred, but it recovered */ | ||
| 969 | case NO_SENSE: /* LLDD got sense data */ | ||
| 970 | /* | ||
| 971 | * Inform the user, but make sure that it's not treated | ||
| 972 | * as a hard error. | ||
| 973 | */ | ||
| 974 | scsi_print_sense("sd", SCpnt); | ||
| 975 | SCpnt->result = 0; | ||
| 976 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | ||
| 977 | good_bytes = this_count; | ||
| 978 | break; | 963 | break; |
| 979 | 964 | case 1024: | |
| 980 | case ILLEGAL_REQUEST: | 965 | start_lba >>= 1; |
| 981 | if (SCpnt->device->use_10_for_rw && | 966 | break; |
| 982 | (SCpnt->cmnd[0] == READ_10 || | 967 | case 2048: |
| 983 | SCpnt->cmnd[0] == WRITE_10)) | 968 | start_lba >>= 2; |
| 984 | SCpnt->device->use_10_for_rw = 0; | 969 | break; |
| 985 | if (SCpnt->device->use_10_for_ms && | 970 | case 4096: |
| 986 | (SCpnt->cmnd[0] == MODE_SENSE_10 || | 971 | start_lba >>= 3; |
| 987 | SCpnt->cmnd[0] == MODE_SELECT_10)) | ||
| 988 | SCpnt->device->use_10_for_ms = 0; | ||
| 989 | break; | 972 | break; |
| 990 | |||
| 991 | default: | 973 | default: |
| 974 | /* Print something here with limiting frequency. */ | ||
| 975 | goto out; | ||
| 992 | break; | 976 | break; |
| 993 | } | 977 | } |
| 978 | /* This computation should always be done in terms of | ||
| 979 | * the resolution of the device's medium. | ||
| 980 | */ | ||
| 981 | good_bytes = (bad_lba - start_lba)*SCpnt->device->sector_size; | ||
| 982 | break; | ||
| 983 | case RECOVERED_ERROR: | ||
| 984 | case NO_SENSE: | ||
| 985 | /* Inform the user, but make sure that it's not treated | ||
| 986 | * as a hard error. | ||
| 987 | */ | ||
| 988 | scsi_print_sense("sd", SCpnt); | ||
| 989 | SCpnt->result = 0; | ||
| 990 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | ||
| 991 | good_bytes = xfer_size; | ||
| 992 | break; | ||
| 993 | case ILLEGAL_REQUEST: | ||
| 994 | if (SCpnt->device->use_10_for_rw && | ||
| 995 | (SCpnt->cmnd[0] == READ_10 || | ||
| 996 | SCpnt->cmnd[0] == WRITE_10)) | ||
| 997 | SCpnt->device->use_10_for_rw = 0; | ||
| 998 | if (SCpnt->device->use_10_for_ms && | ||
| 999 | (SCpnt->cmnd[0] == MODE_SENSE_10 || | ||
| 1000 | SCpnt->cmnd[0] == MODE_SELECT_10)) | ||
| 1001 | SCpnt->device->use_10_for_ms = 0; | ||
| 1002 | break; | ||
| 1003 | default: | ||
| 1004 | break; | ||
| 994 | } | 1005 | } |
| 995 | /* | 1006 | out: |
| 996 | * This calls the generic completion function, now that we know | 1007 | scsi_io_completion(SCpnt, good_bytes); |
| 997 | * how many actual sectors finished, and how many sectors we need | ||
| 998 | * to say have failed. | ||
| 999 | */ | ||
| 1000 | scsi_io_completion(SCpnt, good_bytes, block_sectors << 9); | ||
| 1001 | } | 1008 | } |
| 1002 | 1009 | ||
| 1003 | static int media_not_present(struct scsi_disk *sdkp, | 1010 | static int media_not_present(struct scsi_disk *sdkp, |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 4e607d3065bc..65eef33846bb 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
| @@ -1401,6 +1401,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
| 1401 | Sg_device *sdp = NULL; | 1401 | Sg_device *sdp = NULL; |
| 1402 | struct cdev * cdev = NULL; | 1402 | struct cdev * cdev = NULL; |
| 1403 | int error, k; | 1403 | int error, k; |
| 1404 | unsigned long iflags; | ||
| 1404 | 1405 | ||
| 1405 | disk = alloc_disk(1); | 1406 | disk = alloc_disk(1); |
| 1406 | if (!disk) { | 1407 | if (!disk) { |
| @@ -1428,7 +1429,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
| 1428 | 1429 | ||
| 1429 | error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); | 1430 | error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); |
| 1430 | if (error) | 1431 | if (error) |
| 1431 | goto out; | 1432 | goto cdev_add_err; |
| 1432 | 1433 | ||
| 1433 | sdp->cdev = cdev; | 1434 | sdp->cdev = cdev; |
| 1434 | if (sg_sysfs_valid) { | 1435 | if (sg_sysfs_valid) { |
| @@ -1455,6 +1456,13 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
| 1455 | 1456 | ||
| 1456 | return 0; | 1457 | return 0; |
| 1457 | 1458 | ||
| 1459 | cdev_add_err: | ||
| 1460 | write_lock_irqsave(&sg_dev_arr_lock, iflags); | ||
| 1461 | kfree(sg_dev_arr[k]); | ||
| 1462 | sg_dev_arr[k] = NULL; | ||
| 1463 | sg_nr_dev--; | ||
| 1464 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | ||
| 1465 | |||
| 1458 | out: | 1466 | out: |
| 1459 | put_disk(disk); | 1467 | put_disk(disk); |
| 1460 | if (cdev) | 1468 | if (cdev) |
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) |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index b5218fc0ac86..756ceb93ddc8 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
| @@ -3599,7 +3599,6 @@ static struct st_buffer * | |||
| 3599 | tb->use_sg = max_sg; | 3599 | tb->use_sg = max_sg; |
| 3600 | tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); | 3600 | tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); |
| 3601 | 3601 | ||
| 3602 | tb->in_use = 1; | ||
| 3603 | tb->dma = need_dma; | 3602 | tb->dma = need_dma; |
| 3604 | tb->buffer_size = got; | 3603 | tb->buffer_size = got; |
| 3605 | 3604 | ||
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 411209048d74..05a5cae126ec 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h | |||
| @@ -31,7 +31,6 @@ struct st_request { | |||
| 31 | 31 | ||
| 32 | /* The tape buffer descriptor. */ | 32 | /* The tape buffer descriptor. */ |
| 33 | struct st_buffer { | 33 | struct st_buffer { |
| 34 | unsigned char in_use; | ||
| 35 | unsigned char dma; /* DMA-able buffer */ | 34 | unsigned char dma; /* DMA-able buffer */ |
| 36 | unsigned char do_dio; /* direct i/o set up? */ | 35 | unsigned char do_dio; /* direct i/o set up? */ |
| 37 | int buffer_size; | 36 | int buffer_size; |
