aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx/ql4_bsg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_bsg.c')
-rw-r--r--drivers/scsi/qla4xxx/ql4_bsg.c128
1 files changed, 55 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);
72leave:
76 ha->flash_state = QLFLASH_WAITING; 73 ha->flash_state = QLFLASH_WAITING;
77unmap_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);
137leave:
149 ha->flash_state = QLFLASH_WAITING; 138 ha->flash_state = QLFLASH_WAITING;
150unmap_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