From 7a6a731bd00ca90d0e250867c3b9c05b5ff0fa49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Wed, 21 Nov 2012 09:54:48 +0100 Subject: [SCSI] megaraid_sas: fix memory leak if SGL has zero length entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 98cb7e44 ([SCSI] megaraid_sas: Sanity check user supplied length before passing it to dma_alloc_coherent()) introduced a memory leak. Memory allocated for entries following zero length SGL entries will not be freed. Reference: http://bugs.debian.org/688198 Signed-off-by: Bjørn Mork Cc: Acked-by: Adam Radford Signed-off-by: James Bottomley diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 6002d36..0177295 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4958,10 +4958,12 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, sense, sense_handle); } - for (i = 0; i < ioc->sge_count && kbuff_arr[i]; i++) { - dma_free_coherent(&instance->pdev->dev, - kern_sge32[i].length, - kbuff_arr[i], kern_sge32[i].phys_addr); + for (i = 0; i < ioc->sge_count; i++) { + if (kbuff_arr[i]) + dma_free_coherent(&instance->pdev->dev, + kern_sge32[i].length, + kbuff_arr[i], + kern_sge32[i].phys_addr); } megasas_return_cmd(instance, cmd); -- cgit v0.10.2 From c8a2ba3f50f7445b3d1b822ba1a8168b4234baca Mon Sep 17 00:00:00 2001 From: Yijing Wang Date: Thu, 27 Jun 2013 15:02:49 +0800 Subject: [SCSI] pm8001: use pdev->pm_cap instead of pci_find_capability(..,PCI_CAP_ID_PM) Pci core has been saved pm cap register offset by pdev->pm_cap in pci_pm_init() in init path. So we can use pdev->pm_cap instead of using pci_find_capability(pdev, PCI_CAP_ID_PM) for better performance and simplified code. Tested-by: Lindar Liu Signed-off-by: Yijing Wang Acked-by: Lindar Liu Signed-off-by: James Bottomley diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index e4b9bc7..3861aa1 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -912,14 +912,13 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state) { struct sas_ha_struct *sha = pci_get_drvdata(pdev); struct pm8001_hba_info *pm8001_ha; - int i , pos; + int i; u32 device_state; pm8001_ha = sha->lldd_ha; flush_workqueue(pm8001_wq); scsi_block_requests(pm8001_ha->shost); - pos = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pos == 0) { - printk(KERN_ERR " PCI PM not supported\n"); + if (!pdev->pm_cap) { + dev_err(&pdev->dev, " PCI PM not supported\n"); return -ENODEV; } PM8001_CHIP_DISP->interrupt_disable(pm8001_ha, 0xFF); -- cgit v0.10.2 From 6f94d5de090947eb41efe9d3841d75ad91fd6dc7 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 4 Jun 2013 12:05:07 -0700 Subject: [SCSI] storvsc: Implement multi-channel support Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: James Bottomley diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 9451989..1d4d425 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -328,6 +328,8 @@ static int storvsc_timeout = 180; #define STORVSC_MAX_IO_REQUESTS 128 +static void storvsc_on_channel_callback(void *context); + /* * In Hyper-V, each port/path/target maps to 1 scsi host adapter. In * reality, the path/target is not used (ie always set to 0) so our @@ -364,6 +366,7 @@ struct storvsc_device { bool destroy; bool drain_notify; + bool open_sub_channel; atomic_t num_outstanding_req; struct Scsi_Host *host; @@ -755,12 +758,104 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, return total_copied; } +static void handle_sc_creation(struct vmbus_channel *new_sc) +{ + struct hv_device *device = new_sc->primary_channel->device_obj; + struct storvsc_device *stor_device; + struct vmstorage_channel_properties props; + + stor_device = get_out_stor_device(device); + if (!stor_device) + return; + + if (stor_device->open_sub_channel == false) + return; + + memset(&props, 0, sizeof(struct vmstorage_channel_properties)); + + vmbus_open(new_sc, + storvsc_ringbuffer_size, + storvsc_ringbuffer_size, + (void *)&props, + sizeof(struct vmstorage_channel_properties), + storvsc_on_channel_callback, new_sc); +} + +static void handle_multichannel_storage(struct hv_device *device, int max_chns) +{ + struct storvsc_device *stor_device; + int num_cpus = num_online_cpus(); + int num_sc; + struct storvsc_cmd_request *request; + struct vstor_packet *vstor_packet; + int ret, t; + + num_sc = ((max_chns > num_cpus) ? num_cpus : max_chns); + stor_device = get_out_stor_device(device); + if (!stor_device) + return; + + request = &stor_device->init_request; + vstor_packet = &request->vstor_packet; + + stor_device->open_sub_channel = true; + /* + * Establish a handler for dealing with subchannels. + */ + vmbus_set_sc_create_callback(device->channel, handle_sc_creation); + + /* + * Check to see if sub-channels have already been created. This + * can happen when this driver is re-loaded after unloading. + */ + + if (vmbus_are_subchannels_present(device->channel)) + return; + + stor_device->open_sub_channel = false; + /* + * Request the host to create sub-channels. + */ + memset(request, 0, sizeof(struct storvsc_cmd_request)); + init_completion(&request->wait_event); + vstor_packet->operation = VSTOR_OPERATION_CREATE_SUB_CHANNELS; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; + vstor_packet->sub_channel_count = num_sc; + + ret = vmbus_sendpacket(device->channel, vstor_packet, + (sizeof(struct vstor_packet) - + vmscsi_size_delta), + (unsigned long)request, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + + if (ret != 0) + return; + + t = wait_for_completion_timeout(&request->wait_event, 10*HZ); + if (t == 0) + return; + + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || + vstor_packet->status != 0) + return; + + /* + * Now that we created the sub-channels, invoke the check; this + * may trigger the callback. + */ + stor_device->open_sub_channel = true; + vmbus_are_subchannels_present(device->channel); +} + static int storvsc_channel_init(struct hv_device *device) { struct storvsc_device *stor_device; struct storvsc_cmd_request *request; struct vstor_packet *vstor_packet; int ret, t; + int max_chns; + bool process_sub_channels = false; stor_device = get_out_stor_device(device); if (!stor_device) @@ -855,6 +950,19 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->status != 0) goto cleanup; + /* + * Check to see if multi-channel support is there. + * Hosts that implement protocol version of 5.1 and above + * support multi-channel. + */ + max_chns = vstor_packet->storage_channel_properties.max_channel_cnt; + if ((vmbus_proto_version != VERSION_WIN7) && + (vmbus_proto_version != VERSION_WS2008)) { + if (vstor_packet->storage_channel_properties.flags & + STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL) + process_sub_channels = true; + } + memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; @@ -879,6 +987,9 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->status != 0) goto cleanup; + if (process_sub_channels) + handle_multichannel_storage(device, max_chns); + cleanup: return ret; @@ -1100,7 +1211,8 @@ static void storvsc_on_receive(struct hv_device *device, static void storvsc_on_channel_callback(void *context) { - struct hv_device *device = (struct hv_device *)context; + struct vmbus_channel *channel = (struct vmbus_channel *)context; + struct hv_device *device; struct storvsc_device *stor_device; u32 bytes_recvd; u64 request_id; @@ -1108,13 +1220,17 @@ static void storvsc_on_channel_callback(void *context) struct storvsc_cmd_request *request; int ret; + if (channel->primary_channel != NULL) + device = channel->primary_channel->device_obj; + else + device = channel->device_obj; stor_device = get_in_stor_device(device); if (!stor_device) return; do { - ret = vmbus_recvpacket(device->channel, packet, + ret = vmbus_recvpacket(channel, packet, ALIGN((sizeof(struct vstor_packet) - vmscsi_size_delta), 8), &bytes_recvd, &request_id); @@ -1155,7 +1271,7 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size) ring_size, (void *)&props, sizeof(struct vmstorage_channel_properties), - storvsc_on_channel_callback, device); + storvsc_on_channel_callback, device->channel); if (ret != 0) return ret; @@ -1207,6 +1323,7 @@ static int storvsc_do_io(struct hv_device *device, { struct storvsc_device *stor_device; struct vstor_packet *vstor_packet; + struct vmbus_channel *outgoing_channel; int ret = 0; vstor_packet = &request->vstor_packet; @@ -1217,6 +1334,11 @@ static int storvsc_do_io(struct hv_device *device, request->device = device; + /* + * Select an an appropriate channel to send the request out. + */ + + outgoing_channel = vmbus_get_outgoing_channel(device->channel); vstor_packet->flags |= REQUEST_COMPLETION_FLAG; @@ -1234,7 +1356,7 @@ static int storvsc_do_io(struct hv_device *device, vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB; if (request->data_buffer.len) { - ret = vmbus_sendpacket_multipagebuffer(device->channel, + ret = vmbus_sendpacket_multipagebuffer(outgoing_channel, &request->data_buffer, vstor_packet, (sizeof(struct vstor_packet) - @@ -1643,6 +1765,7 @@ static int storvsc_probe(struct hv_device *device, } stor_device->destroy = false; + stor_device->open_sub_channel = false; init_waitqueue_head(&stor_device->waiting_to_drain); stor_device->device = device; stor_device->host = host; -- cgit v0.10.2 From bde6d0f9877e19fc9d309bbd624da422b18cdc3d Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 4 Jun 2013 12:05:08 -0700 Subject: [SCSI] storvsc: Support FC devices Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: James Bottomley diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 1d4d425..b864e7c 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1702,6 +1702,7 @@ static struct scsi_host_template scsi_driver = { enum { SCSI_GUID, IDE_GUID, + SFC_GUID, }; static const struct hv_vmbus_device_id id_table[] = { @@ -1713,6 +1714,11 @@ static const struct hv_vmbus_device_id id_table[] = { { HV_IDE_GUID, .driver_data = IDE_GUID }, + /* Fibre Channel GUID */ + { + HV_SYNTHFC_GUID, + .driver_data = SFC_GUID + }, { }, }; -- cgit v0.10.2 From bb6a4df6db9e69e225bfc5a9d95a1675342e1873 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Tue, 4 Jun 2013 12:05:09 -0700 Subject: [SCSI] storvsc: Increase the value of STORVSC_MAX_IO_REQUESTS Increase the value of STORVSC_MAX_IO_REQUESTS to 200 requests. The current ringbuffer size can support this higher value. Signed-off-by: K. Y. Srinivasan Reviewed-by: Haiyang Zhang Signed-off-by: James Bottomley diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index b864e7c..83ec1aa 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -326,7 +326,7 @@ MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); */ static int storvsc_timeout = 180; -#define STORVSC_MAX_IO_REQUESTS 128 +#define STORVSC_MAX_IO_REQUESTS 200 static void storvsc_on_channel_callback(void *context); -- cgit v0.10.2 From 754d1243915d0fda6874fa0f1a926d85eb09e0b4 Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Tue, 25 Jun 2013 11:27:16 -0400 Subject: [SCSI] qla2xxx: Clear the MBX_INTR_WAIT flag when the mailbox time-out happens. Signed-off-by: Giridhar Malavali Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index cfa2a20..3cc2105 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -12,7 +12,7 @@ * | Level | Last Value Used | Holes | * ---------------------------------------------------------------------- * | Module Init and Probe | 0x014f | 0x4b,0xba,0xfa | - * | Mailbox commands | 0x1179 | 0x111a-0x111b | + * | Mailbox commands | 0x117a | 0x111a-0x111b | * | | | 0x1155-0x1158 | * | Device Discovery | 0x2095 | 0x2020-0x2022, | * | | | 0x2016 | diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 3587ec2..144effd 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -177,8 +177,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); spin_unlock_irqrestore(&ha->hardware_lock, flags); - wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ); - + if (!wait_for_completion_timeout(&ha->mbx_intr_comp, + mcp->tov * HZ)) { + ql_dbg(ql_dbg_mbx, vha, 0x117a, + "cmd=%x Timeout.\n", command); + spin_lock_irqsave(&ha->hardware_lock, flags); + clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); + spin_unlock_irqrestore(&ha->hardware_lock, flags); + } } else { ql_dbg(ql_dbg_mbx, vha, 0x1011, "Cmd=%x Polling Mode.\n", command); -- cgit v0.10.2 From 8edf3edd8da076008093a8a04d349bbef02ecd88 Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Tue, 25 Jun 2013 11:27:17 -0400 Subject: [SCSI] qla2xxx: Set the index in outstanding command array to NULL when cmd is aborted when the request timeout. Call the generic BSG free routine to unmap the DMA buffers. Signed-off-by: Giridhar Malavali Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 39719f8..5ba0cc1 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -2153,6 +2153,7 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) (sp->type == SRB_ELS_CMD_HST) || (sp->type == SRB_FXIOCB_BCMD)) && (sp->u.bsg_job == bsg_job)) { + req->outstanding_cmds[cnt] = NULL; spin_unlock_irqrestore(&ha->hardware_lock, flags); if (ha->isp_ops->abort_command(sp)) { ql_log(ql_log_warn, vha, 0x7089, @@ -2180,8 +2181,6 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job) done: spin_unlock_irqrestore(&ha->hardware_lock, flags); - if (bsg_job->request->msgcode == FC_BSG_HST_CT) - kfree(sp->fcport); - qla2x00_rel_sp(vha, sp); + sp->free(vha, sp); return 0; } -- cgit v0.10.2 From 3491255e12c5cd5310d855fe276f7971737a1c10 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Tue, 25 Jun 2013 11:27:18 -0400 Subject: [SCSI] qla2xxx: Move qla2x00_free_device to the correct location. Signed-off-by: Giridhar Malavali Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index ad72c1d..c2e2e20 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -104,8 +104,6 @@ MODULE_PARM_DESC(ql2xshiftctondsd, "Set to control shifting of command type processing " "based on total number of SG elements."); -static void qla2x00_free_device(scsi_qla_host_t *); - int ql2xfdmienable=1; module_param(ql2xfdmienable, int, S_IRUGO); MODULE_PARM_DESC(ql2xfdmienable, @@ -237,6 +235,7 @@ static int qla2xxx_eh_host_reset(struct scsi_cmnd *); static int qla2x00_change_queue_depth(struct scsi_device *, int, int); static int qla2x00_change_queue_type(struct scsi_device *, int); +static void qla2x00_free_device(scsi_qla_host_t *); struct scsi_host_template qla2xxx_driver_template = { .module = THIS_MODULE, -- cgit v0.10.2 From 8fbfe2d21445253411c1ff0f69e3129fc11ba57c Mon Sep 17 00:00:00 2001 From: Chad Dupuis Date: Tue, 25 Jun 2013 11:27:19 -0400 Subject: [SCSI] qla2xxx: Do not query FC statistics during chip reset. During a chip reset, the mailbox call to get FC statistics from the ISP will not work resulting in needless mailbox accesses and errors printing out: qla2xxx [0000:05:00.0]-00af:11: Performing ISP error recovery - ha=ffff881fad044800. qla2xxx [0000:05:00.0]-1020:11: **** Failed mbx[0]=4001, mb[1]=4953, mb[2]=5020, mb[3]=b100, cmd=6d ****. qla2xxx [0000:05:00.0]-1020:11: **** Failed mbx[0]=4001, mb[1]=4953, mb[2]=5020, mb[3]=b100, cmd=6d ****. qla2xxx [0000:05:00.0]-1020:11: **** Failed mbx[0]=4001, mb[1]=4953, mb[2]=5020, mb[3]=b100, cmd=6d ****. qla2xxx [0000:05:00.0]-1020:11: **** Failed mbx[0]=4001, mb[1]=4953, mb[2]=5020, mb[3]=b100, cmd=6d ****. qla2xxx [0000:05:00.0]-1020:11: **** Failed mbx[0]=4001, mb[1]=4953, mb[2]=5020, mb[3]=b100, cmd=6d ****. To prevent this, check for a chip reset when an application queries for FC stats and return immediately if a chip reset is occurring. Signed-off-by: Chad Dupuis Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index bf60c63..d7a99ae 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1691,6 +1691,9 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) if (unlikely(pci_channel_offline(ha->pdev))) goto done; + if (qla2x00_reset_active(vha)) + goto done; + stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma); if (stats == NULL) { ql_log(ql_log_warn, vha, 0x707d, @@ -1703,7 +1706,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) if (IS_FWI2_CAPABLE(ha)) { rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma); } else if (atomic_read(&base_vha->loop_state) == LOOP_READY && - !qla2x00_reset_active(vha) && !ha->dpc_active) { + !ha->dpc_active) { /* Must be in a 'READY' state for statistics retrieval. */ rval = qla2x00_get_link_status(base_vha, base_vha->loop_id, stats, stats_dma); -- cgit v0.10.2 From b8eb4136b08f24b159d76b273216d524a26ac8f9 Mon Sep 17 00:00:00 2001 From: Chad Dupuis Date: Tue, 25 Jun 2013 11:27:20 -0400 Subject: [SCSI] qla2xxx: Do not take a second firmware dump when intentionally generating one. When we are intentionally generating a firmware dump by executing the MBC_GEN_SYSTEM_ERROR command, the command actually times out. The normal course of action when a mailbox command times out is to take a firmware dump. However, in this special case we do not want to do this since the MBA_SYSTEM_ERR AEN already generates a firmware dump. Signed-off-by: Chad Dupuis Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 144effd..7257c3c 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -281,9 +281,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) /* * Attempt to capture a firmware dump for further analysis - * of the current firmware state + * of the current firmware state. We do not need to do this + * if we are intentionally generating a dump. */ - ha->isp_ops->fw_dump(vha, 0); + if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) + ha->isp_ops->fw_dump(vha, 0); rval = QLA_FUNCTION_TIMEOUT; } -- cgit v0.10.2 From 1f8deefecdda5a43961dd8062a6cab27e20af5e9 Mon Sep 17 00:00:00 2001 From: Saurav Kashyap Date: Tue, 25 Jun 2013 11:27:21 -0400 Subject: [SCSI] qla2xxx: Fix sparse warning from qla_mr.c and qla_iocb.c. Signed-off-by: Giridhar Malavali Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index c32efc7..95ca32a 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -323,7 +323,7 @@ struct srb_iocb { uint32_t lun; uint32_t data; struct completion comp; - uint32_t comp_status; + __le16 comp_status; } tmf; struct { #define SRB_FXDISC_REQ_DMA_VALID BIT_0 @@ -338,21 +338,21 @@ struct srb_iocb { void *rsp_addr; dma_addr_t req_dma_handle; dma_addr_t rsp_dma_handle; - uint32_t adapter_id; - uint32_t adapter_id_hi; - uint32_t req_func_type; - uint32_t req_data; - uint32_t req_data_extra; - uint32_t result; - uint32_t seq_number; - uint32_t fw_flags; + __le32 adapter_id; + __le32 adapter_id_hi; + __le16 req_func_type; + __le32 req_data; + __le32 req_data_extra; + __le32 result; + __le32 seq_number; + __le16 fw_flags; struct completion fxiocb_comp; - uint32_t reserved_0; + __le32 reserved_0; uint8_t reserved_1; } fxiocb; struct { uint32_t cmd_hndl; - uint32_t comp_status; + __le16 comp_status; struct completion comp; } abt; } u; @@ -1196,14 +1196,14 @@ typedef struct { struct init_cb_fx { uint16_t version; uint16_t reserved_1[13]; - uint16_t request_q_outpointer; - uint16_t response_q_inpointer; + __le16 request_q_outpointer; + __le16 response_q_inpointer; uint16_t reserved_2[2]; - uint16_t response_q_length; - uint16_t request_q_length; + __le16 response_q_length; + __le16 request_q_length; uint16_t reserved_3[2]; - uint32_t request_q_address[2]; - uint32_t response_q_address[2]; + __le32 request_q_address[2]; + __le32 response_q_address[2]; uint16_t reserved_4[4]; uint8_t response_q_msivec; uint8_t reserved_5[19]; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 026bfde..2d98232 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -587,7 +587,7 @@ extern int qlafx00_init_firmware(scsi_qla_host_t *, uint16_t); extern int qlafx00_fw_ready(scsi_qla_host_t *); extern int qlafx00_configure_devices(scsi_qla_host_t *); extern int qlafx00_reset_initialize(scsi_qla_host_t *); -extern int qlafx00_fx_disc(scsi_qla_host_t *, fc_port_t *, uint8_t); +extern int qlafx00_fx_disc(scsi_qla_host_t *, fc_port_t *, uint16_t); extern int qlafx00_process_aen(struct scsi_qla_host *, struct qla_work_evt *); extern int qlafx00_post_aenfx_work(struct scsi_qla_host *, uint32_t, uint32_t *, int); diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 0a5c895..28c38b4 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -83,7 +83,7 @@ static inline void host_to_adap(uint8_t *src, uint8_t *dst, uint32_t bsize) { uint32_t *isrc = (uint32_t *) src; - uint32_t *odest = (uint32_t *) dst; + __le32 *odest = (__le32 *) dst; uint32_t iter = bsize >> 2; for (; iter ; iter--) diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 15e4080..9de372f 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -1863,8 +1863,8 @@ skip_cmd_array: pkt = req->ring_ptr; memset(pkt, 0, REQUEST_ENTRY_SIZE); if (IS_QLAFX00(ha)) { - WRT_REG_BYTE(&pkt->entry_count, req_cnt); - WRT_REG_WORD(&pkt->handle, handle); + WRT_REG_BYTE((void __iomem *)&pkt->entry_count, req_cnt); + WRT_REG_WORD((void __iomem *)&pkt->handle, handle); } else { pkt->entry_count = req_cnt; pkt->handle = handle; diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index a6df558..d799379 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c @@ -707,7 +707,7 @@ qlafx00_tmf_iocb_timeout(void *data) srb_t *sp = (srb_t *)data; struct srb_iocb *tmf = &sp->u.iocb_cmd; - tmf->u.tmf.comp_status = CS_TIMEOUT; + tmf->u.tmf.comp_status = cpu_to_le16((uint16_t)CS_TIMEOUT); complete(&tmf->u.tmf.comp); } @@ -1418,7 +1418,8 @@ qlafx00_init_response_q_entries(struct rsp_que *rsp) pkt = rsp->ring_ptr; for (cnt = 0; cnt < rsp->length; cnt++) { pkt->signature = RESPONSE_PROCESSED; - WRT_REG_DWORD(&pkt->signature, RESPONSE_PROCESSED); + WRT_REG_DWORD((void __iomem *)&pkt->signature, + RESPONSE_PROCESSED); pkt++; } } @@ -1733,7 +1734,7 @@ qla2x00_fxdisc_sp_done(void *data, void *ptr, int res) } int -qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t fx_type) +qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type) { srb_t *sp; struct srb_iocb *fdisc; @@ -1759,13 +1760,13 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t fx_type) fdisc->u.fxiocb.flags = SRB_FXDISC_RESP_DMA_VALID | SRB_FXDISC_REQ_DWRD_VALID; fdisc->u.fxiocb.rsp_len = QLAFX00_PORT_DATA_INFO; - fdisc->u.fxiocb.req_data = fcport->port_id; + fdisc->u.fxiocb.req_data = cpu_to_le32(fcport->port_id); break; case FXDISC_GET_TGT_NODE_INFO: fdisc->u.fxiocb.flags = SRB_FXDISC_RESP_DMA_VALID | SRB_FXDISC_REQ_DWRD_VALID; fdisc->u.fxiocb.rsp_len = QLAFX00_TGT_NODE_INFO; - fdisc->u.fxiocb.req_data = fcport->tgt_id; + fdisc->u.fxiocb.req_data = cpu_to_le32(fcport->tgt_id); break; case FXDISC_GET_TGT_NODE_LIST: fdisc->u.fxiocb.flags = @@ -1851,7 +1852,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t fx_type) sp->name = "fxdisc"; qla2x00_init_timer(sp, FXDISC_TIMEOUT); fdisc->timeout = qla2x00_fxdisc_iocb_timeout; - fdisc->u.fxiocb.req_func_type = fx_type; + fdisc->u.fxiocb.req_func_type = cpu_to_le16(fx_type); sp->done = qla2x00_fxdisc_sp_done; rval = qla2x00_start_sp(sp); @@ -1904,7 +1905,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t fx_type) (uint8_t *)pinfo, 16); memcpy(vha->hw->gid_list, pinfo, QLAFX00_TGT_NODE_LIST_SIZE); } - rval = fdisc->u.fxiocb.result; + rval = le32_to_cpu(fdisc->u.fxiocb.result); done_unmap_dma: if (fdisc->u.fxiocb.rsp_addr) @@ -1927,7 +1928,7 @@ qlafx00_abort_iocb_timeout(void *data) srb_t *sp = (srb_t *)data; struct srb_iocb *abt = &sp->u.iocb_cmd; - abt->u.abt.comp_status = CS_TIMEOUT; + abt->u.abt.comp_status = cpu_to_le16((uint16_t)CS_TIMEOUT); complete(&abt->u.abt.comp); } @@ -2169,14 +2170,14 @@ qlafx00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len, static void qlafx00_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, struct tsk_mgmt_entry_fx00 *pkt, srb_t *sp, - uint16_t sstatus, uint16_t cpstatus) + __le16 sstatus, __le16 cpstatus) { struct srb_iocb *tmf; tmf = &sp->u.iocb_cmd; - if (cpstatus != CS_COMPLETE || - (sstatus & SS_RESPONSE_INFO_LEN_VALID)) - cpstatus = CS_INCOMPLETE; + if (cpstatus != cpu_to_le16((uint16_t)CS_COMPLETE) || + (sstatus & cpu_to_le16((uint16_t)SS_RESPONSE_INFO_LEN_VALID))) + cpstatus = cpu_to_le16((uint16_t)CS_INCOMPLETE); tmf->u.tmf.comp_status = cpstatus; sp->done(vha, sp, 0); } @@ -2194,7 +2195,7 @@ qlafx00_abort_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, return; abt = &sp->u.iocb_cmd; - abt->u.abt.comp_status = le32_to_cpu(pkt->tgt_id_sts); + abt->u.abt.comp_status = pkt->tgt_id_sts; sp->done(vha, sp, 0); } @@ -2216,12 +2217,12 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req, if (sp->type == SRB_FXIOCB_DCMD) { iocb_job = &sp->u.iocb_cmd; - iocb_job->u.fxiocb.seq_number = le32_to_cpu(pkt->seq_no); - iocb_job->u.fxiocb.fw_flags = le32_to_cpu(pkt->fw_iotcl_flags); - iocb_job->u.fxiocb.result = le32_to_cpu(pkt->status); + iocb_job->u.fxiocb.seq_number = pkt->seq_no; + iocb_job->u.fxiocb.fw_flags = pkt->fw_iotcl_flags; + iocb_job->u.fxiocb.result = pkt->status; if (iocb_job->u.fxiocb.flags & SRB_FXDISC_RSP_DWRD_VALID) iocb_job->u.fxiocb.req_data = - le32_to_cpu(pkt->dataword_r); + pkt->dataword_r; } else { bsg_job = sp->u.bsg_job; @@ -2275,10 +2276,10 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) fc_port_t *fcport; struct scsi_cmnd *cp; struct sts_entry_fx00 *sts; - uint16_t comp_status; - uint16_t scsi_status; + __le16 comp_status; + __le16 scsi_status; uint16_t ox_id; - uint8_t lscsi_status; + __le16 lscsi_status; int32_t resid; uint32_t sense_len, par_sense_len, rsp_info_len, resid_len, fw_resid_len; @@ -2292,8 +2293,8 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) sts = (struct sts_entry_fx00 *) pkt; - comp_status = le16_to_cpu(sts->comp_status); - scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK; + comp_status = sts->comp_status; + scsi_status = sts->scsi_status & cpu_to_le16((uint16_t)SS_MASK); hindex = sts->handle; handle = LSW(hindex); @@ -2339,38 +2340,40 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) return; } - lscsi_status = scsi_status & STATUS_MASK; + lscsi_status = scsi_status & cpu_to_le16((uint16_t)STATUS_MASK); fcport = sp->fcport; ox_id = 0; sense_len = par_sense_len = rsp_info_len = resid_len = fw_resid_len = 0; - if (scsi_status & SS_SENSE_LEN_VALID) - sense_len = le32_to_cpu(sts->sense_len); - if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) + if (scsi_status & cpu_to_le16((uint16_t)SS_SENSE_LEN_VALID)) + sense_len = sts->sense_len; + if (scsi_status & cpu_to_le16(((uint16_t)SS_RESIDUAL_UNDER + | (uint16_t)SS_RESIDUAL_OVER))) resid_len = le32_to_cpu(sts->residual_len); - if (comp_status == CS_DATA_UNDERRUN) + if (comp_status == cpu_to_le16((uint16_t)CS_DATA_UNDERRUN)) fw_resid_len = le32_to_cpu(sts->residual_len); rsp_info = sense_data = sts->data; par_sense_len = sizeof(sts->data); /* Check for overrun. */ if (comp_status == CS_COMPLETE && - scsi_status & SS_RESIDUAL_OVER) - comp_status = CS_DATA_OVERRUN; + scsi_status & cpu_to_le16((uint16_t)SS_RESIDUAL_OVER)) + comp_status = cpu_to_le16((uint16_t)CS_DATA_OVERRUN); /* * Based on Host and scsi status generate status code for Linux */ - switch (comp_status) { + switch (le16_to_cpu(comp_status)) { case CS_COMPLETE: case CS_QUEUE_FULL: if (scsi_status == 0) { res = DID_OK << 16; break; } - if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) { + if (scsi_status & cpu_to_le16(((uint16_t)SS_RESIDUAL_UNDER + | (uint16_t)SS_RESIDUAL_OVER))) { resid = resid_len; scsi_set_resid(cp, resid); @@ -2386,19 +2389,20 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) break; } } - res = DID_OK << 16 | lscsi_status; + res = DID_OK << 16 | le16_to_cpu(lscsi_status); - if (lscsi_status == SAM_STAT_TASK_SET_FULL) { + if (lscsi_status == + cpu_to_le16((uint16_t)SAM_STAT_TASK_SET_FULL)) { ql_dbg(ql_dbg_io, fcport->vha, 0x3051, "QUEUE FULL detected.\n"); break; } logit = 0; - if (lscsi_status != SS_CHECK_CONDITION) + if (lscsi_status != cpu_to_le16((uint16_t)SS_CHECK_CONDITION)) break; memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); - if (!(scsi_status & SS_SENSE_LEN_VALID)) + if (!(scsi_status & cpu_to_le16((uint16_t)SS_SENSE_LEN_VALID))) break; qlafx00_handle_sense(sp, sense_data, par_sense_len, sense_len, @@ -2412,7 +2416,7 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) else resid = resid_len; scsi_set_resid(cp, resid); - if (scsi_status & SS_RESIDUAL_UNDER) { + if (scsi_status & cpu_to_le16((uint16_t)SS_RESIDUAL_UNDER)) { if ((IS_FWI2_CAPABLE(ha) || IS_QLAFX00(ha)) && fw_resid_len != resid_len) { ql_dbg(ql_dbg_io, fcport->vha, 0x3052, @@ -2420,7 +2424,8 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) "(0x%x of 0x%x bytes).\n", resid, scsi_bufflen(cp)); - res = DID_ERROR << 16 | lscsi_status; + res = DID_ERROR << 16 | + le16_to_cpu(lscsi_status); goto check_scsi_status; } @@ -2436,8 +2441,9 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) res = DID_ERROR << 16; break; } - } else if (lscsi_status != SAM_STAT_TASK_SET_FULL && - lscsi_status != SAM_STAT_BUSY) { + } else if (lscsi_status != + cpu_to_le16((uint16_t)SAM_STAT_TASK_SET_FULL) && + lscsi_status != cpu_to_le16((uint16_t)SAM_STAT_BUSY)) { /* * scsi status of task set and busy are considered * to be task not completed. @@ -2448,7 +2454,7 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) "of 0x%x bytes).\n", resid, scsi_bufflen(cp)); - res = DID_ERROR << 16 | lscsi_status; + res = DID_ERROR << 16 | le16_to_cpu(lscsi_status); goto check_scsi_status; } else { ql_dbg(ql_dbg_io, fcport->vha, 0x3055, @@ -2456,7 +2462,7 @@ qlafx00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) scsi_status, lscsi_status); } - res = DID_OK << 16 | lscsi_status; + res = DID_OK << 16 | le16_to_cpu(lscsi_status); logit = 0; check_scsi_status: @@ -2465,17 +2471,20 @@ check_scsi_status: * Status. */ if (lscsi_status != 0) { - if (lscsi_status == SAM_STAT_TASK_SET_FULL) { + if (lscsi_status == + cpu_to_le16((uint16_t)SAM_STAT_TASK_SET_FULL)) { ql_dbg(ql_dbg_io, fcport->vha, 0x3056, "QUEUE FULL detected.\n"); logit = 1; break; } - if (lscsi_status != SS_CHECK_CONDITION) + if (lscsi_status != + cpu_to_le16((uint16_t)SS_CHECK_CONDITION)) break; memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); - if (!(scsi_status & SS_SENSE_LEN_VALID)) + if (!(scsi_status & + cpu_to_le16((uint16_t)SS_SENSE_LEN_VALID))) break; qlafx00_handle_sense(sp, sense_data, par_sense_len, @@ -2629,7 +2638,7 @@ qlafx00_multistatus_entry(struct scsi_qla_host *vha, uint32_t handle, hindex, handle_count, i; uint16_t que; struct req_que *req; - uint32_t *handle_ptr; + __le32 *handle_ptr; stsmfx = (struct multi_sts_entry_fx00 *) pkt; @@ -2643,7 +2652,7 @@ qlafx00_multistatus_entry(struct scsi_qla_host *vha, return; } - handle_ptr = (uint32_t *) &stsmfx->handles[0]; + handle_ptr = &stsmfx->handles[0]; for (i = 0; i < handle_count; i++) { hindex = le32_to_cpu(*handle_ptr); @@ -2714,10 +2723,11 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha, if (!vha->flags.online) return; - while (RD_REG_DWORD(&(rsp->ring_ptr->signature)) != + while (RD_REG_DWORD((void __iomem *)&(rsp->ring_ptr->signature)) != RESPONSE_PROCESSED) { lptr = rsp->ring_ptr; - memcpy_fromio(rsp->rsp_pkt, lptr, sizeof(rsp->rsp_pkt)); + memcpy_fromio(rsp->rsp_pkt, (void __iomem *)lptr, + sizeof(rsp->rsp_pkt)); pkt = (struct sts_entry_fx00 *)rsp->rsp_pkt; rsp->ring_index++; @@ -2768,7 +2778,8 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha, break; } next_iter: - WRT_REG_DWORD(&lptr->signature, RESPONSE_PROCESSED); + WRT_REG_DWORD((void __iomem *)&lptr->signature, + RESPONSE_PROCESSED); wmb(); } @@ -2958,8 +2969,7 @@ qlafx00_prep_cont_type1_iocb(struct req_que *req, cont_pkt = (cont_a64_entry_t *)req->ring_ptr; /* Load packet defaults. */ - *((uint32_t *)(&lcont_pkt->entry_type)) = - __constant_cpu_to_le32(CONTINUE_A64_TYPE_FX00); + lcont_pkt->entry_type = CONTINUE_A64_TYPE_FX00; return cont_pkt; } @@ -2969,7 +2979,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt, uint16_t tot_dsds, struct cmd_type_7_fx00 *lcmd_pkt) { uint16_t avail_dsds; - uint32_t *cur_dsd; + __le32 *cur_dsd; scsi_qla_host_t *vha; struct scsi_cmnd *cmd; struct scatterlist *sg; @@ -2986,8 +2996,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt, cont_pkt = NULL; /* Update entry type to indicate Command Type 3 IOCB */ - *((uint32_t *)(&lcmd_pkt->entry_type)) = - __constant_cpu_to_le32(FX00_COMMAND_TYPE_7); + lcmd_pkt->entry_type = FX00_COMMAND_TYPE_7; /* No data transfer */ if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) { @@ -3006,7 +3015,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt, /* One DSD is available in the Command Type 3 IOCB */ avail_dsds = 1; - cur_dsd = (uint32_t *)&lcmd_pkt->dseg_0_address; + cur_dsd = (__le32 *)&lcmd_pkt->dseg_0_address; /* Load data segments */ scsi_for_each_sg(cmd, sg, tot_dsds, i) { @@ -3021,7 +3030,7 @@ qlafx00_build_scsi_iocbs(srb_t *sp, struct cmd_type_7_fx00 *cmd_pkt, memset(&lcont_pkt, 0, REQUEST_ENTRY_SIZE); cont_pkt = qlafx00_prep_cont_type1_iocb(req, &lcont_pkt); - cur_dsd = (uint32_t *)lcont_pkt.dseg_0_address; + cur_dsd = (__le32 *)lcont_pkt.dseg_0_address; avail_dsds = 5; cont = 1; } @@ -3224,13 +3233,13 @@ qlafx00_tm_iocb(srb_t *sp, struct tsk_mgmt_entry_fx00 *ptm_iocb) tm_iocb.timeout = cpu_to_le16(qla2x00_get_async_timeout(vha) + 2); tm_iocb.tgt_id = cpu_to_le16(sp->fcport->tgt_id); tm_iocb.control_flags = cpu_to_le32(fxio->u.tmf.flags); - if (tm_iocb.control_flags == TCF_LUN_RESET) { + if (tm_iocb.control_flags == cpu_to_le32((uint32_t)TCF_LUN_RESET)) { int_to_scsilun(fxio->u.tmf.lun, &llun); host_to_adap((uint8_t *)&llun, (uint8_t *)&tm_iocb.lun, sizeof(struct scsi_lun)); } - memcpy((void __iomem *)ptm_iocb, &tm_iocb, + memcpy((void *)ptm_iocb, &tm_iocb, sizeof(struct tsk_mgmt_entry_fx00)); wmb(); } @@ -3252,7 +3261,7 @@ qlafx00_abort_iocb(srb_t *sp, struct abort_iocb_entry_fx00 *pabt_iocb) abt_iocb.tgt_id_sts = cpu_to_le16(sp->fcport->tgt_id); abt_iocb.req_que_no = cpu_to_le16(req->id); - memcpy((void __iomem *)pabt_iocb, &abt_iocb, + memcpy((void *)pabt_iocb, &abt_iocb, sizeof(struct abort_iocb_entry_fx00)); wmb(); } @@ -3273,13 +3282,12 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) if (sp->type == SRB_FXIOCB_DCMD) { fx_iocb.func_num = - cpu_to_le16(sp->u.iocb_cmd.u.fxiocb.req_func_type); - fx_iocb.adapid = cpu_to_le32(fxio->u.fxiocb.adapter_id); - fx_iocb.adapid_hi = cpu_to_le32(fxio->u.fxiocb.adapter_id_hi); - fx_iocb.reserved_0 = cpu_to_le32(fxio->u.fxiocb.reserved_0); - fx_iocb.reserved_1 = cpu_to_le32(fxio->u.fxiocb.reserved_1); - fx_iocb.dataword_extra = - cpu_to_le32(fxio->u.fxiocb.req_data_extra); + sp->u.iocb_cmd.u.fxiocb.req_func_type; + fx_iocb.adapid = fxio->u.fxiocb.adapter_id; + fx_iocb.adapid_hi = fxio->u.fxiocb.adapter_id_hi; + fx_iocb.reserved_0 = fxio->u.fxiocb.reserved_0; + fx_iocb.reserved_1 = fxio->u.fxiocb.reserved_1; + fx_iocb.dataword_extra = fxio->u.fxiocb.req_data_extra; if (fxio->u.fxiocb.flags & SRB_FXDISC_REQ_DMA_VALID) { fx_iocb.req_dsdcnt = cpu_to_le16(1); @@ -3306,8 +3314,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) } if (fxio->u.fxiocb.flags & SRB_FXDISC_REQ_DWRD_VALID) { - fx_iocb.dataword = - cpu_to_le32(fxio->u.fxiocb.req_data); + fx_iocb.dataword = fxio->u.fxiocb.req_data; } fx_iocb.flags = fxio->u.fxiocb.flags; } else { @@ -3323,21 +3330,21 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) fx_iocb.reserved_1 = piocb_rqst->reserved_1; fx_iocb.dataword_extra = piocb_rqst->dataword_extra; fx_iocb.dataword = piocb_rqst->dataword; - fx_iocb.req_xfrcnt = cpu_to_le16(piocb_rqst->req_len); - fx_iocb.rsp_xfrcnt = cpu_to_le16(piocb_rqst->rsp_len); + fx_iocb.req_xfrcnt = piocb_rqst->req_len; + fx_iocb.rsp_xfrcnt = piocb_rqst->rsp_len; if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID) { int avail_dsds, tot_dsds; cont_a64_entry_t lcont_pkt; cont_a64_entry_t *cont_pkt = NULL; - uint32_t *cur_dsd; + __le32 *cur_dsd; int index = 0, cont = 0; fx_iocb.req_dsdcnt = cpu_to_le16(bsg_job->request_payload.sg_cnt); tot_dsds = - cpu_to_le32(bsg_job->request_payload.sg_cnt); - cur_dsd = (uint32_t *)&fx_iocb.dseg_rq_address[0]; + bsg_job->request_payload.sg_cnt; + cur_dsd = (__le32 *)&fx_iocb.dseg_rq_address[0]; avail_dsds = 1; for_each_sg(bsg_job->request_payload.sg_list, sg, tot_dsds, index) { @@ -3355,7 +3362,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) qlafx00_prep_cont_type1_iocb( sp->fcport->vha->req, &lcont_pkt); - cur_dsd = (uint32_t *) + cur_dsd = (__le32 *) lcont_pkt.dseg_0_address; avail_dsds = 5; cont = 1; @@ -3393,13 +3400,13 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) int avail_dsds, tot_dsds; cont_a64_entry_t lcont_pkt; cont_a64_entry_t *cont_pkt = NULL; - uint32_t *cur_dsd; + __le32 *cur_dsd; int index = 0, cont = 0; fx_iocb.rsp_dsdcnt = cpu_to_le16(bsg_job->reply_payload.sg_cnt); - tot_dsds = cpu_to_le32(bsg_job->reply_payload.sg_cnt); - cur_dsd = (uint32_t *)&fx_iocb.dseg_rsp_address[0]; + tot_dsds = bsg_job->reply_payload.sg_cnt; + cur_dsd = (__le32 *)&fx_iocb.dseg_rsp_address[0]; avail_dsds = 1; for_each_sg(bsg_job->reply_payload.sg_list, sg, @@ -3418,7 +3425,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) qlafx00_prep_cont_type1_iocb( sp->fcport->vha->req, &lcont_pkt); - cur_dsd = (uint32_t *) + cur_dsd = (__le32 *) lcont_pkt.dseg_0_address; avail_dsds = 5; cont = 1; @@ -3453,7 +3460,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) } if (piocb_rqst->flags & SRB_FXDISC_REQ_DWRD_VALID) - fx_iocb.dataword = cpu_to_le32(piocb_rqst->dataword); + fx_iocb.dataword = piocb_rqst->dataword; fx_iocb.flags = piocb_rqst->flags; fx_iocb.entry_count = entry_cnt; } @@ -3462,7 +3469,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) sp->fcport->vha, 0x3047, (uint8_t *)&fx_iocb, sizeof(struct fxdisc_entry_fx00)); - memcpy((void __iomem *)pfxiocb, &fx_iocb, + memcpy((void *)pfxiocb, &fx_iocb, sizeof(struct fxdisc_entry_fx00)); wmb(); } diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h index cc327dc..1a092af 100644 --- a/drivers/scsi/qla2xxx/qla_mr.h +++ b/drivers/scsi/qla2xxx/qla_mr.h @@ -24,10 +24,10 @@ struct cmd_type_7_fx00 { uint32_t handle; /* System handle. */ uint32_t handle_hi; - uint16_t tgt_idx; /* Target Idx. */ + __le16 tgt_idx; /* Target Idx. */ uint16_t timeout; /* Command timeout. */ - uint16_t dseg_count; /* Data segment count. */ + __le16 dseg_count; /* Data segment count. */ uint16_t scsi_rsp_dsd_len; struct scsi_lun lun; /* LUN (LE). */ @@ -41,7 +41,7 @@ struct cmd_type_7_fx00 { uint8_t crn; uint8_t fcp_cdb[MAX_CMDSZ]; /* SCSI command words. */ - uint32_t byte_count; /* Total byte count. */ + __le32 byte_count; /* Total byte count. */ uint32_t dseg_0_address[2]; /* Data segment 0 address. */ uint32_t dseg_0_len; /* Data segment 0 length. */ @@ -81,16 +81,16 @@ struct sts_entry_fx00 { uint32_t handle; /* System handle. */ uint32_t handle_hi; /* System handle. */ - uint16_t comp_status; /* Completion status. */ + __le16 comp_status; /* Completion status. */ uint16_t reserved_0; /* OX_ID used by the firmware. */ - uint32_t residual_len; /* FW calc residual transfer length. */ + __le32 residual_len; /* FW calc residual transfer length. */ uint16_t reserved_1; uint16_t state_flags; /* State flags. */ uint16_t reserved_2; - uint16_t scsi_status; /* SCSI status. */ + __le16 scsi_status; /* SCSI status. */ uint32_t sense_len; /* FCP SENSE length. */ uint8_t data[32]; /* FCP response/sense information. */ @@ -106,7 +106,7 @@ struct multi_sts_entry_fx00 { uint8_t handle_count; uint8_t entry_status; - uint32_t handles[MAX_HANDLE_COUNT]; + __le32 handles[MAX_HANDLE_COUNT]; }; #define TSK_MGMT_IOCB_TYPE_FX00 0x05 @@ -116,21 +116,21 @@ struct tsk_mgmt_entry_fx00 { uint8_t sys_define; uint8_t entry_status; /* Entry Status. */ - uint32_t handle; /* System handle. */ + __le32 handle; /* System handle. */ uint32_t handle_hi; /* System handle. */ - uint16_t tgt_id; /* Target Idx. */ + __le16 tgt_id; /* Target Idx. */ uint16_t reserved_1; uint16_t delay; /* Activity delay in seconds. */ - uint16_t timeout; /* Command timeout. */ + __le16 timeout; /* Command timeout. */ struct scsi_lun lun; /* LUN (LE). */ - uint32_t control_flags; /* Control Flags. */ + __le32 control_flags; /* Control Flags. */ uint8_t reserved_2[32]; }; @@ -143,16 +143,16 @@ struct abort_iocb_entry_fx00 { uint8_t sys_define; /* System defined. */ uint8_t entry_status; /* Entry Status. */ - uint32_t handle; /* System handle. */ - uint32_t handle_hi; /* System handle. */ + __le32 handle; /* System handle. */ + __le32 handle_hi; /* System handle. */ - uint16_t tgt_id_sts; /* Completion status. */ - uint16_t options; + __le16 tgt_id_sts; /* Completion status. */ + __le16 options; - uint32_t abort_handle; /* System handle. */ - uint32_t abort_handle_hi; /* System handle. */ + __le32 abort_handle; /* System handle. */ + __le32 abort_handle_hi; /* System handle. */ - uint16_t req_que_no; + __le16 req_que_no; uint8_t reserved_1[38]; }; @@ -167,17 +167,17 @@ struct ioctl_iocb_entry_fx00 { uint32_t reserved_0; /* System handle. */ uint16_t comp_func_num; - uint16_t fw_iotcl_flags; + __le16 fw_iotcl_flags; - uint32_t dataword_r; /* Data word returned */ + __le32 dataword_r; /* Data word returned */ uint32_t adapid; /* Adapter ID */ uint32_t adapid_hi; /* Adapter ID high */ uint32_t reserved_1; - uint32_t seq_no; + __le32 seq_no; uint8_t reserved_2[20]; uint32_t residuallen; - uint32_t status; + __le32 status; }; #define STATUS_CONT_TYPE_FX00 0x04 @@ -189,26 +189,26 @@ struct fxdisc_entry_fx00 { uint8_t sys_define; /* System Defined. */ uint8_t entry_status; /* Entry Status. */ - uint32_t handle; /* System handle. */ - uint32_t reserved_0; /* System handle. */ + __le32 handle; /* System handle. */ + __le32 reserved_0; /* System handle. */ - uint16_t func_num; - uint16_t req_xfrcnt; - uint16_t req_dsdcnt; - uint16_t rsp_xfrcnt; - uint16_t rsp_dsdcnt; + __le16 func_num; + __le16 req_xfrcnt; + __le16 req_dsdcnt; + __le16 rsp_xfrcnt; + __le16 rsp_dsdcnt; uint8_t flags; uint8_t reserved_1; - uint32_t dseg_rq_address[2]; /* Data segment 0 address. */ - uint32_t dseg_rq_len; /* Data segment 0 length. */ - uint32_t dseg_rsp_address[2]; /* Data segment 1 address. */ - uint32_t dseg_rsp_len; /* Data segment 1 length. */ + __le32 dseg_rq_address[2]; /* Data segment 0 address. */ + __le32 dseg_rq_len; /* Data segment 0 length. */ + __le32 dseg_rsp_address[2]; /* Data segment 1 address. */ + __le32 dseg_rsp_len; /* Data segment 1 length. */ - uint32_t dataword; - uint32_t adapid; - uint32_t adapid_hi; - uint32_t dataword_extra; + __le32 dataword; + __le32 adapid; + __le32 adapid_hi; + __le32 dataword_extra; }; struct qlafx00_tgt_node_info { @@ -421,43 +421,43 @@ struct config_info_data { WRT_REG_DWORD((ha)->cregbase + off, val) struct qla_mt_iocb_rqst_fx00 { - uint32_t reserved_0; + __le32 reserved_0; - uint16_t func_type; + __le16 func_type; uint8_t flags; uint8_t reserved_1; - uint32_t dataword; + __le32 dataword; - uint32_t adapid; - uint32_t adapid_hi; + __le32 adapid; + __le32 adapid_hi; - uint32_t dataword_extra; + __le32 dataword_extra; - uint32_t req_len; + __le32 req_len; - uint32_t rsp_len; + __le32 rsp_len; }; struct qla_mt_iocb_rsp_fx00 { uint32_t reserved_1; uint16_t func_type; - uint16_t ioctl_flags; + __le16 ioctl_flags; - uint32_t ioctl_data; + __le32 ioctl_data; uint32_t adapid; uint32_t adapid_hi; uint32_t reserved_2; - uint32_t seq_number; + __le32 seq_number; uint8_t reserved_3[20]; int32_t res_count; - uint32_t status; + __le32 status; }; -- cgit v0.10.2 From 090fc2e2cf6a2763f609af6f128a812d5051d935 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 11:27:22 -0400 Subject: [SCSI] qla2xxx: Clean up qla24xx_iidma() Remove dead code and simplify a pointer computation. Signed-off-by: Bart Van Assche Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 5ba0cc1..9a30b69 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -1282,14 +1282,7 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job) return -EINVAL; } - port_param = (struct qla_port_param *)((char *)bsg_job->request + - sizeof(struct fc_bsg_request)); - if (!port_param) { - ql_log(ql_log_warn, vha, 0x7047, - "port_param header not provided.\n"); - return -EINVAL; - } - + port_param = (void *)bsg_job->request + sizeof(struct fc_bsg_request); if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) { ql_log(ql_log_warn, vha, 0x7048, "Invalid destination type.\n"); diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 3cc2105..91a1166 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -35,7 +35,8 @@ * | | | 0x70a5,0x70a6, | * | | | 0x70a8,0x70ab, | * | | | 0x70ad-0x70ae, | - * | | | 0x70d1-0x70da | + * | | | 0x70d1-0x70da, | + * | | | 0x7047 | * | Task Management | 0x803c | 0x8025-0x8026 | * | | | 0x800b,0x8039 | * | AER/EEH | 0x9011 | | -- cgit v0.10.2 From a44c72f309224973ffc7c7dfeee6e354c6f3d739 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 11:27:23 -0400 Subject: [SCSI] qla2xxx: Clean up qla84xx_mgmt_cmd() Remove dead code, simplify a pointer computation and move the ql84_mgmt assignment to just before its first use. Signed-off-by: Bart Van Assche Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 9a30b69..b85f002 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -1084,14 +1084,6 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job) return -EINVAL; } - ql84_mgmt = (struct qla_bsg_a84_mgmt *)((char *)bsg_job->request + - sizeof(struct fc_bsg_request)); - if (!ql84_mgmt) { - ql_log(ql_log_warn, vha, 0x703b, - "MGMT header not provided, exiting.\n"); - return -EINVAL; - } - mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); if (!mn) { ql_log(ql_log_warn, vha, 0x703c, @@ -1102,7 +1094,7 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job) memset(mn, 0, sizeof(struct access_chip_84xx)); mn->entry_type = ACCESS_CHIP_IOCB_TYPE; mn->entry_count = 1; - + ql84_mgmt = (void *)bsg_job->request + sizeof(struct fc_bsg_request); switch (ql84_mgmt->mgmt.cmd) { case QLA84_MGMT_READ_MEM: case QLA84_MGMT_GET_INFO: diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 91a1166..74a2121 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -36,7 +36,7 @@ * | | | 0x70a8,0x70ab, | * | | | 0x70ad-0x70ae, | * | | | 0x70d1-0x70da, | - * | | | 0x7047 | + * | | | 0x7047,0x703b | * | Task Management | 0x803c | 0x8025-0x8026 | * | | | 0x800b,0x8039 | * | AER/EEH | 0x9011 | | -- cgit v0.10.2 From 6593d5bdbdb26d848ac5afa469cdca7abd3298df Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 11:27:24 -0400 Subject: [SCSI] qla2xxx: Remove dead code in qla2x00_configure_hba() At the end of qla2x00_configure_hba() we know that rval == QLA_SUCCESS. Hence remove the dead code. Signed-off-by: Bart Van Assche Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 74a2121..91dbd81 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -15,6 +15,7 @@ * | Mailbox commands | 0x117a | 0x111a-0x111b | * | | | 0x1155-0x1158 | * | Device Discovery | 0x2095 | 0x2020-0x2022, | + * | | | 0x2011-0x2012, | * | | | 0x2016 | * | Queue Command and IO tracing | 0x3058 | 0x3006-0x300b | * | | | 0x3027-0x3028 | diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 3565dfd..f2216ed 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2309,14 +2309,6 @@ qla2x00_configure_hba(scsi_qla_host_t *vha) "Topology - %s, Host Loop address 0x%x.\n", connect_type, vha->loop_id); - if (rval) { - ql_log(ql_log_warn, vha, 0x2011, - "%s FAILED\n", __func__); - } else { - ql_dbg(ql_dbg_disc, vha, 0x2012, - "%s success\n", __func__); - } - return(rval); } -- cgit v0.10.2 From c5dcfaac943da1a2981e7488f74b0d4259fbb43f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 11:27:25 -0400 Subject: [SCSI] qla2xxx: Remove two superfluous tests. Since ha->model_desc is an array comparing it against NULL is superfluous. Hence remove these tests. Signed-off-by: Bart Van Assche Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index d0ea8b9..f26442a 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -1370,8 +1370,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *vha) /* Model description. */ eiter = (struct ct_fdmi_hba_attr *) (entries + size); eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); - if (ha->model_desc) - strncpy(eiter->a.model_desc, ha->model_desc, 80); + strncpy(eiter->a.model_desc, ha->model_desc, 80); alen = strlen(eiter->a.model_desc); alen += (alen & 3) ? (4 - (alen & 3)) : 4; eiter->len = cpu_to_be16(4 + alen); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c2e2e20..6df5223 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2839,8 +2839,7 @@ skip_dpc: qla2x00_dfs_setup(base_vha); ql_log(ql_log_info, base_vha, 0x00fb, - "QLogic %s - %s.\n", - ha->model_number, ha->model_desc ? ha->model_desc : ""); + "QLogic %s - %s.\n", ha->model_number, ha->model_desc); ql_log(ql_log_info, base_vha, 0x00fc, "ISP%04X: %s @ %s hdma%c host#=%ld fw=%s.\n", pdev->device, ha->isp_ops->pci_info_str(base_vha, pci_info), -- cgit v0.10.2 From 4e541debb8f8746bd61f41cbb129ce9c6987b9d8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 11:27:26 -0400 Subject: [SCSI] qla2xxx: Remove a dead assignment in qla24xx_build_scsi_crc_2_iocbs(). Since the value of cur_seg is not used and since scsi_prot_sglist() has no side effects it is safe to remove the statement "cur_seg = scsi_port_sglist(cmd)". Detected by Coverity. Signed-off-by: Bart Van Assche Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 9de372f..42ef481 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -1189,7 +1189,6 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, uint32_t *cur_dsd, *fcp_dl; scsi_qla_host_t *vha; struct scsi_cmnd *cmd; - struct scatterlist *cur_seg; int sgc; uint32_t total_bytes = 0; uint32_t data_bytes; @@ -1396,7 +1395,6 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, if (bundling && tot_prot_dsds) { /* Walks dif segments */ - cur_seg = scsi_prot_sglist(cmd); cmd_pkt->control_flags |= __constant_cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE); cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address; -- cgit v0.10.2 From 7f544d00698282655c7abed2262a39f5d9fe9283 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 11:27:27 -0400 Subject: [SCSI] qla2xxx: Remove redundant assignments. The value of the pointer called "nxt" is not used after the "nxt = qla24xx_copy_eft(ha, nxt)" statement. Hence keep the function call but remove the assignment. Signed-off-by: Bart Van Assche Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 91dbd81..df132fe 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -1470,7 +1470,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) nxt = qla2xxx_copy_queues(ha, nxt); - nxt = qla24xx_copy_eft(ha, nxt); + qla24xx_copy_eft(ha, nxt); /* Chain entries -- started with MQ. */ nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); @@ -1789,7 +1789,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) nxt = qla2xxx_copy_queues(ha, nxt); - nxt = qla24xx_copy_eft(ha, nxt); + qla24xx_copy_eft(ha, nxt); /* Chain entries -- started with MQ. */ nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); @@ -2291,7 +2291,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) copy_queue: nxt = qla2xxx_copy_queues(ha, nxt); - nxt = qla24xx_copy_eft(ha, nxt); + qla24xx_copy_eft(ha, nxt); /* Chain entries -- started with MQ. */ nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); -- cgit v0.10.2 From 6ec6f9094a76aa9e732ede2add6cf32d0c2206e3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 11:27:28 -0400 Subject: [SCSI] qla2xxx: Help Coverity with analyzing ct_sns_pkt initialization. Coverity reports "Overrunning struct type ct_sns_req of 1228 bytes by passing it to a function which accesses it at byte offset 8207" for each qla2x00_prep_ct_req(), qla2x00_prep_ct_fdmi_req() and qla24xx_prep_ct_fm_req() call. Help Coverity to recognize that these calls do not trigger a buffer overflow by making it explicit that these three functions initializes both the request and reply structures. This patch does not change any functionality. Signed-off-by: Bart Van Assche Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index f26442a..0926451 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -99,17 +99,17 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, uint32_t req_size, uint32_t rsp_size) * Returns a pointer to the intitialized @ct_req. */ static inline struct ct_sns_req * -qla2x00_prep_ct_req(struct ct_sns_req *ct_req, uint16_t cmd, uint16_t rsp_size) +qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size) { - memset(ct_req, 0, sizeof(struct ct_sns_pkt)); + memset(p, 0, sizeof(struct ct_sns_pkt)); - ct_req->header.revision = 0x01; - ct_req->header.gs_type = 0xFC; - ct_req->header.gs_subtype = 0x02; - ct_req->command = cpu_to_be16(cmd); - ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); + p->p.req.header.revision = 0x01; + p->p.req.header.gs_type = 0xFC; + p->p.req.header.gs_subtype = 0x02; + p->p.req.command = cpu_to_be16(cmd); + p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); - return (ct_req); + return &p->p.req; } static int @@ -188,7 +188,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) GA_NXT_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD, + ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD, GA_NXT_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; @@ -284,8 +284,7 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) gid_pt_rsp_size); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD, - gid_pt_rsp_size); + ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size); ct_rsp = &ha->ct_sns->p.rsp; /* Prepare CT arguments -- port_type */ @@ -359,7 +358,7 @@ qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) GPN_ID_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GPN_ID_CMD, + ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; @@ -421,7 +420,7 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) GNN_ID_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GNN_ID_CMD, + ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD, GNN_ID_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; @@ -495,7 +494,7 @@ qla2x00_rft_id(scsi_qla_host_t *vha) RFT_ID_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD, + ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFT_ID_CMD, RFT_ID_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; @@ -551,7 +550,7 @@ qla2x00_rff_id(scsi_qla_host_t *vha) RFF_ID_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD, + ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFF_ID_CMD, RFF_ID_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; @@ -606,8 +605,7 @@ qla2x00_rnn_id(scsi_qla_host_t *vha) RNN_ID_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD, - RNN_ID_RSP_SIZE); + ct_req = qla2x00_prep_ct_req(ha->ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; /* Prepare CT arguments -- port_id, node_name */ @@ -676,7 +674,7 @@ qla2x00_rsnn_nn(scsi_qla_host_t *vha) ms_pkt = ha->isp_ops->prep_ms_iocb(vha, 0, RSNN_NN_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD, + ct_req = qla2x00_prep_ct_req(ha->ct_sns, RSNN_NN_CMD, RSNN_NN_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; @@ -1262,18 +1260,18 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size) * Returns a pointer to the intitialized @ct_req. */ static inline struct ct_sns_req * -qla2x00_prep_ct_fdmi_req(struct ct_sns_req *ct_req, uint16_t cmd, +qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size) { - memset(ct_req, 0, sizeof(struct ct_sns_pkt)); + memset(p, 0, sizeof(struct ct_sns_pkt)); - ct_req->header.revision = 0x01; - ct_req->header.gs_type = 0xFA; - ct_req->header.gs_subtype = 0x10; - ct_req->command = cpu_to_be16(cmd); - ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); + p->p.req.header.revision = 0x01; + p->p.req.header.gs_type = 0xFA; + p->p.req.header.gs_subtype = 0x10; + p->p.req.command = cpu_to_be16(cmd); + p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); - return ct_req; + return &p->p.req; } /** @@ -1301,8 +1299,7 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *vha) ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD, - RHBA_RSP_SIZE); + ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; /* Prepare FDMI command arguments -- attribute block, attributes. */ @@ -1490,8 +1487,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *vha) DHBA_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD, - DHBA_RSP_SIZE); + ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; /* Prepare FDMI command arguments -- portname. */ @@ -1547,8 +1543,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha) ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD, - RPA_RSP_SIZE); + ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; /* Prepare FDMI command arguments -- attribute block, attributes. */ @@ -1775,7 +1770,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list) GFPN_ID_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFPN_ID_CMD, + ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD, GFPN_ID_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; @@ -1842,18 +1837,18 @@ qla24xx_prep_ms_fm_iocb(scsi_qla_host_t *vha, uint32_t req_size, static inline struct ct_sns_req * -qla24xx_prep_ct_fm_req(struct ct_sns_req *ct_req, uint16_t cmd, +qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size) { - memset(ct_req, 0, sizeof(struct ct_sns_pkt)); + memset(p, 0, sizeof(struct ct_sns_pkt)); - ct_req->header.revision = 0x01; - ct_req->header.gs_type = 0xFA; - ct_req->header.gs_subtype = 0x01; - ct_req->command = cpu_to_be16(cmd); - ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); + p->p.req.header.revision = 0x01; + p->p.req.header.gs_type = 0xFA; + p->p.req.header.gs_subtype = 0x01; + p->p.req.command = cpu_to_be16(cmd); + p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); - return ct_req; + return &p->p.req; } /** @@ -1889,8 +1884,8 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list) GPSC_RSP_SIZE); /* Prepare CT request */ - ct_req = qla24xx_prep_ct_fm_req(&ha->ct_sns->p.req, - GPSC_CMD, GPSC_RSP_SIZE); + ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD, + GPSC_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; /* Prepare CT arguments -- port_name */ @@ -2000,7 +1995,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list) GFF_ID_RSP_SIZE); /* Prepare CT request */ - ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GFF_ID_CMD, + ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD, GFF_ID_RSP_SIZE); ct_rsp = &ha->ct_sns->p.rsp; -- cgit v0.10.2 From b2ec76c5926438bda26b0e316246ae0e79bc810a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 11:27:29 -0400 Subject: [SCSI] qla2xxx: Fix qla2xxx_check_risc_status(). Change the 'rval' variable from QLA_FUNCTION_TIMEOUT into QLA_SUCCESS before starting a loop that is only executed if rval is initialized to QLA_SUCCESS. Coverity reported that loop as "dead code". Signed-off-by: Bart Van Assche Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index d2a4c75..2d8e7b8 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2485,6 +2485,7 @@ qla2xxx_check_risc_status(scsi_qla_host_t *vha) if (rval == QLA_SUCCESS) goto next_test; + rval = QLA_SUCCESS; WRT_REG_DWORD(®->iobase_window, 0x0003); for (cnt = 100; (RD_REG_DWORD(®->iobase_window) & BIT_0) == 0 && rval == QLA_SUCCESS; cnt--) { -- cgit v0.10.2 From 6e97c9d5b85caaef9c2da7e410008df7e6d9d38a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 11:27:30 -0400 Subject: [SCSI] qla2xxx: Remove an unused variable from qla2x00_remove_one(). Signed-off-by: Bart Van Assche Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 6df5223..3e21e9f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -2979,14 +2979,12 @@ qla2x00_remove_one(struct pci_dev *pdev) set_bit(UNLOADING, &base_vha->dpc_flags); mutex_lock(&ha->vport_lock); while (ha->cur_vport_count) { - struct Scsi_Host *scsi_host; - spin_lock_irqsave(&ha->vport_slock, flags); BUG_ON(base_vha->list.next == &ha->vp_list); /* This assumes first entry in ha->vp_list is always base vha */ vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list); - scsi_host = scsi_host_get(vha->host); + scsi_host_get(vha->host); spin_unlock_irqrestore(&ha->vport_slock, flags); mutex_unlock(&ha->vport_lock); -- cgit v0.10.2 From 8c0eb596baa51f2b43949c698c644727ef17805c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 11:27:31 -0400 Subject: [SCSI] qla2xxx: Fix a memory leak in an error path of qla2x00_process_els() Avoid that the fcport structure gets leaked if bsg_job->request->msgcode == FC_BSG_HST_ELS_NOLOGIN, the fcport allocation succeeds and the !vha->flags.online branch is taken. This was detected by Coverity. However, Coverity does not recognize that all qla2x00_process_els() callers specify either FC_BSG_RPT_ELS or FC_BSG_HST_ELS_NOLOGIN in the field bsg_job->request->msgcode and that the value of that field is not modified inside that function. This results in a false positive report about a possible memory leak in an error path for bsg_job->request->msgcode values other than the two mentioned values. Make it easy for Coverity (and for humans) to recognize that there is no fcport leak in the error path by changing the bsg_job->request->msgcode == FC_BSG_HST_ELS_NOLOGIN test into bsg_job->request->msgcode != FC_BSG_RPT_ELS. Signed-off-by: Bart Van Assche Signed-off-by: Saurav Kashyap Signed-off-by: James Bottomley diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index b85f002..417eaad 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -269,6 +269,12 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) type = "FC_BSG_HST_ELS_NOLOGIN"; } + if (!vha->flags.online) { + ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n"); + rval = -EIO; + goto done; + } + /* pass through is supported only for ISP 4Gb or higher */ if (!IS_FWI2_CAPABLE(ha)) { ql_dbg(ql_dbg_user, vha, 0x7001, @@ -326,12 +332,6 @@ qla2x00_process_els(struct fc_bsg_job *bsg_job) NPH_FABRIC_CONTROLLER : NPH_F_PORT; } - if (!vha->flags.online) { - ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n"); - rval = -EIO; - goto done; - } - req_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); @@ -399,7 +399,7 @@ done_unmap_sg: goto done_free_fcport; done_free_fcport: - if (bsg_job->request->msgcode == FC_BSG_HST_ELS_NOLOGIN) + if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) kfree(fcport); done: return rval; -- cgit v0.10.2 From 48e3b9855d6e1b408ec4a808f243e858a78f4482 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Sat, 29 Jun 2013 03:50:34 +0530 Subject: [SCSI] mpt3sas: 2013 source code copyright The Copyright String in all mpt3sas files are changed to 2012-2013. Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley diff --git a/drivers/scsi/mpt3sas/Kconfig b/drivers/scsi/mpt3sas/Kconfig index 81471bf..d53e1b0 100644 --- a/drivers/scsi/mpt3sas/Kconfig +++ b/drivers/scsi/mpt3sas/Kconfig @@ -2,7 +2,7 @@ # Kernel configuration file for the MPT3SAS # # This code is based on drivers/scsi/mpt3sas/Kconfig -# Copyright (C) 2012 LSI Corporation +# Copyright (C) 2012-2013 LSI Corporation # (mailto:DL-MPTFusionLinux@lsi.com) # This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 1836003..673a1b5 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -3,7 +3,7 @@ * for access to MPT (Message Passing Technology) firmware. * * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c - * Copyright (C) 2012 LSI Corporation + * Copyright (C) 2012-2013 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 994656c..3610647 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -3,7 +3,7 @@ * for access to MPT (Message Passing Technology) firmware. * * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h - * Copyright (C) 2012 LSI Corporation + * Copyright (C) 2012-2013 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c index 4db0c7a..936ec03 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_config.c +++ b/drivers/scsi/mpt3sas/mpt3sas_config.c @@ -2,7 +2,7 @@ * This module provides common API for accessing firmware configuration pages * * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.c - * Copyright (C) 2012 LSI Corporation + * Copyright (C) 2012-2013 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 0b402b6..9b89de1 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -3,7 +3,7 @@ * controllers * * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.c - * Copyright (C) 2012 LSI Corporation + * Copyright (C) 2012-2013 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h b/drivers/scsi/mpt3sas/mpt3sas_ctl.h index bd89f4f..53b0c48 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h @@ -3,7 +3,7 @@ * controllers * * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.h - * Copyright (C) 2012 LSI Corporation + * Copyright (C) 2012-2013 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt3sas/mpt3sas_debug.h b/drivers/scsi/mpt3sas/mpt3sas_debug.h index 35405e7..545b22d 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_debug.h +++ b/drivers/scsi/mpt3sas/mpt3sas_debug.h @@ -2,7 +2,7 @@ * Logging Support for MPT (Message Passing Technology) based controllers * * This code is based on drivers/scsi/mpt3sas/mpt3sas_debug.c - * Copyright (C) 2012 LSI Corporation + * Copyright (C) 2012-2013 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index dcbf7c8..73d3b81 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -2,7 +2,7 @@ * Scsi Host Layer for MPT (Message Passing Technology) based controllers * * This code is based on drivers/scsi/mpt3sas/mpt3sas_scsih.c - * Copyright (C) 2012 LSI Corporation + * Copyright (C) 2012-2013 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c index 87ca2b7..dcadd56 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_transport.c +++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c @@ -2,7 +2,7 @@ * SAS Transport Layer for MPT (Message Passing Technology) based controllers * * This code is based on drivers/scsi/mpt3sas/mpt3sas_transport.c - * Copyright (C) 2012 LSI Corporation + * Copyright (C) 2012-2013 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c b/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c index 6f8d621..f6533ab 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c +++ b/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c @@ -3,7 +3,7 @@ * (Message Passing Technology) based controllers * * This code is based on drivers/scsi/mpt3sas/mpt3sas_trigger_diag.c - * Copyright (C) 2012 LSI Corporation + * Copyright (C) 2012-2013 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or diff --git a/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h b/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h index a10c309..bb69392 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h +++ b/drivers/scsi/mpt3sas/mpt3sas_trigger_diag.h @@ -4,7 +4,7 @@ * controllers * * This code is based on drivers/scsi/mpt3sas/mpt3sas_base.h - * Copyright (C) 2012 LSI Corporation + * Copyright (C) 2012-2013 LSI Corporation * (mailto:DL-MPTFusionLinux@lsi.com) * * This program is free software; you can redistribute it and/or -- cgit v0.10.2 From b453ff84de6caf3ad3a988da8444c13b71e3f507 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Sat, 29 Jun 2013 03:51:19 +0530 Subject: [SCSI] mpt3sas: Updated the Hardware timing requirements Hardware timing requirements is updated in order to comply with firmware requirement. Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 673a1b5..5dc280c 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -4090,11 +4090,15 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) writel(host_diagnostic | MPI2_DIAG_RESET_ADAPTER, &ioc->chip->HostDiagnostic); - /* don't access any registers for 50 milliseconds */ - msleep(50); + /*This delay allows the chip PCIe hardware time to finish reset tasks*/ + if (sleep_flag == CAN_SLEEP) + msleep(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000); + else + mdelay(MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC/1000); - /* 300 second max wait */ - for (count = 0; count < 3000000 ; count++) { + /* Approximately 300 second max wait */ + for (count = 0; count < (300000000 / + MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) { host_diagnostic = readl(&ioc->chip->HostDiagnostic); @@ -4103,11 +4107,13 @@ _base_diag_reset(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) if (!(host_diagnostic & MPI2_DIAG_RESET_ADAPTER)) break; - /* wait 1 msec */ + /* Wait to pass the second read delay window */ if (sleep_flag == CAN_SLEEP) - usleep_range(1000, 1500); + msleep(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC + / 1000); else - mdelay(1); + mdelay(MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC + / 1000); } if (host_diagnostic & MPI2_DIAG_HCB_MODE) { -- cgit v0.10.2 From b65cfedf4560af65305bd7b3b9f26c02c6fb3660 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Sat, 29 Jun 2013 03:52:03 +0530 Subject: [SCSI] mpt3sas: fix for kernel panic when driver loads with HBA conected to non LUN 0 configured expander With some enclosures when LUN 0 is not created but LUN 1 or LUN X is created then SCSI scan procedure calls target_alloc, slave_alloc call back functions for LUN 0 and slave_destory() for same LUN 0. In these kind of cases within slave_destroy, pointer to scsi_target in _sas_device structure is set to NULL, following which when slave_alloc for LUN 1 is called then starget would not be set properly for this LUN. So, scsi_target pointer pointing to NULL value would lead to a crash later in the discovery procedure. To solve this issue set the sas_device's scsi_target pointer to scsi_device's scsi_target if it is NULL earlier in slave_alloc callback function. Signed-off-by: Sreekanth Reddy Cc: stable@vger.kernel.org Signed-off-by: James Bottomley diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 73d3b81..9ebc9dc 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -1273,6 +1273,7 @@ _scsih_slave_alloc(struct scsi_device *sdev) struct MPT3SAS_DEVICE *sas_device_priv_data; struct scsi_target *starget; struct _raid_device *raid_device; + struct _sas_device *sas_device; unsigned long flags; sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); @@ -1301,6 +1302,19 @@ _scsih_slave_alloc(struct scsi_device *sdev) spin_unlock_irqrestore(&ioc->raid_device_lock, flags); } + if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) { + spin_lock_irqsave(&ioc->sas_device_lock, flags); + sas_device = mpt3sas_scsih_sas_device_find_by_sas_address(ioc, + sas_target_priv_data->sas_address); + if (sas_device && (sas_device->starget == NULL)) { + sdev_printk(KERN_INFO, sdev, + "%s : sas_device->starget set to starget @ %d\n", + __func__, __LINE__); + sas_device->starget = starget; + } + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + } + return 0; } -- cgit v0.10.2 From 14be49ac965ebd3f8561d57e01ddb22f93f9b454 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Sat, 29 Jun 2013 03:53:02 +0530 Subject: [SCSI] mpt3sas: Infinite loops can occur if MPI2_IOCSTATUS_CONFIG_INVALID_PAGE is not returned Infinite loop can occur if IOCStatus is not equal to MPI2_IOCSTATUS_CONFIG_INVALID_PAGE value in the while loops in functions _scsih_search_responding_sas_devices, _scsih_search_responding_raid_devices and _scsih_search_responding_expanders So, Instead of checking for MPI2_IOCSTATUS_CONFIG_INVALID_PAGE value, in this patch code is modified to check for IOCStatus not equals to MPI2_IOCSTATUS_SUCCESS to break the while loop. Signed-off-by: Sreekanth Reddy Cc: stable@vger.kernel.org Signed-off-by: James Bottomley diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 9ebc9dc..632eba7 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -6406,7 +6406,7 @@ _scsih_search_responding_sas_devices(struct MPT3SAS_ADAPTER *ioc) handle))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; - if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) break; handle = le16_to_cpu(sas_device_pg0.DevHandle); device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); @@ -6508,7 +6508,7 @@ _scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc) &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; - if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) break; handle = le16_to_cpu(volume_pg1.DevHandle); @@ -6532,7 +6532,7 @@ _scsih_search_responding_raid_devices(struct MPT3SAS_ADAPTER *ioc) phys_disk_num))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; - if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) break; phys_disk_num = pd_pg0.PhysDiskNum; handle = le16_to_cpu(pd_pg0.DevHandle); @@ -6611,7 +6611,7 @@ _scsih_search_responding_expanders(struct MPT3SAS_ADAPTER *ioc) ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; - if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) break; handle = le16_to_cpu(expander_pg0.DevHandle); @@ -6756,8 +6756,6 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; - if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) - break; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { pr_info(MPT3SAS_FMT "\tbreak from expander scan: " \ "ioc_status(0x%04x), loginfo(0x%08x)\n", @@ -6801,8 +6799,6 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) phys_disk_num))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; - if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) - break; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { pr_info(MPT3SAS_FMT "\tbreak from phys disk scan: "\ "ioc_status(0x%04x), loginfo(0x%08x)\n", @@ -6868,8 +6864,6 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; - if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) - break; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { pr_info(MPT3SAS_FMT "\tbreak from volume scan: " \ "ioc_status(0x%04x), loginfo(0x%08x)\n", @@ -6928,8 +6922,6 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) handle))) { ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; - if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) - break; if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { pr_info(MPT3SAS_FMT "\tbreak from end device scan:"\ " ioc_status(0x%04x), loginfo(0x%08x)\n", -- cgit v0.10.2 From 17263e754d87fac1be2825b43d984f594a68845e Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Sat, 29 Jun 2013 03:54:07 +0530 Subject: [SCSI] mpt3sas: MPI2.5 Rev F v2.5.1.1 specification Change set in MPI v2.5 Rev F(v2.5.1.1) specification and 2.00.29 header files 1. Added a bit to the IOCExceptions field of the IOCFacts Reply to indicate that the IOC detected a partial memory failure. 2. Added ElapsedSeconds field to RAID Volume Indicator Structure. Added Elapsed Seconds Valid flag to Flags field of this structure. 3. Added ElapsedSeconds field to Integrated RAID Operations Status Event Data. 4. Added two new AbortType values for TargetModeAbort Request, one to abort all I/Os from a single initiator, and the other to abort only Command IUs. 5. Added a new chapter covering DMA Flags and Multicast Modes. 6. In the IOCSettings field of BIOS Page 1, modified the Adapter Support bits description to specify X86 BIOS. 7. Marked bit 0 of the ControlFlags field of SAS IO Unit Page 1 as obsolete. This was the Clear SATA Affiliation flag. 8. Added additional requirements for certain IOCs that support more than eight MSI-x vectors. Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley diff --git a/drivers/scsi/mpt3sas/mpi/mpi2.h b/drivers/scsi/mpt3sas/mpi/mpi2.h index 03317ff..20da8f9 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2012 LSI Corporation. + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2.h @@ -8,7 +8,7 @@ * scatter/gather formats. * Creation Date: June 21, 2006 * - * mpi2.h Version: 02.00.26 + * mpi2.h Version: 02.00.29 * * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 * prefix are for use only on MPI v2.5 products, and must not be used @@ -82,6 +82,10 @@ * 03-29-12 02.00.25 Bumped MPI2_HEADER_VERSION_UNIT. * Added Hard Reset delay timings. * 07-10-12 02.00.26 Bumped MPI2_HEADER_VERSION_UNIT. + * 07-26-12 02.00.27 Bumped MPI2_HEADER_VERSION_UNIT. + * 11-27-12 02.00.28 Bumped MPI2_HEADER_VERSION_UNIT. + * 12-20-12 02.00.29 Bumped MPI2_HEADER_VERSION_UNIT. + * Added MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET. * -------------------------------------------------------------------------- */ @@ -115,7 +119,7 @@ #define MPI2_VERSION_02_05 (0x0205) /*Unit and Dev versioning for this MPI header set */ -#define MPI2_HEADER_VERSION_UNIT (0x1A) +#define MPI2_HEADER_VERSION_UNIT (0x1D) #define MPI2_HEADER_VERSION_DEV (0x00) #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) @@ -274,6 +278,8 @@ typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS { #define MPI2_REPLY_POST_HOST_INDEX_MASK (0x00FFFFFF) #define MPI2_RPHI_MSIX_INDEX_MASK (0xFF000000) #define MPI2_RPHI_MSIX_INDEX_SHIFT (24) +#define MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET (0x0000030C) /*MPI v2.5 only*/ + /* *Defines for the HCBSize and address diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h index d8b2c3e..889aa70 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2011 LSI Corporation. + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_cnfg.h * Title: MPI Configuration messages and pages * Creation Date: November 10, 2006 * - * mpi2_cnfg.h Version: 02.00.22 + * mpi2_cnfg.h Version: 02.00.24 * * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 * prefix are for use only on MPI v2.5 products, and must not be used @@ -155,6 +155,11 @@ * Added UEFIVersion field to BIOS Page 1 and defined new * BiosOptions bits. * Incorporating additions for MPI v2.5. + * 11-27-12 02.00.23 Added MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER. + * Added MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID. + * 12-20-12 02.00.24 Marked MPI2_SASIOUNIT1_CONTROL_CLEAR_AFFILIATION as + * obsolete for MPI v2.5 and later. + * Added some defines for 12G SAS speeds. * -------------------------------------------------------------------------- */ @@ -714,6 +719,7 @@ typedef struct _MPI2_CONFIG_PAGE_MAN_7 { #define MPI2_MANUFACTURING7_PAGEVERSION (0x01) /*defines for the Flags field */ +#define MPI2_MANPAGE7_FLAG_EVENTREPLAY_SLOT_ORDER (0x00000002) #define MPI2_MANPAGE7_FLAG_USE_SLOT_INFO (0x00000001) @@ -1310,6 +1316,9 @@ typedef struct _MPI2_CONFIG_PAGE_BIOS_1 { #define MPI2_BIOSPAGE1_PAGEVERSION (0x05) /*values for BIOS Page 1 BiosOptions field */ +#define MPI2_BIOSPAGE1_OPTIONS_MASK_OEM_ID (0x000000F0) +#define MPI2_BIOSPAGE1_OPTIONS_LSI_OEM_ID (0x00000000) + #define MPI2_BIOSPAGE1_OPTIONS_MASK_UEFI_HII_REGISTRATION (0x00000006) #define MPI2_BIOSPAGE1_OPTIONS_ENABLE_UEFI_HII (0x00000000) #define MPI2_BIOSPAGE1_OPTIONS_DISABLE_UEFI_HII (0x00000002) @@ -1884,6 +1893,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 { #define MPI2_SAS_PRATE_MAX_RATE_1_5 (0x80) #define MPI2_SAS_PRATE_MAX_RATE_3_0 (0x90) #define MPI2_SAS_PRATE_MAX_RATE_6_0 (0xA0) +#define MPI25_SAS_PRATE_MAX_RATE_12_0 (0xB0) #define MPI2_SAS_PRATE_MIN_RATE_MASK (0x0F) #define MPI2_SAS_PRATE_MIN_RATE_NOT_PROGRAMMABLE (0x00) #define MPI2_SAS_PRATE_MIN_RATE_1_5 (0x08) @@ -1897,6 +1907,7 @@ typedef struct _MPI2_CONFIG_PAGE_RD_PDISK_1 { #define MPI2_SAS_HWRATE_MAX_RATE_1_5 (0x80) #define MPI2_SAS_HWRATE_MAX_RATE_3_0 (0x90) #define MPI2_SAS_HWRATE_MAX_RATE_6_0 (0xA0) +#define MPI25_SAS_HWRATE_MAX_RATE_12_0 (0xB0) #define MPI2_SAS_HWRATE_MIN_RATE_MASK (0x0F) #define MPI2_SAS_HWRATE_MIN_RATE_1_5 (0x08) #define MPI2_SAS_HWRATE_MIN_RATE_3_0 (0x09) diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_init.h b/drivers/scsi/mpt3sas/mpi/mpi2_init.h index a079e52..f7928bf 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_init.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_init.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2012 LSI Corporation. + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_init.h diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h index 0de425d..e2bb821 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_ioc.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2012 LSI Corporation. + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_ioc.h * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages * Creation Date: October 11, 2006 * - * mpi2_ioc.h Version: 02.00.21 + * mpi2_ioc.h Version: 02.00.22 * * NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25 * prefix are for use only on MPI v2.5 products, and must not be used @@ -124,6 +124,9 @@ * Marked MPI2_PM_CONTROL_FEATURE_PCIE_LINK as obsolete. * 11-18-11 02.00.20 Incorporating additions for MPI v2.5. * 03-29-12 02.00.21 Added a product specific range to event values. + * 07-26-12 02.00.22 Added MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE. + * Added ElapsedSeconds field to + * MPI2_EVENT_DATA_IR_OPERATION_STATUS. * -------------------------------------------------------------------------- */ @@ -283,6 +286,7 @@ typedef struct _MPI2_IOC_FACTS_REPLY { #define MPI2_IOCFACTS_HDRVERSION_DEV_SHIFT (0) /*IOCExceptions */ +#define MPI2_IOCFACTS_EXCEPT_PARTIAL_MEMORY_FAILURE (0x0200) #define MPI2_IOCFACTS_EXCEPT_IR_FOREIGN_CONFIG_MAX (0x0100) #define MPI2_IOCFACTS_EXCEPT_BOOTSTAT_MASK (0x00E0) @@ -634,7 +638,7 @@ typedef struct _MPI2_EVENT_DATA_IR_OPERATION_STATUS { U8 RAIDOperation; /*0x04 */ U8 PercentComplete; /*0x05 */ U16 Reserved2; /*0x06 */ - U32 Resereved3; /*0x08 */ + U32 ElapsedSeconds; /*0x08 */ } MPI2_EVENT_DATA_IR_OPERATION_STATUS, *PTR_MPI2_EVENT_DATA_IR_OPERATION_STATUS, Mpi2EventDataIrOperationStatus_t, diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_raid.h b/drivers/scsi/mpt3sas/mpi/mpi2_raid.h index d1d9866..7176523 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_raid.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_raid.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2012 LSI Corporation. + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_raid.h * Title: MPI Integrated RAID messages and structures * Creation Date: April 26, 2007 * - * mpi2_raid.h Version: 02.00.08 + * mpi2_raid.h Version: 02.00.09 * * Version History * --------------- @@ -28,6 +28,8 @@ * Added product-specific range to RAID Action values. * 11-18-11 02.00.07 Incorporating additions for MPI v2.5. * 02-06-12 02.00.08 Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN. + * 07-26-12 02.00.09 Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR. + * Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define. * -------------------------------------------------------------------------- */ @@ -269,10 +271,12 @@ typedef struct _MPI2_RAID_VOL_INDICATOR { U64 TotalBlocks; /*0x00 */ U64 BlocksRemaining; /*0x08 */ U32 Flags; /*0x10 */ + U32 ElapsedSeconds; /* 0x14 */ } MPI2_RAID_VOL_INDICATOR, *PTR_MPI2_RAID_VOL_INDICATOR, Mpi2RaidVolIndicator_t, *pMpi2RaidVolIndicator_t; /*defines for RAID Volume Indicator Flags field */ +#define MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID (0x80000000) #define MPI2_RAID_VOL_FLAGS_OP_MASK (0x0000000F) #define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT (0x00000000) #define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001) @@ -312,7 +316,7 @@ typedef struct _MPI2_RAID_COMPATIBILITY_RESULT_STRUCT { /*RAID Action Reply ActionData union */ typedef union _MPI2_RAID_ACTION_REPLY_DATA { - U32 Word[5]; + U32 Word[6]; MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator; U16 VolDevHandle; U8 VolumeState; diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_sas.h b/drivers/scsi/mpt3sas/mpi/mpi2_sas.h index b4e7084a..cba046f 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_sas.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_sas.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2012 LSI Corporation. + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_sas.h diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_tool.h b/drivers/scsi/mpt3sas/mpi/mpi2_tool.h index 71453d1..34e9a7b 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_tool.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_tool.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2012 LSI Corporation. + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_tool.h * Title: MPI diagnostic tool structures and definitions * Creation Date: March 26, 2007 * - * mpi2_tool.h Version: 02.00.09 + * mpi2_tool.h Version: 02.00.10 * * Version History * --------------- @@ -30,6 +30,8 @@ * 11-18-11 02.00.08 Incorporating additions for MPI v2.5. * 07-10-12 02.00.09 Add MPI v2.5 Toolbox Diagnostic CLI Tool Request * message. + * 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that + * it uses MPI Chain SGE as well as MPI Simple SGE. * -------------------------------------------------------------------------- */ @@ -279,7 +281,7 @@ typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST { U16 Reserved6; /*0x0E */ U32 DataLength; /*0x10 */ U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];/*0x14 */ - MPI2_SGE_SIMPLE_UNION SGL; /*0x70 */ + MPI2_MPI_SGE_IO_UNION SGL; /*0x70 */ } MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, *PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, Mpi2ToolboxDiagnosticCliRequest_t, @@ -302,7 +304,7 @@ typedef struct _MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST { U32 Reserved5; /*0x0C */ U32 DataLength; /*0x10 */ U8 DiagnosticCliCommand[MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH];/*0x14 */ - MPI25_SGE_IO_UNION SGL; /*0x70 */ + MPI25_SGE_IO_UNION SGL; /* 0x70 */ } MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, *PTR_MPI25_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, Mpi25ToolboxDiagnosticCliRequest_t, diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_type.h b/drivers/scsi/mpt3sas/mpi/mpi2_type.h index 516f959..ba1fed5 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_type.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_type.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2007 LSI Corporation. + * Copyright (c) 2000-2013 LSI Corporation. * * * Name: mpi2_type.h -- cgit v0.10.2 From f5edbe77d93b99f169d752d91bf31df0432ca990 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Sat, 29 Jun 2013 03:54:51 +0530 Subject: [SCSI] mpt3sas: when async scanning is enabled then while scanning, devices are removed but their transport layer entries are not removed When Async scanning mode is enabled and device scanning is in progress, devices should not be removed. But in actuality, devices are removed but their transport layer entries are not removed. This causes error to add the same device to the transport layer after host reset or diagnostic reset. So, in this patch, modified the code in such a way that device is not removed when Async scanning mode is enabled and device scanning is in progress. Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 632eba7..8cbe8fd 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -675,11 +675,12 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc, * devices while scanning is turned on due to an oops in * scsi_sysfs_add_sdev()->add_device()->sysfs_addrm_start() */ - if (!ioc->is_driver_loading) + if (!ioc->is_driver_loading) { mpt3sas_transport_port_remove(ioc, sas_device->sas_address, sas_device->sas_address_parent); - _scsih_sas_device_remove(ioc, sas_device); + _scsih_sas_device_remove(ioc, sas_device); + } } } @@ -7531,10 +7532,12 @@ _scsih_probe_boot_devices(struct MPT3SAS_ADAPTER *ioc) sas_address_parent)) { _scsih_sas_device_remove(ioc, sas_device); } else if (!sas_device->starget) { - if (!ioc->is_driver_loading) - mpt3sas_transport_port_remove(ioc, sas_address, + if (!ioc->is_driver_loading) { + mpt3sas_transport_port_remove(ioc, + sas_address, sas_address_parent); - _scsih_sas_device_remove(ioc, sas_device); + _scsih_sas_device_remove(ioc, sas_device); + } } } } @@ -7590,13 +7593,14 @@ _scsih_probe_sas(struct MPT3SAS_ADAPTER *ioc) * oops in scsi_sysfs_add_sdev()->add_device()-> * sysfs_addrm_start() */ - if (!ioc->is_driver_loading) + if (!ioc->is_driver_loading) { mpt3sas_transport_port_remove(ioc, sas_device->sas_address, sas_device->sas_address_parent); - list_del(&sas_device->list); - kfree(sas_device); - continue; + list_del(&sas_device->list); + kfree(sas_device); + continue; + } } spin_lock_irqsave(&ioc->sas_device_lock, flags); -- cgit v0.10.2 From e9ce9c86c28c5d44dc408ffe5069597cbbe4663a Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Sat, 29 Jun 2013 03:55:45 +0530 Subject: [SCSI] mpt3sas: Bump driver version to v02.100.00.00 Bump driver version to v02.100.00.00. Signed-off-by: Sreekanth Reddy Signed-off-by: James Bottomley diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 3610647..0ebf5d9 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -70,10 +70,10 @@ #define MPT3SAS_DRIVER_NAME "mpt3sas" #define MPT3SAS_AUTHOR "LSI Corporation " #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" -#define MPT3SAS_DRIVER_VERSION "01.100.01.00" -#define MPT3SAS_MAJOR_VERSION 1 +#define MPT3SAS_DRIVER_VERSION "02.100.00.00" +#define MPT3SAS_MAJOR_VERSION 2 #define MPT3SAS_MINOR_VERSION 100 -#define MPT3SAS_BUILD_VERSION 1 +#define MPT3SAS_BUILD_VERSION 0 #define MPT3SAS_RELEASE_VERSION 00 /* -- cgit v0.10.2 From 518d9df87105a078984c90c75cf6e7f67e3c928c Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 29 Jun 2013 17:59:14 +0900 Subject: [SCSI] scsi_debug: fix invalid address passed to kunmap_atomic() In the function prot_verify_write(), the kmap address 'daddr' is incremented in the loop for each data page. Finally 'daddr' reaches the next page boundary in the end of the loop, and the invalid address is passed to kunmap_atomic(). Fix the issue by not incrementing 'daddr' in the loop and offsetting it by the loop counter on demand. Signed-off-by: Akinobu Mita Acked-by: Douglas Gilbert Acked-by: "Martin K. Petersen" Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 0a537a0..d51bddd 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1899,7 +1899,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, daddr = kmap_atomic(sg_page(dsgl)) + dsgl->offset; /* For each sector-sized chunk in data page */ - for (j = 0 ; j < dsgl->length ; j += scsi_debug_sector_size) { + for (j = 0; j < dsgl->length; j += scsi_debug_sector_size) { /* If we're at the end of the current * protection page advance to the next one @@ -1917,11 +1917,11 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, switch (scsi_debug_guard) { case 1: - csum = ip_compute_csum(daddr, + csum = ip_compute_csum(daddr + j, scsi_debug_sector_size); break; case 0: - csum = cpu_to_be16(crc_t10dif(daddr, + csum = cpu_to_be16(crc_t10dif(daddr + j, scsi_debug_sector_size)); break; default: @@ -1938,7 +1938,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, be16_to_cpu(sdt->guard_tag), be16_to_cpu(csum)); ret = 0x01; - dump_sector(daddr, scsi_debug_sector_size); + dump_sector(daddr + j, scsi_debug_sector_size); goto out; } @@ -1949,7 +1949,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, "%s: REF check failed on sector %lu\n", __func__, (unsigned long)sector); ret = 0x03; - dump_sector(daddr, scsi_debug_sector_size); + dump_sector(daddr + j, scsi_debug_sector_size); goto out; } @@ -1959,7 +1959,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, "%s: REF check failed on sector %lu\n", __func__, (unsigned long)sector); ret = 0x03; - dump_sector(daddr, scsi_debug_sector_size); + dump_sector(daddr + j, scsi_debug_sector_size); goto out; } @@ -1977,7 +1977,6 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, start_sec++; ei_lba++; - daddr += scsi_debug_sector_size; ppage_offset += sizeof(struct sd_dif_tuple); } -- cgit v0.10.2 From fc3fc352b6e7a6452596f8a13cedeaa6bcfe9689 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 29 Jun 2013 17:59:15 +0900 Subject: [SCSI] scsi_debug: fix incorrectly nested kmap_atomic() In the function prot_verify_write(), kmap_atomic()/kunmap_atomic() for data page and kmap_atomic()/kunmap_atomic() for protection information page are not nested each other. It worked perfectly before commit 3e4d3af501cccdc8a8cca41bdbe57d54ad7e7e73 ("mm: stack based kmap_atomic()"). Because the kmap_atomic slot KM_IRQ0 was used for data page and the slot KM_IRQ1 was used for protection page. But KM_types are gone and kmap_atomic() is using stack based implementation. So two different kmap_atomic() usages must be strictly nested now. This change ensures kmap_atomic() usage is strictly nested. Signed-off-by: Akinobu Mita Acked-by: Douglas Gilbert Acked-by: "Martin K. Petersen" Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d51bddd..bcf73e4 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1891,12 +1891,12 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, BUG_ON(scsi_sg_count(SCpnt) == 0); BUG_ON(scsi_prot_sg_count(SCpnt) == 0); - paddr = kmap_atomic(sg_page(psgl)) + psgl->offset; ppage_offset = 0; /* For each data page */ scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) { daddr = kmap_atomic(sg_page(dsgl)) + dsgl->offset; + paddr = kmap_atomic(sg_page(psgl)) + psgl->offset; /* For each sector-sized chunk in data page */ for (j = 0; j < dsgl->length; j += scsi_debug_sector_size) { @@ -1980,19 +1980,18 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, ppage_offset += sizeof(struct sd_dif_tuple); } + kunmap_atomic(paddr); kunmap_atomic(daddr); } - kunmap_atomic(paddr); - dix_writes++; return 0; out: dif_errors++; - kunmap_atomic(daddr); kunmap_atomic(paddr); + kunmap_atomic(daddr); return ret; } -- cgit v0.10.2 From 7cb69d0397233546d82191e524235fdb9d1d91aa Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 29 Jun 2013 17:59:16 +0900 Subject: [SCSI] scsi_debug: fix NULL pointer dereference with parameters dif=0 dix=1 The protection info dif_storep is allocated only when parameter dif is not zero. But it will be accessed when reading or writing to the storage installed with parameter dix is not zero. So kernel crashes if scsi_debug module is loaded with parameters dix=1 and dif=0. This fixes it by making dif_storep available if parameter dix is not zero instead of checking if parameter dif is not zero. Signed-off-by: Akinobu Mita Acked-by: Douglas Gilbert Acked-by: "Martin K. Petersen" Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index bcf73e4..e83e661 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -3372,7 +3372,7 @@ static int __init scsi_debug_init(void) if (scsi_debug_num_parts > 0) sdebug_build_parts(fake_storep, sz); - if (scsi_debug_dif) { + if (scsi_debug_dix) { int dif_size; dif_size = sdebug_store_sectors * sizeof(struct sd_dif_tuple); -- cgit v0.10.2 From e9926b4376544d5a2dc4d310d4d0006c634b1a93 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 29 Jun 2013 17:59:17 +0900 Subject: [SCSI] scsi_debug: invalidate protection info for unmapped region When UNMAP command is issued with the data integrity support enabled, the protection info for the unmapped region is remain unchanged. So READ command for the region later on causes data integrity failure. This fixes it by invalidating protection info for the unmapped region by filling with 0xff pattern. Signed-off-by: Akinobu Mita Acked-by: Douglas Gilbert Acked-by: "Martin K. Petersen" Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index e83e661..83efec2 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -2064,6 +2064,11 @@ static void unmap_region(sector_t lba, unsigned int len) scsi_debug_sector_size * scsi_debug_unmap_granularity); } + if (dif_storep) { + memset(dif_storep + lba, 0xff, + sizeof(*dif_storep) * + scsi_debug_unmap_granularity); + } } lba = map_index_to_lba(index + 1); } -- cgit v0.10.2 From e18d8bea33077d259cc826c6d3fa76d36af61876 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 29 Jun 2013 17:59:18 +0900 Subject: [SCSI] scsi_debug: simplify offset calculation for dif_storep dif_storep is declared as pointer to unsigned char type. But it is actually used to store vmalloced array of struct sd_dif_tuple. This changes the type of dif_storep to the pointer to struct sd_dif_tuple. It simplifies offset calculation for dif_storep and enables to remove hardcoded size of struct sd_dif_tuple. Signed-off-by: Akinobu Mita Acked-by: Douglas Gilbert Acked-by: "Martin K. Petersen" Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 83efec2..fc8b3aa 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -258,7 +258,7 @@ struct sdebug_queued_cmd { static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; static unsigned char * fake_storep; /* ramdisk storage */ -static unsigned char *dif_storep; /* protection info */ +static struct sd_dif_tuple *dif_storep; /* protection info */ static void *map_storep; /* provisioning map */ static unsigned long map_size; @@ -277,11 +277,6 @@ static char sdebug_proc_name[] = "scsi_debug"; static struct bus_type pseudo_lld_bus; -static inline sector_t dif_offset(sector_t sector) -{ - return sector << 3; -} - static struct device_driver sdebug_driverfs_driver = { .name = sdebug_proc_name, .bus = &pseudo_lld_bus, @@ -1727,7 +1722,7 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, start_sec = do_div(tmp_sec, sdebug_store_sectors); - sdt = (struct sd_dif_tuple *)(dif_storep + dif_offset(start_sec)); + sdt = dif_storep + start_sec; for (i = 0 ; i < sectors ; i++) { u16 csum; @@ -1782,16 +1777,17 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, ei_lba++; } - resid = sectors * 8; /* Bytes of protection data to copy into sgl */ + /* Bytes of protection data to copy into sgl */ + resid = sectors * sizeof(*dif_storep); sector = start_sec; scsi_for_each_prot_sg(SCpnt, psgl, scsi_prot_sg_count(SCpnt), i) { int len = min(psgl->length, resid); paddr = kmap_atomic(sg_page(psgl)) + psgl->offset; - memcpy(paddr, dif_storep + dif_offset(sector), len); + memcpy(paddr, dif_storep + sector, len); - sector += len >> 3; + sector += len / sizeof(*dif_storep); if (sector >= sdebug_store_sectors) { /* Force wrap */ tmp_sec = sector; @@ -1968,7 +1964,7 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, * correctness we need to verify each sector * before writing it to "stable" storage */ - memcpy(dif_storep + dif_offset(sector), sdt, 8); + memcpy(dif_storep + sector, sdt, sizeof(*sdt)); sector++; -- cgit v0.10.2 From beb40ea42bd65511bc275a7d58d3753835906be5 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Sat, 29 Jun 2013 17:59:19 +0900 Subject: [SCSI] scsi_debug: reduce duplication between prot_verify_read and prot_verify_write In order to reduce code duplication between prot_verify_read() and prot_verify_write(), this moves common code into the new functions. [jejb: fix unitialised variable warning] Signed-off-by: Akinobu Mita Acked-by: Douglas Gilbert Acked-by: "Martin K. Petersen" Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index fc8b3aa..3f096a6 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1710,6 +1710,50 @@ static int do_device_access(struct scsi_cmnd *scmd, return ret; } +static u16 dif_compute_csum(const void *buf, int len) +{ + u16 csum; + + switch (scsi_debug_guard) { + case 1: + csum = ip_compute_csum(buf, len); + break; + case 0: + csum = cpu_to_be16(crc_t10dif(buf, len)); + break; + } + return csum; +} + +static int dif_verify(struct sd_dif_tuple *sdt, const void *data, + sector_t sector, u32 ei_lba) +{ + u16 csum = dif_compute_csum(data, scsi_debug_sector_size); + + if (sdt->guard_tag != csum) { + pr_err("%s: GUARD check failed on sector %lu rcvd 0x%04x, data 0x%04x\n", + __func__, + (unsigned long)sector, + be16_to_cpu(sdt->guard_tag), + be16_to_cpu(csum)); + return 0x01; + } + if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION && + be32_to_cpu(sdt->ref_tag) != (sector & 0xffffffff)) { + pr_err("%s: REF check failed on sector %lu\n", + __func__, (unsigned long)sector); + return 0x03; + } + if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && + be32_to_cpu(sdt->ref_tag) != ei_lba) { + pr_err("%s: REF check failed on sector %lu\n", + __func__, (unsigned long)sector); + dif_errors++; + return 0x03; + } + return 0; +} + static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, unsigned int sectors, u32 ei_lba) { @@ -1725,53 +1769,19 @@ static int prot_verify_read(struct scsi_cmnd *SCpnt, sector_t start_sec, sdt = dif_storep + start_sec; for (i = 0 ; i < sectors ; i++) { - u16 csum; + int ret; if (sdt[i].app_tag == 0xffff) continue; sector = start_sec + i; - switch (scsi_debug_guard) { - case 1: - csum = ip_compute_csum(fake_storep + - sector * scsi_debug_sector_size, - scsi_debug_sector_size); - break; - case 0: - csum = crc_t10dif(fake_storep + - sector * scsi_debug_sector_size, - scsi_debug_sector_size); - csum = cpu_to_be16(csum); - break; - default: - BUG(); - } - - if (sdt[i].guard_tag != csum) { - printk(KERN_ERR "%s: GUARD check failed on sector %lu" \ - " rcvd 0x%04x, data 0x%04x\n", __func__, - (unsigned long)sector, - be16_to_cpu(sdt[i].guard_tag), - be16_to_cpu(csum)); - dif_errors++; - return 0x01; - } - - if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION && - be32_to_cpu(sdt[i].ref_tag) != (sector & 0xffffffff)) { - printk(KERN_ERR "%s: REF check failed on sector %lu\n", - __func__, (unsigned long)sector); - dif_errors++; - return 0x03; - } - - if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && - be32_to_cpu(sdt[i].ref_tag) != ei_lba) { - printk(KERN_ERR "%s: REF check failed on sector %lu\n", - __func__, (unsigned long)sector); + ret = dif_verify(&sdt[i], + fake_storep + sector * scsi_debug_sector_size, + sector, ei_lba); + if (ret) { dif_errors++; - return 0x03; + return ret; } ei_lba++; @@ -1880,7 +1890,6 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, sector_t tmp_sec = start_sec; sector_t sector; int ppage_offset; - unsigned short csum; sector = do_div(tmp_sec, sdebug_store_sectors); @@ -1911,50 +1920,8 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, sdt = paddr + ppage_offset; - switch (scsi_debug_guard) { - case 1: - csum = ip_compute_csum(daddr + j, - scsi_debug_sector_size); - break; - case 0: - csum = cpu_to_be16(crc_t10dif(daddr + j, - scsi_debug_sector_size)); - break; - default: - BUG(); - ret = 0; - goto out; - } - - if (sdt->guard_tag != csum) { - printk(KERN_ERR - "%s: GUARD check failed on sector %lu " \ - "rcvd 0x%04x, calculated 0x%04x\n", - __func__, (unsigned long)sector, - be16_to_cpu(sdt->guard_tag), - be16_to_cpu(csum)); - ret = 0x01; - dump_sector(daddr + j, scsi_debug_sector_size); - goto out; - } - - if (scsi_debug_dif == SD_DIF_TYPE1_PROTECTION && - be32_to_cpu(sdt->ref_tag) - != (start_sec & 0xffffffff)) { - printk(KERN_ERR - "%s: REF check failed on sector %lu\n", - __func__, (unsigned long)sector); - ret = 0x03; - dump_sector(daddr + j, scsi_debug_sector_size); - goto out; - } - - if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && - be32_to_cpu(sdt->ref_tag) != ei_lba) { - printk(KERN_ERR - "%s: REF check failed on sector %lu\n", - __func__, (unsigned long)sector); - ret = 0x03; + ret = dif_verify(sdt, daddr + j, start_sec, ei_lba); + if (ret) { dump_sector(daddr + j, scsi_debug_sector_size); goto out; } -- cgit v0.10.2 From fec3c1b4575431e2020c5c6502d18b281925ca45 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 29 Jun 2013 00:21:04 +0300 Subject: [SCSI] megaraid_sas: fix a bug for 64 bit arches On 64 bit then -1UL and -1U are not equal, so these conditions don't work as intended and it breaks error handling. Signed-off-by: Dan Carpenter Acked-by: Sumit Saxena Signed-off-by: James Bottomley diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index 8056eac..4f401f7 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -585,7 +585,7 @@ u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe, case 1: /* start with logical arm */ arm = get_arm_from_strip(instance, ld, stripe, map); - if (arm != -1UL) + if (arm != -1U) arm *= 2; break; } @@ -637,7 +637,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, if (raid->level == 6) { logArm = get_arm_from_strip(instance, ld, stripRow, map); - if (logArm == -1UL) + if (logArm == -1U) return FALSE; rowMod = mega_mod64(row, SPAN_ROW_SIZE(map, ld, span)); armQ = SPAN_ROW_SIZE(map, ld, span) - 1 - rowMod; -- cgit v0.10.2 From e2eb7244bc9e4fd130fc8a961224968e22ba48ee Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 2 Jul 2013 15:05:26 +0200 Subject: [SCSI] Fix race between starved list and device removal scsi_run_queue() examines all SCSI devices that are present on the starved list. Since scsi_run_queue() unlocks the SCSI host lock a SCSI device can get removed after it has been removed from the starved list and before its queue is run. Protect against that race condition by holding a reference on the queue while running it. Reported-by: Chanho Min Reviewed-by: Bart Van Assche Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 86d5220..df8bd5a 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -434,6 +434,8 @@ static void scsi_run_queue(struct request_queue *q) list_splice_init(&shost->starved_list, &starved_list); while (!list_empty(&starved_list)) { + struct request_queue *slq; + /* * As long as shost is accepting commands and we have * starved queues, call blk_run_queue. scsi_request_fn @@ -456,11 +458,25 @@ static void scsi_run_queue(struct request_queue *q) continue; } - spin_unlock(shost->host_lock); - spin_lock(sdev->request_queue->queue_lock); - __blk_run_queue(sdev->request_queue); - spin_unlock(sdev->request_queue->queue_lock); - spin_lock(shost->host_lock); + /* + * Once we drop the host lock, a racing scsi_remove_device() + * call may remove the sdev from the starved list and destroy + * it and the queue. Mitigate by taking a reference to the + * queue and never touching the sdev again after we drop the + * host lock. Note: if __scsi_remove_device() invokes + * blk_cleanup_queue() before the queue is run from this + * function then blk_run_queue() will return immediately since + * blk_cleanup_queue() marks the queue with QUEUE_FLAG_DYING. + */ + slq = sdev->request_queue; + if (!blk_get_queue(slq)) + continue; + spin_unlock_irqrestore(shost->host_lock, flags); + + blk_run_queue(slq); + blk_put_queue(slq); + + spin_lock_irqsave(shost->host_lock, flags); } /* put any unprocessed entries back */ list_splice(&starved_list, &shost->starved_list); -- cgit v0.10.2 From 0516c08d10835a8f9169051504cbc9929b3a7f3e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 2 Jul 2013 15:06:33 +0200 Subject: [SCSI] enable destruction of blocked devices which fail LUN scanning If something goes wrong during LUN scanning, e.g. a transport layer failure occurs, then __scsi_remove_device() can get invoked by the LUN scanning code for a SCSI device in state SDEV_CREATED_BLOCK and before the SCSI device has been added to sysfs (is_visible == 0). Make sure that even in this case the transition into state SDEV_DEL occurs. This avoids that __scsi_remove_device() can get invoked a second time by scsi_forget_host() if this last function is invoked from another thread than the thread that performs LUN scanning. Signed-off-by: Bart Van Assche Signed-off-by: James Bottomley diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index df8bd5a..124392f 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2193,6 +2193,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) case SDEV_OFFLINE: case SDEV_TRANSPORT_OFFLINE: case SDEV_CANCEL: + case SDEV_CREATED_BLOCK: break; default: goto illegal; -- cgit v0.10.2 From e0335f67a281cb8eb11868e614ee9390fbbe9b1d Mon Sep 17 00:00:00 2001 From: Mark Rustad Date: Sat, 18 May 2013 04:01:36 +0000 Subject: libfc: Reject PLOGI from nodes with incompatible role Reject a PLOGI from a node with an incompatible role, that is, initiator-to-initiator or target-to-target. Signed-off-by: Mark Rustad Reviewed-by: Yi Zou Tested-by: Jack Morgan Signed-off-by: Robert Love diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 6bbb944..c710d90 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -926,6 +926,20 @@ err: kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); } +static bool +fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata) +{ + if (rdata->ids.roles == FC_PORT_ROLE_UNKNOWN) + return true; + if ((rdata->ids.roles & FC_PORT_ROLE_FCP_TARGET) && + (lport->service_params & FCP_SPPF_INIT_FCN)) + return true; + if ((rdata->ids.roles & FC_PORT_ROLE_FCP_INITIATOR) && + (lport->service_params & FCP_SPPF_TARG_FCN)) + return true; + return false; +} + /** * fc_rport_enter_plogi() - Send Port Login (PLOGI) request * @rdata: The remote port to send a PLOGI to @@ -938,6 +952,12 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata) struct fc_lport *lport = rdata->local_port; struct fc_frame *fp; + if (!fc_rport_compatible_roles(lport, rdata)) { + FC_RPORT_DBG(rdata, "PLOGI suppressed for incompatible role\n"); + fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT); + return; + } + FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n", fc_rport_state(rdata)); @@ -1646,6 +1666,13 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport, rjt_data.explan = ELS_EXPL_NONE; goto reject; } + if (!fc_rport_compatible_roles(lport, rdata)) { + FC_RPORT_DBG(rdata, "Received PLOGI for incompatible role\n"); + mutex_unlock(&rdata->rp_mutex); + rjt_data.reason = ELS_RJT_LOGIC; + rjt_data.explan = ELS_EXPL_NONE; + goto reject; + } /* * Get session payload size from incoming PLOGI. -- cgit v0.10.2 From f07d46bbc9ba9a08b338dec7bb858977d4d822fb Mon Sep 17 00:00:00 2001 From: Neerav Parikh Date: Sat, 18 May 2013 05:12:28 +0000 Subject: fcoe: Fix smatch warning in fcoe_fdmi_info function This patch fixes a smatch warning as below: smatch warnings: drivers/scsi/fcoe/fcoe.c:782 fcoe_fdmi_info() warn: 'fdmi' puts 896 bytes on stack Reported-by: Fengguang Wu Signed-off-by: Neerav Parikh Tested-by: Jack Morgan Signed-off-by: Robert Love diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 32ae6c6..3336e57 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -774,7 +774,6 @@ static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev) struct fcoe_port *port; struct net_device *realdev; int rc; - struct netdev_fcoe_hbainfo fdmi; port = lport_priv(lport); fcoe = port->priv; @@ -788,9 +787,13 @@ static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev) return; if (realdev->netdev_ops->ndo_fcoe_get_hbainfo) { - memset(&fdmi, 0, sizeof(fdmi)); + struct netdev_fcoe_hbainfo *fdmi; + fdmi = kzalloc(sizeof(*fdmi), GFP_KERNEL); + if (!fdmi) + return; + rc = realdev->netdev_ops->ndo_fcoe_get_hbainfo(realdev, - &fdmi); + fdmi); if (rc) { printk(KERN_INFO "fcoe: Failed to retrieve FDMI " "information from netdev.\n"); @@ -800,38 +803,39 @@ static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev) snprintf(fc_host_serial_number(lport->host), FC_SERIAL_NUMBER_SIZE, "%s", - fdmi.serial_number); + fdmi->serial_number); snprintf(fc_host_manufacturer(lport->host), FC_SERIAL_NUMBER_SIZE, "%s", - fdmi.manufacturer); + fdmi->manufacturer); snprintf(fc_host_model(lport->host), FC_SYMBOLIC_NAME_SIZE, "%s", - fdmi.model); + fdmi->model); snprintf(fc_host_model_description(lport->host), FC_SYMBOLIC_NAME_SIZE, "%s", - fdmi.model_description); + fdmi->model_description); snprintf(fc_host_hardware_version(lport->host), FC_VERSION_STRING_SIZE, "%s", - fdmi.hardware_version); + fdmi->hardware_version); snprintf(fc_host_driver_version(lport->host), FC_VERSION_STRING_SIZE, "%s", - fdmi.driver_version); + fdmi->driver_version); snprintf(fc_host_optionrom_version(lport->host), FC_VERSION_STRING_SIZE, "%s", - fdmi.optionrom_version); + fdmi->optionrom_version); snprintf(fc_host_firmware_version(lport->host), FC_VERSION_STRING_SIZE, "%s", - fdmi.firmware_version); + fdmi->firmware_version); /* Enable FDMI lport states */ lport->fdmi_enabled = 1; + kfree(fdmi); } else { lport->fdmi_enabled = 0; printk(KERN_INFO "fcoe: No FDMI support.\n"); -- cgit v0.10.2 From 418a8cfe69c3b6bd4598e9870b9f412e2c247214 Mon Sep 17 00:00:00 2001 From: Yi Zou Date: Sat, 18 May 2013 06:28:17 +0000 Subject: fcoe: fix the link error status block sparse warnings Both fcoe_fc_els_lesb and fc_els_lesb are in __be32 already, and both are exactly the same size in bytes, with somewhat different member names to reflect the fact the former is for Ethernet media the latter is for Fiber Channel, so, remove conversion and use __be32 directly. This fixes the warning from sparse check. Signed-off-by: Yi Zou Reported-by: Fengguang Wu Tested-by: Jack Morgan Signed-off-by: Robert Love diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index f3a5a53..bedd422 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c @@ -180,24 +180,10 @@ void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev) { struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); struct net_device *netdev = fcoe_get_netdev(fip->lp); - struct fcoe_fc_els_lesb *fcoe_lesb; - struct fc_els_lesb fc_lesb; - - __fcoe_get_lesb(fip->lp, &fc_lesb, netdev); - fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb); - - ctlr_dev->lesb.lesb_link_fail = - ntohl(fcoe_lesb->lesb_link_fail); - ctlr_dev->lesb.lesb_vlink_fail = - ntohl(fcoe_lesb->lesb_vlink_fail); - ctlr_dev->lesb.lesb_miss_fka = - ntohl(fcoe_lesb->lesb_miss_fka); - ctlr_dev->lesb.lesb_symb_err = - ntohl(fcoe_lesb->lesb_symb_err); - ctlr_dev->lesb.lesb_err_block = - ntohl(fcoe_lesb->lesb_err_block); - ctlr_dev->lesb.lesb_fcs_error = - ntohl(fcoe_lesb->lesb_fcs_error); + struct fc_els_lesb *fc_lesb; + + fc_lesb = (struct fc_els_lesb *)(&ctlr_dev->lesb); + __fcoe_get_lesb(fip->lp, fc_lesb, netdev); } EXPORT_SYMBOL_GPL(fcoe_ctlr_get_lesb); -- cgit v0.10.2 From 4a80f083dd70a200763e77d3eeee48bdf753c7df Mon Sep 17 00:00:00 2001 From: Robert Love Date: Tue, 11 Jun 2013 07:28:03 +0000 Subject: libfc: Remove extra space in fc_exch_timer_cancel definition Simply remove an extra space that violates coding style. Signed-off-by: Robert Love Tested-by: Jack Morgan Acked-by: Neil Horman diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 8b928c6..e98ea6a 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -337,7 +337,7 @@ static void fc_exch_release(struct fc_exch *ep) * fc_exch_timer_cancel() - cancel exch timer * @ep: The exchange whose timer to be canceled */ -static inline void fc_exch_timer_cancel(struct fc_exch *ep) +static inline void fc_exch_timer_cancel(struct fc_exch *ep) { if (cancel_delayed_work(&ep->timeout_work)) { FC_EXCH_DBG(ep, "Exchange timer canceled\n"); -- cgit v0.10.2 From 3a2926054acf876313afaaddac00a8ad255f6d68 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Tue, 11 Jun 2013 07:28:09 +0000 Subject: libfc: Differentiate echange timer cancellation debug statements There are two debug statements with the same output string regarding echange timer cancellation. This patch simply changes the output of one string so that they can be differentiated. Signed-off-by: Robert Love Tested-by: Jack Morgan Acked-by: Neil Horman diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index e98ea6a..5879929 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -1567,7 +1567,7 @@ static void fc_exch_abts_resp(struct fc_exch *ep, struct fc_frame *fp) fc_exch_rctl_name(fh->fh_r_ctl)); if (cancel_delayed_work_sync(&ep->timeout_work)) { - FC_EXCH_DBG(ep, "Exchange timer canceled\n"); + FC_EXCH_DBG(ep, "Exchange timer canceled due to ABTS response\n"); fc_exch_release(ep); /* release from pending timer hold */ } -- cgit v0.10.2 From a2ceb1fbaa875172345f611a3d37c3662f7e5082 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Tue, 11 Jun 2013 07:28:19 +0000 Subject: libfcoe: Fix meaningless log statement ctlr_dev was initialized to NULL, and never re-assigned. This caused the log statement to always report failure. This patch removes the unused variable and fixes the log statement to always report 'success', as that is what should be logged if the code reaches this point. Signed-off-by: Robert Love Tested-by: Jack Morgan Acked-by: Neil Horman diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index bedd422..f1ae5ed 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c @@ -707,7 +707,6 @@ ssize_t fcoe_ctlr_create_store(struct bus_type *bus, { struct net_device *netdev = NULL; struct fcoe_transport *ft = NULL; - struct fcoe_ctlr_device *ctlr_dev = NULL; int rc = 0; int err; @@ -754,9 +753,8 @@ ssize_t fcoe_ctlr_create_store(struct bus_type *bus, goto out_putdev; } - LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n", - ft->name, (ctlr_dev) ? "succeeded" : "failed", - netdev->name); + LIBFCOE_TRANSPORT_DBG("transport %s succeeded to create fcoe on %s.\n", + ft->name, netdev->name); out_putdev: dev_put(netdev); -- cgit v0.10.2 From d17efa001aacaa774581972230b1a9db1e618ded Mon Sep 17 00:00:00 2001 From: Mark Rustad Date: Sat, 18 May 2013 04:10:07 +0000 Subject: fcoe: Stop fc_rport_priv structure leak When repeatedly doing rmmod and modprobe on the ixgbe driver while FCoE is active in a VN2VN configuration, memory leaks would be discovered by kmemleak with the following backtrace: unreferenced object 0xffff88003d076000 (size 1024): comm "kworker/0:3", pid 2998, jiffies 4295436448 (age 1015.332s) hex dump (first 32 bytes): 48 8a fe 6f 00 88 ff ff 00 00 00 00 00 00 00 00 H..o............ 01 00 00 00 02 00 00 00 7b ac 87 21 1b 00 00 10 ........{..!.... backtrace: [] kmemleak_alloc+0x5b/0xc0 [] __kmalloc+0xd8/0x1b0 [] fc_rport_create+0x48/0x1f0 [libfc] [] fcoe_ctlr_vn_add.isra.10+0x56/0x1a0 [libfcoe] [] fcoe_ctlr_vn_recv+0x8b0/0xab0 [libfcoe] [] fcoe_ctlr_recv_work+0x4c6/0xf60 [libfcoe] [] process_one_work+0x1e4/0x4d0 [] worker_thread+0x10f/0x380 [] kthread+0xea/0xf0 [] ret_from_fork+0x7c/0xb0 [] 0xffffffffffffffff This patch stops the leak of the fc_rport_priv structure. Signed-off-by: Mark Rustad Tested-by: Jack Morgan Signed-off-by: Robert Love diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 795843d..203415e 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -2090,7 +2090,11 @@ static struct fc_rport_operations fcoe_ctlr_vn_rport_ops = { */ static void fcoe_ctlr_disc_stop_locked(struct fc_lport *lport) { + struct fc_rport_priv *rdata; + mutex_lock(&lport->disc.disc_mutex); + list_for_each_entry_rcu(rdata, &lport->disc.rports, peers) + lport->tt.rport_logoff(rdata); lport->disc.disc_callback = NULL; mutex_unlock(&lport->disc.disc_mutex); } -- cgit v0.10.2 From 7a5ed75a782a1f2de7fc773981ecd88bfa7595b1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 25 Jun 2013 17:49:40 +0000 Subject: fcoe: Reduce number of sparse warnings Declare local variables and functions 'static'. This patch does not change any functionality. Signed-off-by: Bart Van Assche Signed-off-by: Robert Love diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c index 8c05ae01..c9382d6 100644 --- a/drivers/scsi/fcoe/fcoe_sysfs.c +++ b/drivers/scsi/fcoe/fcoe_sysfs.c @@ -507,7 +507,7 @@ static const struct attribute_group *fcoe_fcf_attr_groups[] = { NULL, }; -struct bus_type fcoe_bus_type; +static struct bus_type fcoe_bus_type; static int fcoe_bus_match(struct device *dev, struct device_driver *drv) @@ -541,25 +541,25 @@ static void fcoe_fcf_device_release(struct device *dev) kfree(fcf); } -struct device_type fcoe_ctlr_device_type = { +static struct device_type fcoe_ctlr_device_type = { .name = "fcoe_ctlr", .groups = fcoe_ctlr_attr_groups, .release = fcoe_ctlr_device_release, }; -struct device_type fcoe_fcf_device_type = { +static struct device_type fcoe_fcf_device_type = { .name = "fcoe_fcf", .groups = fcoe_fcf_attr_groups, .release = fcoe_fcf_device_release, }; -struct bus_attribute fcoe_bus_attr_group[] = { +static struct bus_attribute fcoe_bus_attr_group[] = { __ATTR(ctlr_create, S_IWUSR, NULL, fcoe_ctlr_create_store), __ATTR(ctlr_destroy, S_IWUSR, NULL, fcoe_ctlr_destroy_store), __ATTR_NULL }; -struct bus_type fcoe_bus_type = { +static struct bus_type fcoe_bus_type = { .name = "fcoe", .match = &fcoe_bus_match, .bus_attrs = fcoe_bus_attr_group, @@ -569,7 +569,7 @@ struct bus_type fcoe_bus_type = { * fcoe_ctlr_device_flush_work() - Flush a FIP ctlr's workqueue * @ctlr: Pointer to the FIP ctlr whose workqueue is to be flushed */ -void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr) +static void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr) { if (!fcoe_ctlr_work_q(ctlr)) { printk(KERN_ERR @@ -590,8 +590,8 @@ void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr) * Return value: * 1 on success / 0 already queued / < 0 for error */ -int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr, - struct work_struct *work) +static int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr, + struct work_struct *work) { if (unlikely(!fcoe_ctlr_work_q(ctlr))) { printk(KERN_ERR @@ -609,7 +609,7 @@ int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr, * fcoe_ctlr_device_flush_devloss() - Flush a FIP ctlr's devloss workqueue * @ctlr: Pointer to FIP ctlr whose workqueue is to be flushed */ -void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr) +static void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr) { if (!fcoe_ctlr_devloss_work_q(ctlr)) { printk(KERN_ERR @@ -631,9 +631,9 @@ void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr) * Return value: * 1 on success / 0 already queued / < 0 for error */ -int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr, - struct delayed_work *work, - unsigned long delay) +static int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr, + struct delayed_work *work, + unsigned long delay) { if (unlikely(!fcoe_ctlr_devloss_work_q(ctlr))) { printk(KERN_ERR -- cgit v0.10.2 From 655ee63cf3714ac0a7ebee4a7dd00fdc54b006fc Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Tue, 2 Jul 2013 00:17:34 -0400 Subject: [SCSI] scsi constants: command, sense key + additional sense strings It has been several years since the SCSI constants.c file has been updated. The attached is against lk 3.10 and brings the command strings, sense keys and additional sense code strings into sync with spc4r36g.pdf. Certain SCSI command names that previously only took the opcode (i.e. byte 0 of the cdb) into account, have been split into several command names using the associated service action field to differentiate. For example, persistent reservations that previously had 2 commands (i.e. "in" and "out") have been expanded to 12 commands (e.g. "Persistent reserve in, read reservation"). Sync SCSI command names, sense key strings and additional sense code strings with SPC-4 draft revision 36g [jejb: whitespace fix] Signed-off-by: Douglas Gilbert Signed-off-by: James Bottomley diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 76e4c03..d35a5d6 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -1,10 +1,10 @@ -/* +/* * ASCII values for a number of symbolic constants, printing functions, * etc. * Additions for SCSI 2 and Linux 2.2.x by D. Gilbert (990422) * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002) * by D. Gilbert and aeb (20020609) - * Update to SPC-4 T10/1713-D Rev 20, 22 May 2009, D. Gilbert 20090624 + * Updated to SPC-4 T10/1713-D Rev 36g, D. Gilbert 20130701 */ #include @@ -21,12 +21,13 @@ /* Commands with service actions that change the command name */ -#define MAINTENANCE_IN 0xa3 -#define MAINTENANCE_OUT 0xa4 #define SERVICE_ACTION_IN_12 0xab #define SERVICE_ACTION_OUT_12 0xa9 +#define SERVICE_ACTION_BIDIRECTIONAL 0x9d #define SERVICE_ACTION_IN_16 0x9e #define SERVICE_ACTION_OUT_16 0x9f +#define THIRD_PARTY_COPY_OUT 0x83 +#define THIRD_PARTY_COPY_IN 0x84 @@ -36,11 +37,11 @@ static const char * cdb_byte0_names[] = { /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL, "Reassign Blocks", /* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL, -/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", +/* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", /* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)", "Reserve(6)", /* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)", -/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", +/* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", /* 1e-1f */ "Prevent/Allow Medium Removal", NULL, /* 20-22 */ NULL, NULL, NULL, /* 23-28 */ "Read Format Capacities", "Set Window", @@ -48,16 +49,16 @@ static const char * cdb_byte0_names[] = { /* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)", "Read updated block", /* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal", -/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", +/* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", /* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)", - "Read Defect Data(10)", -/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", - "Read Buffer", + "Read Defect Data(10)", +/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", + "Read Buffer", /* 3d-3f */ "Update Block", "Read Long(10)", "Write Long(10)", /* 40-41 */ "Change Definition", "Write Same(10)", /* 42-48 */ "Unmap/Read sub-channel", "Read TOC/PMA/ATIP", "Read density support", "Play audio(10)", "Get configuration", - "Play audio msf", "Play audio track/index", + "Play audio msf", "Sanitize/Play audio track/index", /* 49-4f */ "Play track relative(10)", "Get event status notification", "Pause/resume", "Log Select", "Log Sense", "Stop play/scan", NULL, @@ -72,17 +73,17 @@ static const char * cdb_byte0_names[] = { /* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, "Extended CDB", "Variable length", -/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", "Extended copy", - "Receive copy results", +/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", + "Third party copy out", "Third party copy in", /* 85-89 */ "ATA command pass through(16)", "Access control in", - "Access control out", "Read(16)", "Memory Export Out(16)", + "Access control out", "Read(16)", "Compare and Write", /* 8a-8f */ "Write(16)", "ORWrite", "Read attributes", "Write attributes", "Write and verify(16)", "Verify(16)", /* 90-94 */ "Pre-fetch(16)", "Synchronize cache(16)", "Lock/unlock cache(16)", "Write same(16)", NULL, /* 95-99 */ NULL, NULL, NULL, NULL, NULL, -/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in(16)", - "Service action out(16)", +/* 9a-9f */ NULL, NULL, NULL, "Service action bidirectional", + "Service action in(16)", "Service action out(16)", /* a0-a5 */ "Report luns", "ATA command pass through(12)/Blank", "Security protocol in", "Maintenance in", "Maintenance out", "Move medium/play audio(12)", @@ -122,6 +123,7 @@ static const struct value_name_pair maint_out_arr[] = { {0x6, "Set identifying information"}, {0xa, "Set target port groups"}, {0xb, "Change aliases"}, + {0xc, "Remove I_T nexus"}, {0xe, "Set priority"}, {0xf, "Set timestamp"}, {0x10, "Management protocol out"}, @@ -138,10 +140,16 @@ static const struct value_name_pair serv_out12_arr[] = { }; #define SERV_OUT12_SZ ARRAY_SIZE(serv_out12_arr) +static const struct value_name_pair serv_bidi_arr[] = { + {-1, "dummy entry"}, +}; +#define SERV_BIDI_SZ ARRAY_SIZE(serv_bidi_arr) + static const struct value_name_pair serv_in16_arr[] = { {0x10, "Read capacity(16)"}, {0x11, "Read long(16)"}, {0x12, "Get LBA status"}, + {0x13, "Report referrals"}, }; #define SERV_IN16_SZ ARRAY_SIZE(serv_in16_arr) @@ -151,6 +159,51 @@ static const struct value_name_pair serv_out16_arr[] = { }; #define SERV_OUT16_SZ ARRAY_SIZE(serv_out16_arr) +static const struct value_name_pair pr_in_arr[] = { + {0x0, "Persistent reserve in, read keys"}, + {0x1, "Persistent reserve in, read reservation"}, + {0x2, "Persistent reserve in, report capabilities"}, + {0x3, "Persistent reserve in, read full status"}, +}; +#define PR_IN_SZ ARRAY_SIZE(pr_in_arr) + +static const struct value_name_pair pr_out_arr[] = { + {0x0, "Persistent reserve out, register"}, + {0x1, "Persistent reserve out, reserve"}, + {0x2, "Persistent reserve out, release"}, + {0x3, "Persistent reserve out, clear"}, + {0x4, "Persistent reserve out, preempt"}, + {0x5, "Persistent reserve out, preempt and abort"}, + {0x6, "Persistent reserve out, register and ignore existing key"}, + {0x7, "Persistent reserve out, register and move"}, +}; +#define PR_OUT_SZ ARRAY_SIZE(pr_out_arr) + +/* SPC-4 rev 34 renamed the Extended Copy opcode to Third Party Copy Out. + LID1 (List Identifier length: 1 byte) is the Extended Copy found in SPC-2 + and SPC-3 */ +static const struct value_name_pair tpc_out_arr[] = { + {0x0, "Extended copy(LID1)"}, + {0x1, "Extended copy(LID4)"}, + {0x10, "Populate token"}, + {0x11, "Write using token"}, + {0x1c, "Copy operation abort"}, +}; +#define TPC_OUT_SZ ARRAY_SIZE(tpc_out_arr) + +static const struct value_name_pair tpc_in_arr[] = { + {0x0, "Receive copy status(LID1)"}, + {0x1, "Receive copy data(LID1)"}, + {0x3, "Receive copy operating parameters"}, + {0x4, "Receive copy failure details(LID1)"}, + {0x5, "Receive copy status(LID4)"}, + {0x6, "Receive copy data(LID4)"}, + {0x7, "Receive ROD token information"}, + {0x8, "Report all ROD tokens"}, +}; +#define TPC_IN_SZ ARRAY_SIZE(tpc_in_arr) + + static const struct value_name_pair variable_length_arr[] = { {0x1, "Rebuild(32)"}, {0x2, "Regenerate(32)"}, @@ -207,6 +260,7 @@ static const char * get_sa_name(const struct value_name_pair * arr, static void print_opcode_name(unsigned char * cdbp, int cdb_len) { int sa, len, cdb0; + int fin_name = 0; const char * name; cdb0 = cdbp[0]; @@ -219,7 +273,8 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) break; } sa = (cdbp[8] << 8) + cdbp[9]; - name = get_sa_name(variable_length_arr, VARIABLE_LENGTH_SZ, sa); + name = get_sa_name(variable_length_arr, VARIABLE_LENGTH_SZ, + sa); if (name) printk("%s", name); else @@ -232,50 +287,57 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) case MAINTENANCE_IN: sa = cdbp[1] & 0x1f; name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); - if (name) - printk("%s", name); - else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + fin_name = 1; break; case MAINTENANCE_OUT: sa = cdbp[1] & 0x1f; name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa); - if (name) - printk("%s", name); - else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + fin_name = 1; + break; + case PERSISTENT_RESERVE_IN: + sa = cdbp[1] & 0x1f; + name = get_sa_name(pr_in_arr, PR_IN_SZ, sa); + fin_name = 1; + break; + case PERSISTENT_RESERVE_OUT: + sa = cdbp[1] & 0x1f; + name = get_sa_name(pr_out_arr, PR_OUT_SZ, sa); + fin_name = 1; break; case SERVICE_ACTION_IN_12: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa); - if (name) - printk("%s", name); - else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + fin_name = 1; break; case SERVICE_ACTION_OUT_12: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa); - if (name) - printk("%s", name); - else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + fin_name = 1; + break; + case SERVICE_ACTION_BIDIRECTIONAL: + sa = cdbp[1] & 0x1f; + name = get_sa_name(serv_bidi_arr, SERV_BIDI_SZ, sa); + fin_name = 1; break; case SERVICE_ACTION_IN_16: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa); - if (name) - printk("%s", name); - else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + fin_name = 1; break; case SERVICE_ACTION_OUT_16: sa = cdbp[1] & 0x1f; name = get_sa_name(serv_out16_arr, SERV_OUT16_SZ, sa); - if (name) - printk("%s", name); - else - printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + fin_name = 1; + break; + case THIRD_PARTY_COPY_IN: + sa = cdbp[1] & 0x1f; + name = get_sa_name(tpc_in_arr, TPC_IN_SZ, sa); + fin_name = 1; + break; + case THIRD_PARTY_COPY_OUT: + sa = cdbp[1] & 0x1f; + name = get_sa_name(tpc_out_arr, TPC_OUT_SZ, sa); + fin_name = 1; break; default: if (cdb0 < 0xc0) { @@ -288,6 +350,12 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) printk("cdb[0]=0x%x (vendor)", cdb0); break; } + if (fin_name) { + if (name) + printk("%s", name); + else + printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); + } } #else /* ifndef CONFIG_SCSI_CONSTANTS */ @@ -312,10 +380,15 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) break; case MAINTENANCE_IN: case MAINTENANCE_OUT: + case PERSISTENT_RESERVE_IN: + case PERSISTENT_RESERVE_OUT: case SERVICE_ACTION_IN_12: case SERVICE_ACTION_OUT_12: + case SERVICE_ACTION_BIDIRECTIONAL: case SERVICE_ACTION_IN_16: case SERVICE_ACTION_OUT_16: + case THIRD_PARTY_COPY_IN: + case THIRD_PARTY_COPY_OUT: sa = cdbp[1] & 0x1f; printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); break; @@ -327,7 +400,7 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len) break; } } -#endif +#endif void __scsi_print_command(unsigned char *cdb) { @@ -336,7 +409,7 @@ void __scsi_print_command(unsigned char *cdb) print_opcode_name(cdb, 0); len = scsi_command_size(cdb); /* print out all bytes in cdb */ - for (k = 0; k < len; ++k) + for (k = 0; k < len; ++k) printk(" %02x", cdb[k]); printk("\n"); } @@ -404,8 +477,9 @@ struct error_info { /* * The canonical list of T10 Additional Sense Codes is available at: - * http://www.t10.org/lists/asc-num.txt + * http://www.t10.org/lists/asc-num.txt [most recent: 20130605] */ + static const struct error_info additional[] = { {0x0000, "No additional sense information"}, @@ -430,6 +504,8 @@ static const struct error_info additional[] = {0x001C, "Verify operation in progress"}, {0x001D, "ATA pass through information available"}, {0x001E, "Conflicting SA creation request"}, + {0x001F, "Logical unit transitioning to another power condition"}, + {0x0020, "Extended copy information available"}, {0x0100, "No index/sector signal"}, @@ -460,6 +536,17 @@ static const struct error_info additional[] = {0x0412, "Logical unit not ready, offline"}, {0x0413, "Logical unit not ready, SA creation in progress"}, {0x0414, "Logical unit not ready, space allocation in progress"}, + {0x0415, "Logical unit not ready, robotics disabled"}, + {0x0416, "Logical unit not ready, configuration required"}, + {0x0417, "Logical unit not ready, calibration required"}, + {0x0418, "Logical unit not ready, a door is open"}, + {0x0419, "Logical unit not ready, operating in sequential mode"}, + {0x041A, "Logical unit not ready, start stop unit command in " + "progress"}, + {0x041B, "Logical unit not ready, sanitize in progress"}, + {0x041C, "Logical unit not ready, additional power use not yet " + "granted"}, + {0x041D, "Logical unit not ready, configuration in progress"}, {0x0500, "Logical unit does not respond to selection"}, @@ -490,6 +577,7 @@ static const struct error_info additional[] = {0x0B06, "Warning - non-volatile cache now volatile"}, {0x0B07, "Warning - degraded power to non-volatile cache"}, {0x0B08, "Warning - power loss expected"}, + {0x0B09, "Warning - device statistics notification active"}, {0x0C00, "Write error"}, {0x0C01, "Write error - recovered with auto reallocation"}, @@ -505,6 +593,7 @@ static const struct error_info additional[] = {0x0C0B, "Auxiliary memory write error"}, {0x0C0C, "Write error - unexpected unsolicited data"}, {0x0C0D, "Write error - not enough unsolicited data"}, + {0x0C0E, "Multiple write errors"}, {0x0C0F, "Defects in error window"}, {0x0D00, "Error detected by third party temporary initiator"}, @@ -523,6 +612,8 @@ static const struct error_info additional[] = {0x1001, "Logical block guard check failed"}, {0x1002, "Logical block application tag check failed"}, {0x1003, "Logical block reference tag check failed"}, + {0x1004, "Logical block protection error on recover buffered data"}, + {0x1005, "Logical block protection method error"}, {0x1100, "Unrecovered read error"}, {0x1101, "Read retries exhausted"}, @@ -545,6 +636,7 @@ static const struct error_info additional[] = {0x1112, "Auxiliary memory read error"}, {0x1113, "Read error - failed retransmission request"}, {0x1114, "Read error - lba marked bad by application client"}, + {0x1115, "Write after sanitize required"}, {0x1200, "Address mark not found for id field"}, @@ -622,6 +714,7 @@ static const struct error_info additional[] = {0x2009, "Access denied - invalid LU identifier"}, {0x200A, "Access denied - invalid proxy token"}, {0x200B, "Access denied - ACL LUN conflict"}, + {0x200C, "Illegal command when not in append-only mode"}, {0x2100, "Logical block address out of range"}, {0x2101, "Invalid element address"}, @@ -630,6 +723,19 @@ static const struct error_info additional[] = {0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"}, + {0x2300, "Invalid token operation, cause not reportable"}, + {0x2301, "Invalid token operation, unsupported token type"}, + {0x2302, "Invalid token operation, remote token usage not supported"}, + {0x2303, "Invalid token operation, remote rod token creation not " + "supported"}, + {0x2304, "Invalid token operation, token unknown"}, + {0x2305, "Invalid token operation, token corrupt"}, + {0x2306, "Invalid token operation, token revoked"}, + {0x2307, "Invalid token operation, token expired"}, + {0x2308, "Invalid token operation, token cancelled"}, + {0x2309, "Invalid token operation, token deleted"}, + {0x230A, "Invalid token operation, invalid token length"}, + {0x2400, "Invalid field in cdb"}, {0x2401, "CDB decryption error"}, {0x2402, "Obsolete"}, @@ -705,6 +811,7 @@ static const struct error_info additional[] = "event"}, {0x2A13, "Data encryption key instance counter has changed"}, {0x2A14, "SA creation capabilities data has changed"}, + {0x2A15, "Medium removal prevention preempted"}, {0x2B00, "Copy cannot execute since host cannot disconnect"}, @@ -720,6 +827,7 @@ static const struct error_info additional[] = {0x2C09, "Previous reservation conflict status"}, {0x2C0A, "Partition or collection contains user objects"}, {0x2C0B, "Not reserved"}, + {0x2C0C, "Orwrite generation does not match"}, {0x2D00, "Overwrite error on update in place"}, @@ -728,6 +836,7 @@ static const struct error_info additional[] = {0x2F00, "Commands cleared by another initiator"}, {0x2F01, "Commands cleared by power loss notification"}, {0x2F02, "Commands cleared by device server"}, + {0x2F03, "Some commands cleared by queuing layer event"}, {0x3000, "Incompatible medium installed"}, {0x3001, "Cannot read medium - unknown format"}, @@ -745,10 +854,12 @@ static const struct error_info additional[] = {0x3010, "Medium not formatted"}, {0x3011, "Incompatible volume type"}, {0x3012, "Incompatible volume qualifier"}, + {0x3013, "Cleaning volume expired"}, {0x3100, "Medium format corrupted"}, {0x3101, "Format command failed"}, {0x3102, "Zoned formatting failed due to spare linking"}, + {0x3103, "Sanitize command failed"}, {0x3200, "No defect spare location available"}, {0x3201, "Defect list update failure"}, @@ -809,6 +920,8 @@ static const struct error_info additional[] = {0x3B19, "Element enabled"}, {0x3B1A, "Data transfer device removed"}, {0x3B1B, "Data transfer device inserted"}, + {0x3B1C, "Too many logical objects on partition to support " + "operation"}, {0x3D00, "Invalid bits in identify message"}, @@ -839,6 +952,7 @@ static const struct error_info additional[] = {0x3F12, "iSCSI IP address added"}, {0x3F13, "iSCSI IP address removed"}, {0x3F14, "iSCSI IP address changed"}, + {0x3F15, "Inspect referrals sense descriptors"}, /* * {0x40NN, "Ram failure"}, * {0x40NN, "Diagnostic failure on component nn"}, @@ -848,6 +962,7 @@ static const struct error_info additional[] = {0x4300, "Message error"}, {0x4400, "Internal target failure"}, + {0x4401, "Persistent reservation information lost"}, {0x4471, "ATA device failed set features"}, {0x4500, "Select or reselect failure"}, @@ -876,6 +991,21 @@ static const struct error_info additional[] = {0x4B04, "Nak received"}, {0x4B05, "Data offset error"}, {0x4B06, "Initiator response timeout"}, + {0x4B07, "Connection lost"}, + {0x4B08, "Data-in buffer overflow - data buffer size"}, + {0x4B09, "Data-in buffer overflow - data buffer descriptor area"}, + {0x4B0A, "Data-in buffer error"}, + {0x4B0B, "Data-out buffer overflow - data buffer size"}, + {0x4B0C, "Data-out buffer overflow - data buffer descriptor area"}, + {0x4B0D, "Data-out buffer error"}, + {0x4B0E, "PCIe fabric error"}, + {0x4B0F, "PCIe completion timeout"}, + {0x4B10, "PCIe completer abort"}, + {0x4B11, "PCIe poisoned tlp received"}, + {0x4B12, "PCIe eCRC check failed"}, + {0x4B13, "PCIe unsupported request"}, + {0x4B14, "PCIe acs violation"}, + {0x4B15, "PCIe tlp prefix blocked"}, {0x4C00, "Logical unit failed self-configuration"}, /* @@ -897,6 +1027,10 @@ static const struct error_info additional[] = {0x5302, "Medium removal prevented"}, {0x5303, "Medium removal prevented by data transfer element"}, {0x5304, "Medium thread or unthread failure"}, + {0x5305, "Volume identifier invalid"}, + {0x5306, "Volume identifier missing"}, + {0x5307, "Duplicate volume identifier"}, + {0x5308, "Element status unknown"}, {0x5400, "Scsi to host system interface failure"}, @@ -911,6 +1045,9 @@ static const struct error_info additional[] = {0x5508, "Maximum number of supplemental decryption keys exceeded"}, {0x5509, "Medium auxiliary memory not accessible"}, {0x550A, "Data currently unavailable"}, + {0x550B, "Insufficient power for operation"}, + {0x550C, "Insufficient resources to create rod"}, + {0x550D, "Insufficient resources to create rod token"}, {0x5700, "Unable to recover table-of-contents"}, @@ -1069,6 +1206,7 @@ static const struct error_info additional[] = {0x670B, "ATA device feature not enabled"}, {0x6800, "Logical unit not configured"}, + {0x6801, "Subsidiary logical unit not configured"}, {0x6900, "Data loss on logical unit"}, {0x6901, "Multiple logical unit failures"}, @@ -1185,10 +1323,13 @@ static const char * const snstext[] = { "Vendor Specific(9)", "Copy Aborted", /* A: COPY or COMPARE was aborted */ "Aborted Command", /* B: The target aborted the command */ - "Equal", /* C: A SEARCH DATA command found data equal */ + "Equal", /* C: A SEARCH DATA command found data equal, + reserved in SPC-4 rev 36 */ "Volume Overflow", /* D: Medium full with still data to be written */ "Miscompare", /* E: Source data and data on the medium do not agree */ + "Completed", /* F: command completed sense data reported, + may occur for successful command */ }; #endif @@ -1306,7 +1447,7 @@ scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, struct scsi_sense_hdr *sshdr) { int k, num, res; - + res = scsi_normalize_sense(sense_buffer, sense_len, sshdr); if (0 == res) { /* this may be SCSI-1 sense data */ @@ -1459,5 +1600,3 @@ void scsi_print_result(struct scsi_cmnd *cmd) scsi_show_result(cmd->result); } EXPORT_SYMBOL(scsi_print_result); - - -- cgit v0.10.2