Re: [PATCH 02/16] block: simplify blk_init_allocated_queue
On 01/23/2017 04:29 PM, Christoph Hellwig wrote: > Return an errno value instead of the passed in queue so that the callers > don't have to keep track of two queues, and move the assignment of the > request_fn and lock to the caller as passing them as argument doesn't > simplify anything. While we're at it also remove two pointless NULL > assignments, given that the request structure is zeroed on allocation. > > Signed-off-by: Christoph Hellwig > --- > block/blk-core.c | 38 +++--- > drivers/md/dm-rq.c | 3 ++- > include/linux/blkdev.h | 3 +-- > 3 files changed, 18 insertions(+), 26 deletions(-) > Reviewed-by: Hannes Reinecke Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 01/16] block: fix elevator init check
On 01/23/2017 04:29 PM, Christoph Hellwig wrote: > We can't initalize the elevator fields for flushes as flush share space > in struct request with the elevator data. But currently we can't > commnicate that a request is a flush through blk_get_request as we > can only pass READ or WRITE, and the low-level code looks at the > possible NULL bio to check for a flush. > > Fix this by allowing to pass any block op and flags, and by checking for > the flush flags in __get_request. > > Signed-off-by: Christoph Hellwig > --- > block/blk-core.c | 26 -- > 1 file changed, 4 insertions(+), 22 deletions(-) > Reviewed-by: Hannes Reinecke Cheers, Hannes -- Dr. Hannes ReineckeTeamlead Storage & Networking h...@suse.de +49 911 74053 688 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 16/24] aacraid: Add task management functionality
Hi Raghava, [auto build test WARNING on scsi/for-next] [also build test WARNING on v4.10-rc5 next-20170123] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Raghava-Aditya-Renukunta/aacraid-Patchset-for-Smart-Family-card-support/20170124-093617 base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next config: parisc-allyesconfig (attached as .config) compiler: hppa-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=parisc All warnings (new ones prefixed by >>): In file included from include/linux/byteorder/big_endian.h:4:0, from arch/parisc/include/uapi/asm/byteorder.h:4, from arch/parisc/include/asm/bitops.h:10, from include/linux/bitops.h:36, from include/linux/kernel.h:10, from drivers/scsi/aacraid/aachba.c:27: drivers/scsi/aacraid/aachba.c: In function 'aac_build_sghba': include/uapi/linux/byteorder/big_endian.h:32:26: warning: large integer implicitly truncated to unsigned type [-Woverflow] #define __cpu_to_le32(x) ((__force __le32)__swab32((x))) ^ include/linux/byteorder/generic.h:87:21: note: in expansion of macro '__cpu_to_le32' #define cpu_to_le32 __cpu_to_le32 ^ >> drivers/scsi/aacraid/aachba.c:4000:34: note: in expansion of macro >> 'cpu_to_le32' hbacmd->emb_data_desc_count = cpu_to_le32(1); ^~~ drivers/scsi/aacraid/aachba.c: In function 'aac_report_phys_luns': drivers/scsi/aacraid/aachba.c:1801:2: warning: 'addr' may be used uninitialized in this function [-Wmaybe-uninitialized] pci_free_consistent(dev->pdev, datasize, (void *) phys_luns, addr); ^~ drivers/scsi/aacraid/aachba.c:1802:9: warning: 'rcode' may be used uninitialized in this function [-Wmaybe-uninitialized] return rcode; ^ vim +/cpu_to_le32 +4000 drivers/scsi/aacraid/aachba.c 3984 3985 sge--; 3986 /* hba wants the size to be exact */ 3987 if (byte_count > scsi_bufflen(scsicmd)) { 3988 u32 temp = le32_to_cpu(sge->len) - 3989 (byte_count - scsi_bufflen(scsicmd)); 3990 sge->len = cpu_to_le32(temp); 3991 byte_count = scsi_bufflen(scsicmd); 3992 } 3993 3994 if (nseg <= HBA_MAX_SG_EMBEDDED) { 3995 hbacmd->emb_data_desc_count = cpu_to_le32(nseg); 3996 sge->flags = cpu_to_le32(0x4000); 3997 } else { 3998 /* not embedded */ 3999 hbacmd->sge[0].flags = cpu_to_le32(0x8000); > 4000 hbacmd->emb_data_desc_count = cpu_to_le32(1); 4001 hbacmd->sge[0].addr_hi = 4002 cpu_to_le32((u32)(sg_address >> 32)); 4003 hbacmd->sge[0].addr_lo = 4004 cpu_to_le32((u32)(sg_address & 0x)); 4005 } 4006 4007 /* Check for command underflow */ 4008 if (scsicmd->underflow && (byte_count < scsicmd->underflow)) { --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH 17/24] aacraid: Added support to abort cmd and reset lun
Hi Raghava, [auto build test WARNING on scsi/for-next] [also build test WARNING on v4.10-rc5 next-20170123] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Raghava-Aditya-Renukunta/aacraid-Patchset-for-Smart-Family-card-support/20170124-093617 base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next config: x86_64-randconfig-x014-201704 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 Note: it may well be a FALSE warning. FWIW you are at least aware of it now. http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings All warnings (new ones prefixed by >>): drivers/scsi/aacraid/linit.c: In function 'aac_eh_abort': >> drivers/scsi/aacraid/linit.c:685:38: warning: 'command' may be used >> uninitialized in this function [-Wmaybe-uninitialized] if ((fib->hw_fib_va->header.XferState & ~~~ cpu_to_le32 ~~~ (Async | NoResponseExpected)) && (fib->flags & FIB_CONTEXT_FLAG) && ^~ ((command == fib->callback_data)) && ~ vim +/command +685 drivers/scsi/aacraid/linit.c 03d44337 Mark Haverkamp 2007-03-15 669 } b6ef70f3 Salyzyn, Mark2008-01-08 670 break; b6ef70f3 Salyzyn, Mark2008-01-08 671 case TEST_UNIT_READY: 1281d604 Raghava Aditya Renukunta 2017-01-23 672 /* 1281d604 Raghava Aditya Renukunta 2017-01-23 673* Mark associated FIB to not complete, 1281d604 Raghava Aditya Renukunta 2017-01-23 674* eh handler does this 1281d604 Raghava Aditya Renukunta 2017-01-23 675*/ 1281d604 Raghava Aditya Renukunta 2017-01-23 676 for (count = 0; 1281d604 Raghava Aditya Renukunta 2017-01-23 677 count < (host->can_queue + AAC_NUM_MGT_FIB); 1281d604 Raghava Aditya Renukunta 2017-01-23 678 ++count) { b6ef70f3 Salyzyn, Mark2008-01-08 679 struct scsi_cmnd *command; b6ef70f3 Salyzyn, Mark2008-01-08 680 struct fib *fib = &aac->fibs[count]; 1281d604 Raghava Aditya Renukunta 2017-01-23 681 1281d604 Raghava Aditya Renukunta 2017-01-23 682 if ((fib->hw_fib_va->header.XferState & 1281d604 Raghava Aditya Renukunta 2017-01-23 683 cpu_to_le32 1281d604 Raghava Aditya Renukunta 2017-01-23 684 (Async | NoResponseExpected)) && b6ef70f3 Salyzyn, Mark2008-01-08 @685 (fib->flags & FIB_CONTEXT_FLAG) && 1281d604 Raghava Aditya Renukunta 2017-01-23 686 ((command == fib->callback_data)) && b6ef70f3 Salyzyn, Mark2008-01-08 687 (command->device == cmd->device)) { 1281d604 Raghava Aditya Renukunta 2017-01-23 688 fib->flags |= 1281d604 Raghava Aditya Renukunta 2017-01-23 689 FIB_CONTEXT_FLAG_TIMED_OUT; 1281d604 Raghava Aditya Renukunta 2017-01-23 690 command->SCp.phase = 1281d604 Raghava Aditya Renukunta 2017-01-23 691 AAC_OWNER_ERROR_HANDLER; b6ef70f3 Salyzyn, Mark2008-01-08 692 if (command == cmd) b6ef70f3 Salyzyn, Mark2008-01-08 693 ret = SUCCESS; :: The code at line 685 was first introduced by commit :: b6ef70f33ca2a3084b4fea12414550724a9114dc [SCSI] aacraid: OS panic after Adapter panic (hardening). :: TO: Salyzyn, Mark :: CC: James Bottomley --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
Re: [PATCH 05/24] aacraid: Retrieve and update the device types
Hi Raghava, [auto build test WARNING on scsi/for-next] [also build test WARNING on v4.10-rc5 next-20170123] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Raghava-Aditya-Renukunta/aacraid-Patchset-for-Smart-Family-card-support/20170124-093617 base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next config: x86_64-randconfig-x014-201704 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 Note: it may well be a FALSE warning. FWIW you are at least aware of it now. http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings All warnings (new ones prefixed by >>): drivers/scsi/aacraid/aachba.c: In function 'aac_report_phys_luns': >> drivers/scsi/aacraid/aachba.c:1636:9: warning: 'rcode' may be used >> uninitialized in this function [-Wmaybe-uninitialized] return rcode; ^ vim +/rcode +1636 drivers/scsi/aacraid/aachba.c 1620 sg64->count = cpu_to_le32(1); 1621 sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr)); 1622 sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr)); 1623 sg64->sg[0].count = cpu_to_le32(datasize); 1624 1625 rcode = aac_fib_send(ScsiPortCommand64, fibptr, fibsize, 1626 FsaNormal, 1, 1, NULL, NULL); 1627 1628 /* analyse data */ 1629 if (rcode >= 0 && phys_luns->resp_flag == 2) { 1630 /* ok and extended reporting */ 1631 aac_update_hba_map(dev, phys_luns); 1632 } 1633 } 1634 1635 pci_free_consistent(dev->pdev, datasize, (void *) phys_luns, addr); > 1636 return rcode; 1637 } 1638 1639 int aac_get_adapter_info(struct aac_dev* dev) 1640 { 1641 struct fib* fibptr; 1642 int rcode; 1643 u32 tmp, bus, target; 1644 struct aac_adapter_info *info; --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip
[PATCH 08/24] aacraid: Added support for response path
This patch enables the driver to actually process the I/O, or srb replies from adapter. In addition to any HBA1000 or SmartIOC2000 adapter events. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 34 +++ drivers/scsi/aacraid/aacraid.h | 52 +++--- drivers/scsi/aacraid/commsup.c | 17 +- drivers/scsi/aacraid/dpcsup.c | 20 drivers/scsi/aacraid/src.c | 38 ++ 5 files changed, 99 insertions(+), 62 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index c6eb8a5..5465c8a 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -329,7 +329,7 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd, } scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; device = scsicmd->device; - if (unlikely(!device || !scsi_device_online(device))) { + if (unlikely(!device)) { dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n")); aac_fib_complete(fibptr); return 0; @@ -475,16 +475,26 @@ int aac_get_containers(struct aac_dev *dev) if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) maximum_num_containers = MAXIMUM_NUM_CONTAINERS; - fsa_dev_ptr = kzalloc(sizeof(*fsa_dev_ptr) * maximum_num_containers, - GFP_KERNEL); - if (!fsa_dev_ptr) - return -ENOMEM; + if ((dev->fsa_dev == NULL) || + (dev->maximum_num_containers != maximum_num_containers)) { + + fsa_dev_ptr = dev->fsa_dev; - dev->fsa_dev = fsa_dev_ptr; - dev->maximum_num_containers = maximum_num_containers; + dev->fsa_dev = kzalloc(sizeof(*fsa_dev_ptr) * + maximum_num_containers, GFP_KERNEL); - for (index = 0; index < dev->maximum_num_containers; ) { - fsa_dev_ptr[index].devname[0] = '\0'; + kfree(fsa_dev_ptr); + fsa_dev_ptr = NULL; + + + if (!dev->fsa_dev) + return -ENOMEM; + + dev->maximum_num_containers = maximum_num_containers; + } + for (index = 0; index < dev->maximum_num_containers; index++) { + dev->fsa_dev[index].devname[0] = '\0'; + dev->fsa_dev[index].valid = 0; status = aac_probe_container(dev, index); @@ -492,12 +502,6 @@ int aac_get_containers(struct aac_dev *dev) printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n"); break; } - - /* -* If there are no more containers, then stop asking. -*/ - if (++index >= status) - break; } return status; } diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 8c6c4ac..f749215 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -407,7 +407,7 @@ struct aac_fibhdr { __le32 SenderFibAddressHigh;/* upper 32bit of phys. FIB address */ __le32 TimeStamp; /* otherwise timestamp for FW internal use */ } u; - u32 Handle; /* FIB handle used for MSGU commnunication */ + __le32 Handle; /* FIB handle used for MSGU commnunication */ u32 Previous; /* FW internal use */ u32 Next; /* FW internal use */ }; @@ -872,18 +872,20 @@ struct rkt_registers { #define src_inbound rx_inbound struct src_mu_registers { - /* PCI*| Name */ - __le32 reserved0[6]; /* 00h | Reserved */ - __le32 IOAR[2];/* 18h | IOA->host interrupt register */ - __le32 IDR;/* 20h | Inbound Doorbell Register */ - __le32 IISR; /* 24h | Inbound Int. Status Register */ - __le32 reserved1[3]; /* 28h | Reserved */ - __le32 OIMR; /* 34h | Outbound Int. Mask Register */ - __le32 reserved2[25]; /* 38h | Reserved */ - __le32 ODR_R; /* 9ch | Outbound Doorbell Read */ - __le32 ODR_C; /* a0h | Outbound Doorbell Clear */ - __le32 reserved3[6]; /* a4h | Reserved */ - __le32 OMR;/* bch | Outbound Message Register */ + /* PCI*| Name */ + __le32 reserved0[6]; /* 00h | Reserved */ + __le32 IOAR[2];/* 18h | IOA->host interrupt register */ + __le32 IDR;/* 20h | Inbound Doorbell Register */ + __le32 IISR; /* 24h | Inbound Int. Status Register */ + __le32 reserved1[3]; /* 28h | Reserved */ + __le32 OIMR; /* 34h | Outbound Int. Mask R
[PATCH 07/24] aacraid: Process Error for response I/O
Make sure that the driver processes error conditions even in the fast response path for response from the adapter. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 289 ++ 1 file changed, 151 insertions(+), 138 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index db73216..c6eb8a5 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -3065,16 +3065,11 @@ static void aac_srb_callback(void *context, struct fib * fibptr) return; BUG_ON(fibptr == NULL); - dev = fibptr->dev; - - scsi_dma_unmap(scsicmd); - /* expose physical device if expose_physicald flag is on */ - if (scsicmd->cmnd[0] == INQUIRY && !(scsicmd->cmnd[1] & 0x01) - && expose_physicals > 0) - aac_expose_phy_device(scsicmd); + dev = fibptr->dev; srbreply = (struct aac_srb_reply *) fib_data(fibptr); + scsicmd->sense_buffer[0] = '\0'; /* Initialize sense valid flag to false */ if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) { @@ -3087,158 +3082,176 @@ static void aac_srb_callback(void *context, struct fib * fibptr) */ scsi_set_resid(scsicmd, scsi_bufflen(scsicmd) - le32_to_cpu(srbreply->data_xfer_length)); - /* -* First check the fib status -*/ + } - if (le32_to_cpu(srbreply->status) != ST_OK) { - int len; - printk(KERN_WARNING "aac_srb_callback: srb failed, status = %d\n", le32_to_cpu(srbreply->status)); - len = min_t(u32, le32_to_cpu(srbreply->sense_data_size), - SCSI_SENSE_BUFFERSIZE); - scsicmd->result = DID_ERROR << 16 - | COMMAND_COMPLETE << 8 - | SAM_STAT_CHECK_CONDITION; - memcpy(scsicmd->sense_buffer, - srbreply->sense_data, len); - } + scsi_dma_unmap(scsicmd); - /* -* Next check the srb status -*/ - switch ((le32_to_cpu(srbreply->srb_status))&0x3f) { - case SRB_STATUS_ERROR_RECOVERY: - case SRB_STATUS_PENDING: - case SRB_STATUS_SUCCESS: - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; - break; - case SRB_STATUS_DATA_OVERRUN: - switch (scsicmd->cmnd[0]) { - case READ_6: - case WRITE_6: - case READ_10: - case WRITE_10: - case READ_12: - case WRITE_12: - case READ_16: - case WRITE_16: - if (le32_to_cpu(srbreply->data_xfer_length) - < scsicmd->underflow) - printk(KERN_WARNING"aacraid: SCSI CMD underflow\n"); - else - printk(KERN_WARNING"aacraid: SCSI CMD Data Overrun\n"); - scsicmd->result = DID_ERROR << 16 - | COMMAND_COMPLETE << 8; - break; - case INQUIRY: { - scsicmd->result = DID_OK << 16 - | COMMAND_COMPLETE << 8; - break; - } - default: - scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; - break; - } - break; - case SRB_STATUS_ABORTED: - scsicmd->result = DID_ABORT << 16 | ABORT << 8; - break; - case SRB_STATUS_ABORT_FAILED: - /* -* Not sure about this one - but assuming the -* hba was trying to abort for some reason -*/ - scsicmd->result = DID_ERROR << 16 | ABORT << 8; - break; - case SRB_STATUS_PARITY_ERROR: - scsicmd->result = DID_PARITY << 16 - | MSG_PARITY_ERROR << 8; - break; - case SRB_STATUS_NO_DEVICE: - case SRB_STATUS_INVALID_PATH_ID: - case SRB_STATUS_INVALID_TARGET_ID: - case SRB_STATUS_INVALID_LUN: -
[PATCH 06/24] aacraid: Reworked scsi command submission path
Moved the READ and WRITE switch cases to the top. Added a default case to the switch case and replaced duplicate scsi result value with a macro. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 172 +- 1 file changed, 70 insertions(+), 102 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 87789580..db73216 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -106,6 +106,8 @@ #define ASENCODE_LUN_FAILED_SELF_CONFIG0x00 #define ASENCODE_OVERLAPPED_COMMAND0x00 +#define AAC_STAT_GOOD (DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD) + #define BYTE0(x) (unsigned char)(x) #define BYTE1(x) (unsigned char)((x) >> 8) #define BYTE2(x) (unsigned char)((x) >> 16) @@ -2473,8 +2475,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) if((cid >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)) { scsicmd->result = DID_NO_CONNECT << 16; - scsicmd->scsi_done(scsicmd); - return 0; + goto scsi_done_ret; } /* @@ -2509,8 +2510,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) return aac_send_srb_fib(scsicmd); } else { scsicmd->result = DID_NO_CONNECT << 16; - scsicmd->scsi_done(scsicmd); - return 0; + goto scsi_done_ret; } } } @@ -2528,13 +2528,34 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), SCSI_SENSE_BUFFERSIZE)); - scsicmd->scsi_done(scsicmd); - return 0; + goto scsi_done_ret; } - - /* Handle commands here that don't really require going out to the adapter */ switch (scsicmd->cmnd[0]) { + case READ_6: + case READ_10: + case READ_12: + case READ_16: + if (dev->in_reset) + return -1; + return aac_read(scsicmd); + + case WRITE_6: + case WRITE_10: + case WRITE_12: + case WRITE_16: + if (dev->in_reset) + return -1; + return aac_write(scsicmd); + + case SYNCHRONIZE_CACHE: + if (((aac_cache & 6) == 6) && dev->cache_protected) { + scsicmd->result = AAC_STAT_GOOD; + break; + } + /* Issue FIB to tell Firmware to flush it's cache */ + if ((aac_cache & 6) != 2) + return aac_synchronize(scsicmd); case INQUIRY: { struct inquiry_data inq_data; @@ -2557,8 +2578,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) arr[1] = scsicmd->cmnd[2]; scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data)); - scsicmd->result = DID_OK << 16 | - COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; + scsicmd->result = AAC_STAT_GOOD; } else if (scsicmd->cmnd[2] == 0x80) { /* unit serial number page */ arr[3] = setinqserial(dev, &arr[4], @@ -2569,8 +2589,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) if (aac_wwn != 2) return aac_get_container_serial( scsicmd); - scsicmd->result = DID_OK << 16 | - COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; + scsicmd->result = AAC_STAT_GOOD; } else if (scsicmd->cmnd[2] == 0x83) { /* vpd page 0x83 - Device Identification Page */ char *sno = (char *)&inq_data; @@ -2579,8 +2598,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) if (aac_wwn != 2) return aac_get_container_serial( scsicmd); - scsicmd->result = DID_OK << 16 | - COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; + scsicmd->result = AAC_STAT_GOOD; } e
[PATCH 03/24] aacraid: added support for init_struct_8
This patch lays the groundwork for supporting the new HBA-1000 controller family.A new INIT structure INIT_STRUCT_8 has been added which allows for a variable size for MSI-x vectors among other things, and is used for both Series-8, HBA-1000 and SmartIOC-2000. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 8 +- drivers/scsi/aacraid/aacraid.h | 100 +++-- drivers/scsi/aacraid/comminit.c | 238 +--- drivers/scsi/aacraid/commsup.c | 12 +- drivers/scsi/aacraid/linit.c| 2 +- drivers/scsi/aacraid/rkt.c | 2 +- drivers/scsi/aacraid/rx.c | 4 +- drivers/scsi/aacraid/sa.c | 4 +- drivers/scsi/aacraid/src.c | 27 +++-- 9 files changed, 259 insertions(+), 138 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 6678d1f..8a58b96 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1144,7 +1144,9 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3 long ret; aac_fib_init(fib); - if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) { + if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 || + dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) && + !dev->sync_mode) { struct aac_raw_io2 *readcmd2; readcmd2 = (struct aac_raw_io2 *) fib_data(fib); memset(readcmd2, 0, sizeof(struct aac_raw_io2)); @@ -1270,7 +1272,9 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u long ret; aac_fib_init(fib); - if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) { + if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 || + dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) && + !dev->sync_mode) { struct aac_raw_io2 *writecmd2; writecmd2 = (struct aac_raw_io2 *) fib_data(fib); memset(writecmd2, 0, sizeof(struct aac_raw_io2)); diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 01b457b..32888a4 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -82,6 +82,11 @@ enum { #define AAC_DEBUG_INSTRUMENT_AIF_DELETE /* + * Interrupts + */ +#define AAC_MAX_HRRQ 64 + +/* * These macros convert from physical channels to virtual channels */ #define CONTAINER_CHANNEL (0) @@ -491,41 +496,64 @@ enum fib_xfer_state { #define ADAPTER_INIT_STRUCT_REVISION_4 4 // rocket science #define ADAPTER_INIT_STRUCT_REVISION_6 6 /* PMC src */ #define ADAPTER_INIT_STRUCT_REVISION_7 7 /* Denali */ +#define ADAPTER_INIT_STRUCT_REVISION_8 8 // Thor -struct aac_init +union aac_init { - __le32 InitStructRevision; - __le32 Sa_MSIXVectors; - __le32 fsrev; - __le32 CommHeaderAddress; - __le32 FastIoCommAreaAddress; - __le32 AdapterFibsPhysicalAddress; - __le32 AdapterFibsVirtualAddress; - __le32 AdapterFibsSize; - __le32 AdapterFibAlign; - __le32 printfbuf; - __le32 printfbufsiz; - __le32 HostPhysMemPages; /* number of 4k pages of host - physical memory */ - __le32 HostElapsedSeconds; /* number of seconds since 1970. */ - /* -* ADAPTER_INIT_STRUCT_REVISION_4 begins here -*/ - __le32 InitFlags; /* flags for supported features */ + struct _r7 { + __le32 InitStructRevision; + __le32 NoOfMSIXVectors; + __le32 fsrev; + __le32 CommHeaderAddress; + __le32 FastIoCommAreaAddress; + __le32 AdapterFibsPhysicalAddress; + __le32 AdapterFibsVirtualAddress; + __le32 AdapterFibsSize; + __le32 AdapterFibAlign; + __le32 printfbuf; + __le32 printfbufsiz; + /* number of 4k pages of host phys. mem. */ + __le32 HostPhysMemPages; + /* number of seconds since 1970. */ + __le32 HostElapsedSeconds; + /* ADAPTER_INIT_STRUCT_REVISION_4 begins here */ + __le32 InitFlags; /* flags for supported features */ #define INITFLAGS_NEW_COMM_SUPPORTED 0x0001 #define INITFLAGS_DRIVER_USES_UTC_TIME 0x0010 #define INITFLAGS_DRIVER_SUPPORTS_PM 0x0020 #define INITFLAGS_NEW_COMM_TYPE1_SUPPORTED 0x0040 #define INITFLAGS_FAST_JBOD_SUPPORTED 0x0080 #define INITFLAGS_NEW_COMM_TYPE2_SUPPORTED 0x0100 - __le32 MaxIoCommands; /* max outstanding commands */ - __le32 MaxIoSize; /* largest I/O command */ - __le32 MaxFibSize; /* largest FIB to adapter */ - /* ADAPTER_INIT_STRUCT_REVISION_5 b
[PATCH 23/24] aacraid: Change Driver Version Prefix
Change the aacraid driver prefix from 1.2-1 to 1.2.1 Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/linit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 7465175..fdc444f 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -58,7 +58,7 @@ #include "aacraid.h" -#define AAC_DRIVER_VERSION "1.2-1" +#define AAC_DRIVER_VERSION "1.2.1" #ifndef AAC_DRIVER_BRANCH #define AAC_DRIVER_BRANCH "" #endif -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/24] aacraid: Added support for periodic wellness sync
This patch adds a new functions that periodically sync the time of host to the adapter. In addition also informs the adapter that the driver is alive and kicking. Only applicable to the HBA1000 and SMARTIOC2000. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aacraid.h | 3 + drivers/scsi/aacraid/commsup.c | 176 + 2 files changed, 148 insertions(+), 31 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index fb46252..03250b5 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -88,6 +88,9 @@ enum { #define AAC_MAX_NATIVE_SIZE2048 #define CISS_REPORT_PHYSICAL_LUNS 0xc3 +#define WRITE_HOST_WELLNESS0xa5 +#define BMIC_IN0x26 +#define BMIC_OUT 0x27 struct aac_ciss_phys_luns_resp { u8 list_length[4]; /* LUN list length (N-7, big endian) */ diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index dd5819c..fa9b4f9 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -1946,6 +1947,143 @@ static void aac_process_events(struct aac_dev *dev) flags); } +static int aac_send_wellness_command(struct aac_dev *dev, char *wellness_str, + u32 datasize) +{ + struct aac_srb *srbcmd; + struct sgmap64 *sg64; + dma_addr_t addr; + char *dma_buf; + struct fib *fibptr; + int ret = -ENOMEM; + + fibptr = aac_fib_alloc(dev); + if (fibptr) { + aac_fib_init(fibptr); + + dma_buf = pci_alloc_consistent(dev->pdev, datasize, &addr); + if (dma_buf != NULL) { + u32 vbus, vid; + + vbus = (u32)le16_to_cpu( + dev->supplement_adapter_info.VirtDeviceBus); + vid = (u32)le16_to_cpu( + dev->supplement_adapter_info.VirtDeviceTarget); + + srbcmd = (struct aac_srb *)fib_data(fibptr); + + srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); + srbcmd->channel = cpu_to_le32(vbus); + srbcmd->id = cpu_to_le32(vid); + srbcmd->lun = 0; + srbcmd->flags = cpu_to_le32(SRB_DataOut); + srbcmd->timeout = cpu_to_le32(10); + srbcmd->retry_limit = 0; + srbcmd->cdb_size = cpu_to_le32(12); + srbcmd->count = cpu_to_le32(datasize); + + memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); + srbcmd->cdb[0] = BMIC_OUT; + srbcmd->cdb[6] = WRITE_HOST_WELLNESS; + memcpy(dma_buf, (char *)wellness_str, datasize); + + sg64 = (struct sgmap64 *)&srbcmd->sg; + sg64->count = cpu_to_le32(1); + sg64->sg[0].addr[1] = + cpu_to_le32((u32)(((addr) >> 16) >> 16)); + sg64->sg[0].addr[0] = + cpu_to_le32((u32)(addr & 0x)); + sg64->sg[0].count = cpu_to_le32(datasize); + + ret = aac_fib_send(ScsiPortCommand64, fibptr, + sizeof(struct aac_srb), FsaNormal, + 1, 1, NULL, NULL); + + pci_free_consistent(dev->pdev, datasize, + (void *)dma_buf, addr); + } + + /* +* Do not set XferState to zero unless +* receives a response from F/W +*/ + if (ret >= 0) + aac_fib_complete(fibptr); + + /* +* FIB should be freed only after +* getting the response from the F/W +*/ + if (ret != -ERESTARTSYS) + aac_fib_free(fibptr); + } + + return ret; +} + +int aac_send_hosttime(struct aac_dev *dev, struct timeval *now) +{ + int ret = -ENOMEM; + struct fib *fibptr; + + /* +* This whole block needs to be rewritten with helpers +* Changing tabs to a single space should not be allowed!! +*/ + + if (dev->sa_firmware) { + struct tm cur_tm; + char wellness_str[] = "TD\010\0\0\0\0\0\0\0\0\0DW\0\0ZZ"; + u32 datasize = sizeof(wellness_str); + unsigned long local_time; + + local_time = (u32)(now->tv_sec - (sys_tz.tz_minuteswest * 60)); + time_to_tm(local_time, 0, &cur_tm); +
[PATCH 20/24] aacraid: Added ioctl to trigger IOP/IWBR reset
Added a new ioctl interface to trigger an IOP or IWBR reset from ioctl. Primary used by management utility to trigger resets. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/commctrl.c | 19 +++ 2 files changed, 20 insertions(+) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index ed521bb..a94a07d 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2337,6 +2337,7 @@ struct revision #define FSACTL_FORCE_DELETE_DISK CTL_CODE(2120, METHOD_NEITHER) #define FSACTL_GET_CONTAINERS 2131 #define FSACTL_SEND_LARGE_FIB CTL_CODE(2138, METHOD_BUFFERED) +#define FSACTL_RESET_IOP CTL_CODE(2140, METHOD_BUFFERED) /* flags defined for IOP & HW SOFT RESET */ #define HW_IOP_RESET 0x01 #define HW_SOFT_RESET 0x02 diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index b2af77f..4b65b91 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -1011,7 +1011,22 @@ static int aac_get_pci_info(struct aac_dev* dev, void __user *arg) } return 0; } +struct aac_reset_iop { + u8 reset_type; +}; + +static int aac_send_reset_adapter(struct aac_dev *dev, void __user *arg) +{ + struct aac_reset_iop reset; + int retval; + if (copy_from_user((void *)&reset, arg, sizeof(struct aac_reset_iop))) + return -EFAULT; + + retval = aac_reset_adapter(dev, 0, reset.reset_type); + return retval; + +} int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) { @@ -1055,6 +1070,10 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) case FSACTL_GET_PCI_INFO: status = aac_get_pci_info(dev,arg); break; + case FSACTL_RESET_IOP: + status = aac_send_reset_adapter(dev, arg); + break; + default: status = -ENOTTY; break; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/24] aacraid: Added sa firmware support
sa_firmware adds the capability to differentiate the new SmartIOC family of adapters from the series 8 and below. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aacraid.h | 4 ++ drivers/scsi/aacraid/comminit.c | 98 + drivers/scsi/aacraid/linit.c| 2 +- 3 files changed, 45 insertions(+), 59 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 32888a4..057ff78 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1130,6 +1130,7 @@ struct aac_bus_info_response { #define AAC_OPT_SUPPLEMENT_ADAPTER_INFOcpu_to_le32(1<<16) #define AAC_OPT_NEW_COMM cpu_to_le32(1<<17) #define AAC_OPT_NEW_COMM_64cpu_to_le32(1<<18) +#define AAC_OPT_EXTENDED cpu_to_le32(1<<23) #define AAC_OPT_NEW_COMM_TYPE1 cpu_to_le32(1<<28) #define AAC_OPT_NEW_COMM_TYPE2 cpu_to_le32(1<<29) #define AAC_OPT_NEW_COMM_TYPE3 cpu_to_le32(1<<30) @@ -1141,6 +1142,8 @@ struct aac_bus_info_response { #define AAC_COMM_MESSAGE_TYPE2 4 #define AAC_COMM_MESSAGE_TYPE3 5 +#define AAC_EXTOPT_SA_FIRMWARE cpu_to_le32(1<<1) + /* MSIX context */ struct aac_msix_ctx { int vector_no; @@ -1272,6 +1275,7 @@ struct aac_dev u8 printf_enabled; u8 in_reset; u8 msi; + u8 sa_firmware; int management_fib_count; spinlock_t manage_lock; spinlock_t sync_lock; diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index a59e23b..407ccf0 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -75,14 +75,22 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) || (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) || - (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3)) + (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3 && + !dev->sa_firmware)) { host_rrq_size = (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) * sizeof(u32); - else + aac_init_size = sizeof(union aac_init); + } else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3 && + dev->sa_firmware) { + host_rrq_size = (dev->scsi_host_ptr->can_queue + + AAC_NUM_MGT_FIB) * sizeof(u32) * AAC_MAX_MSIX; + aac_init_size = sizeof(union aac_init) + + (AAC_MAX_HRRQ - 1) * sizeof(struct _rrq); + } else { host_rrq_size = 0; - - aac_init_size = sizeof(union aac_init); + aac_init_size = sizeof(union aac_init); + } size = fibsize + aac_init_size + commsize + commalign + printfbufsiz + host_rrq_size; @@ -465,9 +473,13 @@ void aac_define_int_mode(struct aac_dev *dev) if (dev->max_msix > msi_count) dev->max_msix = msi_count; } - dev->vector_cap = - (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) / - msi_count; + if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3 && dev->sa_firmware) + dev->vector_cap = (dev->scsi_host_ptr->can_queue + + AAC_NUM_MGT_FIB); + else + dev->vector_cap = (dev->scsi_host_ptr->can_queue + + AAC_NUM_MGT_FIB) / msi_count; + } struct aac_dev *aac_init_adapter(struct aac_dev *dev) { @@ -526,6 +538,12 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) dev->sync_mode = 1; } } + if ((status[1] & le32_to_cpu(AAC_OPT_EXTENDED)) && + (status[4] & le32_to_cpu(AAC_EXTOPT_SA_FIRMWARE))) + dev->sa_firmware = 1; + else + dev->sa_firmware = 0; + if ((dev->comm_interface == AAC_COMM_MESSAGE) && (status[2] > dev->base_size)) { aac_adapter_ioremap(dev, 0); @@ -562,61 +580,25 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) dev->sg_tablesize = status[2] & 0x; if (dev->pdev->device == PMC_DEVICE_S7 || dev->pdev->device == PMC_DEVICE_S8 || - dev->pdev->device == PMC_DEVICE_S9) - host->can_queue = ((status[3] >> 16) ? (status[3] >> 16) : - (status[3] & 0x)) - AAC_NUM_MGT_FIB; - else - host->can_queue = (status[3] & 0x) - AAC_NUM
[PATCH 19/24] aacraid: Added new IWBR reset
Added a new IWBR soft reset type, reworked the IOP reset interface for a bit. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aacraid.h | 15 +++-- drivers/scsi/aacraid/commsup.c | 15 +++-- drivers/scsi/aacraid/linit.c | 8 ++- drivers/scsi/aacraid/rx.c | 10 ++-- drivers/scsi/aacraid/sa.c | 2 +- drivers/scsi/aacraid/src.c | 129 ++--- 6 files changed, 127 insertions(+), 52 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 58bb7a6..ed521bb 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -882,7 +882,7 @@ struct adapter_ops void (*adapter_enable_int)(struct aac_dev *dev); int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4); int (*adapter_check_health)(struct aac_dev *dev); - int (*adapter_restart)(struct aac_dev *dev, int bled); + int (*adapter_restart)(struct aac_dev *dev, int bled, u8 reset_type); void (*adapter_start)(struct aac_dev *dev); /* Transport operations */ int (*adapter_ioremap)(struct aac_dev * dev, u32 size); @@ -1661,8 +1661,8 @@ struct aac_dev #define aac_adapter_check_health(dev) \ (dev)->a_ops.adapter_check_health(dev) -#define aac_adapter_restart(dev,bled) \ - (dev)->a_ops.adapter_restart(dev,bled) +#define aac_adapter_restart(dev, bled, reset_type) \ + ((dev)->a_ops.adapter_restart(dev, bled, reset_type)) #define aac_adapter_start(dev) \ ((dev)->a_ops.adapter_start(dev)) @@ -2337,6 +2337,13 @@ struct revision #define FSACTL_FORCE_DELETE_DISK CTL_CODE(2120, METHOD_NEITHER) #define FSACTL_GET_CONTAINERS 2131 #define FSACTL_SEND_LARGE_FIB CTL_CODE(2138, METHOD_BUFFERED) +/* flags defined for IOP & HW SOFT RESET */ +#define HW_IOP_RESET 0x01 +#define HW_SOFT_RESET 0x02 +#define IOP_HWSOFT_RESET (HW_IOP_RESET | HW_SOFT_RESET) +/* HW Soft Reset register offset */ +#define IBW_SWR_OFFSET 0x4000 +#define SOFT_RESET_TIME60 struct aac_common @@ -2573,7 +2580,7 @@ unsigned int aac_command_normal(struct aac_queue * q); unsigned int aac_intr_normal(struct aac_dev *dev, u32 Index, int isAif, int isFastResponse, struct hw_fib *aif_fib); -int aac_reset_adapter(struct aac_dev * dev, int forced); +int aac_reset_adapter(struct aac_dev *dev, int forced, u8 reset_type); int aac_check_health(struct aac_dev * dev); int aac_command_thread(void *data); int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx); diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 13c5c10..d6e3fa0 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1455,7 +1455,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) } } -static int _aac_reset_adapter(struct aac_dev *aac, int forced) +static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) { int index, quirks; int retval; @@ -1464,6 +1464,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) struct scsi_cmnd *command; struct scsi_cmnd *command_list; int jafo = 0; + int bled; /* * Assumptions: @@ -1488,7 +1489,8 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) * If a positive health, means in a known DEAD PANIC * state and the adapter could be reset to `try again'. */ - retval = aac_adapter_restart(aac, forced ? 0 : aac_adapter_check_health(aac)); + bled = forced ? 0 : aac_adapter_check_health(aac); + retval = aac_adapter_restart(aac, bled, reset_type); if (retval) goto out; @@ -1598,7 +1600,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced) return retval; } -int aac_reset_adapter(struct aac_dev * aac, int forced) +int aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) { unsigned long flagv = 0; int retval; @@ -1651,7 +1653,9 @@ int aac_reset_adapter(struct aac_dev * aac, int forced) if (forced < 2) aac_send_shutdown(aac); spin_lock_irqsave(host->host_lock, flagv); - retval = _aac_reset_adapter(aac, forced ? forced : ((aac_check_reset != 0) && (aac_check_reset != 1))); + retval = _aac_reset_adapter(aac, + forced ? forced : ((aac_check_reset != 0) && + (aac_check_reset != 1)), reset_type); spin_unlock_irqrestore(host->host_lock, flagv); if ((forced < 2) && (retval == -ENODEV)) { @@ -1814,7 +1818,8 @@ int aac_che
[PATCH 15/24] aacraid: Include HBA direct interface
Added support to send direct pasthru srb commands from management utilty to the controller. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aacraid.h | 175 ++-- drivers/scsi/aacraid/commctrl.c | 294 ++-- drivers/scsi/aacraid/commsup.c | 134 +++--- drivers/scsi/aacraid/dpcsup.c | 136 --- drivers/scsi/aacraid/linit.c| 1 + drivers/scsi/aacraid/src.c | 118 ++-- 6 files changed, 669 insertions(+), 189 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 6709de4..6ca77ff 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -86,6 +86,7 @@ enum { #define AAC_MAX_BUSES 5 #define AAC_MAX_TARGETS256 #define AAC_MAX_NATIVE_SIZE2048 +#define FW_ERROR_BUFFER_SIZE 512 /* Thor AIF events */ #define SA_AIF_HOTPLUG (1<<1) @@ -95,6 +96,141 @@ enum { #define SA_AIF_BPSTAT_CHANGE (1<<30) #define SA_AIF_BPCFG_CHANGE(1<<31) +#define HBA_MAX_SG_EMBEDDED28 +#define HBA_MAX_SG_SEPARATE90 +#define HBA_SENSE_DATA_LEN_MAX 32 +#define HBA_REQUEST_TAG_ERROR_FLAG 0x0002 +#define HBA_SGL_FLAGS_EXT 0x8000UL + +struct aac_hba_sgl { + u32 addr_lo; /* Lower 32-bits of SGL element address */ + u32 addr_hi; /* Upper 32-bits of SGL element address */ + u32 len;/* Length of SGL element in bytes */ + u32 flags; /* SGL element flags */ +}; + +enum { + HBA_IU_TYPE_SCSI_CMD_REQ= 0x40, + HBA_IU_TYPE_SCSI_TM_REQ = 0x41, + HBA_IU_TYPE_SATA_REQ= 0x42, + HBA_IU_TYPE_RESP= 0x60, + HBA_IU_TYPE_COALESCED_RESP = 0x61, + HBA_IU_TYPE_INT_COALESCING_CFG_REQ = 0x70 +}; + +enum { + HBA_CMD_BYTE1_DATA_DIR_IN = 0x1, + HBA_CMD_BYTE1_DATA_DIR_OUT = 0x2, + HBA_CMD_BYTE1_DATA_TYPE_DDR = 0x4, + HBA_CMD_BYTE1_CRYPTO_ENABLE = 0x8 +}; + +enum { + HBA_CMD_BYTE1_BITOFF_DATA_DIR_IN= 0x0, + HBA_CMD_BYTE1_BITOFF_DATA_DIR_OUT, + HBA_CMD_BYTE1_BITOFF_DATA_TYPE_DDR, + HBA_CMD_BYTE1_BITOFF_CRYPTO_ENABLE +}; + +enum { + HBA_RESP_DATAPRES_NO_DATA = 0x0, + HBA_RESP_DATAPRES_RESPONSE_DATA, + HBA_RESP_DATAPRES_SENSE_DATA +}; + +enum { + HBA_RESP_SVCRES_TASK_COMPLETE = 0x0, + HBA_RESP_SVCRES_FAILURE, + HBA_RESP_SVCRES_TMF_COMPLETE, + HBA_RESP_SVCRES_TMF_SUCCEEDED, + HBA_RESP_SVCRES_TMF_REJECTED, + HBA_RESP_SVCRES_TMF_LUN_INVALID +}; + +enum { + HBA_RESP_STAT_IO_ERROR = 0x1, + HBA_RESP_STAT_IO_ABORTED, + HBA_RESP_STAT_NO_PATH_TO_DEVICE, + HBA_RESP_STAT_INVALID_DEVICE, + HBA_RESP_STAT_HBAMODE_DISABLED = 0xE, + HBA_RESP_STAT_UNDERRUN = 0x51, + HBA_RESP_STAT_OVERRUN = 0x75 +}; + +struct aac_hba_cmd_req { + u8 iu_type;/* HBA information unit type */ + /* +* byte1: +* [1:0] DIR - 0=No data, 0x1 = IN, 0x2 = OUT +* [2] TYPE - 0=PCI, 1=DDR +* [3] CRYPTO_ENABLE - 0=Crypto disabled, 1=Crypto enabled +*/ + u8 byte1; + u8 reply_qid; /* Host reply queue to post response to */ + u8 reserved1; + __le32 it_nexus; /* Device handle for the request */ + __le32 request_id; /* Sender context */ + /* Lower 32-bits of tweak value for crypto enabled IOs */ + __le32 tweak_value_lo; + u8 cdb[16];/* SCSI CDB of the command */ + u8 lun[8]; /* SCSI LUN of the command */ + + /* Total data length in bytes to be read/written (if any) */ + __le32 data_length; + + /* [2:0] Task Attribute, [6:3] Command Priority */ + u8 attr_prio; + + /* Number of SGL elements embedded in the HBA req */ + u8 emb_data_desc_count; + + __le16 dek_index; /* DEK index for crypto enabled IOs */ + + /* Lower 32-bits of reserved error data target location on the host */ + __le32 error_ptr_lo; + + /* Upper 32-bits of reserved error data target location on the host */ + __le32 error_ptr_hi; + + /* Length of reserved error data area on the host in bytes */ + __le32 error_length; + + /* Upper 32-bits of tweak value for crypto enabled IOs */ + __le32 tweak_value_hi; + + struct aac_hba_sgl sge[HBA_MAX_SG_SEPARATE+2]; /* SG list space */ + + /* +* structure must not exceed +* AAC_MAX_NATIVE_SIZE-FW_ERROR_BUFFER_SIZE +*/ +}; + +struct aac_hba_resp { +
[PATCH 13/24] aacraid: Added support to set QD of attached drives
Added support to set qd of drives in slave_configure.This only works for HBA1000 attached drives. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/linit.c | 100 --- 1 file changed, 66 insertions(+), 34 deletions(-) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index e2d063d..698d522 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -401,20 +401,33 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, static int aac_slave_configure(struct scsi_device *sdev) { struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata; - if (aac->jbod && (sdev->type == TYPE_DISK)) - sdev->removable = 1; - if ((sdev->type == TYPE_DISK) && + int chn, tid, is_native_device = 0; + + chn = aac_logical_to_phys(sdev_channel(sdev)); + tid = sdev_id(sdev); + if (chn < AAC_MAX_BUSES && tid < AAC_MAX_TARGETS && + aac->hba_map[chn][tid].devtype == AAC_DEVTYPE_NATIVE_RAW) + is_native_device = 1; + + + if (!is_native_device) { + if (aac->jbod && (sdev->type == TYPE_DISK)) + sdev->removable = 1; + if ((sdev->type == TYPE_DISK) && (sdev_channel(sdev) != CONTAINER_CHANNEL) && (!aac->jbod || sdev->inq_periph_qual) && (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))) { - if (expose_physicals == 0) - return -ENXIO; - if (expose_physicals < 0) - sdev->no_uld_attach = 1; + if (expose_physicals == 0) + return -ENXIO; + if (expose_physicals < 0) + sdev->no_uld_attach = 1; + } } - if (sdev->tagged_supported && (sdev->type == TYPE_DISK) && + + if (is_native_device || + (sdev->tagged_supported && (sdev->type == TYPE_DISK) && (!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) && - !sdev->no_uld_attach) { + !sdev->no_uld_attach)) { struct scsi_device * dev; struct Scsi_Host *host = sdev->host; unsigned num_lsu = 0; @@ -428,34 +441,41 @@ static int aac_slave_configure(struct scsi_device *sdev) */ if (sdev->request_queue->rq_timeout < (45 * HZ)) blk_queue_rq_timeout(sdev->request_queue, 45*HZ); - for (cid = 0; cid < aac->maximum_num_containers; ++cid) - if (aac->fsa_dev[cid].valid) - ++num_lsu; - __shost_for_each_device(dev, host) { - if (dev->tagged_supported && (dev->type == TYPE_DISK) && + if (!is_native_device) { + for (cid = 0; cid < aac->maximum_num_containers; ++cid) + if (aac->fsa_dev[cid].valid) + ++num_lsu; + __shost_for_each_device(dev, host) { + if (dev->tagged_supported && + (dev->type == TYPE_DISK) && (!aac->raid_scsi_mode || - (sdev_channel(sdev) != 2)) && + (sdev_channel(sdev) != 2)) && !dev->no_uld_attach) { - if ((sdev_channel(dev) != CONTAINER_CHANNEL) -|| !aac->fsa_dev[sdev_id(dev)].valid) - ++num_lsu; - } else - ++num_one; + if ((sdev_channel(dev) + != CONTAINER_CHANNEL) +|| !aac->fsa_dev[sdev_id(dev)].valid) { + ++num_lsu; + } + } else { + ++num_one; + } + } + if (num_lsu == 0) + ++num_lsu; + depth = (host->can_queue - num_one) / num_lsu; + if (depth > 256) + depth = 256; + else if (depth < 2) + depth = 2; + scsi_change_queue_depth(sdev, depth); + } else { + scsi_change_queue_depth(sdev, + aac->hba_map[chn][tid].qd_limit); } - if (num_lsu == 0)
[PATCH 10/24] aacraid: Reworked aac_command_thread
Reworked aac_command_thread into aac_process_events Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/commsup.c | 410 ++--- 1 file changed, 217 insertions(+), 193 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 31c65ca..dd5819c 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1729,6 +1729,222 @@ int aac_check_health(struct aac_dev * aac) return BlinkLED; } +static void aac_process_events(struct aac_dev *dev) +{ + struct hw_fib *hw_fib, *hw_newfib; + struct fib *fib, *newfib; + struct aac_fib_context *fibctx; + unsigned long flags; + spinlock_t *t_lock; + + spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags); + while (!list_empty(&(dev->queues->queue[HostNormCmdQueue].cmdq))) { + struct list_head *entry; + struct aac_aifcmd *aifcmd; + u32 time_now, time_last; + unsigned long flagv; + unsigned int num; + struct hw_fib **hw_fib_pool, **hw_fib_p; + struct fib **fib_pool, **fib_p; + + set_current_state(TASK_RUNNING); + + entry = dev->queues->queue[HostNormCmdQueue].cmdq.next; + list_del(entry); + + + t_lock = dev->queues->queue[HostNormCmdQueue].lock; + spin_unlock_irqrestore(t_lock, flags); + + fib = list_entry(entry, struct fib, fiblink); + hw_fib = fib->hw_fib_va; + /* +* We will process the FIB here or pass it to a +* worker thread that is TBD. We Really can't +* do anything at this point since we don't have +* anything defined for this thread to do. +*/ + memset(fib, 0, sizeof(struct fib)); + fib->type = FSAFS_NTC_FIB_CONTEXT; + fib->size = sizeof(struct fib); + fib->hw_fib_va = hw_fib; + fib->data = hw_fib->data; + fib->dev = dev; + /* +* We only handle AifRequest fibs from the adapter. +*/ + + aifcmd = (struct aac_aifcmd *) hw_fib->data; + if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) { + /* Handle Driver Notify Events */ + aac_handle_aif(dev, fib); + *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK); + aac_fib_adapter_complete(fib, (u16)sizeof(u32)); + continue; + } + /* +* The u32 here is important and intended. We are using +* 32bit wrapping time to fit the adapter field +*/ + + + /* Sniff events */ + if ((aifcmd->command == cpu_to_le32(AifCmdEventNotify)) || + (aifcmd->command == + cpu_to_le32(AifCmdJobProgress))) { + aac_handle_aif(dev, fib); + } + + time_now = jiffies/HZ; + + /* +* Warning: no sleep allowed while +* holding spinlock. We take the estimate +* and pre-allocate a set of fibs outside the +* lock. +*/ + num = le32_to_cpu(dev->init->r7.AdapterFibsSize) + / sizeof(struct hw_fib); /* some extra */ + spin_lock_irqsave(&dev->fib_lock, flagv); + entry = dev->fib_list.next; + while (entry != &dev->fib_list) { + entry = entry->next; + ++num; + } + spin_unlock_irqrestore(&dev->fib_lock, flagv); + hw_fib_pool = kmalloc_array(num, sizeof(struct hw_fib *), + GFP_KERNEL); + fib_pool = kmalloc_array(num, sizeof(struct fib *), + GFP_KERNEL); + if (num && fib_pool && hw_fib_pool) { + hw_fib_p = hw_fib_pool; + fib_p = fib_pool; + while (hw_fib_p < &hw_fib_pool[num]) { + *(hw_fib_p) = kmalloc(sizeof(struct hw_fib), + GFP_KERNEL); + if (!(*(hw_fib_p++))) { + --hw_fib_p; + break; + } + *(fib_p) = kmalloc(sizeof(struct fib), + GFP_KERNEL); + if (!(*(fib_p++))) { + kfree(*(--hw_fib_p)); +
[PATCH 22/24] aacraid: Update copyrights
Added new copyright messages Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 8 +++- drivers/scsi/aacraid/aacraid.h | 32 drivers/scsi/aacraid/commctrl.c | 3 ++- drivers/scsi/aacraid/comminit.c | 3 ++- drivers/scsi/aacraid/commsup.c | 3 ++- drivers/scsi/aacraid/dpcsup.c | 3 ++- drivers/scsi/aacraid/linit.c| 3 ++- drivers/scsi/aacraid/nark.c | 3 ++- drivers/scsi/aacraid/rkt.c | 3 ++- drivers/scsi/aacraid/rx.c | 3 ++- drivers/scsi/aacraid/sa.c | 3 ++- drivers/scsi/aacraid/src.c | 3 ++- 12 files changed, 59 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index a89e2a5..d2677cd 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -6,7 +6,8 @@ * Adaptec aacraid device driver for Linux. * * Copyright (c) 2000-2010 Adaptec, Inc. - * 2010 PMC-Sierra, Inc. (aacr...@pmc-sierra.com) + * 2010-2015 PMC-Sierra, Inc. (aacr...@pmc-sierra.com) + * 2016-2017 Microsemi Corp. (aacr...@microsemi.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,6 +23,11 @@ * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * + * Module Name: + * aachba.c + * + * Abstract: Contains Interfaces to manage IOs. + * */ #include diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 52a2264..58ee1b3 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1,3 +1,35 @@ +/* + * Adaptec AAC series RAID controller driver + * (c) Copyright 2001 Red Hat Inc. + * + * based on the old aacraid driver that is.. + * Adaptec aacraid device driver for Linux. + * + * Copyright (c) 2000-2010 Adaptec, Inc. + * 2010-2015 PMC-Sierra, Inc. (aacr...@pmc-sierra.com) + * 2016-2017 Microsemi Corp. (aacr...@microsemi.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Module Name: + * aacraid.h + * + * Abstract: Contains all routines for control of the aacraid driver + * + */ + #ifndef _AACRAID_H_ #define _AACRAID_H_ #ifndef dprintk diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 9ade2b4..a704e8d 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -6,7 +6,8 @@ * Adaptec aacraid device driver for Linux. * * Copyright (c) 2000-2010 Adaptec, Inc. - * 2010 PMC-Sierra, Inc. (aacr...@pmc-sierra.com) + * 2010-2015 PMC-Sierra, Inc. (aacr...@pmc-sierra.com) + * 2016-2017 Microsemi Corp. (aacr...@microsemi.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 407ccf0..ca8f8bd 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -6,7 +6,8 @@ * Adaptec aacraid device driver for Linux. * * Copyright (c) 2000-2010 Adaptec, Inc. - * 2010 PMC-Sierra, Inc. (aacr...@pmc-sierra.com) + * 2010-2015 PMC-Sierra, Inc. (aacr...@pmc-sierra.com) + * 2016-2017 Microsemi Corp. (aacr...@microsemi.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index d6e3fa0..0a8a56d 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -6,7 +6,8 @@ * Adaptec aacraid device driver for Linux. * * Copyright (c) 2000-2010 Adaptec, Inc. - * 2010 PMC-Sierra, Inc. (aacr...@pmc-sierra.com) + * 2010-2015 PMC-Sierra, Inc. (aacr...@pmc-sierra.com) + * 2016-2017 Microsemi Corp. (aacr...@microsemi.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by
[PATCH 05/24] aacraid: Retrieve and update the device types
This patch adds support to retrieve the type of each adapter connected device. Applicable to HBA1000 and SmartIOC2000 products Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 141 - drivers/scsi/aacraid/aacraid.h | 60 +- 2 files changed, 199 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 8a58b96..87789580 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1509,11 +1509,138 @@ static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd) return aac_scsi_32(fib, cmd); } +/** + * aac_update hba_map()- update current hba map with data from FW + * @dev: aac_dev structure + * @phys_luns: FW information from report phys luns + * + * Update our hba map with the information gathered from the FW + */ +void aac_update_hba_map(struct aac_dev *dev, + struct aac_ciss_phys_luns_resp *phys_luns) +{ + /* ok and extended reporting */ + u32 lun_count, nexus; + u32 i, bus, target; + u8 expose_flag, attribs; + u8 devtype; + + lun_count = ((phys_luns->list_length[0] << 24) + + (phys_luns->list_length[1] << 16) + + (phys_luns->list_length[2] << 8) + + (phys_luns->list_length[3])) / 24; + + for (i = 0; i < lun_count; ++i) { + + bus = phys_luns->lun[i].level2[1] & 0x3f; + target = phys_luns->lun[i].level2[0]; + expose_flag = phys_luns->lun[i].bus >> 6; + attribs = phys_luns->lun[i].node_ident[9]; + nexus = *((u32 *) &phys_luns->lun[i].node_ident[12]); + + if (bus >= AAC_MAX_BUSES || target >= AAC_MAX_TARGETS) + continue; + + dev->hba_map[bus][target].expose = expose_flag; + + if (expose_flag != 0) { + devtype = AAC_DEVTYPE_RAID_MEMBER; + goto update_devtype; + } + + if (nexus != 0 && (attribs & 8)) { + devtype = AAC_DEVTYPE_NATIVE_RAW; + dev->hba_map[bus][target].rmw_nexus = + nexus; + } else + devtype = AAC_DEVTYPE_ARC_RAW; + + if (devtype != AAC_DEVTYPE_NATIVE_RAW) + goto update_devtype; + +update_devtype: + dev->hba_map[bus][target].devtype = devtype; + } +} + +/** + * aac_report_phys_luns() Process topology change + * @dev: aac_dev structure + * @fibptr:fib pointer + * + * Execute a CISS REPORT PHYS LUNS and process the results into + * the current hba_map. + */ +int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr) +{ + int fibsize, datasize; + struct aac_ciss_phys_luns_resp *phys_luns; + struct aac_srb *srbcmd; + struct sgmap64 *sg64; + dma_addr_t addr; + u32 rcode; + + /* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */ + fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) + + sizeof(struct sgentry64); + datasize = sizeof(struct aac_ciss_phys_luns_resp) + + (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); + + phys_luns = (struct aac_ciss_phys_luns_resp *) pci_alloc_consistent( + dev->pdev, datasize, &addr); + + if (phys_luns != NULL) { + u32 vbus, vid; + + vbus = (u32) le16_to_cpu( + dev->supplement_adapter_info.VirtDeviceBus); + vid = (u32) le16_to_cpu( + dev->supplement_adapter_info.VirtDeviceTarget); + + aac_fib_init(fibptr); + + srbcmd = (struct aac_srb *) fib_data(fibptr); + srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); + srbcmd->channel = cpu_to_le32(vbus); + srbcmd->id = cpu_to_le32(vid); + srbcmd->lun = 0; + srbcmd->flags = cpu_to_le32(SRB_DataIn); + srbcmd->timeout = cpu_to_le32(10); + srbcmd->retry_limit = 0; + srbcmd->cdb_size = cpu_to_le32(12); + srbcmd->count = cpu_to_le32(datasize); + + memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); + srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS; + srbcmd->cdb[1] = 2; /* extended reporting */ + srbcmd->cdb[8] = (u8)(datasize >> 8); + srbcmd->cdb[9] = (u8)(datasize); + + sg64 = (struct sgmap64 *) &srbcmd->sg; + sg64->count = cpu_to_le32(1); + sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr)); + sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr)); + sg64-
[PATCH 24/24] aacraid: update version
Update the driver version to 50740 Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aacraid.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 58ee1b3..e3b79a1 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -97,8 +97,8 @@ enum { #definePMC_GLOBAL_INT_BIT0 0x0001 #ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 41066 -# define AAC_DRIVER_BRANCH "-ms" +# define AAC_DRIVER_BUILD 50740 +# define AAC_DRIVER_BRANCH "-custom" #endif #define MAXIMUM_NUM_CONTAINERS 32 -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 21/24] aacraid: Retrieve HBA host information ioctl
Added a new ioctl interface to retrieve the host device information. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aacraid.h | 52 + drivers/scsi/aacraid/commctrl.c | 26 + 2 files changed, 78 insertions(+) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index a94a07d..52a2264 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2338,6 +2338,7 @@ struct revision #define FSACTL_GET_CONTAINERS 2131 #define FSACTL_SEND_LARGE_FIB CTL_CODE(2138, METHOD_BUFFERED) #define FSACTL_RESET_IOP CTL_CODE(2140, METHOD_BUFFERED) +#define FSACTL_GET_HBA_INFOCTL_CODE(2150, METHOD_BUFFERED) /* flags defined for IOP & HW SOFT RESET */ #define HW_IOP_RESET 0x01 #define HW_SOFT_RESET 0x02 @@ -2377,6 +2378,57 @@ struct aac_common extern struct aac_common aac_config; /* + * This is for management ioctl purpose only. + */ +struct aac_hba_info { + + u8 DriverName[50]; + u8 AdapterNumber; + u8 SystemIoBusNumber; + u8 DeviceNumber; + u32 FunctionNumber; + u32 VendorID; + u32 DeviceID; + u32 SubVendorID; + u32 SubSystemID; + u32 MappedBaseAddressSize; + u32 BasePhysicalAddress_HighPart; + u32 BasePhysicalAddress_LowPart; + + u32 MaxCommandSize; + u32 MaxFibSize; + u32 MaxScatterGatherFromOs; + u32 MaxScatterGatherToFw; + u32 MaxOutstandingFibs; + + u32 QueueStartThreshold; + u32 QueueDumpThreshold; + u32 MaxIoSizeQueued; + u32 OutstandingIO; + + u32 FirmwareBuildNumber; + u32 BIOSBuildNumber; + u32 DriverBuildNumber; + u32 SerialNumber_HighPart; + u32 SerialNumber_LowPart; + u32 SupportedOptions; + u32 FeatureBits; + u32 currentnumberPorts; + + u8 NewCommInterface:1; + u8 NewCommandsSupported:1; + u8 DisablePassthrough:1; + u8 ExposeNonDasd:1; + u8 QueueAllowed:1; + u8 BLEDCheckEnabled:1; + u8 reserved1:1; + u8 reserted2:1; + + u32 reserved3[10]; + +}; + +/* * The following macro is used when sending and receiving FIBs. It is * only used for debugging. */ diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 4b65b91..9ade2b4 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -1011,6 +1011,29 @@ static int aac_get_pci_info(struct aac_dev* dev, void __user *arg) } return 0; } + +static int aac_get_hba_info(struct aac_dev *dev, void __user *arg) +{ + struct aac_hba_info hbainfo; + + hbainfo.AdapterNumber = (u8) dev->id; + hbainfo.SystemIoBusNumber = dev->pdev->bus->number; + hbainfo.DeviceNumber= (dev->pdev->devfn >> 3); + hbainfo.FunctionNumber = (dev->pdev->devfn & 0x0007); + + hbainfo.VendorID= dev->pdev->vendor; + hbainfo.DeviceID= dev->pdev->device; + hbainfo.SubVendorID = dev->pdev->subsystem_vendor; + hbainfo.SubSystemID = dev->pdev->subsystem_device; + + if (copy_to_user(arg, &hbainfo, sizeof(struct aac_hba_info))) { + dprintk((KERN_DEBUG "aacraid: Could not copy hba info\n")); + return -EFAULT; + } + + return 0; +} + struct aac_reset_iop { u8 reset_type; }; @@ -1070,6 +1093,9 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) case FSACTL_GET_PCI_INFO: status = aac_get_pci_info(dev,arg); break; + case FSACTL_GET_HBA_INFO: + status = aac_get_hba_info(dev, arg); + break; case FSACTL_RESET_IOP: status = aac_send_reset_adapter(dev, arg); break; -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 17/24] aacraid: Added support to abort cmd and reset lun
Added task management command support to abort any timed out commands in case of a eh_abort call and to reset lun's in case of eh_reset call. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aacraid.h | 48 ++ drivers/scsi/aacraid/linit.c | 349 +++-- drivers/scsi/aacraid/src.c | 33 +++- 3 files changed, 343 insertions(+), 87 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 6ca77ff..814310a 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -206,6 +206,53 @@ struct aac_hba_cmd_req { */ }; +/* Task Management Functions (TMF) */ +#define HBA_TMF_ABORT_TASK 0x01 +#define HBA_TMF_LUN_RESET 0x08 + +struct aac_hba_tm_req { + u8 iu_type;/* HBA information unit type */ + u8 reply_qid; /* Host reply queue to post response to */ + u8 tmf;/* Task management function */ + u8 reserved1; + + __le32 it_nexus; /* Device handle for the command */ + + u8 lun[8]; /* SCSI LUN */ + + /* Used to hold sender context. */ + __le32 request_id; /* Sender context */ + __le32 reserved2; + + /* Request identifier of managed task */ + __le32 managed_request_id; /* Sender context being managed */ + __le32 reserved3; + + /* Lower 32-bits of reserved error data target location on the host */ + __le32 error_ptr_lo; + /* Upper 32-bits of reserved error data target location on the host */ + __le32 error_ptr_hi; + /* Length of reserved error data area on the host in bytes */ + __le32 error_length; +}; + +struct aac_hba_reset_req { + u8 iu_type;/* HBA information unit type */ + /* 0 - reset specified device, 1 - reset all devices */ + u8 reset_type; + u8 reply_qid; /* Host reply queue to post response to */ + u8 reserved1; + + __le32 it_nexus; /* Device handle for the command */ + __le32 request_id; /* Sender context */ + /* Lower 32-bits of reserved error data target location on the host */ + __le32 error_ptr_lo; + /* Upper 32-bits of reserved error data target location on the host */ + __le32 error_ptr_hi; + /* Length of reserved error data area on the host in bytes */ + __le32 error_length; +}; + struct aac_hba_resp { u8 iu_type;/* HBA information unit type */ u8 reserved1[3]; @@ -223,6 +270,7 @@ struct aac_hba_resp { struct aac_native_hba { union { struct aac_hba_cmd_req cmd; + struct aac_hba_tm_req tmr; u8 cmd_bytes[AAC_MAX_NATIVE_SIZE-FW_ERROR_BUFFER_SIZE]; } cmd; union { diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index e95f1e5..0b06d1d 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -566,46 +566,134 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) struct scsi_device * dev = cmd->device; struct Scsi_Host * host = dev->host; struct aac_dev * aac = (struct aac_dev *)host->hostdata; - int count; + int count, found; + u32 bus, cid; int ret = FAILED; - printk(KERN_ERR "%s: Host adapter abort request (%d,%d,%d,%llu)\n", - AAC_DRIVERNAME, - host->host_no, sdev_channel(dev), sdev_id(dev), dev->lun); - switch (cmd->cmnd[0]) { - case SERVICE_ACTION_IN_16: - if (!(aac->raw_io_interface) || - !(aac->raw_io_64) || - ((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16)) - break; - case INQUIRY: - case READ_CAPACITY: - /* Mark associated FIB to not complete, eh handler does this */ + bus = aac_logical_to_phys(scmd_channel(cmd)); + cid = scmd_id(cmd); + if (aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) { + struct fib *fib; + struct aac_hba_tm_req *tmf; + int status; + u64 address; + __le32 managed_request_id; + + pr_err("%s: Host adapter abort request (%d,%d,%d,%d)\n", +AAC_DRIVERNAME, +host->host_no, sdev_channel(dev), sdev_id(dev), (int)dev->lun); + + found = 0; for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) { - struct fib * fib = &aac->fibs[count]; - if (fib->hw_fib_va->header.XferState && - (fib->flags & FIB_CONTEXT_FLAG) && - (fib->callback_data == cmd)) { - fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; - cmd->SCp.phase = AAC_OWNER_ERROR_HANDLE
[PATCH 18/24] aacraid: VPD 83 type3 support
This patch adds support to retrieve the unique identifier data (VPD page 83 type3) for Logical drives created on SmartIOC 2000 products. In addition added a sysfs device structure to expose the id information. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 180 ++--- drivers/scsi/aacraid/aacraid.h | 2 + drivers/scsi/aacraid/linit.c | 31 +++ 3 files changed, 150 insertions(+), 63 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 0cb4dab..a89e2a5 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -167,46 +167,56 @@ struct inquiry_data { }; /* Added for VPD 0x83 */ -typedef struct { - u8 CodeSet:4; /* VPD_CODE_SET */ - u8 Reserved:4; - u8 IdentifierType:4;/* VPD_IDENTIFIER_TYPE */ - u8 Reserved2:4; - u8 Reserved3; - u8 IdentifierLength; - u8 VendId[8]; - u8 ProductId[16]; - u8 SerialNumber[8]; /* SN in ASCII */ - -} TVPD_ID_Descriptor_Type_1; +struct tvpd_id_descriptor_type_1 { + u8 codeset:4; /* VPD_CODE_SET */ + u8 reserved:4; + u8 identifiertype:4;/* VPD_IDENTIFIER_TYPE */ + u8 reserved2:4; + u8 reserved3; + u8 identifierlength; + u8 venid[8]; + u8 productid[16]; + u8 serialnumber[8]; /* SN in ASCII */ -typedef struct { - u8 CodeSet:4; /* VPD_CODE_SET */ - u8 Reserved:4; - u8 IdentifierType:4;/* VPD_IDENTIFIER_TYPE */ - u8 Reserved2:4; - u8 Reserved3; - u8 IdentifierLength; - struct TEU64Id { +}; + +struct tvpd_id_descriptor_type_2 { + u8 codeset:4; /* VPD_CODE_SET */ + u8 reserved:4; + u8 identifiertype:4;/* VPD_IDENTIFIER_TYPE */ + u8 reserved2:4; + u8 reserved3; + u8 identifierlength; + struct teu64id { u32 Serial; /* The serial number supposed to be 40 bits, * bit we only support 32, so make the last byte zero. */ - u8 Reserved; - u8 VendId[3]; - } EU64Id; + u8 reserved; + u8 venid[3]; + } eu64id; -} TVPD_ID_Descriptor_Type_2; +}; -typedef struct { +struct tvpd_id_descriptor_type_3 { + u8 codeset : 4; /* VPD_CODE_SET */ + u8 reserved : 4; + u8 identifiertype : 4; /* VPD_IDENTIFIER_TYPE */ + u8 reserved2 : 4; + u8 reserved3; + u8 identifierlength; + u8 Identifier[16]; +}; + +struct tvpd_page83 { u8 DeviceType:5; u8 DeviceTypeQualifier:3; u8 PageCode; - u8 Reserved; + u8 reserved; u8 PageLength; - TVPD_ID_Descriptor_Type_1 IdDescriptorType1; - TVPD_ID_Descriptor_Type_2 IdDescriptorType2; - -} TVPD_Page83; + struct tvpd_id_descriptor_type_1 type1; + struct tvpd_id_descriptor_type_2 type2; + struct tvpd_id_descriptor_type_3 type3; +}; /* * M O D U L E G L O B A L S @@ -613,6 +623,7 @@ static void _aac_probe_container2(void * context, struct fib * fibptr) struct fsa_dev_info *fsa_dev_ptr; int (*callback)(struct scsi_cmnd *); struct scsi_cmnd * scsicmd = (struct scsi_cmnd *)context; + int i; if (!aac_valid_context(scsicmd, fibptr)) @@ -635,6 +646,10 @@ static void _aac_probe_container2(void * context, struct fib * fibptr) fsa_dev_ptr->block_size = le32_to_cpu(dresp->mnt[0].fileinfo.bdevinfo.block_size); } + for (i = 0; i < 16; i++) + fsa_dev_ptr->identifier[i] = + dresp->mnt[0].fileinfo.bdevinfo + .identifier[i]; fsa_dev_ptr->valid = 1; /* sense_key holds the current state of the spin-up */ if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY)) @@ -929,6 +944,28 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) inqstrcpy ("V1.0", str->prl); } +static void build_vpd83_type3(struct tvpd_page83 *vpdpage83data, + struct aac_dev *dev, struct scsi_cmnd *scsicmd) +{ + int container; + + vpdpage83data->type3.codeset = 1; + vpdpage83data->type3.identifiertype = 3; + vpdpage83data->type3.identifierlength = sizeof(vpdpage83data->type3) + - 4; + + for (container = 0; container < dev->maximum_num_containers; + container++) { + + if (scmd_id(scsicmd) == container) { + memcpy(vpdpage83data->type3.Identifier, + dev->fsa_dev[container].identifier, +
[PATCH 12/24] aacraid: Retrieve Queue Depth from Adapter FW
Retrieved queue depth from fw and saved it for future use. Only applicable for HBA1000 drives. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 84 - drivers/scsi/aacraid/aacraid.h | 85 +- 2 files changed, 167 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index e762c7b..10a26046 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1516,6 +1516,83 @@ static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd) return aac_scsi_32(fib, cmd); } +int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target) +{ + struct fib *fibptr; + int rcode = -1; + u16 fibsize, datasize; + struct aac_srb *srbcmd; + struct sgmap64 *sg64; + struct aac_ciss_identify_pd *identify_resp; + dma_addr_t addr; + u32 vbus, vid; + u16 temp; + + fibptr = aac_fib_alloc(dev); + if (!fibptr) + return -ENOMEM; + + temp = AAC_MAX_LUN + target; + + fibsize = sizeof(struct aac_srb) - + sizeof(struct sgentry) + sizeof(struct sgentry64); + datasize = sizeof(struct aac_ciss_identify_pd); + + identify_resp = (struct aac_ciss_identify_pd *) + pci_alloc_consistent(dev->pdev, datasize, &addr); + + if (identify_resp != NULL) { + vbus = (u32)le16_to_cpu( + dev->supplement_adapter_info.VirtDeviceBus); + vid = (u32)le16_to_cpu( + dev->supplement_adapter_info.VirtDeviceTarget); + + aac_fib_init(fibptr); + srbcmd = (struct aac_srb *) fib_data(fibptr); + + srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); + srbcmd->channel = cpu_to_le32(vbus); + srbcmd->id = cpu_to_le32(vid); + srbcmd->lun = 0; + srbcmd->flags= cpu_to_le32(SRB_DataIn); + srbcmd->timeout = cpu_to_le32(10); + srbcmd->retry_limit = 0; + srbcmd->cdb_size = cpu_to_le32(12); + srbcmd->count = cpu_to_le32(datasize); + + memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); + srbcmd->cdb[0] = 0x26; + srbcmd->cdb[2] = (u8)(temp & 0x00FF); + + srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE; + + sg64 = (struct sgmap64 *)&srbcmd->sg; + sg64->count = cpu_to_le32(1); + sg64->sg[0].addr[1] = cpu_to_le32((u32)(((addr) >> 16) >> 16)); + sg64->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0x)); + sg64->sg[0].count = cpu_to_le32(datasize); + + rcode = aac_fib_send(ScsiPortCommand64, + fibptr, fibsize, FsaNormal, 1, 1, NULL, NULL); + + if (identify_resp->current_queue_depth_limit <= 0 || + identify_resp->current_queue_depth_limit > 32) + dev->hba_map[bus][target].qd_limit = 32; + else + dev->hba_map[bus][target].qd_limit = + identify_resp->current_queue_depth_limit; + + pci_free_consistent(dev->pdev, datasize, + (void *)identify_resp, addr); + + aac_fib_complete(fibptr); + } + + aac_fib_free(fibptr); + + return rcode; +} + /** * aac_update hba_map()- update current hba map with data from FW * @dev: aac_dev structure @@ -1565,6 +1642,9 @@ void aac_update_hba_map(struct aac_dev *dev, if (devtype != AAC_DEVTYPE_NATIVE_RAW) goto update_devtype; + if (aac_issue_bmic_identify(dev, bus, target) < 0) + dev->hba_map[bus][target].qd_limit = 32; + update_devtype: dev->hba_map[bus][target].devtype = devtype; } @@ -1708,8 +1788,10 @@ int aac_get_adapter_info(struct aac_dev* dev) /* reset all previous mapped devices (i.e. for init. after IOP_RESET) */ for (bus = 0; bus < AAC_MAX_BUSES; bus++) { - for (target = 0; target < AAC_MAX_TARGETS; target++) + for (target = 0; target < AAC_MAX_TARGETS; target++) { dev->hba_map[bus][target].devtype = 0; + dev->hba_map[bus][target].qd_limit = 0; + } } /* diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 03250b5..23c00ab 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -74,7 +74,7 @@ enum { #define AAC_NUM_IO_FIB (1024 - AAC_NUM_MGT_FIB) #define AAC_NUM_FIB(AAC_NUM_IO_FIB + AAC_NUM_MGT_FIB) -#define AAC_MAX_LUN(8) +#define AAC_MAX_LUN(256) #define
[PATCH 02/24] aacraid: Added aacraid.h include guard
Added aacraid.h include guard Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aacraid.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index f059c14..01b457b 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1,3 +1,5 @@ +#ifndef _AACRAID_H_ +#define _AACRAID_H_ #ifndef dprintk # define dprintk(x) #endif @@ -2194,3 +2196,4 @@ extern int aac_commit; extern int update_interval; extern int check_interval; extern int aac_check_reset; +#endif -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 16/24] aacraid: Add task management functionality
Added support to send out task management commands. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 364 +- 1 file changed, 360 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 237d68c..0cb4dab 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -217,9 +217,13 @@ static long aac_build_sg64(struct scsi_cmnd *scsicmd, struct sgmap64 *psg); static long aac_build_sgraw(struct scsi_cmnd *scsicmd, struct sgmapraw *psg); static long aac_build_sgraw2(struct scsi_cmnd *scsicmd, struct aac_raw_io2 *rio2, int sg_max); +static long aac_build_sghba(struct scsi_cmnd *scsicmd, + struct aac_hba_cmd_req *hbacmd, + int sg_max, u64 sg_address); static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int nseg_new); static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); +static int aac_send_hba_fib(struct scsi_cmnd *scsicmd); #ifdef AAC_DETAILED_STATUS_INFO static char *aac_get_status_string(u32 status); #endif @@ -1446,6 +1450,52 @@ static struct aac_srb * aac_scsi_common(struct fib * fib, struct scsi_cmnd * cmd return srbcmd; } +static struct aac_hba_cmd_req *aac_construct_hbacmd(struct fib *fib, + struct scsi_cmnd *cmd) +{ + struct aac_hba_cmd_req *hbacmd; + struct aac_dev *dev; + int bus, target; + u64 address; + + dev = (struct aac_dev *)cmd->device->host->hostdata; + + hbacmd = (struct aac_hba_cmd_req *)fib->hw_fib_va; + memset(hbacmd, 0, 96); /* sizeof(*hbacmd) is not necessary */ + /* iu_type is a parameter of aac_hba_send */ + switch (cmd->sc_data_direction) { + case DMA_TO_DEVICE: + hbacmd->byte1 = 2; + break; + case DMA_FROM_DEVICE: + case DMA_BIDIRECTIONAL: + hbacmd->byte1 = 1; + break; + case DMA_NONE: + default: + break; + } + hbacmd->lun[1] = cpu_to_le32(cmd->device->lun); + + bus = aac_logical_to_phys(scmd_channel(cmd)); + target = scmd_id(cmd); + hbacmd->it_nexus = dev->hba_map[bus][target].rmw_nexus; + + /* we fill in reply_qid later in aac_src_deliver_message */ + /* we fill in iu_type, request_id later in aac_hba_send */ + /* we fill in emb_data_desc_count later in aac_build_sghba */ + + memcpy(hbacmd->cdb, cmd->cmnd, cmd->cmd_len); + hbacmd->data_length = cpu_to_le32(scsi_bufflen(cmd)); + + address = (u64)fib->hw_error_pa; + hbacmd->error_ptr_hi = cpu_to_le32((u32)(address >> 32)); + hbacmd->error_ptr_lo = cpu_to_le32((u32)(address & 0x)); + hbacmd->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE); + + return hbacmd; +} + static void aac_srb_callback(void *context, struct fib * fibptr); static int aac_scsi_64(struct fib * fib, struct scsi_cmnd * cmd) @@ -1516,6 +1566,31 @@ static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd) return aac_scsi_32(fib, cmd); } +static int aac_adapter_hba(struct fib *fib, struct scsi_cmnd *cmd) +{ + struct aac_hba_cmd_req *hbacmd = aac_construct_hbacmd(fib, cmd); + struct aac_dev *dev; + // u16 fibsize; + long ret; + + dev = (struct aac_dev *)cmd->device->host->hostdata; + + ret = aac_build_sghba(cmd, hbacmd, + dev->scsi_host_ptr->sg_tablesize, (u64)fib->hw_sgl_pa); + if (ret < 0) + return ret; + + /* +* Now send the HBA command to the adapter +*/ + fib->hbacmd_size = 64 + le32_to_cpu(hbacmd->emb_data_desc_count) * + sizeof(struct aac_hba_sgl); + + return aac_hba_send(HBA_IU_TYPE_SCSI_CMD_REQ, fib, + (fib_callback) aac_hba_callback, + (void *) cmd); +} + int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target) { struct fib *fibptr; @@ -1528,6 +1603,7 @@ int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target) u32 vbus, vid; u16 temp; + fibptr = aac_fib_alloc(dev); if (!fibptr) return -ENOMEM; @@ -2000,6 +2076,11 @@ int aac_get_adapter_info(struct aac_dev* dev) (dev->scsi_host_ptr->sg_tablesize * 8) + 112; } } + if (!dev->sync_mode && dev->sa_firmware && + dev->scsi_host_ptr->sg_tablesize > HBA_MAX_SG_SEPARATE) + dev->scsi_host_ptr->sg_tablesize = dev->sg_tablesize = + HBA_MAX_SG_SEPARATE; + /* FIB should be freed only after getting the response from the F/W */ if (rcode != -ERESTARTSYS) { a
[PATCH 00/24] aacraid: Patchset for Smart Family card support
This patchset adds support to the HBA1000 and SMARTIOC2000 family of cards. The driver version to now updated to 50740 Raghava Aditya Renukunta (24): [SCSI] aacraid: Remove duplicate irq management code [SCSI] aacraid: Added aacraid.h include guard [SCSI] aacraid: Added support for init_struct_8 [SCSI] aacraid: Added sa firmware support [SCSI] aacraid: Retrieve and update the device types [SCSI] aacraid: Reworked scsi command submission path [SCSI] aacraid: Process Error for response I/O [SCSI] aacraid: Added support for response path [SCSI] aacraid: Added support for read medium error [SCSI] aacraid: Reworked aac_command_thread [SCSI] aacraid: Added support for periodic wellness sync [SCSI] aacraid: Retrieve Queue Depth from Adapter FW [SCSI] aacraid: Added support to set QD of attached drives [SCSI] aacraid: Added support for hotplug [SCSI] aacraid: Include HBA direct interface [SCSI] aacraid: Add task management functionality [SCSI] aacraid: Added support to abort cmd and reset lun [SCSI] aacraid: VPD 83 type3 support [SCSI] aacraid: Added new IWBR reset [SCSI] aacraid: Added ioctl to trigger IOP/IWBR reset [SCSI] aacraid: Retrieve HBA host information ioctl [SCSI] aacraid: Update copyrights [SCSI] aacraid: Change Driver Version Prefix [SCSI] aacraid: Update version drivers/scsi/aacraid/aachba.c | 1291 +-- drivers/scsi/aacraid/aacraid.h | 648 +--- drivers/scsi/aacraid/commctrl.c | 342 --- drivers/scsi/aacraid/comminit.c | 329 +- drivers/scsi/aacraid/commsup.c | 901 +++ drivers/scsi/aacraid/dpcsup.c | 159 +++-- drivers/scsi/aacraid/linit.c| 554 +++-- drivers/scsi/aacraid/nark.c |3 +- drivers/scsi/aacraid/rkt.c |5 +- drivers/scsi/aacraid/rx.c | 17 +- drivers/scsi/aacraid/sa.c |9 +- drivers/scsi/aacraid/src.c | 336 +++--- 12 files changed, 3384 insertions(+), 1210 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/24] aacraid: Added support for hotplug
Added support for drive hotplug add and removal Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 13 ++-- drivers/scsi/aacraid/aacraid.h | 17 +- drivers/scsi/aacraid/commsup.c | 136 + 3 files changed, 159 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 10a26046..237d68c 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1601,7 +1601,7 @@ int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target) * Update our hba map with the information gathered from the FW */ void aac_update_hba_map(struct aac_dev *dev, - struct aac_ciss_phys_luns_resp *phys_luns) + struct aac_ciss_phys_luns_resp *phys_luns, int rescan) { /* ok and extended reporting */ u32 lun_count, nexus; @@ -1646,7 +1646,10 @@ void aac_update_hba_map(struct aac_dev *dev, dev->hba_map[bus][target].qd_limit = 32; update_devtype: - dev->hba_map[bus][target].devtype = devtype; + if (rescan == AAC_INIT) + dev->hba_map[bus][target].devtype = devtype; + else + dev->hba_map[bus][target].new_devtype = devtype; } } @@ -1658,7 +1661,7 @@ void aac_update_hba_map(struct aac_dev *dev, * Execute a CISS REPORT PHYS LUNS and process the results into * the current hba_map. */ -int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr) +int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr, int rescan) { int fibsize, datasize; struct aac_ciss_phys_luns_resp *phys_luns; @@ -1715,7 +1718,7 @@ int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr) /* analyse data */ if (rcode >= 0 && phys_luns->resp_flag == 2) { /* ok and extended reporting */ - aac_update_hba_map(dev, phys_luns); + aac_update_hba_map(dev, phys_luns, rescan); } } @@ -1828,7 +1831,7 @@ int aac_get_adapter_info(struct aac_dev* dev) if (!dev->sync_mode && dev->sa_firmware && dev->supplement_adapter_info.VirtDeviceBus != 0x) { /* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */ - rcode = aac_report_phys_luns(dev, fibptr); + rcode = aac_report_phys_luns(dev, fibptr, AAC_INIT); } if (!dev->in_reset) { diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 23c00ab..6709de4 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -74,7 +74,7 @@ enum { #define AAC_NUM_IO_FIB (1024 - AAC_NUM_MGT_FIB) #define AAC_NUM_FIB(AAC_NUM_IO_FIB + AAC_NUM_MGT_FIB) -#define AAC_MAX_LUN(256) +#define AAC_MAX_LUN256 #define AAC_MAX_HOSTPHYSMEMPAGES (0xf) #define AAC_MAX_32BIT_SGBCOUNT ((unsigned short)256) @@ -87,6 +87,14 @@ enum { #define AAC_MAX_TARGETS256 #define AAC_MAX_NATIVE_SIZE2048 +/* Thor AIF events */ +#define SA_AIF_HOTPLUG (1<<1) +#define SA_AIF_HARDWARE(1<<2) +#define SA_AIF_PDEV_CHANGE (1<<4) +#define SA_AIF_LDEV_CHANGE (1<<5) +#define SA_AIF_BPSTAT_CHANGE (1<<30) +#define SA_AIF_BPCFG_CHANGE(1<<31) + #define CISS_REPORT_PHYSICAL_LUNS 0xc3 #define WRITE_HOST_WELLNESS0xa5 #define CISS_IDENTIFY_PHYSICAL_DEVICE 0x15 @@ -198,6 +206,7 @@ struct aac_ciss_identify_pd { #define CONTAINER_TO_CHANNEL(cont) (CONTAINER_CHANNEL) #define CONTAINER_TO_ID(cont) (cont) #define CONTAINER_TO_LUN(cont) (0) +#define ENCLOSURE_CHANNEL (3) #define PMC_DEVICE_S6 0x28b #define PMC_DEVICE_S7 0x28c @@ -1102,6 +,9 @@ struct fib { u32 hbacmd_size;/* cmd size for native */ }; +#define AAC_INIT 0 +#define AAC_RESCAN 1 + #define AAC_DEVTYPE_RAID_MEMBER1 #define AAC_DEVTYPE_ARC_RAW2 #define AAC_DEVTYPE_NATIVE_RAW 3 @@ -,6 +1123,7 @@ struct fib { struct aac_hba_map_info { __le32 rmw_nexus; /* nexus for native HBA devices */ u8 devtype;/* device type */ + u8 new_devtype; u8 reset_state;/* 0 - no reset, 1..x - */ /* after xth TM LUN reset */ u16 qd_limit; @@ -2321,7 +2334,7 @@ static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor) int aac_acquire_irq(struct aac_dev *dev); void aac_free_irq(struct aac_dev *dev); -int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr); +int aac_report_phys_luns(s
[PATCH 09/24] aacraid: Added support for read medium error
This patch processes Raw IO read medium errors. Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/aachba.c | 10 ++ drivers/scsi/aacraid/aacraid.h | 1 + 2 files changed, 11 insertions(+) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 5465c8a..e762c7b 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -62,6 +62,7 @@ #define SENCODE_END_OF_DATA0x00 #define SENCODE_BECOMING_READY 0x04 #define SENCODE_INIT_CMD_REQUIRED 0x04 +#define SENCODE_UNRECOVERED_READ_ERROR 0x11 #define SENCODE_PARAM_LIST_LENGTH_ERROR0x1A #define SENCODE_INVALID_COMMAND0x20 #define SENCODE_LBA_OUT_OF_RANGE 0x21 @@ -1994,6 +1995,15 @@ static void io_callback(void *context, struct fib * fibptr) min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), SCSI_SENSE_BUFFERSIZE)); break; + case ST_MEDERR: + scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | + SAM_STAT_CHECK_CONDITION; + set_sense(&dev->fsa_dev[cid].sense_data, MEDIUM_ERROR, + SENCODE_UNRECOVERED_READ_ERROR, ASENCODE_NO_SENSE, 0, 0); + memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, + min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), +SCSI_SENSE_BUFFERSIZE)); + break; default: #ifdef AAC_DETAILED_STATUS_INFO printk(KERN_WARNING "io_callback: io failed, status = %d\n", diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index f749215..fb46252 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1462,6 +1462,7 @@ struct aac_dev #defineST_IO 5 #defineST_NXIO 6 #defineST_E2BIG7 +#defineST_MEDERR 8 #defineST_ACCES13 #defineST_EXIST17 #defineST_XDEV 18 -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/24] aacraid: Remove duplicate irq management code
Removed duplicate code that for acquiring and releasing irqs Signed-off-by: Raghava Aditya Renukunta Signed-off-by: Dave Carroll --- drivers/scsi/aacraid/linit.c | 58 +++- 1 file changed, 3 insertions(+), 55 deletions(-) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 3ecbf20..fd26a2d 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1327,35 +1327,12 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) static void aac_release_resources(struct aac_dev *aac) { - int i; - aac_adapter_disable_int(aac); - if (aac->pdev->device == PMC_DEVICE_S6 || - aac->pdev->device == PMC_DEVICE_S7 || - aac->pdev->device == PMC_DEVICE_S8 || - aac->pdev->device == PMC_DEVICE_S9) { - if (aac->max_msix > 1) { - for (i = 0; i < aac->max_msix; i++) - free_irq(pci_irq_vector(aac->pdev, i), - &(aac->aac_msix[i])); - } else { - free_irq(aac->pdev->irq, &(aac->aac_msix[0])); - } - } else { - free_irq(aac->pdev->irq, aac); - } - if (aac->msi) - pci_disable_msi(aac->pdev); - else if (aac->max_msix > 1) - pci_disable_msix(aac->pdev); - + aac_free_irq(aac); } static int aac_acquire_resources(struct aac_dev *dev) { - int i, j; - int instance = dev->id; - const char *name = dev->name; unsigned long status; /* * First clear out all interrupts. Then enable the one's that we @@ -1377,37 +1354,8 @@ static int aac_acquire_resources(struct aac_dev *dev) if (dev->msi_enabled) aac_src_access_devreg(dev, AAC_ENABLE_MSIX); - if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) { - for (i = 0; i < dev->max_msix; i++) { - dev->aac_msix[i].vector_no = i; - dev->aac_msix[i].dev = dev; - - if (request_irq(pci_irq_vector(dev->pdev, i), - dev->a_ops.adapter_intr, - 0, "aacraid", &(dev->aac_msix[i]))) { - printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n", - name, instance, i); - for (j = 0 ; j < i ; j++) - free_irq(pci_irq_vector(dev->pdev, j), -&(dev->aac_msix[j])); - pci_disable_msix(dev->pdev); - goto error_iounmap; - } - } - } else { - dev->aac_msix[0].vector_no = 0; - dev->aac_msix[0].dev = dev; - - if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, - IRQF_SHARED, "aacraid", - &(dev->aac_msix[0])) < 0) { - if (dev->msi) - pci_disable_msi(dev->pdev); - printk(KERN_ERR "%s%d: Interrupt unavailable.\n", - name, instance); - goto error_iounmap; - } - } + if (aac_acquire_irq(dev)) + goto error_iounmap; aac_adapter_enable_int(dev); -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 15/16] block: split scsi_request out of struct request
On Mon, 2017-01-23 at 16:29 +0100, Christoph Hellwig wrote: > @@ -251,11 +251,13 @@ static int __scsi_execute(struct scsi_device *sdev, > const unsigned char *cmd, > * is invalid. Prevent the garbage from being misinterpreted > * and prevent security leaks by zeroing out the excess data. > */ > - if (unlikely(req->resid_len > 0 && req->resid_len <= bufflen)) > - memset(buffer + (bufflen - req->resid_len), 0, > req->resid_len); > + if (unlikely(rq->resid_len > 0 && rq->resid_len <= bufflen)) > + memset(buffer + (bufflen - rq->resid_len), 0, rq->resid_len); > > if (resid) > - *resid = req->resid_len; > + *resid = rq->resid_len; > + if (rq->sense_len) > + memcpy(sense, rq->sense, SCSI_SENSE_BUFFERSIZE); > ret = req->errors; > out: > blk_put_request(req); Hello Christoph, Do we perhaps need a check before the above memcpy() call whether or not sense == NULL? Thanks, Bart.-- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Claims Requirements
The British National Lottery P O Box 1010 3b Olympic Way, Sefton Business Park, Aintree, Liverpool , L30 1RD (Customer Services) Ref: UK/9420X2/68 Batch: 074/05/ZY369 Ticket number:56475600545 188 Lucky Numbers: 05,06,17,20,28,42(Bonus33) WINNING NOTIFICATION: We wish to congratulate and inform you on the selection of cash prize 1,000,000.00 (British Pounds) held on the 20th January 2017 in London Uk.The selection process was carried out through random selection in Our computerized email selection system (ess) from a database of over 250,000 email addresses drawn from which you were selected. And Your e-mail address attached to ticket number: 56475600545 188 with Serial number 5368/02 drew the lucky numbers: 05, 06, 17, 20, 28, 42 (Bonus 33) ,which subsequently won you the lottery in the 1st category i.e match 5 plus bonus. You have therefore been approved to claim a total sum of 1 Million Pounds,(One Million Pounds) in cash credited to fileKTU/ 9023118308/03. This is from a total cash prize of ?1,000,000 Million Pounds,shared amongst the (4)lucky winners in this category i.e Match 6 plus bonus. For due processing of your winning claim,please contact the FIDUCIARY AGENT Information Officer Mr. Francisco pedro who has been assigned to assist you. You are to contact him with the following details for the release of your winnings. Agent Name: Mr. Francisco pedro Tel:+447024077948 Email: mr.franciscopedro...@yahoo.com Contact him, please provide him with the following Requirements below: Claims Requirements: 1.Name in full-- 2.Address--- 3.Nationality--- 4.Age--- 5.Occupation 6.Sex -- 7.Phone/Fax- 8.Present Country--- If you do not contact your claims agent within 5 working days of this Notification, your winnings would be revoked. Winners are advised to keep their winning details/information from the public to avoid Fraudulent claim (IMPORTANT) pending the prize claim by Winner. *Winner under the age of 18 are automatically disqualified. *Staff of the British Lottery are not to partake in this Lottery. Accept my hearty congratulations once again! Regards Mrs. Stella Ellis (Group Coordinator Note that you are not to reply to this E-mail,please contact your claims officer directly to start the processing of your claims application form. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] scsi: storvsc: Add support for FC lightweight host.
Hi, There is no way to issue a lip directly as the current client for this feature ( storvsc ) does not handle that request as a physical fc hba can. Storvsc only has two fc attributes exposed - port_name and node_name. You can rescan the bus with the standard echo "- - -" > /sys/class/scsi_host/hostX/scan. Cathy On 01/22/2017 10:13 PM, Fam Zheng wrote: On Wed, 01/18 15:28, Cathy Avery wrote: Enable FC lightweight host option so that the luns exposed by the driver may be manually scanned. Hi Cathy, out of curiosity: how does this relate to issue_lip operation? And how to trigger manual scan with this patch? Fam -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Booting qla2x00_mailbox_command+0x8ac/0xec0
* Frans van Berckel [170123 12:27]: > Hi Liam, > > On Mon, 2017-01-23 at 10:38 -0500, Liam R. Howlett wrote: > > > < removed most of dmesg > > > > > > [ 64.557099] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) > > > Driver > > > [ 64.633786] qla2xxx [:00:00.0]-0005: : QLogic Fibre Channel > > > HBA Driver: 8.07.00.38-k. > > > [ 64.633966] PCI: Enabling device: (0001:00:04.0), cmd 3 > > > [ 64.634261] qla2xxx [0001:00:04.0]-001d: : Found an ISP2200 irq > > > 20 iobase 0x07fd0010. > > > [ 64.647517] sym0: No NVRAM, ID 7, Fast-20, SE, parity checking > > > [ 64.652483] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) > > > Driver > > > [ 64.655670] qla2xxx [0001:00:04.0]-0050:1: No matching ROM > > > signature. > > > > Is this normal? > > Comparing with a old kernel that boots well. 3.16.0-0.bpo.4-sparc64-smp > #1 SMP Debian 3.16.7-ckt25-2~bpo70+1 (2016-04-12). > > I am getting ... so that looks the same. > > [ 58.792508] qla2xxx [0001:00:04.0]-0050:0: No matching ROM > signature. > > > > [ 64.656401] ehci-pci: EHCI PCI platform driver > > > [ 64.657269] ohci-pci: OHCI PCI platform driver > > > [ 64.664424] sym0: SCSI BUS has been reset. > > > [ 64.667307] scsi host0: sym-2.2.3 > > > [ 64.679180] PCI: Enabling device: (:00:06.1), cmd 147 > > > [ 64.680362] sym1: <875> rev 0x37 at pci :00:06.1 irq 17 > > > [ 64.713347] gem :00:05.1 enp0s5f1: renamed from eth0 > > > [ 64.758542] qla2xxx [0001:00:04.0]-0064:1: Inconsistent NVRAM > > > detected: checksum=0x0 id= > > > [ 64.764091] qla2xxx [0001:00:04.0]-0069:1: NVRAM configuration > > > failed. > > > > Does this happen in the success case? > > Yes a success case, booted 3.16.0 does. > > [ 58.895901] qla2xxx [0001:00:04.0]-0069:0: NVRAM configuration > failed. > > [ 64.786902] qla2xxx 0001:00:04.0: firmware: direct-loading > firmware ql2200_fw.bin > > > [ 64.833101] sym1: No NVRAM, ID 7, Fast-20, SE, parity checking > > > [ 64.843136] sym1: SCSI BUS has been reset. > > > [ 64.845936] scsi host2: sym-2.2.3 > > Witch does, nicely ... > > [ 58.886906] qla2xxx [0001:00:04.0]-0064:0: Inconsistent NVRAM > detected: checksum=0x0 id= > [ 58.889233] PCI: Enabling device: (:00:06.0), cmd 147 > [ 58.889959] qla2xxx [0001:00:04.0]-0065:0: Falling back to > functioning (yet invalid -- WWPN) defaults. > [ 58.890409] sym0: <875> rev 0x37 at pci :00:06.0 irq 16 > [ 58.895901] qla2xxx [0001:00:04.0]-0069:0: NVRAM configuration > failed. > [ 58.911709] qla2xxx 0001:00:04.0: firmware: direct-loading firmware > ql2200_fw.bin > [ 58.985621] sym0: No NVRAM, ID 7, Fast-20, SE, parity checking > [ 58.995808] sym0: SCSI BUS has been reset. > > and some later on ... > > [ 69.700087] qla2xxx [0001:00:04.0]-00fb:0: QLogic QLA22xx - . > [ 69.703176] qla2xxx [0001:00:04.0]-00fc:0: ISP2200: PCI (66 MHz) @ > 0001:00:04.0 hdma- host#=0 fw=2.02.08 TP. > [ 70.244468] scsi 0:0:0:0: Direct- > Access SEAGATE ST373307FSUN72G 0207 PQ: 0 ANSI: 3 > [ 70.252898] scsi 0:0:1:0: Direct-Access FUJITSU MAP3735F > SUN72G 1201 PQ: 0 ANSI: 4 > [ 74.726434] sd 0:0:0:0: [sda] 143374738 512-byte logical blocks: > (73.4 GB/68.3 GiB) > [ 74.729661] sd 0:0:1:0: [sdb] 143374738 512-byte logical blocks: > (73.4 GB/68.3 GiB) > > > > [ 78.162677] ERROR(0): Cheetah error trap taken > > > afsr[0800] afar[07fd00100040] TL1(0) > > > [ 78.165632] ERROR(0): TPC[101ade8c] TNPC[101ade90] O7[101ade80] > > > TSTATE[9911001603] > > > [ 78.168591] ERROR(0): > > > [ 78.168988] TPC > > > [ 78.171864] ERROR(0): M_SYND(0), E_SYND(0) > > > [ 78.174808] ERROR(0): Highest priority error (0800) > > > "Bus error response from system bus" > > > [ 78.177788] ERROR(0): D-cache idx[0] tag[] > > > utag[] stag[] > > > [ 78.180771] ERROR(0): D-cache data0[] > > > data1[] data2[] > > > data3[] > > > [ 78.183808] ERROR(0): I-cache idx[0] tag[] > > > utag[] stag[] u[] > > > l[] > > > [ 78.186839] ERROR(0): I-cache INSN0[] > > > INSN1[] INSN2[] > > > INSN3[] > > > [ 78.189899] ERROR(0): I-cache INSN4[] > > > INSN5[] INSN6[] > > > INSN7[] > > > [ 78.192971] ERROR(0): E-cache idx[100040] tag[e48dc920] > > > [ 78.196010] ERROR(0): E-cache data0[] > > > data1[] data2[] > > > data3[] > > > [ 78.199157] Kernel panic - not syncing: Irrecoverable deferred > > > error trap. > > > [ 78.199157] > > > [ 78.205490] CPU: 0 PID: 80 Comm: systemd-udevd Not tainted > > > 4.9.0-1-sparc64-smp #1 Debian 4.9.2-2 > > > [ 78.208768] Call Trace: > > > [ 78.212074] [0056b7a8] panic+
Re: [PATCH 2/2] qla2xxx: Avoid that issuing a LIP triggers a kernel crash
On 1/23/17, 8:34 AM, "Bart Van Assche" wrote: >Avoid that issuing a LIP as follows: > > find /sys -name 'issue_lip'|while read f; do echo 1 > $f; done > >triggers the following: > >BUG: unable to handle kernel NULL pointer dereference at (null) >Call Trace: > qla2x00_abort_all_cmds+0xed/0x140 [qla2xxx] > qla2x00_abort_isp_cleanup+0x1e3/0x280 [qla2xxx] > qla2x00_abort_isp+0xef/0x690 [qla2xxx] > qla2x00_do_dpc+0x36c/0x880 [qla2xxx] > kthread+0x10c/0x140 > >Fixes: 1535aa75a3d8 ("qla2xxx: fix invalid DMA access after command aborts in >PCI device remove") >Signed-off-by: Bart Van Assche >Cc: Naresh Bannoth >Cc: Mauricio Faria de Oliveira >Cc: Himanshu Madhani >Cc: >--- > drivers/scsi/qla2xxx/qla_os.c | 6 +- > 1 file changed, 5 insertions(+), 1 deletion(-) > >diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c >index 0a000ecf0881..ae9c5a7b239a 100644 >--- a/drivers/scsi/qla2xxx/qla_os.c >+++ b/drivers/scsi/qla2xxx/qla_os.c >@@ -1600,6 +1600,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) > srb_t *sp; > struct qla_hw_data *ha = vha->hw; > struct req_que *req; >+ struct scsi_cmnd *scmd; > > qlt_host_reset_handler(ha); > >@@ -1613,6 +1614,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) > for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { > sp = req->outstanding_cmds[cnt]; > if (sp) { >+ scmd = GET_CMD_SP(sp); >+ > /* Don't abort commands in adapter during EEH >* recovery as it's not accessible/responding. >*/ >@@ -1624,7 +1627,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) >*/ > sp_get(sp); > > spin_unlock_irqrestore(&ha->hardware_lock, flags); >- qla2xxx_eh_abort(GET_CMD_SP(sp)); >+ if (scmd) >+ qla2xxx_eh_abort(scmd); > spin_lock_irqsave(&ha->hardware_lock, > flags); > } > req->outstanding_cmds[cnt] = NULL; >-- >2.11.0 > Looks Good. Acked-by: Himanshu Madhani N�r��yb�X��ǧv�^�){.n�+{���"�{ay�ʇڙ�,j��f���h���z��w��� ���j:+v���w�j�mzZ+�ݢj"��!�i
Re: Booting qla2x00_mailbox_command+0x8ac/0xec0
Hi Liam, On Mon, 2017-01-23 at 10:38 -0500, Liam R. Howlett wrote: > < removed most of dmesg > > > > [ 64.557099] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) > > Driver > > [ 64.633786] qla2xxx [:00:00.0]-0005: : QLogic Fibre Channel > > HBA Driver: 8.07.00.38-k. > > [ 64.633966] PCI: Enabling device: (0001:00:04.0), cmd 3 > > [ 64.634261] qla2xxx [0001:00:04.0]-001d: : Found an ISP2200 irq > > 20 iobase 0x07fd0010. > > [ 64.647517] sym0: No NVRAM, ID 7, Fast-20, SE, parity checking > > [ 64.652483] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) > > Driver > > [ 64.655670] qla2xxx [0001:00:04.0]-0050:1: No matching ROM > > signature. > > Is this normal? Comparing with a old kernel that boots well. 3.16.0-0.bpo.4-sparc64-smp #1 SMP Debian 3.16.7-ckt25-2~bpo70+1 (2016-04-12). I am getting ... so that looks the same. [ 58.792508] qla2xxx [0001:00:04.0]-0050:0: No matching ROM signature. > > [ 64.656401] ehci-pci: EHCI PCI platform driver > > [ 64.657269] ohci-pci: OHCI PCI platform driver > > [ 64.664424] sym0: SCSI BUS has been reset. > > [ 64.667307] scsi host0: sym-2.2.3 > > [ 64.679180] PCI: Enabling device: (:00:06.1), cmd 147 > > [ 64.680362] sym1: <875> rev 0x37 at pci :00:06.1 irq 17 > > [ 64.713347] gem :00:05.1 enp0s5f1: renamed from eth0 > > [ 64.758542] qla2xxx [0001:00:04.0]-0064:1: Inconsistent NVRAM > > detected: checksum=0x0 id= > > [ 64.764091] qla2xxx [0001:00:04.0]-0069:1: NVRAM configuration > > failed. > > Does this happen in the success case? Yes a success case, booted 3.16.0 does. [ 58.895901] qla2xxx [0001:00:04.0]-0069:0: NVRAM configuration failed. [ 64.786902] qla2xxx 0001:00:04.0: firmware: direct-loading firmware ql2200_fw.bin > > [ 64.833101] sym1: No NVRAM, ID 7, Fast-20, SE, parity checking > > [ 64.843136] sym1: SCSI BUS has been reset. > > [ 64.845936] scsi host2: sym-2.2.3 Witch does, nicely ... [ 58.886906] qla2xxx [0001:00:04.0]-0064:0: Inconsistent NVRAM detected: checksum=0x0 id= [ 58.889233] PCI: Enabling device: (:00:06.0), cmd 147 [ 58.889959] qla2xxx [0001:00:04.0]-0065:0: Falling back to functioning (yet invalid -- WWPN) defaults. [ 58.890409] sym0: <875> rev 0x37 at pci :00:06.0 irq 16 [ 58.895901] qla2xxx [0001:00:04.0]-0069:0: NVRAM configuration failed. [ 58.911709] qla2xxx 0001:00:04.0: firmware: direct-loading firmware ql2200_fw.bin [ 58.985621] sym0: No NVRAM, ID 7, Fast-20, SE, parity checking [ 58.995808] sym0: SCSI BUS has been reset. and some later on ... [ 69.700087] qla2xxx [0001:00:04.0]-00fb:0: QLogic QLA22xx - . [ 69.703176] qla2xxx [0001:00:04.0]-00fc:0: ISP2200: PCI (66 MHz) @ 0001:00:04.0 hdma- host#=0 fw=2.02.08 TP. [ 70.244468] scsi 0:0:0:0: Direct- Access SEAGATE ST373307FSUN72G 0207 PQ: 0 ANSI: 3 [ 70.252898] scsi 0:0:1:0: Direct-Access FUJITSU MAP3735F SUN72G 1201 PQ: 0 ANSI: 4 [ 74.726434] sd 0:0:0:0: [sda] 143374738 512-byte logical blocks: (73.4 GB/68.3 GiB) [ 74.729661] sd 0:0:1:0: [sdb] 143374738 512-byte logical blocks: (73.4 GB/68.3 GiB) > > [ 78.162677] ERROR(0): Cheetah error trap taken > > afsr[0800] afar[07fd00100040] TL1(0) > > [ 78.165632] ERROR(0): TPC[101ade8c] TNPC[101ade90] O7[101ade80] > > TSTATE[9911001603] > > [ 78.168591] ERROR(0): > > [ 78.168988] TPC > > [ 78.171864] ERROR(0): M_SYND(0), E_SYND(0) > > [ 78.174808] ERROR(0): Highest priority error (0800) > > "Bus error response from system bus" > > [ 78.177788] ERROR(0): D-cache idx[0] tag[] > > utag[] stag[] > > [ 78.180771] ERROR(0): D-cache data0[] > > data1[] data2[] > > data3[] > > [ 78.183808] ERROR(0): I-cache idx[0] tag[] > > utag[] stag[] u[] > > l[] > > [ 78.186839] ERROR(0): I-cache INSN0[] > > INSN1[] INSN2[] > > INSN3[] > > [ 78.189899] ERROR(0): I-cache INSN4[] > > INSN5[] INSN6[] > > INSN7[] > > [ 78.192971] ERROR(0): E-cache idx[100040] tag[e48dc920] > > [ 78.196010] ERROR(0): E-cache data0[] > > data1[] data2[] > > data3[] > > [ 78.199157] Kernel panic - not syncing: Irrecoverable deferred > > error trap. > > [ 78.199157] > > [ 78.205490] CPU: 0 PID: 80 Comm: systemd-udevd Not tainted > > 4.9.0-1-sparc64-smp #1 Debian 4.9.2-2 > > [ 78.208768] Call Trace: > > [ 78.212074] [0056b7a8] panic+0xe8/0x298 > > [ 78.215400] [00429b8c] > > cheetah_deferred_handler+0x1ec/0x460 > > [ 78.218727] [00405e44] c_deferred+0x18/0x24 > > [ 78.222092] [101ade8c] > > qla2x00_mailbox_command+0x8ac/0xec0 [qla2xxx] > > [ 78.225391] [10
Re: [PATCH 1/2] qla2xxx: Fix a recently introduced memory leak
On 1/23/17, 8:34 AM, "Bart Van Assche" wrote: >qla2x00_probe_one() allocates IRQs before it initializes rsp_q_map >so IRQs must be freed even if rsp_q_map allocation did not occur. >This was detected by kmemleak. > >Fixes: 4fa183455988 ("scsi: qla2xxx: Utilize >pci_alloc_irq_vectors/pci_free_irq_vectors calls") >Signed-off-by: Bart Van Assche >Cc: Michael Hernandez >Cc: Himanshu Madhani >Cc: Christoph Hellwig >Cc: >--- > drivers/scsi/qla2xxx/qla_isr.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c >index dc88a09f9043..a94b0b6bd030 100644 >--- a/drivers/scsi/qla2xxx/qla_isr.c >+++ b/drivers/scsi/qla2xxx/qla_isr.c >@@ -3242,7 +3242,7 @@ qla2x00_free_irqs(scsi_qla_host_t *vha) >* from a probe failure context. >*/ > if (!ha->rsp_q_map || !ha->rsp_q_map[0]) >- return; >+ goto free_irqs; > rsp = ha->rsp_q_map[0]; > > if (ha->flags.msix_enabled) { >@@ -3262,6 +3262,7 @@ qla2x00_free_irqs(scsi_qla_host_t *vha) > free_irq(pci_irq_vector(ha->pdev, 0), rsp); > } > >+free_irqs: > pci_free_irq_vectors(ha->pdev); > } > >-- >2.11.0 Thanks Bart. Looks good. Acked-By: Himanshu Madhani N�r��yb�X��ǧv�^�){.n�+{���"�{ay�ʇڙ�,j��f���h���z��w��� ���j:+v���w�j�mzZ+�ݢj"��!�i
Re: [PATCH 1/2] qla2xxx: Fix a recently introduced memory leak
Thanks Bart, this looks good to me. Reviewed-by: Christoph Hellwig -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] qla2xxx: Fix a recently introduced memory leak
qla2x00_probe_one() allocates IRQs before it initializes rsp_q_map so IRQs must be freed even if rsp_q_map allocation did not occur. This was detected by kmemleak. Fixes: 4fa183455988 ("scsi: qla2xxx: Utilize pci_alloc_irq_vectors/pci_free_irq_vectors calls") Signed-off-by: Bart Van Assche Cc: Michael Hernandez Cc: Himanshu Madhani Cc: Christoph Hellwig Cc: --- drivers/scsi/qla2xxx/qla_isr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index dc88a09f9043..a94b0b6bd030 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3242,7 +3242,7 @@ qla2x00_free_irqs(scsi_qla_host_t *vha) * from a probe failure context. */ if (!ha->rsp_q_map || !ha->rsp_q_map[0]) - return; + goto free_irqs; rsp = ha->rsp_q_map[0]; if (ha->flags.msix_enabled) { @@ -3262,6 +3262,7 @@ qla2x00_free_irqs(scsi_qla_host_t *vha) free_irq(pci_irq_vector(ha->pdev, 0), rsp); } +free_irqs: pci_free_irq_vectors(ha->pdev); } -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] qla2xxx: Avoid that issuing a LIP triggers a kernel crash
Avoid that issuing a LIP as follows: find /sys -name 'issue_lip'|while read f; do echo 1 > $f; done triggers the following: BUG: unable to handle kernel NULL pointer dereference at (null) Call Trace: qla2x00_abort_all_cmds+0xed/0x140 [qla2xxx] qla2x00_abort_isp_cleanup+0x1e3/0x280 [qla2xxx] qla2x00_abort_isp+0xef/0x690 [qla2xxx] qla2x00_do_dpc+0x36c/0x880 [qla2xxx] kthread+0x10c/0x140 Fixes: 1535aa75a3d8 ("qla2xxx: fix invalid DMA access after command aborts in PCI device remove") Signed-off-by: Bart Van Assche Cc: Naresh Bannoth Cc: Mauricio Faria de Oliveira Cc: Himanshu Madhani Cc: --- drivers/scsi/qla2xxx/qla_os.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 0a000ecf0881..ae9c5a7b239a 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1600,6 +1600,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) srb_t *sp; struct qla_hw_data *ha = vha->hw; struct req_que *req; + struct scsi_cmnd *scmd; qlt_host_reset_handler(ha); @@ -1613,6 +1614,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { sp = req->outstanding_cmds[cnt]; if (sp) { + scmd = GET_CMD_SP(sp); + /* Don't abort commands in adapter during EEH * recovery as it's not accessible/responding. */ @@ -1624,7 +1627,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res) */ sp_get(sp); spin_unlock_irqrestore(&ha->hardware_lock, flags); - qla2xxx_eh_abort(GET_CMD_SP(sp)); + if (scmd) + qla2xxx_eh_abort(scmd); spin_lock_irqsave(&ha->hardware_lock, flags); } req->outstanding_cmds[cnt] = NULL; -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] qla2xxx: Two bug fixes
Hello Martin, While testing kernel v4.10-rc5 I ran into two bugs in the qla2xxx driver. The two patches in this series fixes these bugs. Please consider these patches for inclusion in the upstream kernel. Bart Van Assche (2): qla2xxx: Fix a recently introduced memory leak qla2xxx: Avoid that issuing a LIP triggers a kernel crash drivers/scsi/qla2xxx/qla_isr.c | 3 ++- drivers/scsi/qla2xxx/qla_os.c | 6 +- 2 files changed, 7 insertions(+), 2 deletions(-) -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2] mpt3sas: disable ASPM for MPI2 controllers
On 2016/12/28 11:05, ojab wrote: MPI2 controllers sometimes got lost (i. e. disappears from /sys/bus/pci/devices) if ASMP is enabled. Signed-off-by: Slava Kardakov Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=60644 Can I haz Reviewed-by? //wbr ojab -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: split scsi passthrough fields out of struct request
On Mon, Jan 23, 2017 at 08:39:44AM -0700, Jens Axboe wrote: > I'd like to get this in sooner rather than later, so I'll spend some > time reviewing and testing it start this week. I'm assuming you are > targeting 4.11 with this change, right? Yes. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: split scsi passthrough fields out of struct request
On 01/23/2017 08:29 AM, Christoph Hellwig wrote: > Hi all, > > this series splits the support for SCSI passthrough commands from the > main struct request used all over the block layer into a separate > scsi_request structure that drivers that want to support SCSI passthough > need to embedded as the first thing into their request-private data, > similar to how we handle NVMe passthrough commands. > > To support this I've added support for that the private data after > request structure to the legacy request path instead, so that it can > be treated the same way as the blk-mq path. Compare to the current > scsi_cmnd allocator that actually is a major simplification. > > Compared to the previous RFC version the major change is that dm-mpath > works with this version. To make it work I've switched the legacy > request dm-rq to use the same clone and map method as the blk-mq version. I'd like to get this in sooner rather than later, so I'll spend some time reviewing and testing it start this week. I'm assuming you are targeting 4.11 with this change, right? -- Jens Axboe -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Booting qla2x00_mailbox_command+0x8ac/0xec0
* Frans van Berckel [170121 19:34]: > Anyone a idea what could be wrong while booting from the scsi disk on > sparc64. 4.9.0 is mailboxing this error and dumps into initramfs. > > [ 78.162677] ERROR(0): Cheetah error trap taken > afsr[0800] afar[07fd00100040] TL1(0) > [ 78.165632] ERROR(0): TPC[101ade8c] TNPC[101ade90] O7[101ade80] > TSTATE[9911001603] > [ 78.168591] ERROR(0): > [ 78.168988] TPC > [ 78.171864] ERROR(0): M_SYND(0), E_SYND(0) > [ 78.174808] ERROR(0): Highest priority error (0800) "Bus > error response from system bus" > [ 78.177788] ERROR(0): D-cache idx[0] tag[] > utag[] stag[] > [ 78.180771] ERROR(0): D-cache data0[] > data1[] data2[] data3[] > [ 78.183808] ERROR(0): I-cache idx[0] tag[] > utag[] stag[] u[] > l[] > [ 78.186839] ERROR(0): I-cache INSN0[] > INSN1[] INSN2[] INSN3[] > [ 78.189899] ERROR(0): I-cache INSN4[] > INSN5[] INSN6[] INSN7[] > [ 78.192971] ERROR(0): E-cache idx[100040] tag[e48dc920] > [ 78.196010] ERROR(0): E-cache data0[] > data1[] data2[] data3[] > [ 78.199157] Kernel panic - not syncing: Irrecoverable deferred error > trap. > > lsmod does ... > > Module Size Used byNot tainted > hid_generic 1321 0 > usbhid 48130 0 > hid 107802 2 hid_generic,usbhid > ohci_pci4680 0 > ehci_pci4847 0 > ohci_hcd 41274 1 ohci_pci > qla2xxx 715279 1 > ehci_hcd 69278 1 ehci_pci > usbcore 209214 5 > usbhid,ohci_pci,ehci_pci,ohci_hcd,ehci_hcd > firewire_ohci 33604 0 > scsi_transport_fc 46940 1 qla2xxx > sym53c8xx 75770 0 > scsi_transport_spi 22583 1 sym53c8xx > usb_common 3976 1 usbcore > scsi_mod 196717 4 > qla2xxx,scsi_transport_fc,sym53c8xx,scsi_transport_spi > firewire_core 54166 1 firewire_ohci > crc_itu_t 1595 1 firewire_core > sungem 29777 0 > sungem_phy 10858 1 sungem > > Attaching dmesg output ... > > Thanks, > > Frans van Berckel < removed most of dmesg > > [ 64.557099] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver > [ 64.633786] qla2xxx [:00:00.0]-0005: : QLogic Fibre Channel HBA > Driver: 8.07.00.38-k. > [ 64.633966] PCI: Enabling device: (0001:00:04.0), cmd 3 > [ 64.634261] qla2xxx [0001:00:04.0]-001d: : Found an ISP2200 irq 20 iobase > 0x07fd0010. > [ 64.647517] sym0: No NVRAM, ID 7, Fast-20, SE, parity checking > [ 64.652483] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver > [ 64.655670] qla2xxx [0001:00:04.0]-0050:1: No matching ROM signature. Is this normal? > [ 64.656401] ehci-pci: EHCI PCI platform driver > [ 64.657269] ohci-pci: OHCI PCI platform driver > [ 64.664424] sym0: SCSI BUS has been reset. > [ 64.667307] scsi host0: sym-2.2.3 > [ 64.679180] PCI: Enabling device: (:00:06.1), cmd 147 > [ 64.680362] sym1: <875> rev 0x37 at pci :00:06.1 irq 17 > [ 64.713347] gem :00:05.1 enp0s5f1: renamed from eth0 > [ 64.758542] qla2xxx [0001:00:04.0]-0064:1: Inconsistent NVRAM detected: > checksum=0x0 id= > [ 64.764091] qla2xxx [0001:00:04.0]-0069:1: NVRAM configuration failed. Does this happen in the success case? > [ 64.786902] qla2xxx 0001:00:04.0: firmware: direct-loading firmware > ql2200_fw.bin > [ 64.833101] sym1: No NVRAM, ID 7, Fast-20, SE, parity checking > [ 64.843136] sym1: SCSI BUS has been reset. > [ 64.845936] scsi host2: sym-2.2.3 > [ 64.906524] firewire_ohci :00:05.2: added OHCI v1.0 device as card 0, > 4 IR + 4 IT contexts, quirks 0x0 > [ 64.909396] ohci-pci :00:05.3: OHCI PCI host controller > [ 64.912390] ohci-pci :00:05.3: new USB bus registered, assigned bus > number 1 > [ 64.915276] ohci-pci :00:05.3: irq 15, io mem 0x7fe0100 > [ 64.978669] usb usb1: New USB device found, idVendor=1d6b, idProduct=0001 > [ 64.981341] usb usb1: New USB device strings: Mfr=3, Product=2, > SerialNumber=1 > [ 64.984123] usb usb1: Product: OHCI PCI host controller > [ 64.986896] usb usb1: Manufacturer: Linux 4.9.0-1-sparc64-smp ohci_hcd > [ 64.989658] usb usb1: SerialNumber: :00:05.3 > [ 64.993318] hub 1-0:1.0: USB hub found > [ 64.996058] hub 1-0:1.0: 4 ports detected > [ 65.386444] usb 1-3: new low-speed USB device number 2 using ohci-pci > [ 65.422815] firewire_core :00:05.2: created device fw0: GUID > 0003bafffe099239, S400 > [ 65.605176] usb 1-3: New USB device found, idVendor=0430, idProduct
[PATCH 16/16] block: don't assign cmd_flags in __blk_rq_prep_clone
These days we have the proper flags set since request allocation time. Signed-off-by: Christoph Hellwig --- block/blk-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/block/blk-core.c b/block/blk-core.c index fe5cc98..93a9e0b 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2983,7 +2983,6 @@ EXPORT_SYMBOL_GPL(blk_rq_unprep_clone); static void __blk_rq_prep_clone(struct request *dst, struct request *src) { dst->cpu = src->cpu; - dst->cmd_flags = src->cmd_flags | REQ_NOMERGE; dst->cmd_type = src->cmd_type; dst->__sector = blk_rq_pos(src); dst->__data_len = blk_rq_bytes(src); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 12/16] scsi: remove __scsi_alloc_queue
Instead do an internal export of __scsi_init_queue for the transport classes that export BSG nodes. Signed-off-by: Christoph Hellwig --- drivers/scsi/scsi_lib.c | 19 --- drivers/scsi/scsi_transport_fc.c| 6 -- drivers/scsi/scsi_transport_iscsi.c | 3 ++- include/scsi/scsi_host.h| 2 -- include/scsi/scsi_transport.h | 2 ++ 5 files changed, 12 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3d6b364..7950516 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2082,7 +2082,7 @@ static u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost) return bounce_limit; } -static void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q) +void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q) { struct device *dev = shost->dma_dev; @@ -2117,28 +2117,17 @@ static void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q) */ blk_queue_dma_alignment(q, 0x03); } - -struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, -request_fn_proc *request_fn) -{ - struct request_queue *q; - - q = blk_init_queue(request_fn, NULL); - if (!q) - return NULL; - __scsi_init_queue(shost, q); - return q; -} -EXPORT_SYMBOL(__scsi_alloc_queue); +EXPORT_SYMBOL_GPL(__scsi_init_queue); struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) { struct request_queue *q; - q = __scsi_alloc_queue(sdev->host, scsi_request_fn); + q = blk_init_queue(scsi_request_fn, NULL); if (!q) return NULL; + __scsi_init_queue(sdev->host, q); blk_queue_prep_rq(q, scsi_prep_fn); blk_queue_unprep_rq(q, scsi_unprep_fn); blk_queue_softirq_done(q, scsi_softirq_done); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 03577bd..afcedec 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -3776,7 +3776,7 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host) snprintf(bsg_name, sizeof(bsg_name), "fc_host%d", shost->host_no); - q = __scsi_alloc_queue(shost, bsg_request_fn); + q = blk_init_queue(bsg_request_fn, NULL); if (!q) { dev_err(dev, "fc_host%d: bsg interface failed to initialize - no request queue\n", @@ -3784,6 +3784,7 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host) return -ENOMEM; } + __scsi_init_queue(shost, q); err = bsg_setup_queue(dev, q, bsg_name, fc_bsg_dispatch, i->f->dd_bsg_size); if (err) { @@ -3831,12 +3832,13 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport) if (!i->f->bsg_request) return -ENOTSUPP; - q = __scsi_alloc_queue(shost, bsg_request_fn); + q = blk_init_queue(bsg_request_fn, NULL); if (!q) { dev_err(dev, "bsg interface failed to initialize - no request queue\n"); return -ENOMEM; } + __scsi_init_queue(shost, q); err = bsg_setup_queue(dev, q, NULL, fc_bsg_dispatch, i->f->dd_bsg_size); if (err) { dev_err(dev, "failed to setup bsg queue\n"); diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 42bca61..04ebe6e 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1544,10 +1544,11 @@ iscsi_bsg_host_add(struct Scsi_Host *shost, struct iscsi_cls_host *ihost) snprintf(bsg_name, sizeof(bsg_name), "iscsi_host%d", shost->host_no); - q = __scsi_alloc_queue(shost, bsg_request_fn); + q = blk_init_queue(bsg_request_fn, NULL); if (!q) return -ENOMEM; + __scsi_init_queue(shost, q); ret = bsg_setup_queue(dev, q, bsg_name, iscsi_bsg_host_dispatch, 0); if (ret) { shost_printk(KERN_ERR, shost, "bsg interface failed to " diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 36680f1..f4964d7 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -826,8 +826,6 @@ extern void scsi_block_requests(struct Scsi_Host *); struct class_container; -extern struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, - void (*) (struct request_queue *)); /* * These two functions are used to allocate and free a pseudo device * which will connect to the host adapter itself rather than any diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h index 8129239..b6e07b5 100644 --- a/include/scsi/scsi_transport.h +++ b/include/scsi/scsi_transport.h @@ -119,4 +119,6 @@ scsi_transport_de
[PATCH 15/16] block: split scsi_request out of struct request
And require all drivers that want to support BLOCK_PC to allocate it as the first thing of their private data. To support this the legacy IDE and BSG code is switched to set cmd_size on their queues to let the block layer allocate the additional space. Signed-off-by: Christoph Hellwig --- block/blk-core.c | 31 --- block/blk-exec.c | 12 - block/blk-mq.c | 10 block/bsg-lib.c | 34 block/bsg.c | 47 - block/scsi_ioctl.c | 87 ++ drivers/ata/libata-scsi.c| 2 +- drivers/block/cciss.c| 28 +- drivers/block/pktcdvd.c | 6 +-- drivers/block/virtio_blk.c | 11 ++-- drivers/cdrom/cdrom.c| 32 +-- drivers/ide/ide-atapi.c | 43 --- drivers/ide/ide-cd.c | 91 +++- drivers/ide/ide-cd_ioctl.c | 1 + drivers/ide/ide-cd_verbose.c | 6 +-- drivers/ide/ide-devsets.c| 9 ++-- drivers/ide/ide-disk.c | 1 + drivers/ide/ide-eh.c | 2 +- drivers/ide/ide-floppy.c | 4 +- drivers/ide/ide-io.c | 3 +- drivers/ide/ide-ioctls.c | 6 ++- drivers/ide/ide-park.c | 12 +++-- drivers/ide/ide-pm.c | 2 + drivers/ide/ide-probe.c | 36 +++-- drivers/ide/ide-tape.c | 32 +-- drivers/ide/ide-taskfile.c | 1 + drivers/ide/sis5513.c| 2 +- drivers/message/fusion/mptsas.c | 8 +-- drivers/scsi/libfc/fc_lport.c| 2 +- drivers/scsi/libsas/sas_expander.c | 8 +-- drivers/scsi/libsas/sas_host_smp.c | 38 ++--- drivers/scsi/mpt3sas/mpt3sas_transport.c | 8 +-- drivers/scsi/osd/osd_initiator.c | 19 +++ drivers/scsi/osst.c | 15 +++--- drivers/scsi/qla2xxx/qla_bsg.c | 2 +- drivers/scsi/qla2xxx/qla_isr.c | 6 ++- drivers/scsi/qla2xxx/qla_mr.c| 2 +- drivers/scsi/scsi_error.c| 22 drivers/scsi/scsi_lib.c | 48 + drivers/scsi/scsi_transport_sas.c| 5 ++ drivers/scsi/sd.c| 4 +- drivers/scsi/sg.c| 30 ++- drivers/scsi/st.c| 22 drivers/target/target_core_pscsi.c | 11 ++-- fs/nfsd/blocklayout.c| 17 +++--- include/linux/blkdev.h | 11 include/linux/blktrace_api.h | 3 +- include/linux/ide.h | 8 ++- include/scsi/scsi_cmnd.h | 2 + include/scsi/scsi_request.h | 28 ++ kernel/trace/blktrace.c | 32 +-- 51 files changed, 483 insertions(+), 419 deletions(-) create mode 100644 include/scsi/scsi_request.h diff --git a/block/blk-core.c b/block/blk-core.c index 793ef96..fe5cc98 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -132,8 +132,6 @@ void blk_rq_init(struct request_queue *q, struct request *rq) rq->__sector = (sector_t) -1; INIT_HLIST_NODE(&rq->hash); RB_CLEAR_NODE(&rq->rb_node); - rq->cmd = rq->__cmd; - rq->cmd_len = BLK_MAX_CDB; rq->tag = -1; rq->internal_tag = -1; rq->start_time = jiffies; @@ -160,8 +158,6 @@ static void req_bio_endio(struct request *rq, struct bio *bio, void blk_dump_rq_flags(struct request *rq, char *msg) { - int bit; - printk(KERN_INFO "%s: dev %s: type=%x, flags=%llx\n", msg, rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type, (unsigned long long) rq->cmd_flags); @@ -171,13 +167,6 @@ void blk_dump_rq_flags(struct request *rq, char *msg) blk_rq_sectors(rq), blk_rq_cur_sectors(rq)); printk(KERN_INFO " bio %p, biotail %p, len %u\n", rq->bio, rq->biotail, blk_rq_bytes(rq)); - - if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { - printk(KERN_INFO " cdb: "); - for (bit = 0; bit < BLK_MAX_CDB; bit++) - printk("%02x ", rq->cmd[bit]); - printk("\n"); - } } EXPORT_SYMBOL(blk_dump_rq_flags); @@ -1316,18 +1305,6 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask) EXPORT_SYMBOL(blk_get_request); /** - * blk_rq_set_block_pc - initialize a request to type BLOCK_PC - * @rq:request to be initialized - * - */ -void blk_rq_set_block_pc(struct request *rq) -{ - rq->cmd_type = REQ_TYPE_BLOCK_PC; - memset(rq->__cmd, 0, sizeof(rq->__cmd)); -} -EXPORT_SYMBOL(blk_rq_set_block_pc); -
[PATCH 11/16] scsi: remove scsi_cmd_dma_pool
There is no need for GFP_DMA allocations of the scsi_cmnd structures themselves, all that might be DMAed to or from is the actual payload, or the sense buffers. Signed-off-by: Christoph Hellwig --- drivers/scsi/scsi.c | 15 +-- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 469aa0f..2e24f31 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -102,17 +102,10 @@ struct scsi_host_cmd_pool { struct kmem_cache *cmd_slab; unsigned intusers; char*cmd_name; - unsigned intslab_flags; }; static struct scsi_host_cmd_pool scsi_cmd_pool = { .cmd_name = "scsi_cmd_cache", - .slab_flags = SLAB_HWCACHE_ALIGN, -}; - -static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { - .cmd_name = "scsi_cmd_cache(DMA)", - .slab_flags = SLAB_HWCACHE_ALIGN|SLAB_CACHE_DMA, }; static DEFINE_MUTEX(host_cmd_pool_mutex); @@ -290,8 +283,6 @@ scsi_find_host_cmd_pool(struct Scsi_Host *shost) { if (shost->hostt->cmd_size) return shost->hostt->cmd_pool; - if (shost->unchecked_isa_dma) - return &scsi_cmd_dma_pool; return &scsi_cmd_pool; } @@ -318,10 +309,6 @@ scsi_alloc_host_cmd_pool(struct Scsi_Host *shost) return NULL; } - pool->slab_flags = SLAB_HWCACHE_ALIGN; - if (shost->unchecked_isa_dma) - pool->slab_flags |= SLAB_CACHE_DMA; - if (hostt->cmd_size) hostt->cmd_pool = pool; @@ -349,7 +336,7 @@ scsi_get_host_cmd_pool(struct Scsi_Host *shost) if (!pool->users) { pool->cmd_slab = kmem_cache_create(pool->cmd_name, cmd_size, 0, - pool->slab_flags, NULL); + SLAB_HWCACHE_ALIGN, NULL); if (!pool->cmd_slab) goto out_free_pool; } -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 13/16] scsi: allocate scsi_cmnd structures as part of struct request
Rely on the new block layer functionality to allocate additional driver specific data behind struct request instead of implementing it in SCSI itѕelf. Signed-off-by: Christoph Hellwig --- drivers/scsi/hosts.c | 20 +-- drivers/scsi/scsi.c | 319 -- drivers/scsi/scsi_error.c | 17 ++- drivers/scsi/scsi_lib.c | 122 -- drivers/scsi/scsi_priv.h | 8 +- include/scsi/scsi_host.h | 3 - 6 files changed, 95 insertions(+), 394 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 6d29c4a..831a1c8 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -230,19 +230,6 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, } } - /* -* Note that we allocate the freelist even for the MQ case for now, -* as we need a command set aside for scsi_reset_provider. Having -* the full host freelist and one command available for that is a -* little heavy-handed, but avoids introducing a special allocator -* just for this. Eventually the structure of scsi_reset_provider -* will need a major overhaul. -*/ - error = scsi_setup_command_freelist(shost); - if (error) - goto out_destroy_tags; - - if (!shost->shost_gendev.parent) shost->shost_gendev.parent = dev ? dev : &platform_bus; if (!dma_dev) @@ -262,7 +249,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, error = device_add(&shost->shost_gendev); if (error) - goto out_destroy_freelist; + goto out_disable_runtime_pm; scsi_host_set_state(shost, SHOST_RUNNING); get_device(shost->shost_gendev.parent); @@ -312,13 +299,11 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, device_del(&shost->shost_dev); out_del_gendev: device_del(&shost->shost_gendev); - out_destroy_freelist: + out_disable_runtime_pm: device_disable_async_suspend(&shost->shost_gendev); pm_runtime_disable(&shost->shost_gendev); pm_runtime_set_suspended(&shost->shost_gendev); pm_runtime_put_noidle(&shost->shost_gendev); - scsi_destroy_command_freelist(shost); - out_destroy_tags: if (shost_use_blk_mq(shost)) scsi_mq_destroy_tags(shost); fail: @@ -359,7 +344,6 @@ static void scsi_host_dev_release(struct device *dev) kfree(dev_name(&shost->shost_dev)); } - scsi_destroy_command_freelist(shost); if (shost_use_blk_mq(shost)) { if (shost->tag_set.tags) scsi_mq_destroy_tags(shost); diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 2e24f31..3d8d215 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -98,163 +98,6 @@ EXPORT_SYMBOL(scsi_sd_probe_domain); ASYNC_DOMAIN_EXCLUSIVE(scsi_sd_pm_domain); EXPORT_SYMBOL(scsi_sd_pm_domain); -struct scsi_host_cmd_pool { - struct kmem_cache *cmd_slab; - unsigned intusers; - char*cmd_name; -}; - -static struct scsi_host_cmd_pool scsi_cmd_pool = { - .cmd_name = "scsi_cmd_cache", -}; - -static DEFINE_MUTEX(host_cmd_pool_mutex); - -/** - * scsi_host_free_command - internal function to release a command - * @shost: host to free the command for - * @cmd: command to release - * - * the command must previously have been allocated by - * scsi_host_alloc_command. - */ -static void -scsi_host_free_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) -{ - struct scsi_host_cmd_pool *pool = shost->cmd_pool; - - if (cmd->prot_sdb) - kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb); - scsi_free_sense_buffer(shost, cmd->sense_buffer); - kmem_cache_free(pool->cmd_slab, cmd); -} - -/** - * scsi_host_alloc_command - internal function to allocate command - * @shost: SCSI host whose pool to allocate from - * @gfp_mask: mask for the allocation - * - * Returns a fully allocated command with sense buffer and protection - * data buffer (where applicable) or NULL on failure - */ -static struct scsi_cmnd * -scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) -{ - struct scsi_host_cmd_pool *pool = shost->cmd_pool; - struct scsi_cmnd *cmd; - - cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask); - if (!cmd) - goto fail; - - cmd->sense_buffer = scsi_alloc_sense_buffer(shost, gfp_mask, - NUMA_NO_NODE); - if (!cmd->sense_buffer) - goto fail_free_cmd; - - if (scsi_host_get_prot(shost) >= SHOST_DIX_TYPE0_PROTECTION) { - cmd->prot_sdb = kmem_cache_zalloc(scsi_sdb_cache, gfp_mask); - if (!cmd->prot_sdb) - goto fail_free_sense; - } - - return cmd; - -fail_free_sense: -
[PATCH 14/16] block/bsg: move queue creation into bsg_setup_queue
Simply the boilerplate code needed for bsg nodes a bit. Signed-off-by: Christoph Hellwig Reviewed-by: Johannes Thumshirn --- block/bsg-lib.c | 21 +++-- drivers/scsi/scsi_transport_fc.c| 36 drivers/scsi/scsi_transport_iscsi.c | 15 --- include/linux/bsg-lib.h | 5 ++--- 4 files changed, 25 insertions(+), 52 deletions(-) diff --git a/block/bsg-lib.c b/block/bsg-lib.c index 9d652a9..c74acf4 100644 --- a/block/bsg-lib.c +++ b/block/bsg-lib.c @@ -177,7 +177,7 @@ static int bsg_create_job(struct device *dev, struct request *req) * * Drivers/subsys should pass this to the queue init function. */ -void bsg_request_fn(struct request_queue *q) +static void bsg_request_fn(struct request_queue *q) __releases(q->queue_lock) __acquires(q->queue_lock) { @@ -214,24 +214,24 @@ void bsg_request_fn(struct request_queue *q) put_device(dev); spin_lock_irq(q->queue_lock); } -EXPORT_SYMBOL_GPL(bsg_request_fn); /** * bsg_setup_queue - Create and add the bsg hooks so we can receive requests * @dev: device to attach bsg device to - * @q: request queue setup by caller * @name: device to give bsg device * @job_fn: bsg job handler * @dd_job_size: size of LLD data needed for each job - * - * The caller should have setup the reuqest queue with bsg_request_fn - * as the request_fn. */ -int bsg_setup_queue(struct device *dev, struct request_queue *q, - char *name, bsg_job_fn *job_fn, int dd_job_size) +struct request_queue *bsg_setup_queue(struct device *dev, char *name, + bsg_job_fn *job_fn, int dd_job_size) { + struct request_queue *q; int ret; + q = blk_init_queue(bsg_request_fn, NULL); + if (!q) + return ERR_PTR(-ENOMEM); + q->queuedata = dev; q->bsg_job_size = dd_job_size; q->bsg_job_fn = job_fn; @@ -243,9 +243,10 @@ int bsg_setup_queue(struct device *dev, struct request_queue *q, if (ret) { printk(KERN_ERR "%s: bsg interface failed to " "initialize - register queue\n", dev->kobj.name); - return ret; + blk_cleanup_queue(q); + return ERR_PTR(ret); } - return 0; + return q; } EXPORT_SYMBOL_GPL(bsg_setup_queue); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index afcedec..13dcb9b 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -3765,7 +3765,6 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host) struct device *dev = &shost->shost_gendev; struct fc_internal *i = to_fc_internal(shost->transportt); struct request_queue *q; - int err; char bsg_name[20]; fc_host->rqst_q = NULL; @@ -3776,24 +3775,14 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host) snprintf(bsg_name, sizeof(bsg_name), "fc_host%d", shost->host_no); - q = blk_init_queue(bsg_request_fn, NULL); - if (!q) { - dev_err(dev, - "fc_host%d: bsg interface failed to initialize - no request queue\n", - shost->host_no); - return -ENOMEM; - } - - __scsi_init_queue(shost, q); - err = bsg_setup_queue(dev, q, bsg_name, fc_bsg_dispatch, -i->f->dd_bsg_size); - if (err) { + q = bsg_setup_queue(dev, bsg_name, fc_bsg_dispatch, i->f->dd_bsg_size); + if (IS_ERR(q)) { dev_err(dev, "fc_host%d: bsg interface failed to initialize - setup queue\n", shost->host_no); - blk_cleanup_queue(q); - return err; + return PTR_ERR(q); } + __scsi_init_queue(shost, q); blk_queue_rq_timed_out(q, fc_bsg_job_timeout); blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT); fc_host->rqst_q = q; @@ -3825,27 +3814,18 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport) struct device *dev = &rport->dev; struct fc_internal *i = to_fc_internal(shost->transportt); struct request_queue *q; - int err; rport->rqst_q = NULL; if (!i->f->bsg_request) return -ENOTSUPP; - q = blk_init_queue(bsg_request_fn, NULL); - if (!q) { - dev_err(dev, "bsg interface failed to initialize - no request queue\n"); - return -ENOMEM; - } - - __scsi_init_queue(shost, q); - err = bsg_setup_queue(dev, q, NULL, fc_bsg_dispatch, i->f->dd_bsg_size); - if (err) { + q = bsg_setup_queue(dev, NULL, fc_bsg_dispatch, i->f->dd_bsg_size); + if (IS_ERR(q)) { dev_err(dev, "failed to setup bsg queue\n"); - blk_cleanup_queue(q); -
[PATCH 10/16] scsi: respect unchecked_isa_dma for blk-mq
Currently blk-mq always allocates the sense buffer using normal GFP_KERNEL allocation. Refactor the cmd pool code to split the cmd and sense allocation and share the code to allocate the sense buffers as well as the sense buffer slab caches between the legacy and blk-mq path. Note that this switches to lazy allocation of the sense slab caches - the slab caches (not the actual allocations) won't be destroy until the scsi module is unloaded instead of keeping track of hosts using them. Signed-off-by: Christoph Hellwig --- drivers/scsi/hosts.c | 4 drivers/scsi/scsi.c | 24 --- drivers/scsi/scsi_lib.c | 62 +--- drivers/scsi/scsi_priv.h | 5 4 files changed, 73 insertions(+), 22 deletions(-) diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 258a3f9..6d29c4a 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -213,6 +213,10 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, goto fail; } + error = scsi_init_sense_cache(shost); + if (error) + goto fail; + if (shost_use_blk_mq(shost)) { error = scsi_mq_setup_tags(shost); if (error) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 0f93892..469aa0f 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -100,22 +100,18 @@ EXPORT_SYMBOL(scsi_sd_pm_domain); struct scsi_host_cmd_pool { struct kmem_cache *cmd_slab; - struct kmem_cache *sense_slab; unsigned intusers; char*cmd_name; - char*sense_name; unsigned intslab_flags; }; static struct scsi_host_cmd_pool scsi_cmd_pool = { .cmd_name = "scsi_cmd_cache", - .sense_name = "scsi_sense_cache", .slab_flags = SLAB_HWCACHE_ALIGN, }; static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { .cmd_name = "scsi_cmd_cache(DMA)", - .sense_name = "scsi_sense_cache(DMA)", .slab_flags = SLAB_HWCACHE_ALIGN|SLAB_CACHE_DMA, }; @@ -136,7 +132,7 @@ scsi_host_free_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) if (cmd->prot_sdb) kmem_cache_free(scsi_sdb_cache, cmd->prot_sdb); - kmem_cache_free(pool->sense_slab, cmd->sense_buffer); + scsi_free_sense_buffer(shost, cmd->sense_buffer); kmem_cache_free(pool->cmd_slab, cmd); } @@ -158,7 +154,8 @@ scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) if (!cmd) goto fail; - cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab, gfp_mask); + cmd->sense_buffer = scsi_alloc_sense_buffer(shost, gfp_mask, + NUMA_NO_NODE); if (!cmd->sense_buffer) goto fail_free_cmd; @@ -171,7 +168,7 @@ scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) return cmd; fail_free_sense: - kmem_cache_free(pool->sense_slab, cmd->sense_buffer); + scsi_free_sense_buffer(shost, cmd->sense_buffer); fail_free_cmd: kmem_cache_free(pool->cmd_slab, cmd); fail: @@ -301,7 +298,6 @@ scsi_find_host_cmd_pool(struct Scsi_Host *shost) static void scsi_free_host_cmd_pool(struct scsi_host_cmd_pool *pool) { - kfree(pool->sense_name); kfree(pool->cmd_name); kfree(pool); } @@ -317,8 +313,7 @@ scsi_alloc_host_cmd_pool(struct Scsi_Host *shost) return NULL; pool->cmd_name = kasprintf(GFP_KERNEL, "%s_cmd", hostt->proc_name); - pool->sense_name = kasprintf(GFP_KERNEL, "%s_sense", hostt->proc_name); - if (!pool->cmd_name || !pool->sense_name) { + if (!pool->cmd_name) { scsi_free_host_cmd_pool(pool); return NULL; } @@ -357,12 +352,6 @@ scsi_get_host_cmd_pool(struct Scsi_Host *shost) pool->slab_flags, NULL); if (!pool->cmd_slab) goto out_free_pool; - - pool->sense_slab = kmem_cache_create(pool->sense_name, -SCSI_SENSE_BUFFERSIZE, 0, -pool->slab_flags, NULL); - if (!pool->sense_slab) - goto out_free_slab; } pool->users++; @@ -371,8 +360,6 @@ scsi_get_host_cmd_pool(struct Scsi_Host *shost) mutex_unlock(&host_cmd_pool_mutex); return retval; -out_free_slab: - kmem_cache_destroy(pool->cmd_slab); out_free_pool: if (hostt->cmd_size) { scsi_free_host_cmd_pool(pool); @@ -398,7 +385,6 @@ static void scsi_put_host_cmd_pool(struct Scsi_Host *shost) if (!--pool->users) { kmem_cache_destroy(pool->cmd_slab); - kmem_cache_destroy(pool->sense_slab); if (hostt-
[PATCH 04/16] dm: remove incomple BLOCK_PC support
DM tries to copy a few fields around for BLOCK_PC requests, but given that no dm-target ever wires up scsi_cmd_ioctl BLOCK_PC can't actually be sent to dm. Signed-off-by: Christoph Hellwig --- drivers/md/dm-rq.c | 16 1 file changed, 16 deletions(-) diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c index 93f6e9f..3f12916 100644 --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c @@ -270,19 +270,6 @@ static void dm_end_request(struct request *clone, int error) struct mapped_device *md = tio->md; struct request *rq = tio->orig; - if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { - rq->errors = clone->errors; - rq->resid_len = clone->resid_len; - - if (rq->sense) - /* -* We are using the sense buffer of the original -* request. -* So setting the length of the sense data is enough. -*/ - rq->sense_len = clone->sense_len; - } - free_rq_clone(clone); rq_end_stats(md, rq); if (!rq->q->mq_ops) @@ -511,9 +498,6 @@ static int setup_clone(struct request *clone, struct request *rq, if (r) return r; - clone->cmd = rq->cmd; - clone->cmd_len = rq->cmd_len; - clone->sense = rq->sense; clone->end_io = end_clone_request; clone->end_io_data = tio; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/16] scsi: remove gfp_flags member in scsi_host_cmd_pool
When using the slab allocator we already decide at cache creation time if an allocation comes from a GFP_DMA pool using the SLAB_CACHE_DMA flag, and there is no point passing the kmalloc-family only GFP_DMA flag to kmem_cache_alloc. Drop all the infrastructure for doing so. Signed-off-by: Christoph Hellwig --- drivers/scsi/scsi.c | 14 -- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 75455d4..0f93892 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -105,7 +105,6 @@ struct scsi_host_cmd_pool { char*cmd_name; char*sense_name; unsigned intslab_flags; - gfp_t gfp_mask; }; static struct scsi_host_cmd_pool scsi_cmd_pool = { @@ -118,7 +117,6 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { .cmd_name = "scsi_cmd_cache(DMA)", .sense_name = "scsi_sense_cache(DMA)", .slab_flags = SLAB_HWCACHE_ALIGN|SLAB_CACHE_DMA, - .gfp_mask = __GFP_DMA, }; static DEFINE_MUTEX(host_cmd_pool_mutex); @@ -156,12 +154,11 @@ scsi_host_alloc_command(struct Scsi_Host *shost, gfp_t gfp_mask) struct scsi_host_cmd_pool *pool = shost->cmd_pool; struct scsi_cmnd *cmd; - cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask); + cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask); if (!cmd) goto fail; - cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab, -gfp_mask | pool->gfp_mask); + cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab, gfp_mask); if (!cmd->sense_buffer) goto fail_free_cmd; @@ -327,10 +324,8 @@ scsi_alloc_host_cmd_pool(struct Scsi_Host *shost) } pool->slab_flags = SLAB_HWCACHE_ALIGN; - if (shost->unchecked_isa_dma) { + if (shost->unchecked_isa_dma) pool->slab_flags |= SLAB_CACHE_DMA; - pool->gfp_mask = __GFP_DMA; - } if (hostt->cmd_size) hostt->cmd_pool = pool; @@ -424,7 +419,6 @@ static void scsi_put_host_cmd_pool(struct Scsi_Host *shost) */ int scsi_setup_command_freelist(struct Scsi_Host *shost) { - const gfp_t gfp_mask = shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL; struct scsi_cmnd *cmd; spin_lock_init(&shost->free_list_lock); @@ -437,7 +431,7 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) /* * Get one backup command for this host. */ - cmd = scsi_host_alloc_command(shost, gfp_mask); + cmd = scsi_host_alloc_command(shost, GFP_KERNEL); if (!cmd) { scsi_put_host_cmd_pool(shost); shost->cmd_pool = NULL; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/16] scsi_dh_hp_sw: switch to scsi_execute_req_flags()
From: Hannes Reinecke Switch to scsi_execute_req_flags() instead of using the block interface directly. This will set REQ_QUIET and REQ_PREEMPT, but this is okay as we're evaluating the errors anyway and should be able to send the command even if the device is quiesced. Signed-off-by: Hannes Reinecke Signed-off-by: Christoph Hellwig --- drivers/scsi/device_handler/scsi_dh_hp_sw.c | 222 1 file changed, 65 insertions(+), 157 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 308e871..be43c94 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c @@ -38,13 +38,10 @@ #define HP_SW_PATH_PASSIVE 1 struct hp_sw_dh_data { - unsigned char sense[SCSI_SENSE_BUFFERSIZE]; int path_state; int retries; int retry_cnt; struct scsi_device *sdev; - activate_complete callback_fn; - void*callback_data; }; static int hp_sw_start_stop(struct hp_sw_dh_data *); @@ -56,43 +53,34 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *); * * Returns SCSI_DH_DEV_OFFLINED if the sdev is on the passive path */ -static int tur_done(struct scsi_device *sdev, unsigned char *sense) +static int tur_done(struct scsi_device *sdev, struct hp_sw_dh_data *h, + struct scsi_sense_hdr *sshdr) { - struct scsi_sense_hdr sshdr; - int ret; + int ret = SCSI_DH_IO; - ret = scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr); - if (!ret) { - sdev_printk(KERN_WARNING, sdev, - "%s: sending tur failed, no sense available\n", - HP_SW_NAME); - ret = SCSI_DH_IO; - goto done; - } - switch (sshdr.sense_key) { + switch (sshdr->sense_key) { case UNIT_ATTENTION: ret = SCSI_DH_IMM_RETRY; break; case NOT_READY: - if ((sshdr.asc == 0x04) && (sshdr.ascq == 2)) { + if (sshdr->asc == 0x04 && sshdr->ascq == 2) { /* * LUN not ready - Initialization command required * * This is the passive path */ - ret = SCSI_DH_DEV_OFFLINED; + h->path_state = HP_SW_PATH_PASSIVE; + ret = SCSI_DH_OK; break; } /* Fallthrough */ default: sdev_printk(KERN_WARNING, sdev, "%s: sending tur failed, sense %x/%x/%x\n", - HP_SW_NAME, sshdr.sense_key, sshdr.asc, - sshdr.ascq); + HP_SW_NAME, sshdr->sense_key, sshdr->asc, + sshdr->ascq); break; } - -done: return ret; } @@ -105,131 +93,36 @@ static int tur_done(struct scsi_device *sdev, unsigned char *sense) */ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h) { - struct request *req; - int ret; + unsigned char cmd[6] = { TEST_UNIT_READY }; + struct scsi_sense_hdr sshdr; + int ret = SCSI_DH_OK, res; + u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | + REQ_FAILFAST_DRIVER; retry: - req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); - if (IS_ERR(req)) - return SCSI_DH_RES_TEMP_UNAVAIL; - - blk_rq_set_block_pc(req); - req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | - REQ_FAILFAST_DRIVER; - req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY); - req->cmd[0] = TEST_UNIT_READY; - req->timeout = HP_SW_TIMEOUT; - req->sense = h->sense; - memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE); - req->sense_len = 0; - - ret = blk_execute_rq(req->q, NULL, req, 1); - if (ret == -EIO) { - if (req->sense_len > 0) { - ret = tur_done(sdev, h->sense); - } else { + res = scsi_execute_req_flags(sdev, cmd, DMA_NONE, NULL, 0, &sshdr, +HP_SW_TIMEOUT, HP_SW_RETRIES, +NULL, req_flags, 0); + if (res) { + if (scsi_sense_valid(&sshdr)) + ret = tur_done(sdev, h, &sshdr); + else { sdev_printk(KERN_WARNING, sdev, "%s: sending tur failed with %x\n", - HP_SW_NAME, req->errors); + HP_SW_NAME, res); ret = SCSI_DH_IO; } } else { h->path_state = HP_SW_PATH_ACTIVE; ret = SCSI_DH_OK;
[PATCH 05/16] dm: always defer request allocation to the owner of the request_queue
DM already calls blk_mq_alloc_request on the request_queue of the underlying device if it is a blk-mq device. But now that we allow drivers to allocate additional data and initialize it ahead of time we need to do the same for all drivers. Doing so and using the new cmd_size infrastructure in the block layer greatly simplifies the dm-rq and mpath code, and should also make arbitrary combinations of SQ and MQ devices with SQ or MQ device mapper tables easily possible as a further step. Signed-off-by: Christoph Hellwig --- drivers/md/dm-core.h | 1 - drivers/md/dm-mpath.c | 132 -- drivers/md/dm-rq.c| 251 ++ drivers/md/dm-rq.h| 2 +- drivers/md/dm-target.c| 7 -- drivers/md/dm.c | 18 +-- drivers/md/dm.h | 3 +- include/linux/device-mapper.h | 3 - 8 files changed, 81 insertions(+), 336 deletions(-) diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h index 40ceba1..136fda3 100644 --- a/drivers/md/dm-core.h +++ b/drivers/md/dm-core.h @@ -92,7 +92,6 @@ struct mapped_device { * io objects are allocated from here. */ mempool_t *io_pool; - mempool_t *rq_pool; struct bio_set *bs; diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 6400cff..784f237 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -92,12 +92,6 @@ struct multipath { unsigned queue_mode; - /* -* We must use a mempool of dm_mpath_io structs so that we -* can resubmit bios on error. -*/ - mempool_t *mpio_pool; - struct mutex work_mutex; struct work_struct trigger_event; @@ -115,8 +109,6 @@ struct dm_mpath_io { typedef int (*action_fn) (struct pgpath *pgpath); -static struct kmem_cache *_mpio_cache; - static struct workqueue_struct *kmultipathd, *kmpath_handlerd; static void trigger_event(struct work_struct *work); static void activate_path(struct work_struct *work); @@ -209,7 +201,6 @@ static struct multipath *alloc_multipath(struct dm_target *ti) init_waitqueue_head(&m->pg_init_wait); mutex_init(&m->work_mutex); - m->mpio_pool = NULL; m->queue_mode = DM_TYPE_NONE; m->ti = ti; @@ -229,16 +220,7 @@ static int alloc_multipath_stage2(struct dm_target *ti, struct multipath *m) m->queue_mode = DM_TYPE_MQ_REQUEST_BASED; else m->queue_mode = DM_TYPE_REQUEST_BASED; - } - - if (m->queue_mode == DM_TYPE_REQUEST_BASED) { - unsigned min_ios = dm_get_reserved_rq_based_ios(); - - m->mpio_pool = mempool_create_slab_pool(min_ios, _mpio_cache); - if (!m->mpio_pool) - return -ENOMEM; - } - else if (m->queue_mode == DM_TYPE_BIO_BASED) { + } else if (m->queue_mode == DM_TYPE_BIO_BASED) { INIT_WORK(&m->process_queued_bios, process_queued_bios); /* * bio-based doesn't support any direct scsi_dh management; @@ -263,7 +245,6 @@ static void free_multipath(struct multipath *m) kfree(m->hw_handler_name); kfree(m->hw_handler_params); - mempool_destroy(m->mpio_pool); kfree(m); } @@ -272,38 +253,6 @@ static struct dm_mpath_io *get_mpio(union map_info *info) return info->ptr; } -static struct dm_mpath_io *set_mpio(struct multipath *m, union map_info *info) -{ - struct dm_mpath_io *mpio; - - if (!m->mpio_pool) { - /* Use blk-mq pdu memory requested via per_io_data_size */ - mpio = get_mpio(info); - memset(mpio, 0, sizeof(*mpio)); - return mpio; - } - - mpio = mempool_alloc(m->mpio_pool, GFP_ATOMIC); - if (!mpio) - return NULL; - - memset(mpio, 0, sizeof(*mpio)); - info->ptr = mpio; - - return mpio; -} - -static void clear_request_fn_mpio(struct multipath *m, union map_info *info) -{ - /* Only needed for non blk-mq (.request_fn) multipath */ - if (m->mpio_pool) { - struct dm_mpath_io *mpio = info->ptr; - - info->ptr = NULL; - mempool_free(mpio, m->mpio_pool); - } -} - static size_t multipath_per_bio_data_size(void) { return sizeof(struct dm_mpath_io) + sizeof(struct dm_bio_details); @@ -530,16 +479,17 @@ static bool must_push_back_bio(struct multipath *m) /* * Map cloned requests (request-based multipath) */ -static int __multipath_map(struct dm_target *ti, struct request *clone, - union map_info *map_context, - struct request *rq, struct request **__clone) +static int multipath_clone_and_map(struct dm_target *ti, struct request *rq, + union map_info *map_context, +
[PATCH 07/16] scsi_dh_emc: switch to scsi_execute_req_flags()
From: Hannes Reinecke Switch to scsi_execute_req_flags() and scsi_get_vpd_page() instead of open-coding it. Using scsi_execute_req_flags() will set REQ_QUIET and REQ_PREEMPT, but this is okay as we're evaluating the errors anyway and should be able to send the command even if the device is quiesced. Signed-off-by: Hannes Reinecke Signed-off-by: Christoph Hellwig --- drivers/scsi/device_handler/scsi_dh_emc.c | 247 +++--- 1 file changed, 56 insertions(+), 191 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 5b80746..4a7679f 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c @@ -88,12 +88,6 @@ struct clariion_dh_data { */ unsigned char buffer[CLARIION_BUFFER_SIZE]; /* -* SCSI sense buffer for commands -- assumes serial issuance -* and completion sequence of all commands for same multipath. -*/ - unsigned char sense[SCSI_SENSE_BUFFERSIZE]; - unsigned int senselen; - /* * LUN state */ int lun_state; @@ -116,44 +110,38 @@ struct clariion_dh_data { /* * Parse MODE_SELECT cmd reply. */ -static int trespass_endio(struct scsi_device *sdev, char *sense) +static int trespass_endio(struct scsi_device *sdev, + struct scsi_sense_hdr *sshdr) { int err = SCSI_DH_IO; - struct scsi_sense_hdr sshdr; - - if (!scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) { - sdev_printk(KERN_ERR, sdev, "%s: Found valid sense data 0x%2x, " - "0x%2x, 0x%2x while sending CLARiiON trespass " - "command.\n", CLARIION_NAME, sshdr.sense_key, - sshdr.asc, sshdr.ascq); - if ((sshdr.sense_key == 0x05) && (sshdr.asc == 0x04) && -(sshdr.ascq == 0x00)) { - /* -* Array based copy in progress -- do not send -* mode_select or copy will be aborted mid-stream. -*/ - sdev_printk(KERN_INFO, sdev, "%s: Array Based Copy in " - "progress while sending CLARiiON trespass " - "command.\n", CLARIION_NAME); - err = SCSI_DH_DEV_TEMP_BUSY; - } else if ((sshdr.sense_key == 0x02) && (sshdr.asc == 0x04) && - (sshdr.ascq == 0x03)) { - /* -* LUN Not Ready - Manual Intervention Required -* indicates in-progress ucode upgrade (NDU). -*/ - sdev_printk(KERN_INFO, sdev, "%s: Detected in-progress " - "ucode upgrade NDU operation while sending " - "CLARiiON trespass command.\n", CLARIION_NAME); - err = SCSI_DH_DEV_TEMP_BUSY; - } else - err = SCSI_DH_DEV_FAILED; - } else { - sdev_printk(KERN_INFO, sdev, - "%s: failed to send MODE SELECT, no sense available\n", - CLARIION_NAME); - } + sdev_printk(KERN_ERR, sdev, "%s: Found valid sense data 0x%2x, " + "0x%2x, 0x%2x while sending CLARiiON trespass " + "command.\n", CLARIION_NAME, sshdr->sense_key, + sshdr->asc, sshdr->ascq); + + if (sshdr->sense_key == 0x05 && sshdr->asc == 0x04 && + sshdr->ascq == 0x00) { + /* +* Array based copy in progress -- do not send +* mode_select or copy will be aborted mid-stream. +*/ + sdev_printk(KERN_INFO, sdev, "%s: Array Based Copy in " + "progress while sending CLARiiON trespass " + "command.\n", CLARIION_NAME); + err = SCSI_DH_DEV_TEMP_BUSY; + } else if (sshdr->sense_key == 0x02 && sshdr->asc == 0x04 && + sshdr->ascq == 0x03) { + /* +* LUN Not Ready - Manual Intervention Required +* indicates in-progress ucode upgrade (NDU). +*/ + sdev_printk(KERN_INFO, sdev, "%s: Detected in-progress " + "ucode upgrade NDU operation while sending " + "CLARiiON trespass command.\n", CLARIION_NAME); + err = SCSI_DH_DEV_TEMP_BUSY; + } else + err = SCSI_DH_DEV_FAILED; return err; } @@ -257,103 +245,15 @@ static char * parse_sp_model(struct scsi_device *sdev, unsigned char *buffer) return sp_model; } -/* - * Get block request for REQ_BLOCK_PC command issued to path. Currently - * limited to MODE_SELECT (trespass) and I
[PATCH 06/16] scsi_dh_rdac: switch to scsi_execute_req_flags()
From: Hannes Reinecke Switch to scsi_execute_req_flags() and scsi_get_vpd_page() instead of open-coding it. Using scsi_execute_req_flags() will set REQ_QUIET and REQ_PREEMPT, but this is okay as we're evaluating the errors anyway and should be able to send the command even if the device is quiesced. Signed-off-by: Hannes Reinecke Signed-off-by: Christoph Hellwig --- drivers/scsi/device_handler/scsi_dh_rdac.c | 174 + 1 file changed, 51 insertions(+), 123 deletions(-) diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 00d9c32..b64eaae 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -205,7 +205,6 @@ struct rdac_dh_data { #define RDAC_NON_PREFERRED 1 charpreferred; - unsigned char sense[SCSI_SENSE_BUFFERSIZE]; union { struct c2_inquiry c2; struct c4_inquiry c4; @@ -262,40 +261,12 @@ do { \ sdev_printk(KERN_INFO, sdev, RDAC_NAME ": " f "\n", ## arg); \ } while (0); -static struct request *get_rdac_req(struct scsi_device *sdev, - void *buffer, unsigned buflen, int rw) +static unsigned int rdac_failover_get(struct rdac_controller *ctlr, + struct list_head *list, + unsigned char *cdb) { - struct request *rq; - struct request_queue *q = sdev->request_queue; - - rq = blk_get_request(q, rw, GFP_NOIO); - - if (IS_ERR(rq)) { - sdev_printk(KERN_INFO, sdev, - "get_rdac_req: blk_get_request failed.\n"); - return NULL; - } - blk_rq_set_block_pc(rq); - - if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) { - blk_put_request(rq); - sdev_printk(KERN_INFO, sdev, - "get_rdac_req: blk_rq_map_kern failed.\n"); - return NULL; - } - - rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | -REQ_FAILFAST_DRIVER; - rq->retries = RDAC_RETRIES; - rq->timeout = RDAC_TIMEOUT; - - return rq; -} - -static struct request *rdac_failover_get(struct scsi_device *sdev, - struct rdac_dh_data *h, struct list_head *list) -{ - struct request *rq; + struct scsi_device *sdev = ctlr->ms_sdev; + struct rdac_dh_data *h = sdev->handler_data; struct rdac_mode_common *common; unsigned data_size; struct rdac_queue_data *qdata; @@ -332,27 +303,17 @@ static struct request *rdac_failover_get(struct scsi_device *sdev, lun_table[qdata->h->lun] = 0x81; } - /* get request for block layer packet command */ - rq = get_rdac_req(sdev, &h->ctlr->mode_select, data_size, WRITE); - if (!rq) - return NULL; - /* Prepare the command. */ if (h->ctlr->use_ms10) { - rq->cmd[0] = MODE_SELECT_10; - rq->cmd[7] = data_size >> 8; - rq->cmd[8] = data_size & 0xff; + cdb[0] = MODE_SELECT_10; + cdb[7] = data_size >> 8; + cdb[8] = data_size & 0xff; } else { - rq->cmd[0] = MODE_SELECT; - rq->cmd[4] = data_size; + cdb[0] = MODE_SELECT; + cdb[4] = data_size; } - rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); - - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = 0; - return rq; + return data_size; } static void release_controller(struct kref *kref) @@ -400,46 +361,14 @@ static struct rdac_controller *get_controller(int index, char *array_name, return ctlr; } -static int submit_inquiry(struct scsi_device *sdev, int page_code, - unsigned int len, struct rdac_dh_data *h) -{ - struct request *rq; - struct request_queue *q = sdev->request_queue; - int err = SCSI_DH_RES_TEMP_UNAVAIL; - - rq = get_rdac_req(sdev, &h->inq, len, READ); - if (!rq) - goto done; - - /* Prepare the command. */ - rq->cmd[0] = INQUIRY; - rq->cmd[1] = 1; - rq->cmd[2] = page_code; - rq->cmd[4] = len; - rq->cmd_len = COMMAND_SIZE(INQUIRY); - - rq->sense = h->sense; - memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); - rq->sense_len = 0; - - err = blk_execute_rq(q, NULL, rq, 1); - if (err == -EIO) - err = SCSI_DH_IO; - - blk_put_request(rq); -done: - return err; -} - static int get_lun_info(struct scsi_device *sdev, struct rdac_dh_data *h, char *array_name, u8 *array_id) { - int err, i; - struct c8_inquiry *inqp; + int err = SCSI_DH_IO, i; + stru
[PATCH 03/16] block: allow specifying size for extra command data
This mirrors the blk-mq capabilities to allocate extra drivers-specific data behind struct request by setting a cmd_size field, as well as having a constructor / destructor for it. Signed-off-by: Christoph Hellwig --- block/blk-core.c | 59 -- block/blk-flush.c | 5 ++--- block/blk-sysfs.c | 7 -- include/linux/blkdev.h | 7 ++ 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index d2c2fc9..793ef96 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -606,17 +606,41 @@ void blk_cleanup_queue(struct request_queue *q) EXPORT_SYMBOL(blk_cleanup_queue); /* Allocate memory local to the request queue */ -static void *alloc_request_struct(gfp_t gfp_mask, void *data) +static void *alloc_request_simple(gfp_t gfp_mask, void *data) { - int nid = (int)(long)data; - return kmem_cache_alloc_node(request_cachep, gfp_mask, nid); + struct request_queue *q = data; + + return kmem_cache_alloc_node(request_cachep, gfp_mask, q->node); } -static void free_request_struct(void *element, void *unused) +static void free_request_simple(void *element, void *data) { kmem_cache_free(request_cachep, element); } +static void *alloc_request_size(gfp_t gfp_mask, void *data) +{ + struct request_queue *q = data; + struct request *rq; + + rq = kmalloc_node(sizeof(struct request) + q->cmd_size, gfp_mask, + q->node); + if (rq && q->init_rq_fn && q->init_rq_fn(q, rq, gfp_mask) < 0) { + kfree(rq); + rq = NULL; + } + return rq; +} + +static void free_request_size(void *element, void *data) +{ + struct request_queue *q = data; + + if (q->exit_rq_fn) + q->exit_rq_fn(q, element); + kfree(element); +} + int blk_init_rl(struct request_list *rl, struct request_queue *q, gfp_t gfp_mask) { @@ -629,10 +653,15 @@ int blk_init_rl(struct request_list *rl, struct request_queue *q, init_waitqueue_head(&rl->wait[BLK_RW_SYNC]); init_waitqueue_head(&rl->wait[BLK_RW_ASYNC]); - rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, alloc_request_struct, - free_request_struct, - (void *)(long)q->node, gfp_mask, - q->node); + if (q->cmd_size) { + rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, + alloc_request_size, free_request_size, + q, gfp_mask, q->node); + } else { + rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, + alloc_request_simple, free_request_simple, + q, gfp_mask, q->node); + } if (!rl->rq_pool) return -ENOMEM; @@ -846,12 +875,15 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio); int blk_init_allocated_queue(struct request_queue *q) { - q->fq = blk_alloc_flush_queue(q, NUMA_NO_NODE, 0); + q->fq = blk_alloc_flush_queue(q, NUMA_NO_NODE, q->cmd_size); if (!q->fq) return -ENOMEM; + if (q->init_rq_fn && q->init_rq_fn(q, q->fq->flush_rq, GFP_KERNEL)) + goto out_free_flush_queue; + if (blk_init_rl(&q->root_rl, q, GFP_KERNEL)) - goto fail; + goto out_exit_flush_rq; INIT_WORK(&q->timeout_work, blk_timeout_work); q->queue_flags |= QUEUE_FLAG_DEFAULT; @@ -869,13 +901,16 @@ int blk_init_allocated_queue(struct request_queue *q) /* init elevator */ if (elevator_init(q, NULL)) { mutex_unlock(&q->sysfs_lock); - goto fail; + goto out_exit_flush_rq; } mutex_unlock(&q->sysfs_lock); return 0; -fail: +out_exit_flush_rq: + if (q->exit_rq_fn) + q->exit_rq_fn(q, q->fq->flush_rq); +out_free_flush_queue: blk_free_flush_queue(q->fq); wbt_exit(q); return -ENOMEM; diff --git a/block/blk-flush.c b/block/blk-flush.c index d7de34e..bf3ba3c 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -547,11 +547,10 @@ struct blk_flush_queue *blk_alloc_flush_queue(struct request_queue *q, if (!fq) goto fail; - if (q->mq_ops) { + if (q->mq_ops) spin_lock_init(&fq->mq_flush_lock); - rq_sz = round_up(rq_sz + cmd_size, cache_line_size()); - } + rq_sz = round_up(rq_sz + cmd_size, cache_line_size()); fq->flush_rq = kzalloc_node(rq_sz, GFP_KERNEL, node); if (!fq->flush_rq) goto fail_rq; diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 1dbce05..894f773 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -814,10 +814,13 @@ static void blk_release_queue(struct ko
[PATCH 02/16] block: simplify blk_init_allocated_queue
Return an errno value instead of the passed in queue so that the callers don't have to keep track of two queues, and move the assignment of the request_fn and lock to the caller as passing them as argument doesn't simplify anything. While we're at it also remove two pointless NULL assignments, given that the request structure is zeroed on allocation. Signed-off-by: Christoph Hellwig --- block/blk-core.c | 38 +++--- drivers/md/dm-rq.c | 3 ++- include/linux/blkdev.h | 3 +-- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 732b719..d2c2fc9 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -823,15 +823,19 @@ EXPORT_SYMBOL(blk_init_queue); struct request_queue * blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id) { - struct request_queue *uninit_q, *q; + struct request_queue *q; - uninit_q = blk_alloc_queue_node(GFP_KERNEL, node_id); - if (!uninit_q) + q = blk_alloc_queue_node(GFP_KERNEL, node_id); + if (!q) return NULL; - q = blk_init_allocated_queue(uninit_q, rfn, lock); - if (!q) - blk_cleanup_queue(uninit_q); + q->request_fn = rfn; + if (lock) + q->queue_lock = lock; + if (blk_init_allocated_queue(q) < 0) { + blk_cleanup_queue(q); + return NULL; + } return q; } @@ -839,30 +843,19 @@ EXPORT_SYMBOL(blk_init_queue_node); static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio); -struct request_queue * -blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn, -spinlock_t *lock) -{ - if (!q) - return NULL; +int blk_init_allocated_queue(struct request_queue *q) +{ q->fq = blk_alloc_flush_queue(q, NUMA_NO_NODE, 0); if (!q->fq) - return NULL; + return -ENOMEM; if (blk_init_rl(&q->root_rl, q, GFP_KERNEL)) goto fail; INIT_WORK(&q->timeout_work, blk_timeout_work); - q->request_fn = rfn; - q->prep_rq_fn = NULL; - q->unprep_rq_fn = NULL; q->queue_flags |= QUEUE_FLAG_DEFAULT; - /* Override internal queue lock with supplied lock pointer */ - if (lock) - q->queue_lock = lock; - /* * This also sets hw/phys segments, boundary and size */ @@ -880,13 +873,12 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn, } mutex_unlock(&q->sysfs_lock); - - return q; + return 0; fail: blk_free_flush_queue(q->fq); wbt_exit(q); - return NULL; + return -ENOMEM; } EXPORT_SYMBOL(blk_init_allocated_queue); diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c index 9d7275f..93f6e9f 100644 --- a/drivers/md/dm-rq.c +++ b/drivers/md/dm-rq.c @@ -823,7 +823,8 @@ static void dm_old_request_fn(struct request_queue *q) int dm_old_init_request_queue(struct mapped_device *md) { /* Fully initialize the queue */ - if (!blk_init_allocated_queue(md->queue, dm_old_request_fn, NULL)) + md->queue->request_fn = dm_old_request_fn; + if (blk_init_allocated_queue(md->queue) < 0) return -EINVAL; /* disable dm_old_request_fn's merge heuristic by default */ diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 8e0b57e..a036c4a 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1131,8 +1131,7 @@ extern void blk_unprep_request(struct request *); extern struct request_queue *blk_init_queue_node(request_fn_proc *rfn, spinlock_t *lock, int node_id); extern struct request_queue *blk_init_queue(request_fn_proc *, spinlock_t *); -extern struct request_queue *blk_init_allocated_queue(struct request_queue *, - request_fn_proc *, spinlock_t *); +extern int blk_init_allocated_queue(struct request_queue *); extern void blk_cleanup_queue(struct request_queue *); extern void blk_queue_make_request(struct request_queue *, make_request_fn *); extern void blk_queue_bounce_limit(struct request_queue *, u64); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
split scsi passthrough fields out of struct request
Hi all, this series splits the support for SCSI passthrough commands from the main struct request used all over the block layer into a separate scsi_request structure that drivers that want to support SCSI passthough need to embedded as the first thing into their request-private data, similar to how we handle NVMe passthrough commands. To support this I've added support for that the private data after request structure to the legacy request path instead, so that it can be treated the same way as the blk-mq path. Compare to the current scsi_cmnd allocator that actually is a major simplification. Compared to the previous RFC version the major change is that dm-mpath works with this version. To make it work I've switched the legacy request dm-rq to use the same clone and map method as the blk-mq version. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/16] block: fix elevator init check
We can't initalize the elevator fields for flushes as flush share space in struct request with the elevator data. But currently we can't commnicate that a request is a flush through blk_get_request as we can only pass READ or WRITE, and the low-level code looks at the possible NULL bio to check for a flush. Fix this by allowing to pass any block op and flags, and by checking for the flush flags in __get_request. Signed-off-by: Christoph Hellwig --- block/blk-core.c | 26 -- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index a61f140..732b719 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -1022,25 +1022,6 @@ int blk_update_nr_requests(struct request_queue *q, unsigned int nr) return 0; } -/* - * Determine if elevator data should be initialized when allocating the - * request associated with @bio. - */ -static bool blk_rq_should_init_elevator(struct bio *bio) -{ - if (!bio) - return true; - - /* -* Flush requests do not use the elevator so skip initialization. -* This allows a request to share the flush and elevator data. -*/ - if (bio->bi_opf & (REQ_PREFLUSH | REQ_FUA)) - return false; - - return true; -} - /** * __get_request - get a free request * @rl: request list to allocate from @@ -1119,10 +1100,13 @@ static struct request *__get_request(struct request_list *rl, unsigned int op, * request is freed. This guarantees icq's won't be destroyed and * makes creating new ones safe. * +* Flush requests do not use the elevator so skip initialization. +* This allows a request to share the flush and elevator data. +* * Also, lookup icq while holding queue_lock. If it doesn't exist, * it will be created after releasing queue_lock. */ - if (blk_rq_should_init_elevator(bio) && !blk_queue_bypass(q)) { + if (!(op & (REQ_PREFLUSH | REQ_FUA)) && !blk_queue_bypass(q)) { rq_flags |= RQF_ELVPRIV; q->nr_rqs_elvpriv++; if (et->icq_cache && ioc) @@ -1276,8 +1260,6 @@ static struct request *blk_old_get_request(struct request_queue *q, int rw, { struct request *rq; - BUG_ON(rw != READ && rw != WRITE); - /* create ioc upfront */ create_io_context(gfp_mask, q->node); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mpt3sas: Force request partial completion alignment
On 01/23/2017 07:05 AM, Sreekanth Reddy wrote: > On Wed, Dec 28, 2016 at 6:21 PM, Guilherme G. Piccoli > wrote: >> From: Ram Pai >> >> The firmware or device, possibly under a heavy I/O load, can return >> on a partial unaligned boundary. Scsi-ml expects these requests to be >> completed on an alignment boundary. Scsi-ml blindly requeues the I/O >> without checking the alignment boundary of the I/O request for the >> remaining bytes. This leads to errors, since devices cannot perform >> non-aligned read/write operations. >> >> This patch fixes the issue in the driver. It aligns unaligned >> completions of FS requests, by truncating them to the nearest >> alignment boundary. >> >> Reported-by: Mauricio Faria De Oliveira >> Signed-off-by: Guilherme G. Piccoli >> Signed-off-by: Ram Pai >> --- >> drivers/scsi/mpt3sas/mpt3sas_scsih.c | 16 >> 1 file changed, 16 insertions(+) >> >> diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c >> b/drivers/scsi/mpt3sas/mpt3sas_scsih.c >> index b5c966e..55332a3 100644 >> --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c >> +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c >> @@ -4644,6 +4644,8 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, >> u8 msix_index, u32 reply) >> struct MPT3SAS_DEVICE *sas_device_priv_data; >> u32 response_code = 0; >> unsigned long flags; >> + unsigned int sector_sz; >> + struct request *req; >> >> mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); >> scmd = _scsih_scsi_lookup_get_clear(ioc, smid); >> @@ -4703,6 +4705,20 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, >> u8 msix_index, u32 reply) >> } >> >> xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); >> + >> + /* In case of bogus fw or device, we could end up having >> +* unaligned partial completion. We can force alignment here, >> +* then scsi-ml does not need to handle this misbehavior. >> +*/ >> + sector_sz = scmd->device->sector_size; >> + req = scmd->request; >> + if (unlikely(sector_sz && req && (req->cmd_type == REQ_TYPE_FS) && >> + (xfer_cnt % sector_sz))) { >> + sdev_printk(KERN_INFO, scmd->device, >> + "unaligned partial completion avoided\n"); > > [Sreekanth] Patch looks good. But can we print xfer_cnt & sector_sz > values along with above print. > > Also if it is generic drive issue, then can we move this work around > to SCSI Mid Layer? > Thank you! I'll send a v2 including your suggestion. Regarding a fix in scsi-ml, we tried already: https://lkml.org/lkml/2016/12/19/591 Reception wasn't in favor of the patch; they suggested we patch the driver instead, then we sent the current change only for mpt3sas. Thanks, Guilherme >> + xfer_cnt = (xfer_cnt / sector_sz) * sector_sz; >> + } >> + >> scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt); >> if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) >> log_info = le32_to_cpu(mpi_reply->IOCLogInfo); >> -- >> 2.1.0 >> > -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 3/4] mpt3sas: Fix Firmware fault state 0x2100 during heavy 4K RR FIO stress test.
Due existence of loop in the IO path our HBA will receive heavy IOs and also as driver is not updating the Reply Post Host Index frequently, So there will be a high chance that our Firmware unable to find any free entry in the Reply Post Descriptor Queue (i.e. Queue overflow occurs) and can observe 0x2100 firmware fault. So to fix this, we have defined a thresh hold value. After continuously processing this thresh hold number of reply descriptors driver will update the Reply Descriptor Host Index so that this thresh hold number of reply descriptors entries will be freed and these entries will be available for firmware and we won't observe this Firmware fault. We have defined this threshold value as 1/3rd of the hba queue depth. Signed-off-by: Chaitra P B Signed-off-by: Suganath Prabu S --- drivers/scsi/mpt3sas/mpt3sas_base.c | 19 +++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 722fab9..a3fe1fb 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -1040,6 +1040,25 @@ _base_interrupt(int irq, void *bus_id) reply_q->reply_post_free[reply_q->reply_post_host_index]. Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; completed_cmds++; + /* Update the reply post host index after continuously +* processing the threshold number of Reply Descriptors. +* So that FW can find enough entries to post the Reply +* Descriptors in the reply descriptor post queue. +*/ + if (completed_cmds > ioc->hba_queue_depth/3) { + if (ioc->combined_reply_queue) { + writel(reply_q->reply_post_host_index | + ((msix_index & 7) << +MPI2_RPHI_MSIX_INDEX_SHIFT), + ioc->replyPostRegisterIndex[msix_index/8]); + } else { + writel(reply_q->reply_post_host_index | + (msix_index << +MPI2_RPHI_MSIX_INDEX_SHIFT), + &ioc->chip->ReplyPostHostIndex); + } + completed_cmds = 1; + } if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) goto out; if (!reply_q->reply_post_host_index) -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/4] mpt3sas: Fix for Crusader to achieve product targets with SAS devices.
Small glitch/degraded performance in Crusader is improved with SAS drives by removing unnecessary spinlocks while clearing scsi command in drivers internal lookup table. Signed-off-by: Chaitra P B Signed-off-by: Suganath Prabu S --- drivers/scsi/mpt3sas/mpt3sas_base.c |1 + drivers/scsi/mpt3sas/mpt3sas_base.h |1 + drivers/scsi/mpt3sas/mpt3sas_ctl.c |4 +++- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 31 --- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index f00ef88..722fab9 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -5522,6 +5522,7 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) goto out_free_resources; ioc->non_operational_loop = 0; + ioc->got_task_abort_from_ioctl = 0; return 0; out_free_resources: diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index dcb33f4..83cfa16 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -1000,6 +1000,7 @@ struct MPT3SAS_ADAPTER { u8 broadcast_aen_busy; u16 broadcast_aen_pending; u8 shost_recovery; + u8 got_task_abort_from_ioctl; struct mutexreset_in_progress_mutex; spinlock_t ioc_reset_in_progress_lock; diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 95f0f24..02fe1c4 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -826,16 +826,18 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, "TASK_MGMT: handle(0x%04x), task_type(0x%02x)\n", ioc->name, le16_to_cpu(tm_request->DevHandle), tm_request->TaskType)); - + ioc->got_task_abort_from_ioctl = 1; if (tm_request->TaskType == MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK || tm_request->TaskType == MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK) { if (_ctl_set_task_mid(ioc, &karg, tm_request)) { mpt3sas_base_free_smid(ioc, smid); + ioc->got_task_abort_from_ioctl = 0; goto out; } } + ioc->got_task_abort_from_ioctl = 0; if (test_bit(device_handle, ioc->device_remove_in_progress)) { dtmprintk(ioc, pr_info(MPT3SAS_FMT diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 2c6a689..cc05e4f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -1074,6 +1074,26 @@ _scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc, u16 smid) } /** + * __scsih_scsi_lookup_get_clear - returns scmd entry without + * holding any lock. + * @ioc: per adapter object + * @smid: system request message index + * + * Returns the smid stored scmd pointer. + * Then will dereference the stored scmd pointer. + */ +static inline struct scsi_cmnd * +__scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, + u16 smid) +{ + struct scsi_cmnd *scmd = NULL; + + swap(scmd, ioc->scsi_lookup[smid - 1].scmd); + + return scmd; +} + +/** * _scsih_scsi_lookup_get_clear - returns scmd entry * @ioc: per adapter object * @smid: system request message index @@ -1088,8 +1108,7 @@ _scsih_scsi_lookup_get_clear(struct MPT3SAS_ADAPTER *ioc, u16 smid) struct scsi_cmnd *scmd; spin_lock_irqsave(&ioc->scsi_lookup_lock, flags); - scmd = ioc->scsi_lookup[smid - 1].scmd; - ioc->scsi_lookup[smid - 1].scmd = NULL; + scmd = __scsih_scsi_lookup_get_clear(ioc, smid); spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags); return scmd; @@ -4659,7 +4678,13 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) unsigned long flags; mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); - scmd = _scsih_scsi_lookup_get_clear(ioc, smid); + + if (ioc->broadcast_aen_busy || ioc->pci_error_recovery || + ioc->got_task_abort_from_ioctl) + scmd = _scsih_scsi_lookup_get_clear(ioc, smid); + else + scmd = __scsih_scsi_lookup_get_clear(ioc, smid); + if (scmd == NULL) return 1; -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/4] mpt3sas: Updating driver version to v15.100.00.00
Updated driver version to "15.100.00.00" Signed-off-by: Chaitra P B Signed-off-by: Suganath Prabu S Reviewed-by: Johannes Thumshirn --- drivers/scsi/mpt3sas/mpt3sas_base.h |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 83cfa16..4ab634f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -73,9 +73,9 @@ #define MPT3SAS_DRIVER_NAME"mpt3sas" #define MPT3SAS_AUTHOR "Avago Technologies " #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver" -#define MPT3SAS_DRIVER_VERSION "14.101.00.00" -#define MPT3SAS_MAJOR_VERSION 14 -#define MPT3SAS_MINOR_VERSION 101 +#define MPT3SAS_DRIVER_VERSION "15.100.00.00" +#define MPT3SAS_MAJOR_VERSION 15 +#define MPT3SAS_MINOR_VERSION 100 #define MPT3SAS_BUILD_VERSION 0 #define MPT3SAS_RELEASE_VERSION00 -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/4] mpt3sas: Added print to notify cable running at a degraded speed.
Driver processes the event MPI26_EVENT_ACTIVE_CABLE_DEGRADED when a cable is present and is running at a degraded speed (below the SAS3 12 Gb/s rate). Prints added to inform the user that the cable is not running at optimal speed. Signed-off-by: Chaitra P B Signed-off-by: Suganath Prabu S --- drivers/scsi/mpt3sas/mpi/mpi2_ioc.h |2 ++ drivers/scsi/mpt3sas/mpt3sas_scsih.c | 25 + 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h index 8bae305..af4be40 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h @@ -624,6 +624,8 @@ typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT { /* defines for ReasonCode field */ #define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER (0x00) +#define MPI26_EVENT_ACTIVE_CABLE_PRESENT(0x01) +#define MPI26_EVENT_ACTIVE_CABLE_DEGRADED (0x02) /*Hard Reset Received Event data */ diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 75f3fce..2c6a689 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -8028,15 +8028,24 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION: ActiveCableEventData = (Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData; - if (ActiveCableEventData->ReasonCode == - MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER) { - pr_info(MPT3SAS_FMT "Currently an active cable with ReceptacleID %d", - ioc->name, ActiveCableEventData->ReceptacleID); - pr_info("cannot be powered and devices connected to this active cable"); - pr_info("will not be seen. This active cable"); - pr_info("requires %d mW of power", - ActiveCableEventData->ActiveCablePowerRequirement); + switch (ActiveCableEventData->ReasonCode) { + case MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER: + pr_notice(MPT3SAS_FMT "Receptacle ID %d: This active cable" + " requires %d mW of power\n", ioc->name, +ActiveCableEventData->ReceptacleID, +ActiveCableEventData->ActiveCablePowerRequirement); + pr_notice(MPT3SAS_FMT "Receptacle ID %d: Devices connected" + " to this active cable will not be seen\n", +ioc->name, ActiveCableEventData->ReceptacleID); + break; + + case MPI26_EVENT_ACTIVE_CABLE_DEGRADED: + pr_notice(MPT3SAS_FMT "ReceptacleID %d: This cable", + ioc->name, ActiveCableEventData->ReceptacleID); + pr_notice(" is not running at an optimal speed(12 Gb/s)\n"); + break; } + break; default: /* ignore the rest */ -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/4] mpt3sas driver Enhancements and defect fixes:
Here is the change list: Posting 4 patches for mpt3sas driver enhancement and defect fixes. * Handle cable event for notifying degraded speed. * Performance improvement for Crusader. * Fix Firmware fault state 0x2100 during heavy 4K RR FIO stress test. * Updated driver version to 15.100.00.00 Chaitra P B (4): mpt3sas: Added print to notify cable running at a degraded speed. mpt3sas: Fix for Crusader to achieve product targets with SAS devices. mpt3sas: Fix Firmware fault state 0x2100 during heavy 4K RR FIO stress test. mpt3sas: Updating driver version to v15.100.00.00 drivers/scsi/mpt3sas/mpi/mpi2_ioc.h |2 + drivers/scsi/mpt3sas/mpt3sas_base.c | 20 drivers/scsi/mpt3sas/mpt3sas_base.h |7 ++-- drivers/scsi/mpt3sas/mpt3sas_ctl.c |4 ++- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 56 +++--- 5 files changed, 74 insertions(+), 15 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] mpt3sas: Force request partial completion alignment
On Wed, Dec 28, 2016 at 6:21 PM, Guilherme G. Piccoli wrote: > From: Ram Pai > > The firmware or device, possibly under a heavy I/O load, can return > on a partial unaligned boundary. Scsi-ml expects these requests to be > completed on an alignment boundary. Scsi-ml blindly requeues the I/O > without checking the alignment boundary of the I/O request for the > remaining bytes. This leads to errors, since devices cannot perform > non-aligned read/write operations. > > This patch fixes the issue in the driver. It aligns unaligned > completions of FS requests, by truncating them to the nearest > alignment boundary. > > Reported-by: Mauricio Faria De Oliveira > Signed-off-by: Guilherme G. Piccoli > Signed-off-by: Ram Pai > --- > drivers/scsi/mpt3sas/mpt3sas_scsih.c | 16 > 1 file changed, 16 insertions(+) > > diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c > b/drivers/scsi/mpt3sas/mpt3sas_scsih.c > index b5c966e..55332a3 100644 > --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c > +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c > @@ -4644,6 +4644,8 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, > u8 msix_index, u32 reply) > struct MPT3SAS_DEVICE *sas_device_priv_data; > u32 response_code = 0; > unsigned long flags; > + unsigned int sector_sz; > + struct request *req; > > mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply); > scmd = _scsih_scsi_lookup_get_clear(ioc, smid); > @@ -4703,6 +4705,20 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, > u8 msix_index, u32 reply) > } > > xfer_cnt = le32_to_cpu(mpi_reply->TransferCount); > + > + /* In case of bogus fw or device, we could end up having > +* unaligned partial completion. We can force alignment here, > +* then scsi-ml does not need to handle this misbehavior. > +*/ > + sector_sz = scmd->device->sector_size; > + req = scmd->request; > + if (unlikely(sector_sz && req && (req->cmd_type == REQ_TYPE_FS) && > + (xfer_cnt % sector_sz))) { > + sdev_printk(KERN_INFO, scmd->device, > + "unaligned partial completion avoided\n"); [Sreekanth] Patch looks good. But can we print xfer_cnt & sector_sz values along with above print. Also if it is generic drive issue, then can we move this work around to SCSI Mid Layer? > + xfer_cnt = (xfer_cnt / sector_sz) * sector_sz; > + } > + > scsi_set_resid(scmd, scsi_bufflen(scmd) - xfer_cnt); > if (ioc_status & MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) > log_info = le32_to_cpu(mpi_reply->IOCLogInfo); > -- > 2.1.0 > -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html