Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livep...
[cascardo/linux.git] / drivers / scsi / qla4xxx / ql4_bsg.c
1 /*
2  * QLogic iSCSI HBA Driver
3  * Copyright (c) 2011-2013 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
43         ha->flash_state = QLFLASH_READING;
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:
73         ha->flash_state = QLFLASH_WAITING;
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
109         ha->flash_state = QLFLASH_WRITING;
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:
138         ha->flash_state = QLFLASH_WAITING;
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;
149         uint32_t status[MBOX_REG_COUNT];
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
449 static void ql4xxx_execute_diag_cmd(struct bsg_job *bsg_job)
450 {
451         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
452         struct scsi_qla_host *ha = to_qla_host(host);
453         struct iscsi_bsg_request *bsg_req = bsg_job->request;
454         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
455         uint8_t *rsp_ptr = NULL;
456         uint32_t mbox_cmd[MBOX_REG_COUNT];
457         uint32_t mbox_sts[MBOX_REG_COUNT];
458         int status = QLA_ERROR;
459
460         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
461
462         if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
463                 ql4_printk(KERN_INFO, ha, "%s: Adapter reset in progress. Invalid Request\n",
464                            __func__);
465                 bsg_reply->result = DID_ERROR << 16;
466                 goto exit_diag_mem_test;
467         }
468
469         bsg_reply->reply_payload_rcv_len = 0;
470         memcpy(mbox_cmd, &bsg_req->rqst_data.h_vendor.vendor_cmd[1],
471                sizeof(uint32_t) * MBOX_REG_COUNT);
472
473         DEBUG2(ql4_printk(KERN_INFO, ha,
474                           "%s: mbox_cmd: %08X %08X %08X %08X %08X %08X %08X %08X\n",
475                           __func__, mbox_cmd[0], mbox_cmd[1], mbox_cmd[2],
476                           mbox_cmd[3], mbox_cmd[4], mbox_cmd[5], mbox_cmd[6],
477                           mbox_cmd[7]));
478
479         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],
480                                          &mbox_sts[0]);
481
482         DEBUG2(ql4_printk(KERN_INFO, ha,
483                           "%s: mbox_sts: %08X %08X %08X %08X %08X %08X %08X %08X\n",
484                           __func__, mbox_sts[0], mbox_sts[1], mbox_sts[2],
485                           mbox_sts[3], mbox_sts[4], mbox_sts[5], mbox_sts[6],
486                           mbox_sts[7]));
487
488         if (status == QLA_SUCCESS)
489                 bsg_reply->result = DID_OK << 16;
490         else
491                 bsg_reply->result = DID_ERROR << 16;
492
493         /* Send mbox_sts to application */
494         bsg_job->reply_len = sizeof(struct iscsi_bsg_reply) + sizeof(mbox_sts);
495         rsp_ptr = ((uint8_t *)bsg_reply) + sizeof(struct iscsi_bsg_reply);
496         memcpy(rsp_ptr, mbox_sts, sizeof(mbox_sts));
497
498 exit_diag_mem_test:
499         DEBUG2(ql4_printk(KERN_INFO, ha,
500                           "%s: bsg_reply->result = x%x, status = %s\n",
501                           __func__, bsg_reply->result, STATUS(status)));
502
503         bsg_job_done(bsg_job, bsg_reply->result,
504                      bsg_reply->reply_payload_rcv_len);
505 }
506
507 static int qla4_83xx_wait_for_loopback_config_comp(struct scsi_qla_host *ha,
508                                                    int wait_for_link)
509 {
510         int status = QLA_SUCCESS;
511
512         if (!wait_for_completion_timeout(&ha->idc_comp, (IDC_COMP_TOV * HZ))) {
513                 ql4_printk(KERN_INFO, ha, "%s: IDC Complete notification not received, Waiting for another %d timeout",
514                            __func__, ha->idc_extend_tmo);
515                 if (ha->idc_extend_tmo) {
516                         if (!wait_for_completion_timeout(&ha->idc_comp,
517                                                 (ha->idc_extend_tmo * HZ))) {
518                                 ha->notify_idc_comp = 0;
519                                 ha->notify_link_up_comp = 0;
520                                 ql4_printk(KERN_WARNING, ha, "%s: Aborting: IDC Complete notification not received",
521                                            __func__);
522                                 status = QLA_ERROR;
523                                 goto exit_wait;
524                         } else {
525                                 DEBUG2(ql4_printk(KERN_INFO, ha,
526                                                   "%s: IDC Complete notification received\n",
527                                                   __func__));
528                         }
529                 }
530         } else {
531                 DEBUG2(ql4_printk(KERN_INFO, ha,
532                                   "%s: IDC Complete notification received\n",
533                                   __func__));
534         }
535         ha->notify_idc_comp = 0;
536
537         if (wait_for_link) {
538                 if (!wait_for_completion_timeout(&ha->link_up_comp,
539                                                  (IDC_COMP_TOV * HZ))) {
540                         ha->notify_link_up_comp = 0;
541                         ql4_printk(KERN_WARNING, ha, "%s: Aborting: LINK UP notification not received",
542                                    __func__);
543                         status = QLA_ERROR;
544                         goto exit_wait;
545                 } else {
546                         DEBUG2(ql4_printk(KERN_INFO, ha,
547                                           "%s: LINK UP notification received\n",
548                                           __func__));
549                 }
550                 ha->notify_link_up_comp = 0;
551         }
552
553 exit_wait:
554         return status;
555 }
556
557 static int qla4_83xx_pre_loopback_config(struct scsi_qla_host *ha,
558                                          uint32_t *mbox_cmd)
559 {
560         uint32_t config = 0;
561         int status = QLA_SUCCESS;
562
563         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
564
565         status = qla4_83xx_get_port_config(ha, &config);
566         if (status != QLA_SUCCESS)
567                 goto exit_pre_loopback_config;
568
569         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Default port config=%08X\n",
570                           __func__, config));
571
572         if ((config & ENABLE_INTERNAL_LOOPBACK) ||
573             (config & ENABLE_EXTERNAL_LOOPBACK)) {
574                 ql4_printk(KERN_INFO, ha, "%s: Loopback diagnostics already in progress. Invalid requiest\n",
575                            __func__);
576                 goto exit_pre_loopback_config;
577         }
578
579         if (mbox_cmd[1] == QL_DIAG_CMD_TEST_INT_LOOPBACK)
580                 config |= ENABLE_INTERNAL_LOOPBACK;
581
582         if (mbox_cmd[1] == QL_DIAG_CMD_TEST_EXT_LOOPBACK)
583                 config |= ENABLE_EXTERNAL_LOOPBACK;
584
585         config &= ~ENABLE_DCBX;
586
587         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: New port config=%08X\n",
588                           __func__, config));
589
590         ha->notify_idc_comp = 1;
591         ha->notify_link_up_comp = 1;
592
593         /* get the link state */
594         qla4xxx_get_firmware_state(ha);
595
596         status = qla4_83xx_set_port_config(ha, &config);
597         if (status != QLA_SUCCESS) {
598                 ha->notify_idc_comp = 0;
599                 ha->notify_link_up_comp = 0;
600                 goto exit_pre_loopback_config;
601         }
602 exit_pre_loopback_config:
603         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: status = %s\n", __func__,
604                           STATUS(status)));
605         return status;
606 }
607
608 static int qla4_83xx_post_loopback_config(struct scsi_qla_host *ha,
609                                           uint32_t *mbox_cmd)
610 {
611         int status = QLA_SUCCESS;
612         uint32_t config = 0;
613
614         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
615
616         status = qla4_83xx_get_port_config(ha, &config);
617         if (status != QLA_SUCCESS)
618                 goto exit_post_loopback_config;
619
620         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: port config=%08X\n", __func__,
621                           config));
622
623         if (mbox_cmd[1] == QL_DIAG_CMD_TEST_INT_LOOPBACK)
624                 config &= ~ENABLE_INTERNAL_LOOPBACK;
625         else if (mbox_cmd[1] == QL_DIAG_CMD_TEST_EXT_LOOPBACK)
626                 config &= ~ENABLE_EXTERNAL_LOOPBACK;
627
628         config |= ENABLE_DCBX;
629
630         DEBUG2(ql4_printk(KERN_INFO, ha,
631                           "%s: Restore default port config=%08X\n", __func__,
632                           config));
633
634         ha->notify_idc_comp = 1;
635         if (ha->addl_fw_state & FW_ADDSTATE_LINK_UP)
636                 ha->notify_link_up_comp = 1;
637
638         status = qla4_83xx_set_port_config(ha, &config);
639         if (status != QLA_SUCCESS) {
640                 ql4_printk(KERN_INFO, ha, "%s: Scheduling adapter reset\n",
641                            __func__);
642                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
643                 clear_bit(AF_LOOPBACK, &ha->flags);
644                 goto exit_post_loopback_config;
645         }
646
647 exit_post_loopback_config:
648         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: status = %s\n", __func__,
649                           STATUS(status)));
650         return status;
651 }
652
653 static void qla4xxx_execute_diag_loopback_cmd(struct bsg_job *bsg_job)
654 {
655         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
656         struct scsi_qla_host *ha = to_qla_host(host);
657         struct iscsi_bsg_request *bsg_req = bsg_job->request;
658         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
659         uint8_t *rsp_ptr = NULL;
660         uint32_t mbox_cmd[MBOX_REG_COUNT];
661         uint32_t mbox_sts[MBOX_REG_COUNT];
662         int wait_for_link = 1;
663         int status = QLA_ERROR;
664
665         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
666
667         bsg_reply->reply_payload_rcv_len = 0;
668
669         if (test_bit(AF_LOOPBACK, &ha->flags)) {
670                 ql4_printk(KERN_INFO, ha, "%s: Loopback Diagnostics already in progress. Invalid Request\n",
671                            __func__);
672                 bsg_reply->result = DID_ERROR << 16;
673                 goto exit_loopback_cmd;
674         }
675
676         if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
677                 ql4_printk(KERN_INFO, ha, "%s: Adapter reset in progress. Invalid Request\n",
678                            __func__);
679                 bsg_reply->result = DID_ERROR << 16;
680                 goto exit_loopback_cmd;
681         }
682
683         memcpy(mbox_cmd, &bsg_req->rqst_data.h_vendor.vendor_cmd[1],
684                sizeof(uint32_t) * MBOX_REG_COUNT);
685
686         if (is_qla8032(ha) || is_qla8042(ha)) {
687                 status = qla4_83xx_pre_loopback_config(ha, mbox_cmd);
688                 if (status != QLA_SUCCESS) {
689                         bsg_reply->result = DID_ERROR << 16;
690                         goto exit_loopback_cmd;
691                 }
692
693                 status = qla4_83xx_wait_for_loopback_config_comp(ha,
694                                                                  wait_for_link);
695                 if (status != QLA_SUCCESS) {
696                         bsg_reply->result = DID_TIME_OUT << 16;
697                         goto restore;
698                 }
699         }
700
701         DEBUG2(ql4_printk(KERN_INFO, ha,
702                           "%s: mbox_cmd: %08X %08X %08X %08X %08X %08X %08X %08X\n",
703                           __func__, mbox_cmd[0], mbox_cmd[1], mbox_cmd[2],
704                           mbox_cmd[3], mbox_cmd[4], mbox_cmd[5], mbox_cmd[6],
705                           mbox_cmd[7]));
706
707         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],
708                                 &mbox_sts[0]);
709
710         if (status == QLA_SUCCESS)
711                 bsg_reply->result = DID_OK << 16;
712         else
713                 bsg_reply->result = DID_ERROR << 16;
714
715         DEBUG2(ql4_printk(KERN_INFO, ha,
716                           "%s: mbox_sts: %08X %08X %08X %08X %08X %08X %08X %08X\n",
717                           __func__, mbox_sts[0], mbox_sts[1], mbox_sts[2],
718                           mbox_sts[3], mbox_sts[4], mbox_sts[5], mbox_sts[6],
719                           mbox_sts[7]));
720
721         /* Send mbox_sts to application */
722         bsg_job->reply_len = sizeof(struct iscsi_bsg_reply) + sizeof(mbox_sts);
723         rsp_ptr = ((uint8_t *)bsg_reply) + sizeof(struct iscsi_bsg_reply);
724         memcpy(rsp_ptr, mbox_sts, sizeof(mbox_sts));
725 restore:
726         if (is_qla8032(ha) || is_qla8042(ha)) {
727                 status = qla4_83xx_post_loopback_config(ha, mbox_cmd);
728                 if (status != QLA_SUCCESS) {
729                         bsg_reply->result = DID_ERROR << 16;
730                         goto exit_loopback_cmd;
731                 }
732
733                 /* for pre_loopback_config() wait for LINK UP only
734                  * if PHY LINK is UP */
735                 if (!(ha->addl_fw_state & FW_ADDSTATE_LINK_UP))
736                         wait_for_link = 0;
737
738                 status = qla4_83xx_wait_for_loopback_config_comp(ha,
739                                                                  wait_for_link);
740                 if (status != QLA_SUCCESS) {
741                         bsg_reply->result = DID_TIME_OUT << 16;
742                         goto exit_loopback_cmd;
743                 }
744         }
745 exit_loopback_cmd:
746         DEBUG2(ql4_printk(KERN_INFO, ha,
747                           "%s: bsg_reply->result = x%x, status = %s\n",
748                           __func__, bsg_reply->result, STATUS(status)));
749         bsg_job_done(bsg_job, bsg_reply->result,
750                      bsg_reply->reply_payload_rcv_len);
751 }
752
753 static int qla4xxx_execute_diag_test(struct bsg_job *bsg_job)
754 {
755         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
756         struct scsi_qla_host *ha = to_qla_host(host);
757         struct iscsi_bsg_request *bsg_req = bsg_job->request;
758         uint32_t diag_cmd;
759         int rval = -EINVAL;
760
761         DEBUG2(ql4_printk(KERN_INFO, ha, "%s: in\n", __func__));
762
763         diag_cmd = bsg_req->rqst_data.h_vendor.vendor_cmd[1];
764         if (diag_cmd == MBOX_CMD_DIAG_TEST) {
765                 switch (bsg_req->rqst_data.h_vendor.vendor_cmd[2]) {
766                 case QL_DIAG_CMD_TEST_DDR_SIZE:
767                 case QL_DIAG_CMD_TEST_DDR_RW:
768                 case QL_DIAG_CMD_TEST_ONCHIP_MEM_RW:
769                 case QL_DIAG_CMD_TEST_NVRAM:
770                 case QL_DIAG_CMD_TEST_FLASH_ROM:
771                 case QL_DIAG_CMD_TEST_DMA_XFER:
772                 case QL_DIAG_CMD_SELF_DDR_RW:
773                 case QL_DIAG_CMD_SELF_ONCHIP_MEM_RW:
774                         /* Execute diag test for adapter RAM/FLASH */
775                         ql4xxx_execute_diag_cmd(bsg_job);
776                         /* Always return success as we want to sent bsg_reply
777                          * to Application */
778                         rval = QLA_SUCCESS;
779                         break;
780
781                 case QL_DIAG_CMD_TEST_INT_LOOPBACK:
782                 case QL_DIAG_CMD_TEST_EXT_LOOPBACK:
783                         /* Execute diag test for Network */
784                         qla4xxx_execute_diag_loopback_cmd(bsg_job);
785                         /* Always return success as we want to sent bsg_reply
786                          * to Application */
787                         rval = QLA_SUCCESS;
788                         break;
789                 default:
790                         ql4_printk(KERN_ERR, ha, "%s: Invalid diag test: 0x%x\n",
791                                    __func__,
792                                    bsg_req->rqst_data.h_vendor.vendor_cmd[2]);
793                 }
794         } else if ((diag_cmd == MBOX_CMD_SET_LED_CONFIG) ||
795                    (diag_cmd == MBOX_CMD_GET_LED_CONFIG)) {
796                 ql4xxx_execute_diag_cmd(bsg_job);
797                 rval = QLA_SUCCESS;
798         } else {
799                 ql4_printk(KERN_ERR, ha, "%s: Invalid diag cmd: 0x%x\n",
800                            __func__, diag_cmd);
801         }
802
803         return rval;
804 }
805
806 /**
807  * qla4xxx_process_vendor_specific - handle vendor specific bsg request
808  * @job: iscsi_bsg_job to handle
809  **/
810 int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job)
811 {
812         struct iscsi_bsg_reply *bsg_reply = bsg_job->reply;
813         struct iscsi_bsg_request *bsg_req = bsg_job->request;
814         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
815         struct scsi_qla_host *ha = to_qla_host(host);
816
817         switch (bsg_req->rqst_data.h_vendor.vendor_cmd[0]) {
818         case QLISCSI_VND_READ_FLASH:
819                 return qla4xxx_read_flash(bsg_job);
820
821         case QLISCSI_VND_UPDATE_FLASH:
822                 return qla4xxx_update_flash(bsg_job);
823
824         case QLISCSI_VND_GET_ACB_STATE:
825                 return qla4xxx_get_acb_state(bsg_job);
826
827         case QLISCSI_VND_READ_NVRAM:
828                 return qla4xxx_read_nvram(bsg_job);
829
830         case QLISCSI_VND_UPDATE_NVRAM:
831                 return qla4xxx_update_nvram(bsg_job);
832
833         case QLISCSI_VND_RESTORE_DEFAULTS:
834                 return qla4xxx_restore_defaults(bsg_job);
835
836         case QLISCSI_VND_GET_ACB:
837                 return qla4xxx_bsg_get_acb(bsg_job);
838
839         case QLISCSI_VND_DIAG_TEST:
840                 return qla4xxx_execute_diag_test(bsg_job);
841
842         default:
843                 ql4_printk(KERN_ERR, ha, "%s: invalid BSG vendor command: "
844                            "0x%x\n", __func__, bsg_req->msgcode);
845                 bsg_reply->result = (DID_ERROR << 16);
846                 bsg_reply->reply_payload_rcv_len = 0;
847                 bsg_job_done(bsg_job, bsg_reply->result,
848                              bsg_reply->reply_payload_rcv_len);
849                 return -ENOSYS;
850         }
851 }
852
853 /**
854  * qla4xxx_bsg_request - handle bsg request from ISCSI transport
855  * @job: iscsi_bsg_job to handle
856  */
857 int qla4xxx_bsg_request(struct bsg_job *bsg_job)
858 {
859         struct iscsi_bsg_request *bsg_req = bsg_job->request;
860         struct Scsi_Host *host = iscsi_job_to_shost(bsg_job);
861         struct scsi_qla_host *ha = to_qla_host(host);
862
863         switch (bsg_req->msgcode) {
864         case ISCSI_BSG_HST_VENDOR:
865                 return qla4xxx_process_vendor_specific(bsg_job);
866
867         default:
868                 ql4_printk(KERN_ERR, ha, "%s: invalid BSG command: 0x%x\n",
869                            __func__, bsg_req->msgcode);
870         }
871
872         return -ENOSYS;
873 }