diff options
author | Harish Zunjarrao <harish.zunjarrao@qlogic.com> | 2011-08-01 06:26:14 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-08-27 10:36:30 -0400 |
commit | ef7830bb62c9edf34fc4e849a53d7e87bf51de4a (patch) | |
tree | e2b1585eb1833328f696a7684c8f4b1e2204ecff /drivers/scsi/qla4xxx | |
parent | 943c157b7934a3b9fcf5290328be3b84d1a1a104 (diff) |
[SCSI] qla4xxx: Code cleanup for read/update flash using BSG
- Corrected return status
- Added reset active check
- Removed unused dma_map_sg calls
- Added debug prints on failure
Signed-off-by: Harish Zunjarrao <harish.zunjarrao@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_bsg.c | 128 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_def.h | 10 |
2 files changed, 65 insertions, 73 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_bsg.c b/drivers/scsi/qla4xxx/ql4_bsg.c index daa2b0f8e309..15032f130f22 100644 --- a/drivers/scsi/qla4xxx/ql4_bsg.c +++ b/drivers/scsi/qla4xxx/ql4_bsg.c | |||
@@ -16,36 +16,31 @@ qla4xxx_read_flash(struct bsg_job *bsg_job) | |||
16 | struct scsi_qla_host *ha = to_qla_host(host); | 16 | struct scsi_qla_host *ha = to_qla_host(host); |
17 | struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; | 17 | struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; |
18 | struct iscsi_bsg_request *bsg_req = bsg_job->request; | 18 | struct iscsi_bsg_request *bsg_req = bsg_job->request; |
19 | uint32_t sg_cnt; | ||
20 | uint32_t offset = 0; | 19 | uint32_t offset = 0; |
21 | uint32_t length = 0; | 20 | uint32_t length = 0; |
22 | dma_addr_t flash_dma; | 21 | dma_addr_t flash_dma; |
23 | uint8_t *flash = NULL; | 22 | uint8_t *flash = NULL; |
24 | int rval = 0; | 23 | int rval = -EINVAL; |
25 | 24 | ||
26 | bsg_reply->reply_payload_rcv_len = 0; | 25 | bsg_reply->reply_payload_rcv_len = 0; |
27 | 26 | ||
28 | if (unlikely(pci_channel_offline(ha->pdev))) | 27 | if (unlikely(pci_channel_offline(ha->pdev))) |
29 | return -EINVAL; | 28 | goto leave; |
30 | 29 | ||
31 | if (ha->flash_state != QLFLASH_WAITING) | 30 | if (ql4xxx_reset_active(ha)) { |
32 | return -EBUSY; | 31 | ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); |
33 | 32 | rval = -EBUSY; | |
34 | /* TODO: Add check for adapter online, reset active?? */ | 33 | goto leave; |
35 | sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, | 34 | } |
36 | bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); | ||
37 | |||
38 | if (!sg_cnt) | ||
39 | return -ENOMEM; | ||
40 | 35 | ||
41 | if (sg_cnt != bsg_job->reply_payload.sg_cnt) { | 36 | if (ha->flash_state != QLFLASH_WAITING) { |
42 | ql4_printk(KERN_ERR, ha, "dma mapping resulted in different" | 37 | ql4_printk(KERN_ERR, ha, "%s: another flash operation " |
43 | " sg counts, sg_cnt: %x dma_sg_cnt: %x\n", | 38 | "active\n", __func__); |
44 | bsg_job->reply_payload.sg_cnt, sg_cnt); | 39 | rval = -EBUSY; |
45 | rval = -EAGAIN; | 40 | goto leave; |
46 | goto unmap_sg; | ||
47 | } | 41 | } |
48 | 42 | ||
43 | ha->flash_state = QLFLASH_READING; | ||
49 | offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; | 44 | offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; |
50 | length = bsg_job->reply_payload.payload_len; | 45 | length = bsg_job->reply_payload.payload_len; |
51 | 46 | ||
@@ -55,31 +50,27 @@ qla4xxx_read_flash(struct bsg_job *bsg_job) | |||
55 | ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash " | 50 | ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash " |
56 | "data\n", __func__); | 51 | "data\n", __func__); |
57 | rval = -ENOMEM; | 52 | rval = -ENOMEM; |
58 | goto unmap_sg; | 53 | goto leave; |
59 | } | 54 | } |
60 | 55 | ||
61 | ha->flash_state = QLFLASH_READING; | 56 | rval = qla4xxx_get_flash(ha, flash_dma, offset, length); |
62 | if (qla4xxx_get_flash(ha, flash_dma, offset, length)) | 57 | if (rval) { |
63 | bsg_reply->result = (DID_ERROR << 16); | 58 | ql4_printk(KERN_ERR, ha, "%s: get flash failed\n", __func__); |
64 | else { | 59 | bsg_reply->result = DID_ERROR << 16; |
65 | sg_copy_from_buffer(bsg_job->reply_payload.sg_list, | 60 | rval = -EIO; |
66 | bsg_job->reply_payload.sg_cnt, | 61 | } else { |
67 | flash, length); | 62 | bsg_reply->reply_payload_rcv_len = |
68 | 63 | sg_copy_from_buffer(bsg_job->reply_payload.sg_list, | |
69 | bsg_reply->result = DID_OK; | 64 | bsg_job->reply_payload.sg_cnt, |
70 | bsg_reply->reply_payload_rcv_len = length; | 65 | flash, length); |
66 | bsg_reply->result = DID_OK << 16; | ||
71 | } | 67 | } |
72 | 68 | ||
73 | if (flash) | 69 | bsg_job_done(bsg_job, bsg_reply->result, |
74 | dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma); | 70 | bsg_reply->reply_payload_rcv_len); |
75 | 71 | dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma); | |
72 | leave: | ||
76 | ha->flash_state = QLFLASH_WAITING; | 73 | ha->flash_state = QLFLASH_WAITING; |
77 | unmap_sg: | ||
78 | dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, | ||
79 | bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE); | ||
80 | if (!rval) | ||
81 | bsg_job_done(bsg_job, bsg_reply->result, | ||
82 | bsg_reply->reply_payload_rcv_len); | ||
83 | return rval; | 74 | return rval; |
84 | } | 75 | } |
85 | 76 | ||
@@ -90,36 +81,32 @@ qla4xxx_update_flash(struct bsg_job *bsg_job) | |||
90 | struct scsi_qla_host *ha = to_qla_host(host); | 81 | struct scsi_qla_host *ha = to_qla_host(host); |
91 | struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; | 82 | struct iscsi_bsg_reply *bsg_reply = bsg_job->reply; |
92 | struct iscsi_bsg_request *bsg_req = bsg_job->request; | 83 | struct iscsi_bsg_request *bsg_req = bsg_job->request; |
93 | uint32_t sg_cnt; | ||
94 | uint32_t length = 0; | 84 | uint32_t length = 0; |
95 | uint32_t offset = 0; | 85 | uint32_t offset = 0; |
96 | uint32_t options = 0; | 86 | uint32_t options = 0; |
97 | dma_addr_t flash_dma; | 87 | dma_addr_t flash_dma; |
98 | uint8_t *flash = NULL; | 88 | uint8_t *flash = NULL; |
99 | int rval = 0; | 89 | int rval = -EINVAL; |
100 | 90 | ||
101 | bsg_reply->reply_payload_rcv_len = 0; | 91 | bsg_reply->reply_payload_rcv_len = 0; |
102 | 92 | ||
103 | if (unlikely(pci_channel_offline(ha->pdev))) | 93 | if (unlikely(pci_channel_offline(ha->pdev))) |
104 | return -EINVAL; | 94 | goto leave; |
105 | |||
106 | if (ha->flash_state != QLFLASH_WAITING) | ||
107 | return -EBUSY; | ||
108 | 95 | ||
109 | sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, | 96 | if (ql4xxx_reset_active(ha)) { |
110 | bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); | 97 | ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__); |
111 | 98 | rval = -EBUSY; | |
112 | if (!sg_cnt) | 99 | goto leave; |
113 | return -ENOMEM; | 100 | } |
114 | 101 | ||
115 | if (sg_cnt != bsg_job->request_payload.sg_cnt) { | 102 | if (ha->flash_state != QLFLASH_WAITING) { |
116 | ql4_printk(KERN_ERR, ha, "dma mapping resulted in different " | 103 | ql4_printk(KERN_ERR, ha, "%s: another flash operation " |
117 | "sg counts request_sg_cnt: %x dma_request_sg_cnt: " | 104 | "active\n", __func__); |
118 | "%x\n", bsg_job->request_payload.sg_cnt, sg_cnt); | 105 | rval = -EBUSY; |
119 | rval = -EAGAIN; | 106 | goto leave; |
120 | goto unmap_sg; | ||
121 | } | 107 | } |
122 | 108 | ||
109 | ha->flash_state = QLFLASH_WRITING; | ||
123 | length = bsg_job->request_payload.payload_len; | 110 | length = bsg_job->request_payload.payload_len; |
124 | offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; | 111 | offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1]; |
125 | options = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; | 112 | options = bsg_req->rqst_data.h_vendor.vendor_cmd[2]; |
@@ -130,30 +117,25 @@ qla4xxx_update_flash(struct bsg_job *bsg_job) | |||
130 | ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash " | 117 | ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash " |
131 | "data\n", __func__); | 118 | "data\n", __func__); |
132 | rval = -ENOMEM; | 119 | rval = -ENOMEM; |
133 | goto unmap_sg; | 120 | goto leave; |
134 | } | 121 | } |
135 | 122 | ||
136 | ha->flash_state = QLFLASH_WRITING; | ||
137 | sg_copy_to_buffer(bsg_job->request_payload.sg_list, | 123 | sg_copy_to_buffer(bsg_job->request_payload.sg_list, |
138 | bsg_job->request_payload.sg_cnt, flash, length); | 124 | bsg_job->request_payload.sg_cnt, flash, length); |
139 | 125 | ||
140 | if (qla4xxx_set_flash(ha, flash_dma, offset, length, options)) | 126 | rval = qla4xxx_set_flash(ha, flash_dma, offset, length, options); |
141 | bsg_reply->result = (DID_ERROR << 16); | 127 | if (rval) { |
142 | else { | 128 | ql4_printk(KERN_ERR, ha, "%s: set flash failed\n", __func__); |
143 | bsg_reply->result = DID_OK; | 129 | bsg_reply->result = DID_ERROR << 16; |
144 | bsg_reply->reply_payload_rcv_len = length; | 130 | rval = -EIO; |
145 | } | 131 | } else |
146 | 132 | bsg_reply->result = DID_OK << 16; | |
147 | if (flash) | 133 | |
148 | dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma); | 134 | bsg_job_done(bsg_job, bsg_reply->result, |
135 | bsg_reply->reply_payload_rcv_len); | ||
136 | dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma); | ||
137 | leave: | ||
149 | ha->flash_state = QLFLASH_WAITING; | 138 | ha->flash_state = QLFLASH_WAITING; |
150 | unmap_sg: | ||
151 | dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list, | ||
152 | bsg_job->reply_payload.sg_cnt, DMA_TO_DEVICE); | ||
153 | |||
154 | if (!rval) | ||
155 | bsg_job_done(bsg_job, bsg_reply->result, | ||
156 | bsg_reply->reply_payload_rcv_len); | ||
157 | return rval; | 139 | return rval; |
158 | } | 140 | } |
159 | 141 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 90dc621a926a..74c71af7cb5d 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -803,6 +803,16 @@ static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a) | |||
803 | ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK); | 803 | ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK); |
804 | } | 804 | } |
805 | 805 | ||
806 | static inline int ql4xxx_reset_active(struct scsi_qla_host *ha) | ||
807 | { | ||
808 | return test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) || | ||
809 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || | ||
810 | test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags) || | ||
811 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || | ||
812 | test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags) || | ||
813 | test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags); | ||
814 | |||
815 | } | ||
806 | /*---------------------------------------------------------------------------*/ | 816 | /*---------------------------------------------------------------------------*/ |
807 | 817 | ||
808 | /* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */ | 818 | /* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */ |