Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ql4_bsg.c
Go to the documentation of this file.
1 /*
2  * QLogic iSCSI HBA Driver
3  * Copyright (c) 2011 QLogic Corporation
4  *
5  * See LICENSE.qla4xxx for copyright and licensing details.
6  */
7 
8 #include "ql4_def.h"
9 #include "ql4_glbl.h"
10 #include "ql4_bsg.h"
11 
12 static int
13 qla4xxx_read_flash(struct bsg_job *bsg_job)
14 {
15  struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
16  struct scsi_qla_host *ha = to_qla_host(host);
17  struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
18  struct iscsi_bsg_request *bsg_req = bsg_job->request;
19  uint32_t offset = 0;
20  uint32_t length = 0;
21  dma_addr_t flash_dma;
22  uint8_t *flash = NULL;
23  int rval = -EINVAL;
24 
25  bsg_reply->reply_payload_rcv_len = 0;
26 
27  if (unlikely(pci_channel_offline(ha->pdev)))
28  goto leave;
29 
30  if (ql4xxx_reset_active(ha)) {
31  ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
32  rval = -EBUSY;
33  goto leave;
34  }
35 
36  if (ha->flash_state != QLFLASH_WAITING) {
37  ql4_printk(KERN_ERR, ha, "%s: another flash operation "
38  "active\n", __func__);
39  rval = -EBUSY;
40  goto leave;
41  }
42 
44  offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
45  length = bsg_job->reply_payload.payload_len;
46 
47  flash = dma_alloc_coherent(&ha->pdev->dev, length, &flash_dma,
48  GFP_KERNEL);
49  if (!flash) {
50  ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash "
51  "data\n", __func__);
52  rval = -ENOMEM;
53  goto leave;
54  }
55 
56  rval = qla4xxx_get_flash(ha, flash_dma, offset, length);
57  if (rval) {
58  ql4_printk(KERN_ERR, ha, "%s: get flash failed\n", __func__);
59  bsg_reply->result = DID_ERROR << 16;
60  rval = -EIO;
61  } else {
62  bsg_reply->reply_payload_rcv_len =
63  sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
64  bsg_job->reply_payload.sg_cnt,
65  flash, length);
66  bsg_reply->result = DID_OK << 16;
67  }
68 
69  bsg_job_done(bsg_job, bsg_reply->result,
70  bsg_reply->reply_payload_rcv_len);
71  dma_free_coherent(&ha->pdev->dev, length, flash, flash_dma);
72 leave:
74  return rval;
75 }
76 
77 static int
78 qla4xxx_update_flash(struct bsg_job *bsg_job)
79 {
80  struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
81  struct scsi_qla_host *ha = to_qla_host(host);
82  struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
83  struct iscsi_bsg_request *bsg_req = bsg_job->request;
84  uint32_t length = 0;
85  uint32_t offset = 0;
86  uint32_t options = 0;
87  dma_addr_t flash_dma;
88  uint8_t *flash = NULL;
89  int rval = -EINVAL;
90 
91  bsg_reply->reply_payload_rcv_len = 0;
92 
93  if (unlikely(pci_channel_offline(ha->pdev)))
94  goto leave;
95 
96  if (ql4xxx_reset_active(ha)) {
97  ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
98  rval = -EBUSY;
99  goto leave;
100  }
101 
102  if (ha->flash_state != QLFLASH_WAITING) {
103  ql4_printk(KERN_ERR, ha, "%s: another flash operation "
104  "active\n", __func__);
105  rval = -EBUSY;
106  goto leave;
107  }
108 
110  length = bsg_job->request_payload.payload_len;
111  offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
112  options = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
113 
114  flash = dma_alloc_coherent(&ha->pdev->dev, length, &flash_dma,
115  GFP_KERNEL);
116  if (!flash) {
117  ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash "
118  "data\n", __func__);
119  rval = -ENOMEM;
120  goto leave;
121  }
122 
123  sg_copy_to_buffer(bsg_job->request_payload.sg_list,
124  bsg_job->request_payload.sg_cnt, flash, length);
125 
126  rval = qla4xxx_set_flash(ha, flash_dma, offset, length, options);
127  if (rval) {
128  ql4_printk(KERN_ERR, ha, "%s: set flash failed\n", __func__);
129  bsg_reply->result = DID_ERROR << 16;
130  rval = -EIO;
131  } else
132  bsg_reply->result = DID_OK << 16;
133 
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:
139  return rval;
140 }
141 
142 static int
143 qla4xxx_get_acb_state(struct bsg_job *bsg_job)
144 {
145  struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
146  struct scsi_qla_host *ha = to_qla_host(host);
147  struct iscsi_bsg_request *bsg_req = bsg_job->request;
148  struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
150  uint32_t acb_idx;
151  uint32_t ip_idx;
152  int rval = -EINVAL;
153 
154  bsg_reply->reply_payload_rcv_len = 0;
155 
156  if (unlikely(pci_channel_offline(ha->pdev)))
157  goto leave;
158 
159  /* Only 4022 and above adapters are supported */
160  if (is_qla4010(ha))
161  goto leave;
162 
163  if (ql4xxx_reset_active(ha)) {
164  ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
165  rval = -EBUSY;
166  goto leave;
167  }
168 
169  if (bsg_job->reply_payload.payload_len < sizeof(status)) {
170  ql4_printk(KERN_ERR, ha, "%s: invalid payload len %d\n",
171  __func__, bsg_job->reply_payload.payload_len);
172  rval = -EINVAL;
173  goto leave;
174  }
175 
176  acb_idx = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
177  ip_idx = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
178 
179  rval = qla4xxx_get_ip_state(ha, acb_idx, ip_idx, status);
180  if (rval) {
181  ql4_printk(KERN_ERR, ha, "%s: get ip state failed\n",
182  __func__);
183  bsg_reply->result = DID_ERROR << 16;
184  rval = -EIO;
185  } else {
186  bsg_reply->reply_payload_rcv_len =
187  sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
188  bsg_job->reply_payload.sg_cnt,
189  status, sizeof(status));
190  bsg_reply->result = DID_OK << 16;
191  }
192 
193  bsg_job_done(bsg_job, bsg_reply->result,
194  bsg_reply->reply_payload_rcv_len);
195 leave:
196  return rval;
197 }
198 
199 static int
200 qla4xxx_read_nvram(struct bsg_job *bsg_job)
201 {
202  struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
203  struct scsi_qla_host *ha = to_qla_host(host);
204  struct iscsi_bsg_request *bsg_req = bsg_job->request;
205  struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
206  uint32_t offset = 0;
207  uint32_t len = 0;
208  uint32_t total_len = 0;
209  dma_addr_t nvram_dma;
210  uint8_t *nvram = NULL;
211  int rval = -EINVAL;
212 
213  bsg_reply->reply_payload_rcv_len = 0;
214 
215  if (unlikely(pci_channel_offline(ha->pdev)))
216  goto leave;
217 
218  /* Only 40xx adapters are supported */
219  if (!(is_qla4010(ha) || is_qla4022(ha) || is_qla4032(ha)))
220  goto leave;
221 
222  if (ql4xxx_reset_active(ha)) {
223  ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
224  rval = -EBUSY;
225  goto leave;
226  }
227 
228  offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
229  len = bsg_job->reply_payload.payload_len;
230  total_len = offset + len;
231 
232  /* total len should not be greater than max NVRAM size */
233  if ((is_qla4010(ha) && total_len > QL4010_NVRAM_SIZE) ||
234  ((is_qla4022(ha) || is_qla4032(ha)) &&
235  total_len > QL40X2_NVRAM_SIZE)) {
236  ql4_printk(KERN_ERR, ha, "%s: offset+len greater than max"
237  " nvram size, offset=%d len=%d\n",
238  __func__, offset, len);
239  goto leave;
240  }
241 
242  nvram = dma_alloc_coherent(&ha->pdev->dev, len, &nvram_dma,
243  GFP_KERNEL);
244  if (!nvram) {
245  ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for nvram "
246  "data\n", __func__);
247  rval = -ENOMEM;
248  goto leave;
249  }
250 
251  rval = qla4xxx_get_nvram(ha, nvram_dma, offset, len);
252  if (rval) {
253  ql4_printk(KERN_ERR, ha, "%s: get nvram failed\n", __func__);
254  bsg_reply->result = DID_ERROR << 16;
255  rval = -EIO;
256  } else {
257  bsg_reply->reply_payload_rcv_len =
258  sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
259  bsg_job->reply_payload.sg_cnt,
260  nvram, len);
261  bsg_reply->result = DID_OK << 16;
262  }
263 
264  bsg_job_done(bsg_job, bsg_reply->result,
265  bsg_reply->reply_payload_rcv_len);
266  dma_free_coherent(&ha->pdev->dev, len, nvram, nvram_dma);
267 leave:
268  return rval;
269 }
270 
271 static int
272 qla4xxx_update_nvram(struct bsg_job *bsg_job)
273 {
274  struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
275  struct scsi_qla_host *ha = to_qla_host(host);
276  struct iscsi_bsg_request *bsg_req = bsg_job->request;
277  struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
278  uint32_t offset = 0;
279  uint32_t len = 0;
280  uint32_t total_len = 0;
281  dma_addr_t nvram_dma;
282  uint8_t *nvram = NULL;
283  int rval = -EINVAL;
284 
285  bsg_reply->reply_payload_rcv_len = 0;
286 
287  if (unlikely(pci_channel_offline(ha->pdev)))
288  goto leave;
289 
290  if (!(is_qla4010(ha) || is_qla4022(ha) || is_qla4032(ha)))
291  goto leave;
292 
293  if (ql4xxx_reset_active(ha)) {
294  ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
295  rval = -EBUSY;
296  goto leave;
297  }
298 
299  offset = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
300  len = bsg_job->request_payload.payload_len;
301  total_len = offset + len;
302 
303  /* total len should not be greater than max NVRAM size */
304  if ((is_qla4010(ha) && total_len > QL4010_NVRAM_SIZE) ||
305  ((is_qla4022(ha) || is_qla4032(ha)) &&
306  total_len > QL40X2_NVRAM_SIZE)) {
307  ql4_printk(KERN_ERR, ha, "%s: offset+len greater than max"
308  " nvram size, offset=%d len=%d\n",
309  __func__, offset, len);
310  goto leave;
311  }
312 
313  nvram = dma_alloc_coherent(&ha->pdev->dev, len, &nvram_dma,
314  GFP_KERNEL);
315  if (!nvram) {
316  ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for flash "
317  "data\n", __func__);
318  rval = -ENOMEM;
319  goto leave;
320  }
321 
322  sg_copy_to_buffer(bsg_job->request_payload.sg_list,
323  bsg_job->request_payload.sg_cnt, nvram, len);
324 
325  rval = qla4xxx_set_nvram(ha, nvram_dma, offset, len);
326  if (rval) {
327  ql4_printk(KERN_ERR, ha, "%s: set nvram failed\n", __func__);
328  bsg_reply->result = DID_ERROR << 16;
329  rval = -EIO;
330  } else
331  bsg_reply->result = DID_OK << 16;
332 
333  bsg_job_done(bsg_job, bsg_reply->result,
334  bsg_reply->reply_payload_rcv_len);
335  dma_free_coherent(&ha->pdev->dev, len, nvram, nvram_dma);
336 leave:
337  return rval;
338 }
339 
340 static int
341 qla4xxx_restore_defaults(struct bsg_job *bsg_job)
342 {
343  struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
344  struct scsi_qla_host *ha = to_qla_host(host);
345  struct iscsi_bsg_request *bsg_req = bsg_job->request;
346  struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
347  uint32_t region = 0;
348  uint32_t field0 = 0;
349  uint32_t field1 = 0;
350  int rval = -EINVAL;
351 
352  bsg_reply->reply_payload_rcv_len = 0;
353 
354  if (unlikely(pci_channel_offline(ha->pdev)))
355  goto leave;
356 
357  if (is_qla4010(ha))
358  goto leave;
359 
360  if (ql4xxx_reset_active(ha)) {
361  ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
362  rval = -EBUSY;
363  goto leave;
364  }
365 
366  region = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
367  field0 = bsg_req->rqst_data.h_vendor.vendor_cmd[2];
368  field1 = bsg_req->rqst_data.h_vendor.vendor_cmd[3];
369 
370  rval = qla4xxx_restore_factory_defaults(ha, region, field0, field1);
371  if (rval) {
372  ql4_printk(KERN_ERR, ha, "%s: set nvram failed\n", __func__);
373  bsg_reply->result = DID_ERROR << 16;
374  rval = -EIO;
375  } else
376  bsg_reply->result = DID_OK << 16;
377 
378  bsg_job_done(bsg_job, bsg_reply->result,
379  bsg_reply->reply_payload_rcv_len);
380 leave:
381  return rval;
382 }
383 
384 static int
385 qla4xxx_bsg_get_acb(struct bsg_job *bsg_job)
386 {
387  struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
388  struct scsi_qla_host *ha = to_qla_host(host);
389  struct iscsi_bsg_request *bsg_req = bsg_job->request;
390  struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
391  uint32_t acb_type = 0;
392  uint32_t len = 0;
393  dma_addr_t acb_dma;
394  uint8_t *acb = NULL;
395  int rval = -EINVAL;
396 
397  bsg_reply->reply_payload_rcv_len = 0;
398 
399  if (unlikely(pci_channel_offline(ha->pdev)))
400  goto leave;
401 
402  /* Only 4022 and above adapters are supported */
403  if (is_qla4010(ha))
404  goto leave;
405 
406  if (ql4xxx_reset_active(ha)) {
407  ql4_printk(KERN_ERR, ha, "%s: reset active\n", __func__);
408  rval = -EBUSY;
409  goto leave;
410  }
411 
412  acb_type = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
413  len = bsg_job->reply_payload.payload_len;
414  if (len < sizeof(struct addr_ctrl_blk)) {
415  ql4_printk(KERN_ERR, ha, "%s: invalid acb len %d\n",
416  __func__, len);
417  rval = -EINVAL;
418  goto leave;
419  }
420 
421  acb = dma_alloc_coherent(&ha->pdev->dev, len, &acb_dma, GFP_KERNEL);
422  if (!acb) {
423  ql4_printk(KERN_ERR, ha, "%s: dma alloc failed for acb "
424  "data\n", __func__);
425  rval = -ENOMEM;
426  goto leave;
427  }
428 
429  rval = qla4xxx_get_acb(ha, acb_dma, acb_type, len);
430  if (rval) {
431  ql4_printk(KERN_ERR, ha, "%s: get acb failed\n", __func__);
432  bsg_reply->result = DID_ERROR << 16;
433  rval = -EIO;
434  } else {
435  bsg_reply->reply_payload_rcv_len =
436  sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
437  bsg_job->reply_payload.sg_cnt,
438  acb, len);
439  bsg_reply->result = DID_OK << 16;
440  }
441 
442  bsg_job_done(bsg_job, bsg_reply->result,
443  bsg_reply->reply_payload_rcv_len);
444  dma_free_coherent(&ha->pdev->dev, len, acb, acb_dma);
445 leave:
446  return rval;
447 }
448 
453 int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job)
454 {
455  struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
456  struct iscsi_bsg_request *bsg_req = bsg_job->request;
457  struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
458  struct scsi_qla_host *ha = to_qla_host(host);
459 
460  switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
462  return qla4xxx_read_flash(bsg_job);
463 
465  return qla4xxx_update_flash(bsg_job);
466 
468  return qla4xxx_get_acb_state(bsg_job);
469 
471  return qla4xxx_read_nvram(bsg_job);
472 
474  return qla4xxx_update_nvram(bsg_job);
475 
477  return qla4xxx_restore_defaults(bsg_job);
478 
479  case QLISCSI_VND_GET_ACB:
480  return qla4xxx_bsg_get_acb(bsg_job);
481 
482  default:
483  ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: "
484  "0x%x\n", __func__, bsg_req->msgcode);
485  bsg_reply->result = (DID_ERROR << 16);
486  bsg_reply->reply_payload_rcv_len = 0;
487  bsg_job_done(bsg_job, bsg_reply->result,
488  bsg_reply->reply_payload_rcv_len);
489  return -ENOSYS;
490  }
491 }
492 
497 int qla4xxx_bsg_request(struct bsg_job *bsg_job)
498 {
499  struct iscsi_bsg_request *bsg_req = bsg_job->request;
500  struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
501  struct scsi_qla_host *ha = to_qla_host(host);
502 
503  switch (bsg_req->msgcode) {
505  return qla4xxx_process_vendor_specific(bsg_job);
506 
507  default:
508  ql4_printk(KERN_ERR, ha, "%s: invalid BSG command: 0x%x\n",
509  __func__, bsg_req->msgcode);
510  }
511 
512  return -ENOSYS;
513 }