Unreachable code
File: drivers/scsi/lpfc/.tmp_lpfc_scsi.o.preproc
Full description: The code is unreachable by any path. Superfluous semicolon, break or return statement.
Importance: 3
Checker: ReachabilityChecker
Trace:
This one is:
False positive index (the lower the better): 0
File contents (this file is distributed under the terms specified in the original file):
1|int _dump_buf_done;
2|
3|static char *dif_op_str[] = {
4| "SCSI_PROT_NORMAL",
5| "SCSI_PROT_READ_INSERT",
6| "SCSI_PROT_WRITE_STRIP",
7| "SCSI_PROT_READ_STRIP",
8| "SCSI_PROT_WRITE_INSERT",
9| "SCSI_PROT_READ_PASS",
10| "SCSI_PROT_WRITE_PASS",
11|};
12|static void
13|lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
14|static void
15|lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb);
16|
17|static void
18|lpfc_debug_save_data(struct lpfc_hba *phba, struct scsi_cmnd *cmnd)
19|{
20| void *src, *dst;
21| struct scatterlist *sgde = scsi_sglist(cmnd);
22|
23| if (!_dump_buf_data) {
24| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9050 BLKGRD: ERROR %s _dump_buf_data is NULL\n", phba->brd_no, __func__); } } while (0)
25|
26| ;
27| return;
28| }
29|
30|
31| if (!sgde) {
32| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9051 BLKGRD: ERROR: data scatterlist is null\n", phba->brd_no); } } while (0)
33| ;
34| return;
35| }
36|
37| dst = (void *) _dump_buf_data;
38| while (sgde) {
39| src = sg_virt(sgde);
40| __st_memcpy_st__(dst, src, sgde->length);
41| dst += sgde->length;
42| sgde = sg_next(sgde);
43| }
44|}
45|
46|static void
47|lpfc_debug_save_dif(struct lpfc_hba *phba, struct scsi_cmnd *cmnd)
48|{
49| void *src, *dst;
50| struct scatterlist *sgde = scsi_prot_sglist(cmnd);
51|
52| if (!_dump_buf_dif) {
53| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9052 BLKGRD: ERROR %s _dump_buf_data is NULL\n", phba->brd_no, __func__); } } while (0)
54|
55| ;
56| return;
57| }
58|
59| if (!sgde) {
60| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9053 BLKGRD: ERROR: prot scatterlist is null\n", phba->brd_no); } } while (0)
61| ;
62| return;
63| }
64|
65| dst = _dump_buf_dif;
66| while (sgde) {
67| src = sg_virt(sgde);
68| __st_memcpy_st__(dst, src, sgde->length);
69| dst += sgde->length;
70| sgde = sg_next(sgde);
71| }
72|}
73|static void
74|lpfc_sli4_set_rsp_sgl_last(struct lpfc_hba *phba,
75| struct lpfc_scsi_buf *lpfc_cmd)
76|{
77| struct sli4_sge *sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl;
78| if (sgl) {
79| sgl += 1;
80| sgl->word2 = (( __u32)(__le32)(sgl->word2));
81| ((sgl)->word2 = ((((1) & 0x00000001) << 31) | ((sgl)->word2 & ~(0x00000001 << 31))));
82| sgl->word2 = (( __le32)(__u32)(sgl->word2));
83| }
84|}
85|static void
86|lpfc_update_stats(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
87|{
88| struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
89| struct lpfc_nodelist *pnode = rdata->pnode;
90| struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
91| unsigned long flags;
92| struct Scsi_Host *shost = cmd->device->host;
93| struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
94| unsigned long latency;
95| int i;
96|
97| if (cmd->result)
98| return;
99|
100| latency = jiffies_to_msecs((long)jiffies - (long)lpfc_cmd->start_time);
101|
102| __st_spin_lock_irqsave_st__(shost->host_lock, flags);
103| if (!vport->stat_data_enabled ||
104| vport->stat_data_blocked ||
105| !pnode ||
106| !pnode->lat_data ||
107| (phba->bucket_type == 0)) {
108| __st_spin_unlock_irqrestore_st__(shost->host_lock, flags);
109| return;
110| }
111|
112| if (phba->bucket_type == 1) {
113| i = (latency + phba->bucket_step - 1 - phba->bucket_base)/
114| phba->bucket_step;
115|
116| if (i < 0)
117| i = 0;
118| else if (i >= 20)
119| i = 20 - 1;
120| } else {
121| for (i = 0; i < 20 -1; i++)
122| if (latency <= (phba->bucket_base +
123| ((1<bucket_step)))
124| break;
125| }
126|
127| pnode->lat_data[i].cmd_count++;
128| __st_spin_unlock_irqrestore_st__(shost->host_lock, flags);
129|}
130|static void
131|lpfc_send_sdev_queuedepth_change_event(struct lpfc_hba *phba,
132| struct lpfc_vport *vport,
133| struct lpfc_nodelist *ndlp,
134| uint32_t lun,
135| uint32_t old_val,
136| uint32_t new_val)
137|{
138| struct lpfc_fast_path_event *fast_path_evt;
139| unsigned long flags;
140|
141| fast_path_evt = lpfc_alloc_fast_evt(phba);
142| if (!fast_path_evt)
143| return;
144|
145| fast_path_evt->un.queue_depth_evt.scsi_event.event_type =
146| 0x0200;
147| fast_path_evt->un.queue_depth_evt.scsi_event.subcategory =
148| 0x0040;
149|
150|
151| fast_path_evt->un.queue_depth_evt.scsi_event.lun = lun;
152| if (ndlp && (((ndlp)->nlp_usg_map & 0x1) && !((ndlp)->nlp_usg_map & 0x8))) {
153| __st_memcpy_st__(&fast_path_evt->un.queue_depth_evt.scsi_event.wwpn,
154| &ndlp->nlp_portname, sizeof(struct lpfc_name));
155| __st_memcpy_st__(&fast_path_evt->un.queue_depth_evt.scsi_event.wwnn,
156| &ndlp->nlp_nodename, sizeof(struct lpfc_name));
157| }
158|
159| fast_path_evt->un.queue_depth_evt.oldval = old_val;
160| fast_path_evt->un.queue_depth_evt.newval = new_val;
161| fast_path_evt->vport = vport;
162|
163| fast_path_evt->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT;
164| __st_spin_lock_irqsave_st__(&phba->hbalock, flags);
165| list_add_tail(&fast_path_evt->work_evt.evt_listp, &phba->work_list);
166| __st_spin_unlock_irqrestore_st__(&phba->hbalock, flags);
167| lpfc_worker_wake_up(phba);
168|
169| return;
170|}
171|int
172|lpfc_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason)
173|{
174| struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
175| struct lpfc_hba *phba = vport->phba;
176| struct lpfc_rport_data *rdata;
177| unsigned long new_queue_depth, old_queue_depth;
178|
179| old_queue_depth = sdev->queue_depth;
180| scsi_adjust_queue_depth(sdev, scsi_get_tag_type(sdev), qdepth);
181| new_queue_depth = sdev->queue_depth;
182| rdata = sdev->hostdata;
183| if (rdata)
184| lpfc_send_sdev_queuedepth_change_event(phba, vport,
185| rdata->pnode, sdev->lun,
186| old_queue_depth,
187| new_queue_depth);
188| return sdev->queue_depth;
189|}
190|void
191|lpfc_rampdown_queue_depth(struct lpfc_hba *phba)
192|{
193| unsigned long flags;
194| uint32_t evt_posted;
195|
196| __st_spin_lock_irqsave_st__(&phba->hbalock, flags);
197| atomic_inc(&phba->num_rsrc_err);
198| phba->last_rsrc_error_time = jiffies;
199|
200| if ((phba->last_ramp_down_time + (1 * 250)) > jiffies) {
201| __st_spin_unlock_irqrestore_st__(&phba->hbalock, flags);
202| return;
203| }
204|
205| phba->last_ramp_down_time = jiffies;
206|
207| __st_spin_unlock_irqrestore_st__(&phba->hbalock, flags);
208|
209| __st_spin_lock_irqsave_st__(&phba->pport->work_port_lock, flags);
210| evt_posted = phba->pport->work_port_events & 0x800;
211| if (!evt_posted)
212| phba->pport->work_port_events |= 0x800;
213| __st_spin_unlock_irqrestore_st__(&phba->pport->work_port_lock, flags);
214|
215| if (!evt_posted)
216| lpfc_worker_wake_up(phba);
217| return;
218|}
219|static inline void
220|lpfc_rampup_queue_depth(struct lpfc_vport *vport,
221| uint32_t queue_depth)
222|{
223| unsigned long flags;
224| struct lpfc_hba *phba = vport->phba;
225| uint32_t evt_posted;
226| atomic_inc(&phba->num_cmd_success);
227|
228| if (vport->cfg_lun_queue_depth <= queue_depth)
229| return;
230| __st_spin_lock_irqsave_st__(&phba->hbalock, flags);
231| if ((({ unsigned long __dummy; typeof(phba->last_ramp_up_time + (300 * 250)) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)(phba->last_ramp_up_time + (300 * 250)) < 0))
232| ||
233| (({ unsigned long __dummy; typeof(phba->last_rsrc_error_time + (300 * 250)) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)(phba->last_rsrc_error_time + (300 * 250)) < 0))
234| ) {
235| __st_spin_unlock_irqrestore_st__(&phba->hbalock, flags);
236| return;
237| }
238| phba->last_ramp_up_time = jiffies;
239| __st_spin_unlock_irqrestore_st__(&phba->hbalock, flags);
240|
241| __st_spin_lock_irqsave_st__(&phba->pport->work_port_lock, flags);
242| evt_posted = phba->pport->work_port_events & 0x1000;
243| if (!evt_posted)
244| phba->pport->work_port_events |= 0x1000;
245| __st_spin_unlock_irqrestore_st__(&phba->pport->work_port_lock, flags);
246|
247| if (!evt_posted)
248| lpfc_worker_wake_up(phba);
249| return;
250|}
251|void
252|lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
253|{
254| struct lpfc_vport **vports;
255| struct Scsi_Host *shost;
256| struct scsi_device *sdev;
257| unsigned long new_queue_depth;
258| unsigned long num_rsrc_err, num_cmd_success;
259| int i;
260|
261| num_rsrc_err = atomic_read(&phba->num_rsrc_err);
262| num_cmd_success = atomic_read(&phba->num_cmd_success);
263|
264| vports = lpfc_create_vport_work_array(phba);
265| if (vports != ((void *)0))
266| for (i = 0; i <= phba->max_vports && vports[i] != ((void *)0); i++) {
267| shost = lpfc_shost_from_vport(vports[i]);
268| for ((sdev) = __scsi_iterate_devices((shost), ((void *)0)); (sdev); (sdev) = __scsi_iterate_devices((shost), (sdev))) {
269| new_queue_depth =
270| sdev->queue_depth * num_rsrc_err /
271| (num_rsrc_err + num_cmd_success);
272| if (!new_queue_depth)
273| new_queue_depth = sdev->queue_depth - 1;
274| else
275| new_queue_depth = sdev->queue_depth -
276| new_queue_depth;
277| lpfc_change_queue_depth(sdev, new_queue_depth,
278| SCSI_QDEPTH_DEFAULT);
279| }
280| }
281| lpfc_destroy_vport_work_array(phba, vports);
282| atomic_set(&phba->num_rsrc_err, 0);
283| atomic_set(&phba->num_cmd_success, 0);
284|}
285|void
286|lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
287|{
288| struct lpfc_vport **vports;
289| struct Scsi_Host *shost;
290| struct scsi_device *sdev;
291| int i;
292|
293| vports = lpfc_create_vport_work_array(phba);
294| if (vports != ((void *)0))
295| for (i = 0; i <= phba->max_vports && vports[i] != ((void *)0); i++) {
296| shost = lpfc_shost_from_vport(vports[i]);
297| for ((sdev) = __scsi_iterate_devices((shost), ((void *)0)); (sdev); (sdev) = __scsi_iterate_devices((shost), (sdev))) {
298| if (vports[i]->cfg_lun_queue_depth <=
299| sdev->queue_depth)
300| continue;
301| lpfc_change_queue_depth(sdev,
302| sdev->queue_depth+1,
303| SCSI_QDEPTH_RAMP_UP);
304| }
305| }
306| lpfc_destroy_vport_work_array(phba, vports);
307| atomic_set(&phba->num_rsrc_err, 0);
308| atomic_set(&phba->num_cmd_success, 0);
309|}
310|void
311|lpfc_scsi_dev_block(struct lpfc_hba *phba)
312|{
313| struct lpfc_vport **vports;
314| struct Scsi_Host *shost;
315| struct scsi_device *sdev;
316| struct fc_rport *rport;
317| int i;
318|
319| vports = lpfc_create_vport_work_array(phba);
320| if (vports != ((void *)0))
321| for (i = 0; i <= phba->max_vports && vports[i] != ((void *)0); i++) {
322| shost = lpfc_shost_from_vport(vports[i]);
323| for ((sdev) = __scsi_iterate_devices((shost), ((void *)0)); (sdev); (sdev) = __scsi_iterate_devices((shost), (sdev))) {
324| rport = scsi_is_fc_rport(scsi_target(sdev)->dev.parent) ? ({ const typeof( ((struct fc_rport *)0)->dev ) *__mptr = (scsi_target(sdev)->dev.parent); (struct fc_rport *)( (char *)__mptr - 1 );}) : ((void *)0);
325| fc_remote_port_delete(rport);
326| }
327| }
328| lpfc_destroy_vport_work_array(phba, vports);
329|}
330|static int
331|lpfc_new_scsi_buf_s3(struct lpfc_vport *vport, int num_to_alloc)
332|{
333| struct lpfc_hba *phba = vport->phba;
334| struct lpfc_scsi_buf *psb;
335| struct ulp_bde64 *bpl;
336| IOCB_t *iocb;
337| dma_addr_t pdma_phys_fcp_cmd;
338| dma_addr_t pdma_phys_fcp_rsp;
339| dma_addr_t pdma_phys_bpl;
340| uint16_t iotag;
341| int bcnt;
342|
343| for (bcnt = 0; bcnt < num_to_alloc; bcnt++) {
344| psb = kzalloc(sizeof(struct lpfc_scsi_buf), __st_GFP_KERNEL_st__);
345| if (!psb)
346| break;
347|
348|
349|
350|
351|
352|
353|
354| psb->data = dma_pool_alloc(phba->lpfc_scsi_dma_buf_pool, __st_GFP_KERNEL_st__, &psb->dma_handle)
355| ;
356| if (!psb->data) {
357| kfree(psb);
358| break;
359| }
360|
361|
362| __st_memset_st__(psb->data, 0, phba->cfg_sg_dma_buf_size);
363|
364|
365| iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq);
366| if (iotag == 0) {
367| dma_pool_free(phba->lpfc_scsi_dma_buf_pool, psb->data, psb->dma_handle)
368| ;
369| kfree(psb);
370| break;
371| }
372| psb->cur_iocbq.iocb_flag |= 4;
373|
374| psb->fcp_cmnd = psb->data;
375| psb->fcp_rsp = psb->data + sizeof(struct fcp_cmnd);
376| psb->fcp_bpl = psb->data + sizeof(struct fcp_cmnd) +
377| sizeof(struct fcp_rsp);
378|
379|
380| bpl = psb->fcp_bpl;
381| pdma_phys_fcp_cmd = psb->dma_handle;
382| pdma_phys_fcp_rsp = psb->dma_handle + sizeof(struct fcp_cmnd);
383| pdma_phys_bpl = psb->dma_handle + sizeof(struct fcp_cmnd) +
384| sizeof(struct fcp_rsp);
385|
386|
387|
388|
389|
390|
391| bpl[0].addrHigh = (( __u32)(__le32)(((uint32_t) (0xffffffff & (((u64)(pdma_phys_fcp_cmd))>>32)))));
392| bpl[0].addrLow = (( __u32)(__le32)(((uint32_t) (0xffffffff & (u64)(pdma_phys_fcp_cmd)))));
393| bpl[0].tus.f.bdeSize = sizeof(struct fcp_cmnd);
394| bpl[0].tus.f.bdeFlags = 0x00;
395| bpl[0].tus.w = (( __u32)(__le32)(bpl[0].tus.w));
396|
397|
398| bpl[1].addrHigh = (( __u32)(__le32)(((uint32_t) (0xffffffff & (((u64)(pdma_phys_fcp_rsp))>>32)))));
399| bpl[1].addrLow = (( __u32)(__le32)(((uint32_t) (0xffffffff & (u64)(pdma_phys_fcp_rsp)))));
400| bpl[1].tus.f.bdeSize = sizeof(struct fcp_rsp);
401| bpl[1].tus.f.bdeFlags = 0x00;
402| bpl[1].tus.w = (( __u32)(__le32)(bpl[1].tus.w));
403|
404|
405|
406|
407|
408| iocb = &psb->cur_iocbq.iocb;
409| iocb->un.fcpi64.bdl.ulpIoTag32 = 0;
410| if ((phba->sli_rev == 3) &&
411| !(phba->sli3_options & 0x20)) {
412|
413| iocb->un.fcpi64.bdl.bdeFlags = 0x01;
414| iocb->un.fcpi64.bdl.bdeSize = sizeof(struct fcp_cmnd);
415| iocb->un.fcpi64.bdl.addrLow = 1
416| ;
417| iocb->un.fcpi64.bdl.addrHigh = 0;
418| iocb->ulpBdeCount = 0;
419| iocb->ulpLe = 0;
420|
421| iocb->unsli3.fcp_ext.rbde.tus.f.bdeFlags =
422| 0x00;
423| iocb->unsli3.fcp_ext.rbde.tus.f.bdeSize =
424| sizeof(struct fcp_rsp);
425| iocb->unsli3.fcp_ext.rbde.addrLow =
426| ((uint32_t) (0xffffffff & (u64)(pdma_phys_fcp_rsp)));
427| iocb->unsli3.fcp_ext.rbde.addrHigh =
428| ((uint32_t) (0xffffffff & (((u64)(pdma_phys_fcp_rsp))>>32)));
429| } else {
430| iocb->un.fcpi64.bdl.bdeFlags = 0x40;
431| iocb->un.fcpi64.bdl.bdeSize =
432| (2 * sizeof(struct ulp_bde64));
433| iocb->un.fcpi64.bdl.addrLow =
434| ((uint32_t) (0xffffffff & (u64)(pdma_phys_bpl)));
435| iocb->un.fcpi64.bdl.addrHigh =
436| ((uint32_t) (0xffffffff & (((u64)(pdma_phys_bpl))>>32)));
437| iocb->ulpBdeCount = 1;
438| iocb->ulpLe = 1;
439| }
440| iocb->ulpClass = 2;
441| psb->status = 0x0;
442|
443| psb->cur_iocbq.context1 = psb;
444| lpfc_release_scsi_buf_s3(phba, psb);
445|
446| }
447|
448| return bcnt;
449|}
450|void
451|lpfc_sli4_fcp_xri_aborted(struct lpfc_hba *phba,
452| struct sli4_wcqe_xri_aborted *axri)
453|{
454| uint16_t xri = (((axri)->word2 >> 0) & 0x0000FFFF);
455| struct lpfc_scsi_buf *psb, *next_psb;
456| unsigned long iflag = 0;
457| struct lpfc_iocbq *iocbq;
458| int i;
459| struct lpfc_sli_ring *pring = &phba->sli.ring[2];
460|
461| __st_spin_lock_irqsave_st__(&phba->hbalock, iflag);
462| __st_spin_lock_st__(&phba->sli4_hba.abts_scsi_buf_list_lock);
463| for (psb = ({ const typeof( ((typeof(*psb) *)0)->list ) *__mptr = ((&phba->sli4_hba.lpfc_abts_scsi_buf_list)->next); (typeof(*psb) *)( (char *)__mptr - 1 );}), next_psb = ({ const typeof( ((typeof(*psb) *)0)->list ) *__mptr = (psb->list.next); (typeof(*psb) *)( (char *)__mptr - 1 );}); &psb->list != (&phba->sli4_hba.lpfc_abts_scsi_buf_list); psb = next_psb, next_psb = ({ const typeof( ((typeof(*next_psb) *)0)->list ) *__mptr = (next_psb->list.next); (typeof(*next_psb) *)( (char *)__mptr - 1 );}))
464| {
465| if (psb->cur_iocbq.sli4_xritag == xri) {
466| list_del(&psb->list);
467| psb->exch_busy = 0;
468| psb->status = 0x0;
469| __st_spin_unlock_st__(
470| &phba->sli4_hba.abts_scsi_buf_list_lock);
471| __st_spin_unlock_irqrestore_st__(&phba->hbalock, iflag);
472| lpfc_release_scsi_buf_s4(phba, psb);
473| return;
474| }
475| }
476| __st_spin_unlock_st__(&phba->sli4_hba.abts_scsi_buf_list_lock);
477| for (i = 1; i <= phba->sli.last_iotag; i++) {
478| iocbq = phba->sli.iocbq_lookup[i];
479|
480| if (!(iocbq->iocb_flag & 4) ||
481| (iocbq->iocb_flag & 1))
482| continue;
483| if (iocbq->sli4_xritag != xri)
484| continue;
485| psb = ({ const typeof( ((struct lpfc_scsi_buf *)0)->cur_iocbq ) *__mptr = (iocbq); (struct lpfc_scsi_buf *)( (char *)__mptr - 1 );});
486| psb->exch_busy = 0;
487| __st_spin_unlock_irqrestore_st__(&phba->hbalock, iflag);
488| if (pring->txq_cnt)
489| lpfc_worker_wake_up(phba);
490| return;
491|
492| }
493| __st_spin_unlock_irqrestore_st__(&phba->hbalock, iflag);
494|}
495|int
496|lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *phba)
497|{
498| struct lpfc_scsi_buf *psb;
499| int index, status, bcnt = 0, rcnt = 0, rc = 0;
500| struct list_head sblist = { &(sblist), &(sblist) };
501|
502| for (index = 0; index < phba->sli4_hba.scsi_xri_cnt; index++) {
503| psb = phba->sli4_hba.lpfc_scsi_psb_array[index];
504| if (psb) {
505|
506| list_del(&psb->list);
507|
508| list_add_tail(&psb->list, &sblist);
509| if (++rcnt == 254) {
510| bcnt = rcnt;
511| rcnt = 0;
512| }
513| } else
514|
515| bcnt = rcnt;
516|
517| if (index == phba->sli4_hba.scsi_xri_cnt - 1)
518|
519| bcnt = rcnt;
520|
521|
522| if (bcnt == 0)
523| continue;
524|
525| status = lpfc_sli4_post_scsi_sgl_block(phba, &sblist, bcnt);
526|
527| bcnt = 0;
528| while (!list_empty(&sblist)) {
529| do { psb = ((void *)0); if (!list_empty(&sblist)) { psb = ({ const typeof( ((struct lpfc_scsi_buf *)0)->list ) *__mptr = ((&sblist)->next); (struct lpfc_scsi_buf *)( (char *)__mptr - 1 );}); list_del_init(&psb->list); } } while(0)
530| ;
531| if (status) {
532|
533| psb->exch_busy = 1;
534| rc++;
535| } else {
536| psb->exch_busy = 0;
537| psb->status = 0x0;
538| }
539|
540| lpfc_release_scsi_buf_s4(phba, psb);
541| }
542| }
543| return rc;
544|}
545|static int
546|lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc)
547|{
548| struct lpfc_hba *phba = vport->phba;
549| struct lpfc_scsi_buf *psb;
550| struct sli4_sge *sgl;
551| IOCB_t *iocb;
552| dma_addr_t pdma_phys_fcp_cmd;
553| dma_addr_t pdma_phys_fcp_rsp;
554| dma_addr_t pdma_phys_bpl, pdma_phys_bpl1;
555| uint16_t iotag, last_xritag = ((uint16_t)-1);
556| int status = 0, index;
557| int bcnt;
558| int non_sequential_xri = 0;
559| struct list_head sblist = { &(sblist), &(sblist) };
560|
561| for (bcnt = 0; bcnt < num_to_alloc; bcnt++) {
562| psb = kzalloc(sizeof(struct lpfc_scsi_buf), __st_GFP_KERNEL_st__);
563| if (!psb)
564| break;
565|
566|
567|
568|
569|
570|
571|
572| psb->data = dma_pool_alloc(phba->lpfc_scsi_dma_buf_pool, __st_GFP_KERNEL_st__, &psb->dma_handle)
573| ;
574| if (!psb->data) {
575| kfree(psb);
576| break;
577| }
578|
579|
580| __st_memset_st__(psb->data, 0, phba->cfg_sg_dma_buf_size);
581|
582|
583| iotag = lpfc_sli_next_iotag(phba, &psb->cur_iocbq);
584| if (iotag == 0) {
585| dma_pool_free(phba->lpfc_scsi_dma_buf_pool, psb->data, psb->dma_handle)
586| ;
587| kfree(psb);
588| break;
589| }
590|
591| psb->cur_iocbq.sli4_xritag = lpfc_sli4_next_xritag(phba);
592| if (psb->cur_iocbq.sli4_xritag == ((uint16_t)-1)) {
593| dma_pool_free(phba->lpfc_scsi_dma_buf_pool, psb->data, psb->dma_handle)
594| ;
595| kfree(psb);
596| break;
597| }
598| if (last_xritag != ((uint16_t)-1)
599| && psb->cur_iocbq.sli4_xritag != (last_xritag+1)) {
600| non_sequential_xri = 1;
601| } else
602| list_add_tail(&psb->list, &sblist);
603| last_xritag = psb->cur_iocbq.sli4_xritag;
604|
605| index = phba->sli4_hba.scsi_xri_cnt++;
606| psb->cur_iocbq.iocb_flag |= 4;
607|
608| psb->fcp_bpl = psb->data;
609| psb->fcp_cmnd = (psb->data + phba->cfg_sg_dma_buf_size)
610| - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp));
611| psb->fcp_rsp = (struct fcp_rsp *)((uint8_t *)psb->fcp_cmnd +
612| sizeof(struct fcp_cmnd));
613|
614|
615| sgl = (struct sli4_sge *)psb->fcp_bpl;
616| pdma_phys_bpl = psb->dma_handle;
617| pdma_phys_fcp_cmd =
618| (psb->dma_handle + phba->cfg_sg_dma_buf_size)
619| - (sizeof(struct fcp_cmnd) + sizeof(struct fcp_rsp));
620| pdma_phys_fcp_rsp = pdma_phys_fcp_cmd + sizeof(struct fcp_cmnd);
621|
622|
623|
624|
625|
626|
627| sgl->addr_hi = (( __le32)(__u32)(((uint32_t) (0xffffffff & (((u64)(pdma_phys_fcp_cmd))>>32)))));
628| sgl->addr_lo = (( __le32)(__u32)(((uint32_t) (0xffffffff & (u64)(pdma_phys_fcp_cmd)))));
629| ((sgl)->word2 = ((((0) & 0x00000001) << 31) | ((sgl)->word2 & ~(0x00000001 << 31))));
630| sgl->word2 = (( __le32)(__u32)(sgl->word2));
631| sgl->sge_len = (( __le32)(__u32)(sizeof(struct fcp_cmnd)));
632| sgl++;
633|
634|
635| sgl->addr_hi = (( __le32)(__u32)(((uint32_t) (0xffffffff & (((u64)(pdma_phys_fcp_rsp))>>32)))));
636| sgl->addr_lo = (( __le32)(__u32)(((uint32_t) (0xffffffff & (u64)(pdma_phys_fcp_rsp)))));
637| ((sgl)->word2 = ((((1) & 0x00000001) << 31) | ((sgl)->word2 & ~(0x00000001 << 31))));
638| sgl->word2 = (( __le32)(__u32)(sgl->word2));
639| sgl->sge_len = (( __le32)(__u32)(sizeof(struct fcp_rsp)));
640|
641|
642|
643|
644|
645| iocb = &psb->cur_iocbq.iocb;
646| iocb->un.fcpi64.bdl.ulpIoTag32 = 0;
647| iocb->un.fcpi64.bdl.bdeFlags = 0x00;
648|
649|
650|
651|
652| iocb->un.fcpi64.bdl.bdeSize = sizeof(struct fcp_cmnd);
653| iocb->un.fcpi64.bdl.addrLow = ((uint32_t) (0xffffffff & (u64)(pdma_phys_fcp_cmd)));
654| iocb->un.fcpi64.bdl.addrHigh = ((uint32_t) (0xffffffff & (((u64)(pdma_phys_fcp_cmd))>>32)));
655| iocb->ulpBdeCount = 1;
656| iocb->ulpLe = 1;
657| iocb->ulpClass = 2;
658| psb->cur_iocbq.context1 = psb;
659| if (phba->cfg_sg_dma_buf_size > 4096)
660| pdma_phys_bpl1 = pdma_phys_bpl + 4096;
661| else
662| pdma_phys_bpl1 = 0;
663| psb->dma_phys_bpl = pdma_phys_bpl;
664| phba->sli4_hba.lpfc_scsi_psb_array[index] = psb;
665| if (non_sequential_xri) {
666| status = lpfc_sli4_post_sgl(phba, pdma_phys_bpl,
667| pdma_phys_bpl1,
668| psb->cur_iocbq.sli4_xritag);
669| if (status) {
670|
671| psb->exch_busy = 1;
672| } else {
673| psb->exch_busy = 0;
674| psb->status = 0x0;
675| }
676|
677| lpfc_release_scsi_buf_s4(phba, psb);
678| break;
679| }
680| }
681| if (bcnt) {
682| status = lpfc_sli4_post_scsi_sgl_block(phba, &sblist, bcnt);
683|
684| while (!list_empty(&sblist)) {
685| do { psb = ((void *)0); if (!list_empty(&sblist)) { psb = ({ const typeof( ((struct lpfc_scsi_buf *)0)->list ) *__mptr = ((&sblist)->next); (struct lpfc_scsi_buf *)( (char *)__mptr - 1 );}); list_del_init(&psb->list); } } while(0)
686| ;
687| if (status) {
688|
689| psb->exch_busy = 1;
690| } else {
691| psb->exch_busy = 0;
692| psb->status = 0x0;
693| }
694|
695| lpfc_release_scsi_buf_s4(phba, psb);
696| }
697| }
698|
699| return bcnt + non_sequential_xri;
700|}
701|static inline int
702|lpfc_new_scsi_buf(struct lpfc_vport *vport, int num_to_alloc)
703|{
704| return vport->phba->lpfc_new_scsi_buf(vport, num_to_alloc);
705|}
706|static struct lpfc_scsi_buf*
707|lpfc_get_scsi_buf(struct lpfc_hba * phba)
708|{
709| struct lpfc_scsi_buf * lpfc_cmd = ((void *)0);
710| struct list_head *scsi_buf_list = &phba->lpfc_scsi_buf_list;
711| unsigned long iflag = 0;
712|
713| __st_spin_lock_irqsave_st__(&phba->scsi_buf_list_lock, iflag);
714| do { lpfc_cmd = ((void *)0); if (!list_empty(scsi_buf_list)) { lpfc_cmd = ({ const typeof( ((struct lpfc_scsi_buf *)0)->list ) *__mptr = ((scsi_buf_list)->next); (struct lpfc_scsi_buf *)( (char *)__mptr - 1 );}); list_del_init(&lpfc_cmd->list); } } while(0);
715| if (lpfc_cmd) {
716| lpfc_cmd->seg_cnt = 0;
717| lpfc_cmd->nonsg_phys = 0;
718| lpfc_cmd->prot_seg_cnt = 0;
719| }
720| __st_spin_unlock_irqrestore_st__(&phba->scsi_buf_list_lock, iflag);
721| return lpfc_cmd;
722|}
723|static void
724|lpfc_release_scsi_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
725|{
726| unsigned long iflag = 0;
727|
728| __st_spin_lock_irqsave_st__(&phba->scsi_buf_list_lock, iflag);
729| psb->pCmd = ((void *)0);
730| list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list);
731| __st_spin_unlock_irqrestore_st__(&phba->scsi_buf_list_lock, iflag);
732|}
733|static void
734|lpfc_release_scsi_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
735|{
736| unsigned long iflag = 0;
737|
738| if (psb->exch_busy) {
739| __st_spin_lock_irqsave_st__(&phba->sli4_hba.abts_scsi_buf_list_lock,
740| iflag);
741| psb->pCmd = ((void *)0);
742| list_add_tail(&psb->list,
743| &phba->sli4_hba.lpfc_abts_scsi_buf_list);
744| __st_spin_unlock_irqrestore_st__(&phba->sli4_hba.abts_scsi_buf_list_lock,
745| iflag);
746| } else {
747|
748| __st_spin_lock_irqsave_st__(&phba->scsi_buf_list_lock, iflag);
749| psb->pCmd = ((void *)0);
750| list_add_tail(&psb->list, &phba->lpfc_scsi_buf_list);
751| __st_spin_unlock_irqrestore_st__(&phba->scsi_buf_list_lock, iflag);
752| }
753|}
754|static void
755|lpfc_release_scsi_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
756|{
757|
758| phba->lpfc_release_scsi_buf(phba, psb);
759|}
760|static int
761|lpfc_scsi_prep_dma_buf_s3(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
762|{
763| struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd;
764| struct scatterlist *sgel = ((void *)0);
765| struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
766| struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl;
767| struct lpfc_iocbq *iocbq = &lpfc_cmd->cur_iocbq;
768| IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
769| struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde;
770| dma_addr_t physaddr;
771| uint32_t num_bde = 0;
772| int nseg, datadir = scsi_cmnd->sc_data_direction;
773|
774|
775|
776|
777|
778|
779|
780| bpl += 2;
781| if (scsi_sg_count(scsi_cmnd)) {
782|
783|
784|
785|
786|
787|
788|
789| nseg = dma_map_sg_attrs(&phba->pcidev->dev, scsi_sglist(scsi_cmnd), scsi_sg_count(scsi_cmnd), datadir, ((void *)0))
790| ;
791| if (!nseg)
792| return 1;
793|
794| lpfc_cmd->seg_cnt = nseg;
795| if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
796| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9064 BLKGRD: %s: Too many sg segments from " "dma_map_sg. Config %d, seg_cnt %d\n", phba->brd_no, __func__, phba->cfg_sg_seg_cnt, lpfc_cmd->seg_cnt); } } while (0)
797|
798|
799|
800| ;
801| scsi_dma_unmap(scsi_cmnd);
802| return 1;
803| }
804| for (num_bde = 0, sgel = (scsi_sglist(scsi_cmnd)); num_bde < (nseg); num_bde++, sgel = sg_next(sgel)) {
805| physaddr = ((sgel)->dma_address);
806| if (phba->sli_rev == 3 &&
807| !(phba->sli3_options & 0x20) &&
808| !(iocbq->iocb_flag & 0x100) &&
809| nseg <= 3) {
810| data_bde->tus.f.bdeFlags = 0x00;
811| data_bde->tus.f.bdeSize = ((sgel)->dma_length);
812| data_bde->addrLow = ((uint32_t) (0xffffffff & (u64)(physaddr)));
813| data_bde->addrHigh = ((uint32_t) (0xffffffff & (((u64)(physaddr))>>32)));
814| data_bde++;
815| } else {
816| bpl->tus.f.bdeFlags = 0x00;
817| bpl->tus.f.bdeSize = ((sgel)->dma_length);
818| bpl->tus.w = (( __u32)(__le32)(bpl->tus.w));
819| bpl->addrLow =
820| (( __u32)(__le32)(((uint32_t) (0xffffffff & (u64)(physaddr)))));
821| bpl->addrHigh =
822| (( __u32)(__le32)(((uint32_t) (0xffffffff & (((u64)(physaddr))>>32)))));
823| bpl++;
824| }
825| }
826| }
827|
828|
829|
830|
831|
832|
833|
834| if (phba->sli_rev == 3 &&
835| !(phba->sli3_options & 0x20) &&
836| !(iocbq->iocb_flag & 0x100)) {
837| if (num_bde > 3) {
838|
839|
840|
841|
842|
843| physaddr = lpfc_cmd->dma_handle;
844| data_bde->tus.f.bdeFlags = 0x40;
845| data_bde->tus.f.bdeSize = (num_bde *
846| sizeof(struct ulp_bde64));
847| physaddr += (sizeof(struct fcp_cmnd) +
848| sizeof(struct fcp_rsp) +
849| (2 * sizeof(struct ulp_bde64)));
850| data_bde->addrHigh = ((uint32_t) (0xffffffff & (((u64)(physaddr))>>32)));
851| data_bde->addrLow = ((uint32_t) (0xffffffff & (u64)(physaddr)));
852|
853| iocb_cmd->unsli3.fcp_ext.ebde_count = 2;
854| } else {
855|
856| iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1);
857| }
858| } else {
859| iocb_cmd->un.fcpi64.bdl.bdeSize =
860| ((num_bde + 2) * sizeof(struct ulp_bde64));
861| iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1);
862| }
863| fcp_cmnd->fcpDl = (( __be32)(__builtin_constant_p((__u32)((scsi_bufflen(scsi_cmnd)))) ? ((__u32)( (((__u32)((scsi_bufflen(scsi_cmnd))) & (__u32)0x000000ffUL) << 24) | (((__u32)((scsi_bufflen(scsi_cmnd))) & (__u32)0x0000ff00UL) << 8) | (((__u32)((scsi_bufflen(scsi_cmnd))) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((scsi_bufflen(scsi_cmnd))) & (__u32)0xff000000UL) >> 24))) : __fswab32((scsi_bufflen(scsi_cmnd)))));
864|
865|
866|
867|
868|
869| iocb_cmd->un.fcpi.fcpi_parm = scsi_bufflen(scsi_cmnd);
870| return 0;
871|}
872|static int
873|lpfc_sc_to_bg_opcodes(struct lpfc_hba *phba, struct scsi_cmnd *sc,
874| uint8_t *txop, uint8_t *rxop)
875|{
876| uint8_t guard_type = scsi_host_get_guard(sc->device->host);
877| uint8_t ret = 0;
878|
879| if (guard_type == SHOST_DIX_GUARD_IP) {
880| switch (scsi_get_prot_op(sc)) {
881| case SCSI_PROT_READ_INSERT:
882| case SCSI_PROT_WRITE_STRIP:
883| *txop = 0x3;
884| *rxop = 0x2;
885| break;
886|
887| case SCSI_PROT_READ_STRIP:
888| case SCSI_PROT_WRITE_INSERT:
889| *txop = 0x0;
890| *rxop = 0x1;
891| break;
892|
893| case SCSI_PROT_READ_PASS:
894| case SCSI_PROT_WRITE_PASS:
895| *txop = 0x7;
896| *rxop = 0x6;
897| break;
898|
899| case SCSI_PROT_NORMAL:
900| default:
901| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9063 BLKGRD: Bad op/guard:%d/%d combination\n", phba->brd_no, scsi_get_prot_op(sc), guard_type); } } while (0)
902|
903| ;
904| ret = 1;
905| break;
906|
907| }
908| } else if (guard_type == SHOST_DIX_GUARD_CRC) {
909| switch (scsi_get_prot_op(sc)) {
910| case SCSI_PROT_READ_STRIP:
911| case SCSI_PROT_WRITE_INSERT:
912| *txop = 0x0;
913| *rxop = 0x1;
914| break;
915|
916| case SCSI_PROT_READ_PASS:
917| case SCSI_PROT_WRITE_PASS:
918| *txop = 0x4;
919| *rxop = 0x4;
920| break;
921|
922| case SCSI_PROT_READ_INSERT:
923| case SCSI_PROT_WRITE_STRIP:
924| case SCSI_PROT_NORMAL:
925| default:
926| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9075 BLKGRD: Bad op/guard:%d/%d combination\n", phba->brd_no, scsi_get_prot_op(sc), guard_type); } } while (0)
927|
928| ;
929| ret = 1;
930| break;
931| }
932| } else {
933|
934| __st_BUG_st__();
935| }
936|
937| return ret;
938|}
939|
940|struct scsi_dif_tuple {
941| __be16 guard_tag;
942| __be16 app_tag;
943| __be32 ref_tag;
944|};
945|
946|static inline unsigned
947|lpfc_cmd_blksize(struct scsi_cmnd *sc)
948|{
949| return sc->device->sector_size;
950|}
951|static inline void
952|lpfc_get_cmd_dif_parms(struct scsi_cmnd *sc, uint16_t *apptagmask,
953| uint16_t *apptagval, uint32_t *reftag)
954|{
955| struct scsi_dif_tuple *spt;
956| unsigned char op = scsi_get_prot_op(sc);
957| unsigned int protcnt = scsi_prot_sg_count(sc);
958| static int cnt;
959|
960| if (protcnt && (op == SCSI_PROT_WRITE_STRIP ||
961| op == SCSI_PROT_WRITE_PASS)) {
962|
963| cnt++;
964| spt = lowmem_page_address(sg_page(scsi_prot_sglist(sc))) +
965| scsi_prot_sglist(sc)[0].offset;
966| *apptagmask = 0;
967| *apptagval = 0;
968| *reftag = (( __be32)(__builtin_constant_p((__u32)((spt->ref_tag))) ? ((__u32)( (((__u32)((spt->ref_tag)) & (__u32)0x000000ffUL) << 24) | (((__u32)((spt->ref_tag)) & (__u32)0x0000ff00UL) << 8) | (((__u32)((spt->ref_tag)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((spt->ref_tag)) & (__u32)0xff000000UL) >> 24))) : __fswab32((spt->ref_tag))));
969|
970| } else {
971|
972| *reftag = (uint32_t) (0xffffffff & scsi_get_lba(sc));
973| *apptagmask = 0;
974| *apptagval = 0;
975| }
976|}
977|static int
978|lpfc_bg_setup_bpl(struct lpfc_hba *phba, struct scsi_cmnd *sc,
979| struct ulp_bde64 *bpl, int datasegcnt)
980|{
981| struct scatterlist *sgde = ((void *)0);
982| struct lpfc_pde5 *pde5 = ((void *)0);
983| struct lpfc_pde6 *pde6 = ((void *)0);
984| dma_addr_t physaddr;
985| int i = 0, num_bde = 0, status;
986| int datadir = sc->sc_data_direction;
987| unsigned blksize;
988| uint32_t reftag;
989| uint16_t apptagmask, apptagval;
990| uint8_t txop, rxop;
991|
992| status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop);
993| if (status)
994| goto out;
995|
996|
997| blksize = lpfc_cmd_blksize(sc);
998| lpfc_get_cmd_dif_parms(sc, &apptagmask, &apptagval, &reftag);
999|
1000|
1001| pde5 = (struct lpfc_pde5 *) bpl;
1002| __st_memset_st__(pde5, 0, sizeof(struct lpfc_pde5));
1003| ((pde5)->word0 = ((((0x85) & 0x000000ff) << 24) | ((pde5)->word0 & ~(0x000000ff << 24))));
1004| pde5->reftag = reftag;
1005|
1006|
1007| pde5->word0 = (( __le32)(__u32)(pde5->word0));
1008| pde5->reftag = (( __le32)(__u32)(pde5->reftag));
1009|
1010|
1011| num_bde++;
1012| bpl++;
1013| pde6 = (struct lpfc_pde6 *) bpl;
1014|
1015|
1016| __st_memset_st__(pde6, 0, sizeof(struct lpfc_pde6));
1017| ((pde6)->word0 = ((((0x86) & 0x000000ff) << 24) | ((pde6)->word0 & ~(0x000000ff << 24))));
1018| ((pde6)->word2 = ((((txop) & 0x0000000f) << 28) | ((pde6)->word2 & ~(0x0000000f << 28))));
1019| ((pde6)->word2 = ((((rxop) & 0x0000000f) << 24) | ((pde6)->word2 & ~(0x0000000f << 24))));
1020| if (datadir == DMA_FROM_DEVICE) {
1021| ((pde6)->word2 = ((((1) & 0x00000001) << 22) | ((pde6)->word2 & ~(0x00000001 << 22))));
1022| ((pde6)->word2 = ((((1) & 0x00000001) << 21) | ((pde6)->word2 & ~(0x00000001 << 21))));
1023| ((pde6)->word2 = ((((1) & 0x00000001) << 20) | ((pde6)->word2 & ~(0x00000001 << 20))));
1024| }
1025| ((pde6)->word2 = ((((1) & 0x00000001) << 19) | ((pde6)->word2 & ~(0x00000001 << 19))));
1026| ((pde6)->word2 = ((((apptagval) & 0x0000ffff) << 0) | ((pde6)->word2 & ~(0x0000ffff << 0))));
1027|
1028|
1029| pde6->word0 = (( __le32)(__u32)(pde6->word0));
1030| pde6->word1 = (( __le32)(__u32)(pde6->word1));
1031| pde6->word2 = (( __le32)(__u32)(pde6->word2));
1032|
1033|
1034| num_bde++;
1035| bpl++;
1036|
1037|
1038| for (i = 0, sgde = (scsi_sglist(sc)); i < (datasegcnt); i++, sgde = sg_next(sgde)) {
1039| physaddr = ((sgde)->dma_address);
1040| bpl->addrLow = (( __u32)(__le32)(((uint32_t) (0xffffffff & (u64)(physaddr)))));
1041| bpl->addrHigh = (( __u32)(__le32)(((uint32_t) (0xffffffff & (((u64)(physaddr))>>32)))));
1042| bpl->tus.f.bdeSize = ((sgde)->dma_length);
1043| if (datadir == DMA_TO_DEVICE)
1044| bpl->tus.f.bdeFlags = 0x00;
1045| else
1046| bpl->tus.f.bdeFlags = 0x08;
1047| bpl->tus.w = (( __u32)(__le32)(bpl->tus.w));
1048| bpl++;
1049| num_bde++;
1050| }
1051|
1052|out:
1053| return num_bde;
1054|}
1055|static int
1056|lpfc_bg_setup_bpl_prot(struct lpfc_hba *phba, struct scsi_cmnd *sc,
1057| struct ulp_bde64 *bpl, int datacnt, int protcnt)
1058|{
1059| struct scatterlist *sgde = ((void *)0);
1060| struct scatterlist *sgpe = ((void *)0);
1061| struct lpfc_pde5 *pde5 = ((void *)0);
1062| struct lpfc_pde6 *pde6 = ((void *)0);
1063| struct ulp_bde64 *prot_bde = ((void *)0);
1064| dma_addr_t dataphysaddr, protphysaddr;
1065| unsigned short curr_data = 0, curr_prot = 0;
1066| unsigned int split_offset, protgroup_len;
1067| unsigned int protgrp_blks, protgrp_bytes;
1068| unsigned int remainder, subtotal;
1069| int status;
1070| int datadir = sc->sc_data_direction;
1071| unsigned char pgdone = 0, alldone = 0;
1072| unsigned blksize;
1073| uint32_t reftag;
1074| uint16_t apptagmask, apptagval;
1075| uint8_t txop, rxop;
1076| int num_bde = 0;
1077|
1078| sgpe = scsi_prot_sglist(sc);
1079| sgde = scsi_sglist(sc);
1080|
1081| if (!sgpe || !sgde) {
1082| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000040) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9020 Invalid s/g entry: data=0x%p prot=0x%p\n", phba->brd_no, sgpe, sgde); } } while (0)
1083|
1084| ;
1085| return 0;
1086| }
1087|
1088| status = lpfc_sc_to_bg_opcodes(phba, sc, &txop, &rxop);
1089| if (status)
1090| goto out;
1091|
1092|
1093| blksize = lpfc_cmd_blksize(sc);
1094| lpfc_get_cmd_dif_parms(sc, &apptagmask, &apptagval, &reftag);
1095|
1096| split_offset = 0;
1097| do {
1098|
1099| pde5 = (struct lpfc_pde5 *) bpl;
1100| __st_memset_st__(pde5, 0, sizeof(struct lpfc_pde5));
1101| ((pde5)->word0 = ((((0x85) & 0x000000ff) << 24) | ((pde5)->word0 & ~(0x000000ff << 24))));
1102| pde5->reftag = reftag;
1103|
1104|
1105| pde5->word0 = (( __le32)(__u32)(pde5->word0));
1106| pde5->reftag = (( __le32)(__u32)(pde5->reftag));
1107|
1108|
1109| num_bde++;
1110| bpl++;
1111| pde6 = (struct lpfc_pde6 *) bpl;
1112|
1113|
1114| __st_memset_st__(pde6, 0, sizeof(struct lpfc_pde6));
1115| ((pde6)->word0 = ((((0x86) & 0x000000ff) << 24) | ((pde6)->word0 & ~(0x000000ff << 24))));
1116| ((pde6)->word2 = ((((txop) & 0x0000000f) << 28) | ((pde6)->word2 & ~(0x0000000f << 28))));
1117| ((pde6)->word2 = ((((rxop) & 0x0000000f) << 24) | ((pde6)->word2 & ~(0x0000000f << 24))));
1118| ((pde6)->word2 = ((((1) & 0x00000001) << 22) | ((pde6)->word2 & ~(0x00000001 << 22))));
1119| ((pde6)->word2 = ((((1) & 0x00000001) << 21) | ((pde6)->word2 & ~(0x00000001 << 21))));
1120| ((pde6)->word2 = ((((1) & 0x00000001) << 20) | ((pde6)->word2 & ~(0x00000001 << 20))));
1121| ((pde6)->word2 = ((((1) & 0x00000001) << 19) | ((pde6)->word2 & ~(0x00000001 << 19))));
1122| ((pde6)->word2 = ((((apptagval) & 0x0000ffff) << 0) | ((pde6)->word2 & ~(0x0000ffff << 0))));
1123|
1124|
1125| pde6->word0 = (( __le32)(__u32)(pde6->word0));
1126| pde6->word1 = (( __le32)(__u32)(pde6->word1));
1127| pde6->word2 = (( __le32)(__u32)(pde6->word2));
1128|
1129|
1130| num_bde++;
1131| bpl++;
1132|
1133|
1134| prot_bde = (struct ulp_bde64 *) bpl;
1135| protphysaddr = ((sgpe)->dma_address);
1136| prot_bde->addrHigh = (( __u32)(__le32)(((uint32_t) (0xffffffff & (u64)(protphysaddr)))));
1137| prot_bde->addrLow = (( __u32)(__le32)(((uint32_t) (0xffffffff & (((u64)(protphysaddr))>>32)))));
1138| protgroup_len = ((sgpe)->dma_length);
1139|
1140|
1141| __st_BUG_ON_st__(protgroup_len % 8);
1142|
1143| protgrp_blks = protgroup_len / 8;
1144| protgrp_bytes = protgrp_blks * blksize;
1145|
1146| prot_bde->tus.f.bdeSize = protgroup_len;
1147| prot_bde->tus.f.bdeFlags = 0x87;
1148| prot_bde->tus.w = (( __u32)(__le32)(bpl->tus.w));
1149|
1150| curr_prot++;
1151| num_bde++;
1152|
1153|
1154| pgdone = 0;
1155| subtotal = 0;
1156| while (!pgdone) {
1157| if (!sgde) {
1158| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9065 BLKGRD:%s Invalid data segment\n", phba->brd_no, __func__); } } while (0)
1159|
1160| ;
1161| return 0;
1162| }
1163| bpl++;
1164| dataphysaddr = ((sgde)->dma_address) + split_offset;
1165| bpl->addrLow = (( __u32)(__le32)(((uint32_t) (0xffffffff & (u64)(dataphysaddr)))));
1166| bpl->addrHigh = (( __u32)(__le32)(((uint32_t) (0xffffffff & (((u64)(dataphysaddr))>>32)))));
1167|
1168| remainder = ((sgde)->dma_length) - split_offset;
1169|
1170| if ((subtotal + remainder) <= protgrp_bytes) {
1171|
1172| bpl->tus.f.bdeSize = remainder;
1173| split_offset = 0;
1174|
1175| if ((subtotal + remainder) == protgrp_bytes)
1176| pgdone = 1;
1177| } else {
1178|
1179| bpl->tus.f.bdeSize = protgrp_bytes - subtotal;
1180| split_offset += bpl->tus.f.bdeSize;
1181| }
1182|
1183| subtotal += bpl->tus.f.bdeSize;
1184|
1185| if (datadir == DMA_TO_DEVICE)
1186| bpl->tus.f.bdeFlags = 0x00;
1187| else
1188| bpl->tus.f.bdeFlags = 0x08;
1189| bpl->tus.w = (( __u32)(__le32)(bpl->tus.w));
1190|
1191| num_bde++;
1192| curr_data++;
1193|
1194| if (split_offset)
1195| break;
1196|
1197|
1198| sgde = sg_next(sgde);
1199|
1200| }
1201|
1202|
1203| if (curr_prot == protcnt) {
1204| alldone = 1;
1205| } else if (curr_prot < protcnt) {
1206|
1207| sgpe = sg_next(sgpe);
1208| bpl++;
1209|
1210|
1211| reftag += protgrp_blks;
1212| } else {
1213|
1214| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9054 BLKGRD: bug in %s\n", phba->brd_no, __func__); } } while (0)
1215| ;
1216| }
1217|
1218| } while (!alldone);
1219|
1220|out:
1221|
1222| return num_bde;
1223|}
1224|
1225|
1226|
1227|
1228|
1229|
1230|
1231|static int
1232|lpfc_prot_group_type(struct lpfc_hba *phba, struct scsi_cmnd *sc)
1233|{
1234| int ret = LPFC_PG_TYPE_INVALID;
1235| unsigned char op = scsi_get_prot_op(sc);
1236|
1237| switch (op) {
1238| case SCSI_PROT_READ_STRIP:
1239| case SCSI_PROT_WRITE_INSERT:
1240| ret = LPFC_PG_TYPE_NO_DIF;
1241| break;
1242| case SCSI_PROT_READ_INSERT:
1243| case SCSI_PROT_WRITE_STRIP:
1244| case SCSI_PROT_READ_PASS:
1245| case SCSI_PROT_WRITE_PASS:
1246| ret = LPFC_PG_TYPE_DIF_BUF;
1247| break;
1248| default:
1249| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000040) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9021 Unsupported protection op:%d\n", phba->brd_no, op); } } while (0)
1250| ;
1251| break;
1252| }
1253|
1254| return ret;
1255|}
1256|
1257|
1258|
1259|
1260|
1261|
1262|static int
1263|lpfc_bg_scsi_prep_dma_buf(struct lpfc_hba *phba,
1264| struct lpfc_scsi_buf *lpfc_cmd)
1265|{
1266| struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd;
1267| struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
1268| struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl;
1269| IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
1270| uint32_t num_bde = 0;
1271| int datasegcnt, protsegcnt, datadir = scsi_cmnd->sc_data_direction;
1272| int prot_group_type = 0;
1273| int diflen, fcpdl;
1274| unsigned blksize;
1275|
1276|
1277|
1278|
1279|
1280| bpl += 2;
1281| if (scsi_sg_count(scsi_cmnd)) {
1282|
1283|
1284|
1285|
1286|
1287|
1288| datasegcnt = dma_map_sg_attrs(&phba->pcidev->dev, scsi_sglist(scsi_cmnd), scsi_sg_count(scsi_cmnd), datadir, ((void *)0))
1289|
1290| ;
1291| if (!datasegcnt)
1292| return 1;
1293|
1294| lpfc_cmd->seg_cnt = datasegcnt;
1295| if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
1296| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9067 BLKGRD: %s: Too many sg segments" " from dma_map_sg. Config %d, seg_cnt" " %d\n", phba->brd_no, __func__, phba->cfg_sg_seg_cnt, lpfc_cmd->seg_cnt); } } while (0)
1297|
1298|
1299|
1300|
1301| ;
1302| scsi_dma_unmap(scsi_cmnd);
1303| return 1;
1304| }
1305|
1306| prot_group_type = lpfc_prot_group_type(phba, scsi_cmnd);
1307|
1308| switch (prot_group_type) {
1309| case LPFC_PG_TYPE_NO_DIF:
1310| num_bde = lpfc_bg_setup_bpl(phba, scsi_cmnd, bpl,
1311| datasegcnt);
1312|
1313| if (num_bde < 2)
1314| goto err;
1315| break;
1316| case LPFC_PG_TYPE_DIF_BUF:{
1317|
1318|
1319|
1320|
1321|
1322| protsegcnt = dma_map_sg_attrs(&phba->pcidev->dev, scsi_prot_sglist(scsi_cmnd), scsi_prot_sg_count(scsi_cmnd), datadir, ((void *)0))
1323|
1324| ;
1325| if (!protsegcnt) {
1326| scsi_dma_unmap(scsi_cmnd);
1327| return 1;
1328| }
1329|
1330| lpfc_cmd->prot_seg_cnt = protsegcnt;
1331| if (lpfc_cmd->prot_seg_cnt
1332| > phba->cfg_prot_sg_seg_cnt) {
1333| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9068 BLKGRD: %s: Too many prot sg " "segments from dma_map_sg. Config %d," "prot_seg_cnt %d\n", phba->brd_no, __func__, phba->cfg_prot_sg_seg_cnt, lpfc_cmd->prot_seg_cnt); } } while (0)
1334|
1335|
1336|
1337|
1338| ;
1339| dma_unmap_sg_attrs(&phba->pcidev->dev, scsi_prot_sglist(scsi_cmnd), scsi_prot_sg_count(scsi_cmnd), datadir, ((void *)0))
1340|
1341|
1342| ;
1343| scsi_dma_unmap(scsi_cmnd);
1344| return 1;
1345| }
1346|
1347| num_bde = lpfc_bg_setup_bpl_prot(phba, scsi_cmnd, bpl,
1348| datasegcnt, protsegcnt);
1349|
1350| if (num_bde < 3)
1351| goto err;
1352| break;
1353| }
1354| case LPFC_PG_TYPE_INVALID:
1355| default:
1356| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000040) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9022 Unexpected protection group %i\n", phba->brd_no, prot_group_type); } } while (0)
1357|
1358| ;
1359| return 1;
1360| }
1361| }
1362|
1363|
1364|
1365|
1366|
1367|
1368|
1369| iocb_cmd->un.fcpi64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
1370| iocb_cmd->un.fcpi64.bdl.bdeSize += (num_bde * sizeof(struct ulp_bde64));
1371| iocb_cmd->ulpBdeCount = 1;
1372| iocb_cmd->ulpLe = 1;
1373|
1374| fcpdl = scsi_bufflen(scsi_cmnd);
1375|
1376| if (scsi_get_prot_type(scsi_cmnd) == SCSI_PROT_DIF_TYPE1) {
1377|
1378|
1379|
1380|
1381|
1382| blksize = lpfc_cmd_blksize(scsi_cmnd);
1383| diflen = (fcpdl / blksize) * 8;
1384| fcpdl += diflen;
1385| }
1386| fcp_cmnd->fcpDl = (__builtin_constant_p((__u32)(( __u32)(__be32)(fcpdl))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcpdl)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcpdl)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcpdl)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcpdl)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcpdl)));
1387|
1388|
1389|
1390|
1391|
1392| iocb_cmd->un.fcpi.fcpi_parm = fcpdl;
1393|
1394| return 0;
1395|err:
1396| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000040) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9023 Could not setup all needed BDE's" "prot_group_type=%d, num_bde=%d\n", phba->brd_no, prot_group_type, num_bde); } } while (0)
1397|
1398|
1399| ;
1400| return 1;
1401|}
1402|static int
1403|lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd,
1404| struct lpfc_iocbq *pIocbOut)
1405|{
1406| struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
1407| struct sli3_bg_fields *bgf = &pIocbOut->iocb.unsli3.sli3_bg;
1408| int ret = 0;
1409| uint32_t bghm = bgf->bghm;
1410| uint32_t bgstat = bgf->bgstat;
1411| uint64_t failing_sector = 0;
1412|
1413| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9069 BLKGRD: BG ERROR in cmd" " 0x%x lba 0x%llx blk cnt 0x%x " "bgstat=0x%x bghm=0x%x\n", phba->brd_no, cmd->cmnd[0], (unsigned long long)scsi_get_lba(cmd), blk_rq_sectors(cmd->request), bgstat, bghm); } } while (0)
1414|
1415|
1416|
1417| ;
1418|
1419| __st_spin_lock_st__(&_dump_buf_lock);
1420| if (!_dump_buf_done) {
1421| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9070 BLKGRD: Saving" " Data for %u blocks to debugfs\n", phba->brd_no, (cmd->cmnd[7] << 8 | cmd->cmnd[8])); } } while (0)
1422|
1423| ;
1424| lpfc_debug_save_data(phba, cmd);
1425|
1426|
1427| if (lpfc_prot_group_type(phba, cmd) ==
1428| LPFC_PG_TYPE_DIF_BUF) {
1429| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9071 BLKGRD: " "Saving DIF for %u blocks to debugfs\n", phba->brd_no, (cmd->cmnd[7] << 8 | cmd->cmnd[8])); } } while (0)
1430|
1431| ;
1432| lpfc_debug_save_dif(phba, cmd);
1433| }
1434|
1435| _dump_buf_done = 1;
1436| }
1437| __st_spin_unlock_st__(&_dump_buf_lock);
1438|
1439| if (lpfc_bgs_get_invalid_prof(bgstat)) {
1440| cmd->result = (((0x07) << 16) | 0);
1441| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9072 BLKGRD: Invalid" " BlockGuard profile. bgstat:0x%x\n", phba->brd_no, bgstat); } } while (0)
1442|
1443| ;
1444| ret = (-1);
1445| goto out;
1446| }
1447|
1448| if (lpfc_bgs_get_uninit_dif_block(bgstat)) {
1449| cmd->result = (((0x07) << 16) | 0);
1450| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9073 BLKGRD: " "Invalid BlockGuard DIF Block. bgstat:0x%x\n", phba->brd_no, bgstat); } } while (0)
1451|
1452| ;
1453| ret = (-1);
1454| goto out;
1455| }
1456|
1457| if (lpfc_bgs_get_guard_err(bgstat)) {
1458| ret = 1;
1459|
1460| scsi_build_sense_buffer(1, cmd->sense_buffer, 0x05,
1461| 0x10, 0x1);
1462| cmd->result = 0x08 << 24
1463| | (((0x05) << 16) | 0x02);
1464| phba->bg_guard_err_cnt++;
1465| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9055 BLKGRD: guard_tag error\n", phba->brd_no); } } while (0)
1466| ;
1467| }
1468|
1469| if (lpfc_bgs_get_reftag_err(bgstat)) {
1470| ret = 1;
1471|
1472| scsi_build_sense_buffer(1, cmd->sense_buffer, 0x05,
1473| 0x10, 0x3);
1474| cmd->result = 0x08 << 24
1475| | (((0x05) << 16) | 0x02);
1476|
1477| phba->bg_reftag_err_cnt++;
1478| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9056 BLKGRD: ref_tag error\n", phba->brd_no); } } while (0)
1479| ;
1480| }
1481|
1482| if (lpfc_bgs_get_apptag_err(bgstat)) {
1483| ret = 1;
1484|
1485| scsi_build_sense_buffer(1, cmd->sense_buffer, 0x05,
1486| 0x10, 0x2);
1487| cmd->result = 0x08 << 24
1488| | (((0x05) << 16) | 0x02);
1489|
1490| phba->bg_apptag_err_cnt++;
1491| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9061 BLKGRD: app_tag error\n", phba->brd_no); } } while (0)
1492| ;
1493| }
1494|
1495| if (lpfc_bgs_get_hi_water_mark_present(bgstat)) {
1496|
1497|
1498|
1499|
1500| cmd->sense_buffer[8] = 0;
1501| cmd->sense_buffer[9] = 0xa;
1502| bghm /= cmd->device->sector_size;
1503|
1504| failing_sector = scsi_get_lba(cmd);
1505| failing_sector += bghm;
1506|
1507| put_unaligned_be64(failing_sector, &cmd->sense_buffer[10]);
1508| }
1509|
1510| if (!ret) {
1511|
1512| cmd->result = (((0x07) << 16) | 0);
1513| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9057 BLKGRD: no errors reported!\n", phba->brd_no); } } while (0)
1514| ;
1515| }
1516|
1517|out:
1518| return ret;
1519|}
1520|static int
1521|lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1522|{
1523| struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd;
1524| struct scatterlist *sgel = ((void *)0);
1525| struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
1526| struct sli4_sge *sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl;
1527| IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
1528| dma_addr_t physaddr;
1529| uint32_t num_bde = 0;
1530| uint32_t dma_len;
1531| uint32_t dma_offset = 0;
1532| int nseg;
1533|
1534|
1535|
1536|
1537|
1538|
1539|
1540| if (scsi_sg_count(scsi_cmnd)) {
1541|
1542|
1543|
1544|
1545|
1546|
1547|
1548| nseg = scsi_dma_map(scsi_cmnd);
1549| if (!nseg)
1550| return 1;
1551| sgl += 1;
1552|
1553| sgl->word2 = (( __u32)(__le32)(sgl->word2));
1554| ((sgl)->word2 = ((((0) & 0x00000001) << 31) | ((sgl)->word2 & ~(0x00000001 << 31))));
1555| sgl->word2 = (( __le32)(__u32)(sgl->word2));
1556| sgl += 1;
1557|
1558| lpfc_cmd->seg_cnt = nseg;
1559| if (lpfc_cmd->seg_cnt > phba->cfg_sg_seg_cnt) {
1560| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9074 BLKGRD:" " %s: Too many sg segments from " "dma_map_sg. Config %d, seg_cnt %d\n", phba->brd_no, __func__, phba->cfg_sg_seg_cnt, lpfc_cmd->seg_cnt); } } while (0)
1561|
1562|
1563|
1564| ;
1565| scsi_dma_unmap(scsi_cmnd);
1566| return 1;
1567| }
1568| for (num_bde = 0, sgel = (scsi_sglist(scsi_cmnd)); num_bde < (nseg); num_bde++, sgel = sg_next(sgel)) {
1569| physaddr = ((sgel)->dma_address);
1570| dma_len = ((sgel)->dma_length);
1571| sgl->addr_lo = (( __le32)(__u32)(((uint32_t) (0xffffffff & (u64)(physaddr)))));
1572| sgl->addr_hi = (( __le32)(__u32)(((uint32_t) (0xffffffff & (((u64)(physaddr))>>32)))));
1573| if ((num_bde + 1) == nseg)
1574| ((sgl)->word2 = ((((1) & 0x00000001) << 31) | ((sgl)->word2 & ~(0x00000001 << 31))));
1575| else
1576| ((sgl)->word2 = ((((0) & 0x00000001) << 31) | ((sgl)->word2 & ~(0x00000001 << 31))));
1577| ((sgl)->word2 = ((((dma_offset) & 0x00FFFFFF) << 0) | ((sgl)->word2 & ~(0x00FFFFFF << 0))));
1578| sgl->word2 = (( __le32)(__u32)(sgl->word2));
1579| sgl->sge_len = (( __le32)(__u32)(dma_len));
1580| dma_offset += dma_len;
1581| sgl++;
1582| }
1583| } else {
1584| sgl += 1;
1585|
1586| sgl->word2 = (( __u32)(__le32)(sgl->word2));
1587| ((sgl)->word2 = ((((1) & 0x00000001) << 31) | ((sgl)->word2 & ~(0x00000001 << 31))));
1588| sgl->word2 = (( __le32)(__u32)(sgl->word2));
1589| }
1590|
1591|
1592|
1593|
1594|
1595|
1596|
1597| fcp_cmnd->fcpDl = (( __be32)(__builtin_constant_p((__u32)((scsi_bufflen(scsi_cmnd)))) ? ((__u32)( (((__u32)((scsi_bufflen(scsi_cmnd))) & (__u32)0x000000ffUL) << 24) | (((__u32)((scsi_bufflen(scsi_cmnd))) & (__u32)0x0000ff00UL) << 8) | (((__u32)((scsi_bufflen(scsi_cmnd))) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((scsi_bufflen(scsi_cmnd))) & (__u32)0xff000000UL) >> 24))) : __fswab32((scsi_bufflen(scsi_cmnd)))));
1598|
1599|
1600|
1601|
1602|
1603| iocb_cmd->un.fcpi.fcpi_parm = scsi_bufflen(scsi_cmnd);
1604| return 0;
1605|}
1606|static inline int
1607|lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
1608|{
1609| return phba->lpfc_scsi_prep_dma_buf(phba, lpfc_cmd);
1610|}
1611|static void
1612|lpfc_send_scsi_error_event(struct lpfc_hba *phba, struct lpfc_vport *vport,
1613| struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_iocbq *rsp_iocb) {
1614| struct scsi_cmnd *cmnd = lpfc_cmd->pCmd;
1615| struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp;
1616| uint32_t resp_info = fcprsp->rspStatus2;
1617| uint32_t scsi_status = fcprsp->rspStatus3;
1618| uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm;
1619| struct lpfc_fast_path_event *fast_path_evt = ((void *)0);
1620| struct lpfc_nodelist *pnode = lpfc_cmd->rdata->pnode;
1621| unsigned long flags;
1622|
1623| if (!pnode || !(((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8)))
1624| return;
1625|
1626|
1627| if ((cmnd->result == 0x28) ||
1628| (cmnd->result == 0x08)) {
1629| fast_path_evt = lpfc_alloc_fast_evt(phba);
1630| if (!fast_path_evt)
1631| return;
1632| fast_path_evt->un.scsi_evt.event_type =
1633| 0x0200;
1634| fast_path_evt->un.scsi_evt.subcategory =
1635| (cmnd->result == 0x28) ?
1636| 0x0001 : 0x0002;
1637| fast_path_evt->un.scsi_evt.lun = cmnd->device->lun;
1638| __st_memcpy_st__(&fast_path_evt->un.scsi_evt.wwpn,
1639| &pnode->nlp_portname, sizeof(struct lpfc_name));
1640| __st_memcpy_st__(&fast_path_evt->un.scsi_evt.wwnn,
1641| &pnode->nlp_nodename, sizeof(struct lpfc_name));
1642| } else if ((resp_info & 0x02) && fcprsp->rspSnsLen &&
1643| ((cmnd->cmnd[0] == 0x28) || (cmnd->cmnd[0] == 0x2a))) {
1644| fast_path_evt = lpfc_alloc_fast_evt(phba);
1645| if (!fast_path_evt)
1646| return;
1647| fast_path_evt->un.check_cond_evt.scsi_event.event_type =
1648| 0x0200;
1649| fast_path_evt->un.check_cond_evt.scsi_event.subcategory =
1650| 0x0004;
1651| fast_path_evt->un.check_cond_evt.scsi_event.lun =
1652| cmnd->device->lun;
1653| __st_memcpy_st__(&fast_path_evt->un.check_cond_evt.scsi_event.wwpn,
1654| &pnode->nlp_portname, sizeof(struct lpfc_name));
1655| __st_memcpy_st__(&fast_path_evt->un.check_cond_evt.scsi_event.wwnn,
1656| &pnode->nlp_nodename, sizeof(struct lpfc_name));
1657| fast_path_evt->un.check_cond_evt.sense_key =
1658| cmnd->sense_buffer[2] & 0xf;
1659| fast_path_evt->un.check_cond_evt.asc = cmnd->sense_buffer[12];
1660| fast_path_evt->un.check_cond_evt.ascq = cmnd->sense_buffer[13];
1661| } else if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) &&
1662| fcpi_parm &&
1663| (((__builtin_constant_p((__u32)(( __u32)(__be32)(fcprsp->rspResId))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcprsp->rspResId))) != fcpi_parm) ||
1664| ((scsi_status == 0x00) &&
1665| !(resp_info & (0x08 | 0x04))))) {
1666|
1667|
1668|
1669|
1670| fast_path_evt = lpfc_alloc_fast_evt(phba);
1671| if (!fast_path_evt)
1672| return;
1673| fast_path_evt->un.read_check_error.header.event_type =
1674| 0x0100;
1675| fast_path_evt->un.read_check_error.header.subcategory =
1676| 0x04;
1677| __st_memcpy_st__(&fast_path_evt->un.read_check_error.header.wwpn,
1678| &pnode->nlp_portname, sizeof(struct lpfc_name));
1679| __st_memcpy_st__(&fast_path_evt->un.read_check_error.header.wwnn,
1680| &pnode->nlp_nodename, sizeof(struct lpfc_name));
1681| fast_path_evt->un.read_check_error.lun = cmnd->device->lun;
1682| fast_path_evt->un.read_check_error.opcode = cmnd->cmnd[0];
1683| fast_path_evt->un.read_check_error.fcpiparam =
1684| fcpi_parm;
1685| } else
1686| return;
1687|
1688| fast_path_evt->vport = vport;
1689| __st_spin_lock_irqsave_st__(&phba->hbalock, flags);
1690| list_add_tail(&fast_path_evt->work_evt.evt_listp, &phba->work_list);
1691| __st_spin_unlock_irqrestore_st__(&phba->hbalock, flags);
1692| lpfc_worker_wake_up(phba);
1693| return;
1694|}
1695|static void
1696|lpfc_scsi_unprep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *psb)
1697|{
1698|
1699|
1700|
1701|
1702|
1703|
1704| if (psb->seg_cnt > 0)
1705| scsi_dma_unmap(psb->pCmd);
1706| if (psb->prot_seg_cnt > 0)
1707| dma_unmap_sg_attrs(&phba->pcidev->dev, scsi_prot_sglist(psb->pCmd), scsi_prot_sg_count(psb->pCmd), psb->pCmd->sc_data_direction, ((void *)0))
1708|
1709| ;
1710|}
1711|static void
1712|lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
1713| struct lpfc_iocbq *rsp_iocb)
1714|{
1715| struct scsi_cmnd *cmnd = lpfc_cmd->pCmd;
1716| struct fcp_cmnd *fcpcmd = lpfc_cmd->fcp_cmnd;
1717| struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp;
1718| uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm;
1719| uint32_t resp_info = fcprsp->rspStatus2;
1720| uint32_t scsi_status = fcprsp->rspStatus3;
1721| uint32_t *lp;
1722| uint32_t host_status = 0x00;
1723| uint32_t rsplen = 0;
1724| uint32_t logit = 0x00000040 | 0x00001000;
1725|
1726|
1727|
1728|
1729|
1730|
1731|
1732| if (fcpcmd->fcpCntl2) {
1733| scsi_status = 0;
1734| goto out;
1735| }
1736|
1737| if (resp_info & 0x01) {
1738| rsplen = (__builtin_constant_p((__u32)(( __u32)(__be32)(fcprsp->rspRspLen))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcprsp->rspRspLen)));
1739| if (rsplen != 0 && rsplen != 4 && rsplen != 8) {
1740| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "2719 Invalid response length: " "tgt x%x lun x%x cmnd x%x rsplen x%x\n", (vport)->phba->brd_no, vport->vpi, cmnd->device->id, cmnd->device->lun, cmnd->cmnd[0], rsplen); } } while (0)
1741|
1742|
1743|
1744|
1745| ;
1746| host_status = 0x07;
1747| goto out;
1748| }
1749| if (fcprsp->rspInfo3 != 0x00) {
1750| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "2757 Protocol failure detected during " "processing of FCP I/O op: " "tgt x%x lun x%x cmnd x%x rspInfo3 x%x\n", (vport)->phba->brd_no, vport->vpi, cmnd->device->id, cmnd->device->lun, cmnd->cmnd[0], fcprsp->rspInfo3); } } while (0)
1751|
1752|
1753|
1754|
1755|
1756| ;
1757| host_status = 0x07;
1758| goto out;
1759| }
1760| }
1761|
1762| if ((resp_info & 0x02) && fcprsp->rspSnsLen) {
1763| uint32_t snslen = (__builtin_constant_p((__u32)(( __u32)(__be32)(fcprsp->rspSnsLen))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcprsp->rspSnsLen)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcprsp->rspSnsLen)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspSnsLen)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspSnsLen)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcprsp->rspSnsLen)));
1764| if (snslen > 96)
1765| snslen = 96;
1766|
1767| if (resp_info & 0x01)
1768| rsplen = (__builtin_constant_p((__u32)(( __u32)(__be32)(fcprsp->rspRspLen))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcprsp->rspRspLen)));
1769| __st_memcpy_st__(cmnd->sense_buffer, &fcprsp->rspInfo0 + rsplen, snslen);
1770| }
1771| lp = (uint32_t *)cmnd->sense_buffer;
1772|
1773| if (!scsi_status && (resp_info & 0x08))
1774| logit = 0x00000040;
1775|
1776| do { { if (((logit) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9024 FCP command x%x failed: x%x SNS x%x x%x " "Data: x%x x%x x%x x%x x%x\n", (vport)->phba->brd_no, vport->vpi, cmnd->cmnd[0], scsi_status, (__builtin_constant_p((__u32)(( __u32)(__be32)(*lp))) ? ((__u32)( (((__u32)(( __u32)(__be32)(*lp)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(*lp)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(*lp)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(*lp)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(*lp))), (__builtin_constant_p((__u32)(( __u32)(__be32)(*(lp + 3)))) ? ((__u32)( (((__u32)(( __u32)(__be32)(*(lp + 3))) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(*(lp + 3))) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(*(lp + 3))) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(*(lp + 3))) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(*(lp + 3)))), resp_info, (__builtin_constant_p((__u32)(( __u32)(__be32)(fcprsp->rspResId))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcprsp->rspResId))), (__builtin_constant_p((__u32)(( __u32)(__be32)(fcprsp->rspSnsLen))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcprsp->rspSnsLen)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcprsp->rspSnsLen)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspSnsLen)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspSnsLen)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcprsp->rspSnsLen))), (__builtin_constant_p((__u32)(( __u32)(__be32)(fcprsp->rspRspLen))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspRspLen)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcprsp->rspRspLen))), fcprsp->rspInfo3); } } while (0)
1777|
1778|
1779|
1780|
1781|
1782|
1783|
1784| ;
1785|
1786| scsi_set_resid(cmnd, 0);
1787| if (resp_info & 0x08) {
1788| scsi_set_resid(cmnd, (__builtin_constant_p((__u32)(( __u32)(__be32)(fcprsp->rspResId))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcprsp->rspResId))));
1789|
1790| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<6>"[1] <= '3')) dev_printk("<6>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9025 FCP Read Underrun, expected %d, " "residual %d Data: x%x x%x x%x\n", (vport)->phba->brd_no, vport->vpi, (__builtin_constant_p((__u32)(( __u32)(__be32)(fcpcmd->fcpDl))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcpcmd->fcpDl))), scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0], cmnd->underflow); } } while (0)
1791|
1792|
1793|
1794|
1795| ;
1796|
1797|
1798|
1799|
1800|
1801|
1802| if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) &&
1803| fcpi_parm &&
1804| (scsi_get_resid(cmnd) != fcpi_parm)) {
1805| do { { if (((0x00000040 | 0x00001000) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9026 FCP Read Check Error " "and Underrun Data: x%x x%x x%x x%x\n", (vport)->phba->brd_no, vport->vpi, (__builtin_constant_p((__u32)(( __u32)(__be32)(fcpcmd->fcpDl))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcpcmd->fcpDl))), scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0]); } } while (0)
1806|
1807|
1808|
1809|
1810|
1811| ;
1812| scsi_set_resid(cmnd, scsi_bufflen(cmnd));
1813| host_status = 0x07;
1814| }
1815|
1816|
1817|
1818|
1819|
1820|
1821| if (!(resp_info & 0x02) &&
1822| (scsi_status == 0x00) &&
1823| (scsi_bufflen(cmnd) - scsi_get_resid(cmnd)
1824| < cmnd->underflow)) {
1825| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<6>"[1] <= '3')) dev_printk("<6>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9027 FCP command x%x residual " "underrun converted to error " "Data: x%x x%x x%x\n", (vport)->phba->brd_no, vport->vpi, cmnd->cmnd[0], scsi_bufflen(cmnd), scsi_get_resid(cmnd), cmnd->underflow); } } while (0)
1826|
1827|
1828|
1829|
1830| ;
1831| host_status = 0x07;
1832| }
1833| } else if (resp_info & 0x04) {
1834| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9028 FCP command x%x residual overrun error. " "Data: x%x x%x\n", (vport)->phba->brd_no, vport->vpi, cmnd->cmnd[0], scsi_bufflen(cmnd), scsi_get_resid(cmnd)); } } while (0)
1835|
1836|
1837| ;
1838| host_status = 0x07;
1839|
1840|
1841|
1842|
1843|
1844| } else if (fcpi_parm && (cmnd->sc_data_direction == DMA_FROM_DEVICE)) {
1845| do { { if (((0x00000040 | 0x00001000) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9029 FCP Read Check Error Data: " "x%x x%x x%x x%x x%x\n", (vport)->phba->brd_no, vport->vpi, (__builtin_constant_p((__u32)(( __u32)(__be32)(fcpcmd->fcpDl))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcpcmd->fcpDl)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcpcmd->fcpDl))), (__builtin_constant_p((__u32)(( __u32)(__be32)(fcprsp->rspResId))) ? ((__u32)( (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__be32)(fcprsp->rspResId)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__be32)(fcprsp->rspResId))), fcpi_parm, cmnd->cmnd[0], scsi_status); } } while (0)
1846|
1847|
1848|
1849|
1850| ;
1851| switch (scsi_status) {
1852| case 0x00:
1853| case 0x02:
1854|
1855|
1856|
1857|
1858|
1859| host_status = 0x07;
1860| break;
1861| }
1862| scsi_set_resid(cmnd, scsi_bufflen(cmnd));
1863| }
1864|
1865| out:
1866| cmnd->result = (((host_status) << 16) | scsi_status);
1867| lpfc_send_scsi_error_event(vport->phba, vport, lpfc_cmd, rsp_iocb);
1868|}
1869|static void
1870|lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
1871| struct lpfc_iocbq *pIocbOut)
1872|{
1873| struct lpfc_scsi_buf *lpfc_cmd =
1874| (struct lpfc_scsi_buf *) pIocbIn->context1;
1875| struct lpfc_vport *vport = pIocbIn->vport;
1876| struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
1877| struct lpfc_nodelist *pnode = rdata->pnode;
1878| struct scsi_cmnd *cmd;
1879| int result;
1880| struct scsi_device *tmp_sdev;
1881| int depth;
1882| unsigned long flags;
1883| struct lpfc_fast_path_event *fast_path_evt;
1884| struct Scsi_Host *shost;
1885| uint32_t queue_depth, scsi_id;
1886|
1887|
1888| if (!(lpfc_cmd->pCmd))
1889| return;
1890| cmd = lpfc_cmd->pCmd;
1891| shost = cmd->device->host;
1892|
1893| lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
1894| lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
1895|
1896| lpfc_cmd->exch_busy = pIocbOut->iocb_flag & 0x40;
1897|
1898| if (pnode && (((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8)))
1899| atomic_dec(&pnode->cmd_pending);
1900|
1901| if (lpfc_cmd->status) {
1902| if (lpfc_cmd->status == 0x3 &&
1903| (lpfc_cmd->result & 0x100))
1904| lpfc_cmd->status = 0x10;
1905| else if (lpfc_cmd->status >= 0x11)
1906| lpfc_cmd->status = 0xF;
1907|
1908| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9030 FCP cmd x%x failed <%d/%d> " "status: x%x result: x%x Data: x%x x%x\n", (vport)->phba->brd_no, vport->vpi, cmd->cmnd[0], cmd->device ? cmd->device->id : 0xffff, cmd->device ? cmd->device->lun : 0xffff, lpfc_cmd->status, lpfc_cmd->result, pIocbOut->iocb.un1.t1.ulpContext, lpfc_cmd->cur_iocbq.iocb.un1.t1.ulpIoTag); } } while (0)
1909|
1910|
1911|
1912|
1913|
1914|
1915|
1916| ;
1917|
1918| switch (lpfc_cmd->status) {
1919| case 0x1:
1920|
1921| lpfc_handle_fcp_err(vport, lpfc_cmd, pIocbOut);
1922| break;
1923| case 0x6:
1924| case 0x7:
1925| cmd->result = (((0x0e) << 16) | 0);
1926| fast_path_evt = lpfc_alloc_fast_evt(phba);
1927| if (!fast_path_evt)
1928| break;
1929| fast_path_evt->un.fabric_evt.event_type =
1930| 0x0100;
1931| fast_path_evt->un.fabric_evt.subcategory =
1932| (lpfc_cmd->status == 0x6) ?
1933| 0x02 : 0x01;
1934| if (pnode && (((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8))) {
1935| __st_memcpy_st__(&fast_path_evt->un.fabric_evt.wwpn,
1936| &pnode->nlp_portname,
1937| sizeof(struct lpfc_name));
1938| __st_memcpy_st__(&fast_path_evt->un.fabric_evt.wwnn,
1939| &pnode->nlp_nodename,
1940| sizeof(struct lpfc_name));
1941| }
1942| fast_path_evt->vport = vport;
1943| fast_path_evt->work_evt.evt =
1944| LPFC_EVT_FASTPATH_MGMT_EVT;
1945| __st_spin_lock_irqsave_st__(&phba->hbalock, flags);
1946| list_add_tail(&fast_path_evt->work_evt.evt_listp,
1947| &phba->work_list);
1948| __st_spin_unlock_irqrestore_st__(&phba->hbalock, flags);
1949| lpfc_worker_wake_up(phba);
1950| break;
1951| case 0x3:
1952| if (lpfc_cmd->result == 0x04 ||
1953| lpfc_cmd->result == 0x11 ||
1954| lpfc_cmd->result == 0x16 ||
1955| lpfc_cmd->result == 0x47) {
1956| cmd->result = (((0x0d) << 16) | 0);
1957| break;
1958| }
1959|
1960| if ((lpfc_cmd->result == 0x0E ||
1961| lpfc_cmd->result == 0x0D) &&
1962| pIocbOut->iocb.unsli3.sli3_bg.bgstat) {
1963| if (scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL) {
1964|
1965|
1966|
1967|
1968| lpfc_parse_bg_err(phba, lpfc_cmd,
1969| pIocbOut);
1970| break;
1971| } else {
1972| do { { if (((0x00000200) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9031 non-zero BGSTAT " "on unprotected cmd\n", (vport)->phba->brd_no, vport->vpi); } } while (0)
1973|
1974|
1975| ;
1976| }
1977| }
1978|
1979|
1980| default:
1981| cmd->result = (((0x07) << 16) | 0);
1982| break;
1983| }
1984|
1985| if (!pnode || !(((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8))
1986| || (pnode->nlp_state != 0x6))
1987| cmd->result = (((0x0e) << 16) | 0x08)
1988| ;
1989| } else {
1990| cmd->result = (((0x00) << 16) | 0);
1991| }
1992|
1993| if (cmd->result || lpfc_cmd->fcp_rsp->rspSnsLen) {
1994| uint32_t *lp = (uint32_t *)cmd->sense_buffer;
1995|
1996| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<6>"[1] <= '3')) dev_printk("<6>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0710 Iodone <%d/%d> cmd %p, error " "x%x SNS x%x x%x Data: x%x x%x\n", (vport)->phba->brd_no, vport->vpi, cmd->device->id, cmd->device->lun, cmd, cmd->result, *lp, *(lp + 3), cmd->retries, scsi_get_resid(cmd)); } } while (0)
1997|
1998|
1999|
2000|
2001| ;
2002| }
2003|
2004| lpfc_update_stats(phba, lpfc_cmd);
2005| result = cmd->result;
2006| if (vport->cfg_max_scsicmpl_time &&
2007| (({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(lpfc_cmd->start_time + msecs_to_jiffies(vport->cfg_max_scsicmpl_time)) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(lpfc_cmd->start_time + msecs_to_jiffies(vport->cfg_max_scsicmpl_time)) - (long)(jiffies) < 0))
2008| ) {
2009| __st_spin_lock_irqsave_st__(shost->host_lock, flags);
2010| if (pnode && (((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8))) {
2011| if (pnode->cmd_qdepth >
2012| atomic_read(&pnode->cmd_pending) &&
2013| (atomic_read(&pnode->cmd_pending) >
2014| 10) &&
2015| ((cmd->cmnd[0] == 0x28) ||
2016| (cmd->cmnd[0] == 0x2a)))
2017| pnode->cmd_qdepth =
2018| atomic_read(&pnode->cmd_pending);
2019|
2020| pnode->last_change_time = jiffies;
2021| }
2022| __st_spin_unlock_irqrestore_st__(shost->host_lock, flags);
2023| } else if (pnode && (((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8))) {
2024| if ((pnode->cmd_qdepth < vport->cfg_tgt_queue_depth) &&
2025| (({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(pnode->last_change_time + msecs_to_jiffies(40000)) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(pnode->last_change_time + msecs_to_jiffies(40000)) - (long)(jiffies) < 0))
2026| ) {
2027| __st_spin_lock_irqsave_st__(shost->host_lock, flags);
2028| depth = pnode->cmd_qdepth * 5
2029| / 100;
2030| depth = depth ? depth : 1;
2031| pnode->cmd_qdepth += depth;
2032| if (pnode->cmd_qdepth > vport->cfg_tgt_queue_depth)
2033| pnode->cmd_qdepth = vport->cfg_tgt_queue_depth;
2034| pnode->last_change_time = jiffies;
2035| __st_spin_unlock_irqrestore_st__(shost->host_lock, flags);
2036| }
2037| }
2038|
2039| lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
2040|
2041|
2042| queue_depth = cmd->device->queue_depth;
2043| scsi_id = cmd->device->id;
2044| cmd->scsi_done(cmd);
2045|
2046| if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
2047|
2048|
2049|
2050|
2051| __st_spin_lock_irqsave_st__(shost->host_lock, flags);
2052| lpfc_cmd->pCmd = ((void *)0);
2053| if (lpfc_cmd->waitq)
2054| __wake_up(lpfc_cmd->waitq, (1 | 2), 1, ((void *)0));
2055| __st_spin_unlock_irqrestore_st__(shost->host_lock, flags);
2056| lpfc_release_scsi_buf(phba, lpfc_cmd);
2057| return;
2058| }
2059|
2060| if (!result)
2061| lpfc_rampup_queue_depth(vport, queue_depth);
2062|
2063|
2064|
2065|
2066|
2067| if (result == 0x28 && pnode &&
2068| (((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8))) {
2069| for ((tmp_sdev) = __scsi_iterate_devices((shost), ((void *)0)); (tmp_sdev); (tmp_sdev) = __scsi_iterate_devices((shost), (tmp_sdev))) {
2070| if (tmp_sdev->id != scsi_id)
2071| continue;
2072| depth = scsi_track_queue_full(tmp_sdev,
2073| tmp_sdev->queue_depth-1);
2074| if (depth <= 0)
2075| continue;
2076| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0711 detected queue full - lun queue " "depth adjusted to %d.\n", (vport)->phba->brd_no, vport->vpi, depth); } } while (0)
2077|
2078| ;
2079| lpfc_send_sdev_queuedepth_change_event(phba, vport,
2080| pnode,
2081| tmp_sdev->lun,
2082| depth+1, depth);
2083| }
2084| }
2085|
2086|
2087|
2088|
2089|
2090| __st_spin_lock_irqsave_st__(shost->host_lock, flags);
2091| lpfc_cmd->pCmd = ((void *)0);
2092| if (lpfc_cmd->waitq)
2093| __wake_up(lpfc_cmd->waitq, (1 | 2), 1, ((void *)0));
2094| __st_spin_unlock_irqrestore_st__(shost->host_lock, flags);
2095|
2096| lpfc_release_scsi_buf(phba, lpfc_cmd);
2097|}
2098|static void
2099|lpfc_fcpcmd_to_iocb(uint8_t *data, struct fcp_cmnd *fcp_cmnd)
2100|{
2101| int i, j;
2102| for (i = 0, j = 0; i < sizeof(struct fcp_cmnd);
2103| i += sizeof(uint32_t), j++) {
2104| ((uint32_t *)data)[j] = (( __be32)(__builtin_constant_p((__u32)((((uint32_t *)fcp_cmnd)[j]))) ? ((__u32)( (((__u32)((((uint32_t *)fcp_cmnd)[j])) & (__u32)0x000000ffUL) << 24) | (((__u32)((((uint32_t *)fcp_cmnd)[j])) & (__u32)0x0000ff00UL) << 8) | (((__u32)((((uint32_t *)fcp_cmnd)[j])) & (__u32)0x00ff0000UL) >> 8) | (((__u32)((((uint32_t *)fcp_cmnd)[j])) & (__u32)0xff000000UL) >> 24))) : __fswab32((((uint32_t *)fcp_cmnd)[j]))));
2105| }
2106|}
2107|static void
2108|lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
2109| struct lpfc_nodelist *pnode)
2110|{
2111| struct lpfc_hba *phba = vport->phba;
2112| struct scsi_cmnd *scsi_cmnd = lpfc_cmd->pCmd;
2113| struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
2114| IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
2115| struct lpfc_iocbq *piocbq = &(lpfc_cmd->cur_iocbq);
2116| int datadir = scsi_cmnd->sc_data_direction;
2117| char tag[2];
2118|
2119| if (!pnode || !(((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8)))
2120| return;
2121|
2122| lpfc_cmd->fcp_rsp->rspSnsLen = 0;
2123|
2124| lpfc_cmd->fcp_cmnd->fcpCntl2 = 0;
2125|
2126| int_to_scsilun(lpfc_cmd->pCmd->device->lun,
2127| &lpfc_cmd->fcp_cmnd->fcp_lun);
2128|
2129| __st_memcpy_st__(&fcp_cmnd->fcpCdb[0], scsi_cmnd->cmnd, 16);
2130|
2131| if (scsi_populate_tag_msg(scsi_cmnd, tag)) {
2132| switch (tag[0]) {
2133| case 0x21:
2134| fcp_cmnd->fcpCntl1 = 0x01;
2135| break;
2136| case 0x22:
2137| fcp_cmnd->fcpCntl1 = 0x02;
2138| break;
2139| default:
2140| fcp_cmnd->fcpCntl1 = 0x00;
2141| break;
2142| }
2143| } else
2144| fcp_cmnd->fcpCntl1 = 0;
2145|
2146|
2147|
2148|
2149|
2150|
2151|
2152| if (scsi_sg_count(scsi_cmnd)) {
2153| if (datadir == DMA_TO_DEVICE) {
2154| iocb_cmd->ulpCommand = 0x98;
2155| if (phba->sli_rev < 4) {
2156| iocb_cmd->un.fcpi.fcpi_parm = 0;
2157| iocb_cmd->ulpPU = 0;
2158| } else
2159| iocb_cmd->ulpPU = 2;
2160| fcp_cmnd->fcpCntl3 = 0x01;
2161| phba->fc4OutputRequests++;
2162| } else {
2163| iocb_cmd->ulpCommand = 0x9A;
2164| iocb_cmd->ulpPU = 2;
2165| fcp_cmnd->fcpCntl3 = 0x02;
2166| phba->fc4InputRequests++;
2167| }
2168| } else {
2169| iocb_cmd->ulpCommand = 0x9C;
2170| iocb_cmd->un.fcpi.fcpi_parm = 0;
2171| iocb_cmd->ulpPU = 0;
2172| fcp_cmnd->fcpCntl3 = 0;
2173| phba->fc4ControlRequests++;
2174| }
2175| if (phba->sli_rev == 3 &&
2176| !(phba->sli3_options & 0x20))
2177| lpfc_fcpcmd_to_iocb(iocb_cmd->unsli3.fcp_ext.icd, fcp_cmnd);
2178|
2179|
2180|
2181|
2182| piocbq->iocb.un1.t1.ulpContext = pnode->nlp_rpi;
2183| if (pnode->nlp_fcp_info & 0x10)
2184| piocbq->iocb.ulpFCP2Rcvy = 1;
2185| else
2186| piocbq->iocb.ulpFCP2Rcvy = 0;
2187|
2188| piocbq->iocb.ulpClass = (pnode->nlp_fcp_info & 0x0f);
2189| piocbq->context1 = lpfc_cmd;
2190| piocbq->iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl;
2191| piocbq->iocb.ulpTimeout = lpfc_cmd->timeout;
2192| piocbq->vport = vport;
2193|}
2194|static int
2195|lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
2196| struct lpfc_scsi_buf *lpfc_cmd,
2197| unsigned int lun,
2198| uint8_t task_mgmt_cmd)
2199|{
2200| struct lpfc_iocbq *piocbq;
2201| IOCB_t *piocb;
2202| struct fcp_cmnd *fcp_cmnd;
2203| struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
2204| struct lpfc_nodelist *ndlp = rdata->pnode;
2205|
2206| if (!ndlp || !(((ndlp)->nlp_usg_map & 0x1) && !((ndlp)->nlp_usg_map & 0x8)) ||
2207| ndlp->nlp_state != 0x6)
2208| return 0;
2209|
2210| piocbq = &(lpfc_cmd->cur_iocbq);
2211| piocbq->vport = vport;
2212|
2213| piocb = &piocbq->iocb;
2214|
2215| fcp_cmnd = lpfc_cmd->fcp_cmnd;
2216|
2217| __st_memset_st__(fcp_cmnd, 0, sizeof(struct fcp_cmnd));
2218| int_to_scsilun(lun, &fcp_cmnd->fcp_lun);
2219| fcp_cmnd->fcpCntl2 = task_mgmt_cmd;
2220| if (vport->phba->sli_rev == 3 &&
2221| !(vport->phba->sli3_options & 0x20))
2222| lpfc_fcpcmd_to_iocb(piocb->unsli3.fcp_ext.icd, fcp_cmnd);
2223| piocb->ulpCommand = 0x9C;
2224| piocb->un1.t1.ulpContext = ndlp->nlp_rpi;
2225| if (ndlp->nlp_fcp_info & 0x10) {
2226| piocb->ulpFCP2Rcvy = 1;
2227| }
2228| piocb->ulpClass = (ndlp->nlp_fcp_info & 0x0f);
2229|
2230|
2231| if (lpfc_cmd->timeout > 0xff) {
2232|
2233|
2234|
2235|
2236| piocb->ulpTimeout = 0;
2237| } else
2238| piocb->ulpTimeout = lpfc_cmd->timeout;
2239|
2240| if (vport->phba->sli_rev == 4)
2241| lpfc_sli4_set_rsp_sgl_last(vport->phba, lpfc_cmd);
2242|
2243| return 1;
2244|}
2245|int
2246|lpfc_scsi_api_table_setup(struct lpfc_hba *phba, uint8_t dev_grp)
2247|{
2248|
2249| phba->lpfc_scsi_unprep_dma_buf = lpfc_scsi_unprep_dma_buf;
2250| phba->lpfc_scsi_prep_cmnd = lpfc_scsi_prep_cmnd;
2251| phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf;
2252|
2253| switch (dev_grp) {
2254| case 0x1:
2255| phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s3;
2256| phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s3;
2257| phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s3;
2258| break;
2259| case 0x2:
2260| phba->lpfc_new_scsi_buf = lpfc_new_scsi_buf_s4;
2261| phba->lpfc_scsi_prep_dma_buf = lpfc_scsi_prep_dma_buf_s4;
2262| phba->lpfc_release_scsi_buf = lpfc_release_scsi_buf_s4;
2263| break;
2264| default:
2265| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000008) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "1418 Invalid HBA PCI-device group: 0x%x\n", phba->brd_no, dev_grp); } } while (0)
2266|
2267| ;
2268| return -19;
2269| break;
|This node is unreachable prev next
2270| }
2271| phba->lpfc_get_scsi_buf = lpfc_get_scsi_buf;
2272| phba->lpfc_rampdown_queue_depth = lpfc_rampdown_queue_depth;
2273| phba->lpfc_scsi_cmd_iocb_cmpl = lpfc_scsi_cmd_iocb_cmpl;
2274| return 0;
2275|}
2276|static void
2277|lpfc_tskmgmt_def_cmpl(struct lpfc_hba *phba,
2278| struct lpfc_iocbq *cmdiocbq,
2279| struct lpfc_iocbq *rspiocbq)
2280|{
2281| struct lpfc_scsi_buf *lpfc_cmd =
2282| (struct lpfc_scsi_buf *) cmdiocbq->context1;
2283| if (lpfc_cmd)
2284| lpfc_release_scsi_buf(phba, lpfc_cmd);
2285| return;
2286|}
2287|const char *
2288|lpfc_info(struct Scsi_Host *host)
2289|{
2290| struct lpfc_vport *vport = (struct lpfc_vport *) host->hostdata;
2291| struct lpfc_hba *phba = vport->phba;
2292| int len;
2293| static char lpfcinfobuf[384];
2294|
2295| __st_memset_st__(lpfcinfobuf,0,384);
2296| if (phba && phba->pcidev){
2297| strncpy(lpfcinfobuf, phba->ModelDesc, 256);
2298| len = strlen(lpfcinfobuf);
2299| snprintf(lpfcinfobuf + len,
2300| 384-len,
2301| " on PCI bus %02x device %02x irq %d",
2302| phba->pcidev->bus->number,
2303| phba->pcidev->devfn,
2304| phba->pcidev->irq);
2305| len = strlen(lpfcinfobuf);
2306| if (phba->Port[0]) {
2307| snprintf(lpfcinfobuf + len,
2308| 384-len,
2309| " port %s",
2310| phba->Port);
2311| }
2312| len = strlen(lpfcinfobuf);
2313| if (phba->sli4_hba.link_state.logical_speed) {
2314| snprintf(lpfcinfobuf + len,
2315| 384-len,
2316| " Logical Link Speed: %d Mbps",
2317| phba->sli4_hba.link_state.logical_speed * 10);
2318| }
2319| }
2320| return lpfcinfobuf;
2321|}
2322|static __inline__ void lpfc_poll_rearm_timer(struct lpfc_hba * phba)
2323|{
2324| unsigned long poll_tmo_expires =
2325| (jiffies + msecs_to_jiffies(phba->cfg_poll_tmo));
2326|
2327| if (phba->sli.ring[0].txcmplq_cnt)
2328| mod_timer(&phba->fcp_poll_timer,
2329| poll_tmo_expires);
2330|}
2331|
2332|
2333|
2334|
2335|
2336|
2337|
2338|void lpfc_poll_start_timer(struct lpfc_hba * phba)
2339|{
2340| lpfc_poll_rearm_timer(phba);
2341|}
2342|void lpfc_poll_timeout(unsigned long ptr)
2343|{
2344| struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
2345|
2346| if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
2347| lpfc_sli_handle_fast_ring_event(phba,
2348| &phba->sli.ring[0], 0x00000001);
2349|
2350| if (phba->cfg_poll & DISABLE_FCP_RING_INT)
2351| lpfc_poll_rearm_timer(phba);
2352| }
2353|}
2354|static int
2355|lpfc_queuecommand_lck(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
2356|{
2357| struct Scsi_Host *shost = cmnd->device->host;
2358| struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2359| struct lpfc_hba *phba = vport->phba;
2360| struct lpfc_rport_data *rdata = cmnd->device->hostdata;
2361| struct lpfc_nodelist *ndlp;
2362| struct lpfc_scsi_buf *lpfc_cmd;
2363| struct fc_rport *rport = scsi_is_fc_rport(scsi_target(cmnd->device)->dev.parent) ? ({ const typeof( ((struct fc_rport *)0)->dev ) *__mptr = (scsi_target(cmnd->device)->dev.parent); (struct fc_rport *)( (char *)__mptr - 1 );}) : ((void *)0);
2364| int err;
2365|
2366| err = fc_remote_port_chkready(rport);
2367| if (err) {
2368| cmnd->result = err;
2369| goto out_fail_command;
2370| }
2371| ndlp = rdata->pnode;
2372|
2373| if (!(phba->sli3_options & 0x20) &&
2374| scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) {
2375|
2376| do { { uint32_t log_verbose = (phba)->pport ? (phba)->pport->cfg_log_verbose : (phba)->cfg_log_verbose; if (((0x00000200) & log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((phba)->pcidev)->dev, "%d:" "9058 BLKGRD: ERROR: rcvd protected cmd:%02x" " op:%02x str=%s without registering for" " BlockGuard - Rejecting command\n", phba->brd_no, cmnd->cmnd[0], scsi_get_prot_op(cmnd), dif_op_str[scsi_get_prot_op(cmnd)]); } } while (0)
2377|
2378|
2379|
2380|
2381| ;
2382| goto out_fail_command;
2383| }
2384|
2385|
2386|
2387|
2388|
2389| if (!ndlp || !(((ndlp)->nlp_usg_map & 0x1) && !((ndlp)->nlp_usg_map & 0x8))) {
2390| cmnd->result = (((0x0e) << 16) | 0);
2391| goto out_fail_command;
2392| }
2393| if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth)
2394| goto out_host_busy;
2395|
2396| lpfc_cmd = lpfc_get_scsi_buf(phba);
2397| if (lpfc_cmd == ((void *)0)) {
2398| lpfc_rampdown_queue_depth(phba);
2399|
2400| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<6>"[1] <= '3')) dev_printk("<6>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0707 driver's buffer pool is empty, " "IO busied\n", (vport)->phba->brd_no, vport->vpi); } } while (0)
2401|
2402| ;
2403| goto out_host_busy;
2404| }
2405|
2406|
2407|
2408|
2409|
2410| lpfc_cmd->pCmd = cmnd;
2411| lpfc_cmd->rdata = rdata;
2412| lpfc_cmd->timeout = 0;
2413| lpfc_cmd->start_time = jiffies;
2414| cmnd->host_scribble = (unsigned char *)lpfc_cmd;
2415| cmnd->scsi_done = done;
2416|
2417| if (scsi_get_prot_op(cmnd) != SCSI_PROT_NORMAL) {
2418| if (vport->phba->cfg_enable_bg) {
2419| do { { if (((0x00000200) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9033 BLKGRD: rcvd protected cmd:%02x op:%02x " "str=%s\n", (vport)->phba->brd_no, vport->vpi, cmnd->cmnd[0], scsi_get_prot_op(cmnd), dif_op_str[scsi_get_prot_op(cmnd)]); } } while (0)
2420|
2421|
2422|
2423| ;
2424| do { { if (((0x00000200) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9034 BLKGRD: CDB: %02x %02x %02x %02x %02x " "%02x %02x %02x %02x %02x\n", (vport)->phba->brd_no, vport->vpi, cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2], cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5], cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8], cmnd->cmnd[9]); } } while (0)
2425|
2426|
2427|
2428|
2429|
2430| ;
2431| if (cmnd->cmnd[0] == 0x28)
2432| do { { if (((0x00000200) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9035 BLKGRD: READ @ sector %llu, " "count %u\n", (vport)->phba->brd_no, vport->vpi, (unsigned long long)scsi_get_lba(cmnd), blk_rq_sectors(cmnd->request)); } } while (0)
2433|
2434|
2435|
2436| ;
2437| else if (cmnd->cmnd[0] == 0x2a)
2438| do { { if (((0x00000200) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9036 BLKGRD: WRITE @ sector %llu, " "count %u cmd=%p\n", (vport)->phba->brd_no, vport->vpi, (unsigned long long)scsi_get_lba(cmnd), blk_rq_sectors(cmnd->request), cmnd); } } while (0)
2439|
2440|
2441|
2442|
2443| ;
2444| }
2445|
2446| err = lpfc_bg_scsi_prep_dma_buf(phba, lpfc_cmd);
2447| } else {
2448| if (vport->phba->cfg_enable_bg) {
2449| do { { if (((0x00000200) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9038 BLKGRD: rcvd unprotected cmd:" "%02x op:%02x str=%s\n", (vport)->phba->brd_no, vport->vpi, cmnd->cmnd[0], scsi_get_prot_op(cmnd), dif_op_str[scsi_get_prot_op(cmnd)]); } } while (0)
2450|
2451|
2452|
2453| ;
2454| do { { if (((0x00000200) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9039 BLKGRD: CDB: %02x %02x %02x " "%02x %02x %02x %02x %02x %02x %02x\n", (vport)->phba->brd_no, vport->vpi, cmnd->cmnd[0], cmnd->cmnd[1], cmnd->cmnd[2], cmnd->cmnd[3], cmnd->cmnd[4], cmnd->cmnd[5], cmnd->cmnd[6], cmnd->cmnd[7], cmnd->cmnd[8], cmnd->cmnd[9]); } } while (0)
2455|
2456|
2457|
2458|
2459|
2460|
2461| ;
2462| if (cmnd->cmnd[0] == 0x28)
2463| do { { if (((0x00000200) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9040 dbg: READ @ sector %llu, " "count %u\n", (vport)->phba->brd_no, vport->vpi, (unsigned long long)scsi_get_lba(cmnd), blk_rq_sectors(cmnd->request)); } } while (0)
2464|
2465|
2466|
2467| ;
2468| else if (cmnd->cmnd[0] == 0x2a)
2469| do { { if (((0x00000200) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9041 dbg: WRITE @ sector %llu, " "count %u cmd=%p\n", (vport)->phba->brd_no, vport->vpi, (unsigned long long)scsi_get_lba(cmnd), blk_rq_sectors(cmnd->request), cmnd); } } while (0)
2470|
2471|
2472|
2473| ;
2474| else
2475| do { { if (((0x00000200) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "9042 dbg: parser not implemented\n", (vport)->phba->brd_no, vport->vpi); } } while (0)
2476| ;
2477| }
2478| err = lpfc_scsi_prep_dma_buf(phba, lpfc_cmd);
2479| }
2480|
2481| if (err)
2482| goto out_host_busy_free_buf;
2483|
2484| lpfc_scsi_prep_cmnd(vport, lpfc_cmd, ndlp);
2485|
2486| atomic_inc(&ndlp->cmd_pending);
2487| err = lpfc_sli_issue_iocb(phba, 0,
2488| &lpfc_cmd->cur_iocbq, 1);
2489| if (err) {
2490| atomic_dec(&ndlp->cmd_pending);
2491| goto out_host_busy_free_buf;
2492| }
2493| if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
2494| __st_spin_unlock_st__(shost->host_lock);
2495| lpfc_sli_handle_fast_ring_event(phba,
2496| &phba->sli.ring[0], 0x00000001);
2497|
2498| __st_spin_lock_st__(shost->host_lock);
2499| if (phba->cfg_poll & DISABLE_FCP_RING_INT)
2500| lpfc_poll_rearm_timer(phba);
2501| }
2502|
2503| return 0;
2504|
2505| out_host_busy_free_buf:
2506| lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
2507| lpfc_release_scsi_buf(phba, lpfc_cmd);
2508| out_host_busy:
2509| return 0x1055;
2510|
2511| out_fail_command:
2512| done(cmnd);
2513| return 0;
2514|}
2515|
2516|static int lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmd) { unsigned long irq_flags; int rc; do { do { ({ unsigned long __dummy; typeof(irq_flags) __dummy2; (void)(&__dummy == &__dummy2); 1; }); irq_flags = _raw_spin_lock_irqsave(spinlock_check(shost->host_lock)); } while (0); } while (0); scsi_cmd_get_serial(shost, cmd); rc = lpfc_queuecommand_lck (cmd, cmd->scsi_done); spin_unlock_irqrestore(shost->host_lock, irq_flags); return rc; }
2517|static int
2518|lpfc_abort_handler(struct scsi_cmnd *cmnd)
2519|{
2520| struct Scsi_Host *shost = cmnd->device->host;
2521| struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2522| struct lpfc_hba *phba = vport->phba;
2523| struct lpfc_iocbq *iocb;
2524| struct lpfc_iocbq *abtsiocb;
2525| struct lpfc_scsi_buf *lpfc_cmd;
2526| IOCB_t *cmd, *icmd;
2527| int ret = 0x2002;
2528| wait_queue_head_t waitq = ({ do { static struct lock_class_key __key; __init_waitqueue_head((&waitq), &__key); } while (0); waitq; });
2529|
2530| ret = fc_block_scsi_eh(cmnd);
2531| if (ret)
2532| return ret;
2533| lpfc_cmd = (struct lpfc_scsi_buf *)cmnd->host_scribble;
2534| if (!lpfc_cmd) {
2535| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "2873 SCSI Layer I/O Abort Request IO CMPL Status " "x%x ID %d " "LUN %d snum %#lx\n", (vport)->phba->brd_no, vport->vpi, ret, cmnd->device->id, cmnd->device->lun, cmnd->serial_number); } } while (0)
2536|
2537|
2538|
2539| ;
2540| return 0x2002;
2541| }
2542| iocb = &lpfc_cmd->cur_iocbq;
2543| if (lpfc_cmd->pCmd != cmnd)
2544| goto out;
2545|
2546| __st_BUG_ON_st__(iocb->context1 != lpfc_cmd);
2547|
2548| abtsiocb = lpfc_sli_get_iocbq(phba);
2549| if (abtsiocb == ((void *)0)) {
2550| ret = 0x2003;
2551| goto out;
2552| }
2553|
2554|
2555|
2556|
2557|
2558|
2559|
2560| cmd = &iocb->iocb;
2561| icmd = &abtsiocb->iocb;
2562| icmd->un.acxri.abortType = 0x00000001;
2563| icmd->un.acxri.abortContextTag = cmd->un1.t1.ulpContext;
2564| if (phba->sli_rev == 4)
2565| icmd->un.acxri.abortIoTag = iocb->sli4_xritag;
2566| else
2567| icmd->un.acxri.abortIoTag = cmd->un1.t1.ulpIoTag;
2568|
2569| icmd->ulpLe = 1;
2570| icmd->ulpClass = cmd->ulpClass;
2571|
2572|
2573| abtsiocb->fcp_wqidx = iocb->fcp_wqidx;
2574| abtsiocb->iocb_flag |= 0x80;
2575|
2576| if (lpfc_is_link_up(phba))
2577| icmd->ulpCommand = 0x0E;
2578| else
2579| icmd->ulpCommand = 0x10;
2580|
2581| abtsiocb->iocb_cmpl = lpfc_sli_abort_fcp_cmpl;
2582| abtsiocb->vport = vport;
2583| if (lpfc_sli_issue_iocb(phba, 0, abtsiocb, 0) ==
2584| 2) {
2585| lpfc_sli_release_iocbq(phba, abtsiocb);
2586| ret = 0x2003;
2587| goto out;
2588| }
2589|
2590| if (phba->cfg_poll & DISABLE_FCP_RING_INT)
2591| lpfc_sli_handle_fast_ring_event(phba,
2592| &phba->sli.ring[0], 0x00000001);
2593|
2594| lpfc_cmd->waitq = &waitq;
2595|
2596| ({ long __ret = (2*vport->cfg_devloss_tmo*250); if (!((lpfc_cmd->pCmd != cmnd))) do { wait_queue_t __wait = { .private = get_current(), .func = autoremove_wake_function, .task_list = { &((__wait).task_list), &((__wait).task_list) }, }; for (;;) { prepare_to_wait(&waitq, &__wait, 2); if ((lpfc_cmd->pCmd != cmnd)) break; __ret = schedule_timeout(__ret); if (!__ret) break; } finish_wait(&waitq, &__wait); } while (0); __ret; })
2597|
2598| ;
2599|
2600| __st_spin_lock_irq_st__(shost->host_lock);
2601| lpfc_cmd->waitq = ((void *)0);
2602| __st_spin_unlock_irq_st__(shost->host_lock);
2603|
2604| if (lpfc_cmd->pCmd == cmnd) {
2605| ret = 0x2003;
2606| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0748 abort handler timed out waiting " "for abort to complete: ret %#x, ID %d, " "LUN %d, snum %#lx\n", (vport)->phba->brd_no, vport->vpi, ret, cmnd->device->id, cmnd->device->lun, cmnd->serial_number); } } while (0)
2607|
2608|
2609|
2610|
2611| ;
2612| }
2613|
2614| out:
2615| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0749 SCSI Layer I/O Abort Request Status x%x ID %d " "LUN %d snum %#lx\n", (vport)->phba->brd_no, vport->vpi, ret, cmnd->device->id, cmnd->device->lun, cmnd->serial_number); } } while (0)
2616|
2617|
2618| ;
2619| return ret;
2620|}
2621|
2622|static char *
2623|lpfc_taskmgmt_name(uint8_t task_mgmt_cmd)
2624|{
2625| switch (task_mgmt_cmd) {
2626| case 0x02:
2627| return "ABORT_TASK_SET";
2628| case 0x04:
2629| return "FCP_CLEAR_TASK_SET";
2630| case 0x08:
2631| return "FCP_BUS_RESET";
2632| case 0x10:
2633| return "FCP_LUN_RESET";
2634| case 0x20:
2635| return "FCP_TARGET_RESET";
2636| case 0x40:
2637| return "FCP_CLEAR_ACA";
2638| case 0x80:
2639| return "FCP_TERMINATE_TASK";
2640| default:
2641| return "unknown";
2642| }
2643|}
2644|static int
2645|lpfc_send_taskmgmt(struct lpfc_vport *vport, struct lpfc_rport_data *rdata,
2646| unsigned tgt_id, unsigned int lun_id,
2647| uint8_t task_mgmt_cmd)
2648|{
2649| struct lpfc_hba *phba = vport->phba;
2650| struct lpfc_scsi_buf *lpfc_cmd;
2651| struct lpfc_iocbq *iocbq;
2652| struct lpfc_iocbq *iocbqrsp;
2653| struct lpfc_nodelist *pnode = rdata->pnode;
2654| int ret;
2655| int status;
2656|
2657| if (!pnode || !(((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8)))
2658| return 0x2003;
2659|
2660| lpfc_cmd = lpfc_get_scsi_buf(phba);
2661| if (lpfc_cmd == ((void *)0))
2662| return 0x2003;
2663| lpfc_cmd->timeout = 60;
2664| lpfc_cmd->rdata = rdata;
2665|
2666| status = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun_id,
2667| task_mgmt_cmd);
2668| if (!status) {
2669| lpfc_release_scsi_buf(phba, lpfc_cmd);
2670| return 0x2003;
2671| }
2672|
2673| iocbq = &lpfc_cmd->cur_iocbq;
2674| iocbqrsp = lpfc_sli_get_iocbq(phba);
2675| if (iocbqrsp == ((void *)0)) {
2676| lpfc_release_scsi_buf(phba, lpfc_cmd);
2677| return 0x2003;
2678| }
2679|
2680| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<6>"[1] <= '3')) dev_printk("<6>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0702 Issue %s to TGT %d LUN %d " "rpi x%x nlp_flag x%x\n", (vport)->phba->brd_no, vport->vpi, lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id, pnode->nlp_rpi, pnode->nlp_flag); } } while (0)
2681|
2682|
2683|
2684| ;
2685|
2686| status = lpfc_sli_issue_iocb_wait(phba, 0,
2687| iocbq, iocbqrsp, lpfc_cmd->timeout);
2688| if (status != 0) {
2689| if (status == 3) {
2690| iocbq->iocb_cmpl = lpfc_tskmgmt_def_cmpl;
2691| ret = 0x2007;
2692| } else
2693| ret = 0x2003;
2694| lpfc_cmd->status = 0x10;
2695| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0727 TMF %s to TGT %d LUN %d failed (%d, %d)\n", (vport)->phba->brd_no, vport->vpi, lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id, iocbqrsp->iocb.ulpStatus, iocbqrsp->iocb.un.ulpWord[4]); } } while (0)
2696|
2697|
2698|
2699| ;
2700| } else if (status == 1)
2701| ret = 0x2003;
2702| else
2703| ret = 0x2002;
2704|
2705| lpfc_sli_release_iocbq(phba, iocbqrsp);
2706|
2707| if (ret != 0x2007)
2708| lpfc_release_scsi_buf(phba, lpfc_cmd);
2709|
2710| return ret;
2711|}
2712|static int
2713|lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct scsi_cmnd *cmnd)
2714|{
2715| struct lpfc_rport_data *rdata = cmnd->device->hostdata;
2716| struct lpfc_nodelist *pnode;
2717| unsigned long later;
2718|
2719| if (!rdata) {
2720| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<6>"[1] <= '3')) dev_printk("<6>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0797 Tgt Map rport failure: rdata x%p\n", (vport)->phba->brd_no, vport->vpi, rdata); } } while (0)
2721| ;
2722| return 0x2003;
2723| }
2724| pnode = rdata->pnode;
2725|
2726|
2727|
2728|
2729| later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies;
2730| while ((({ unsigned long __dummy; typeof(later) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)(later) < 0))) {
2731| if (!pnode || !(((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8)))
2732| return 0x2003;
2733| if (pnode->nlp_state == 0x6)
2734| return 0x2002;
2735| schedule_timeout_uninterruptible(msecs_to_jiffies(500));
2736| rdata = cmnd->device->hostdata;
2737| if (!rdata)
2738| return 0x2003;
2739| pnode = rdata->pnode;
2740| }
2741| if (!pnode || !(((pnode)->nlp_usg_map & 0x1) && !((pnode)->nlp_usg_map & 0x8)) ||
2742| (pnode->nlp_state != 0x6))
2743| return 0x2003;
2744| return 0x2002;
2745|}
2746|static int
2747|lpfc_reset_flush_io_context(struct lpfc_vport *vport, uint16_t tgt_id,
2748| uint64_t lun_id, lpfc_ctx_cmd context)
2749|{
2750| struct lpfc_hba *phba = vport->phba;
2751| unsigned long later;
2752| int cnt;
2753|
2754| cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context);
2755| if (cnt)
2756| lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
2757| tgt_id, lun_id, context);
2758| later = msecs_to_jiffies(2 * vport->cfg_devloss_tmo * 1000) + jiffies;
2759| while ((({ unsigned long __dummy; typeof(later) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ({ unsigned long __dummy; typeof(jiffies) __dummy2; (void)(&__dummy == &__dummy2); 1; }) && ((long)(jiffies) - (long)(later) < 0)) && cnt) {
2760| schedule_timeout_uninterruptible(msecs_to_jiffies(20));
2761| cnt = lpfc_sli_sum_iocb(vport, tgt_id, lun_id, context);
2762| }
2763| if (cnt) {
2764| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0724 I/O flush failure for context %s : cnt x%x\n", (vport)->phba->brd_no, vport->vpi, ((context == LPFC_CTX_LUN) ? "LUN" : ((context == LPFC_CTX_TGT) ? "TGT" : ((context == LPFC_CTX_HOST) ? "HOST" : "Unknown"))), cnt); } } while (0)
2765|
2766|
2767|
2768|
2769| ;
2770| return 0x2003;
2771| }
2772| return 0x2002;
2773|}
2774|static int
2775|lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
2776|{
2777| struct Scsi_Host *shost = cmnd->device->host;
2778| struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2779| struct lpfc_rport_data *rdata = cmnd->device->hostdata;
2780| struct lpfc_nodelist *pnode;
2781| unsigned tgt_id = cmnd->device->id;
2782| unsigned int lun_id = cmnd->device->lun;
2783| struct lpfc_scsi_event_header scsi_event;
2784| int status;
2785|
2786| if (!rdata) {
2787| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0798 Device Reset rport failure: rdata x%p\n", (vport)->phba->brd_no, vport->vpi, rdata); } } while (0)
2788| ;
2789| return 0x2003;
2790| }
2791| pnode = rdata->pnode;
2792| status = fc_block_scsi_eh(cmnd);
2793| if (status)
2794| return status;
2795|
2796| status = lpfc_chk_tgt_mapped(vport, cmnd);
2797| if (status == 0x2003) {
2798| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0721 Device Reset rport failure: rdata x%p\n", (vport)->phba->brd_no, vport->vpi, rdata); } } while (0)
2799| ;
2800| return 0x2003;
2801| }
2802|
2803| scsi_event.event_type = 0x0200;
2804| scsi_event.subcategory = 0x0008;
2805| scsi_event.lun = lun_id;
2806| __st_memcpy_st__(scsi_event.wwpn, &pnode->nlp_portname, sizeof(struct lpfc_name));
2807| __st_memcpy_st__(scsi_event.wwnn, &pnode->nlp_nodename, sizeof(struct lpfc_name));
2808|
2809| fc_host_post_vendor_event(shost, fc_get_event_number(),
2810| sizeof(scsi_event), (char *)&scsi_event, (((__u64)0x01 << 56) | 0x10df));
2811|
2812| status = lpfc_send_taskmgmt(vport, rdata, tgt_id, lun_id,
2813| 0x10);
2814|
2815| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0713 SCSI layer issued Device Reset (%d, %d) " "return x%x\n", (vport)->phba->brd_no, vport->vpi, tgt_id, lun_id, status); } } while (0)
2816|
2817| ;
2818|
2819|
2820|
2821|
2822|
2823|
2824|
2825| status = lpfc_reset_flush_io_context(vport, tgt_id, lun_id,
2826| LPFC_CTX_LUN);
2827| return status;
2828|}
2829|static int
2830|lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
2831|{
2832| struct Scsi_Host *shost = cmnd->device->host;
2833| struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2834| struct lpfc_rport_data *rdata = cmnd->device->hostdata;
2835| struct lpfc_nodelist *pnode;
2836| unsigned tgt_id = cmnd->device->id;
2837| unsigned int lun_id = cmnd->device->lun;
2838| struct lpfc_scsi_event_header scsi_event;
2839| int status;
2840|
2841| if (!rdata) {
2842| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0799 Target Reset rport failure: rdata x%p\n", (vport)->phba->brd_no, vport->vpi, rdata); } } while (0)
2843| ;
2844| return 0x2003;
2845| }
2846| pnode = rdata->pnode;
2847| status = fc_block_scsi_eh(cmnd);
2848| if (status)
2849| return status;
2850|
2851| status = lpfc_chk_tgt_mapped(vport, cmnd);
2852| if (status == 0x2003) {
2853| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0722 Target Reset rport failure: rdata x%p\n", (vport)->phba->brd_no, vport->vpi, rdata); } } while (0)
2854| ;
2855| return 0x2003;
2856| }
2857|
2858| scsi_event.event_type = 0x0200;
2859| scsi_event.subcategory = 0x0010;
2860| scsi_event.lun = 0;
2861| __st_memcpy_st__(scsi_event.wwpn, &pnode->nlp_portname, sizeof(struct lpfc_name));
2862| __st_memcpy_st__(scsi_event.wwnn, &pnode->nlp_nodename, sizeof(struct lpfc_name));
2863|
2864| fc_host_post_vendor_event(shost, fc_get_event_number(),
2865| sizeof(scsi_event), (char *)&scsi_event, (((__u64)0x01 << 56) | 0x10df));
2866|
2867| status = lpfc_send_taskmgmt(vport, rdata, tgt_id, lun_id,
2868| 0x20);
2869|
2870| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0723 SCSI layer issued Target Reset (%d, %d) " "return x%x\n", (vport)->phba->brd_no, vport->vpi, tgt_id, lun_id, status); } } while (0)
2871|
2872| ;
2873|
2874|
2875|
2876|
2877|
2878|
2879|
2880| status = lpfc_reset_flush_io_context(vport, tgt_id, lun_id,
2881| LPFC_CTX_TGT);
2882| return status;
2883|}
2884|static int
2885|lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
2886|{
2887| struct Scsi_Host *shost = cmnd->device->host;
2888| struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
2889| struct lpfc_nodelist *ndlp = ((void *)0);
2890| struct lpfc_scsi_event_header scsi_event;
2891| int match;
2892| int ret = 0x2002, status, i;
2893|
2894| scsi_event.event_type = 0x0200;
2895| scsi_event.subcategory = 0x0020;
2896| scsi_event.lun = 0;
2897| __st_memcpy_st__(scsi_event.wwpn, &vport->fc_portname, sizeof(struct lpfc_name));
2898| __st_memcpy_st__(scsi_event.wwnn, &vport->fc_nodename, sizeof(struct lpfc_name));
2899|
2900| fc_host_post_vendor_event(shost, fc_get_event_number(),
2901| sizeof(scsi_event), (char *)&scsi_event, (((__u64)0x01 << 56) | 0x10df));
2902|
2903| ret = fc_block_scsi_eh(cmnd);
2904| if (ret)
2905| return ret;
2906|
2907|
2908|
2909|
2910|
2911|
2912| for (i = 0; i < 4096; i++) {
2913|
2914| match = 0;
2915| __st_spin_lock_irq_st__(shost->host_lock);
2916| for (ndlp = ({ const typeof( ((typeof(*ndlp) *)0)->nlp_listp ) *__mptr = ((&vport->fc_nodes)->next); (typeof(*ndlp) *)( (char *)__mptr - 1 );}); __builtin_prefetch(ndlp->nlp_listp.next), &ndlp->nlp_listp != (&vport->fc_nodes); ndlp = ({ const typeof( ((typeof(*ndlp) *)0)->nlp_listp ) *__mptr = (ndlp->nlp_listp.next); (typeof(*ndlp) *)( (char *)__mptr - 1 );})) {
2917| if (!(((ndlp)->nlp_usg_map & 0x1) && !((ndlp)->nlp_usg_map & 0x8)))
2918| continue;
2919| if (ndlp->nlp_state == 0x6 &&
2920| ndlp->nlp_sid == i &&
2921| ndlp->rport) {
2922| match = 1;
2923| break;
2924| }
2925| }
2926| __st_spin_unlock_irq_st__(shost->host_lock);
2927| if (!match)
2928| continue;
2929|
2930| status = lpfc_send_taskmgmt(vport, ndlp->rport->dd_data,
2931| i, 0, 0x20);
2932|
2933| if (status != 0x2002) {
2934| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0700 Bus Reset on target %d failed\n", (vport)->phba->brd_no, vport->vpi, i); } } while (0)
2935|
2936| ;
2937| ret = 0x2003;
2938| }
2939| }
2940|
2941|
2942|
2943|
2944|
2945|
2946|
2947| status = lpfc_reset_flush_io_context(vport, 0, 0, LPFC_CTX_HOST);
2948| if (status != 0x2002)
2949| ret = 0x2003;
2950|
2951| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<3>"[1] <= '3')) dev_printk("<3>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0714 SCSI layer issued Bus Reset Data: x%x\n", (vport)->phba->brd_no, vport->vpi, ret); } } while (0)
2952| ;
2953| return ret;
2954|}
2955|static int
2956|lpfc_slave_alloc(struct scsi_device *sdev)
2957|{
2958| struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
2959| struct lpfc_hba *phba = vport->phba;
2960| struct fc_rport *rport = scsi_is_fc_rport(scsi_target(sdev)->dev.parent) ? ({ const typeof( ((struct fc_rport *)0)->dev ) *__mptr = (scsi_target(sdev)->dev.parent); (struct fc_rport *)( (char *)__mptr - 1 );}) : ((void *)0);
2961| uint32_t total = 0;
2962| uint32_t num_to_alloc = 0;
2963| int num_allocated = 0;
2964| uint32_t sdev_cnt;
2965|
2966| if (!rport || fc_remote_port_chkready(rport))
2967| return -6;
2968|
2969| sdev->hostdata = rport->dd_data;
2970| sdev_cnt = (atomic_add_return(1, &phba->sdev_cnt));
2971| total = phba->total_scsi_bufs;
2972| num_to_alloc = vport->cfg_lun_queue_depth + 2;
2973|
2974|
2975| if ((sdev_cnt * (vport->cfg_lun_queue_depth + 2)) < total)
2976| return 0;
2977|
2978|
2979| if (total >= phba->cfg_hba_queue_depth - 20 ) {
2980| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0704 At limitation of %d preallocated " "command buffers\n", (vport)->phba->brd_no, vport->vpi, total); } } while (0)
2981|
2982| ;
2983| return 0;
2984|
2985| } else if (total + num_to_alloc >
2986| phba->cfg_hba_queue_depth - 20 ) {
2987| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0705 Allocation request of %d " "command buffers will exceed max of %d. " "Reducing allocation request to %d.\n", (vport)->phba->brd_no, vport->vpi, num_to_alloc, phba->cfg_hba_queue_depth, (phba->cfg_hba_queue_depth - total)); } } while (0)
2988|
2989|
2990|
2991|
2992| ;
2993| num_to_alloc = phba->cfg_hba_queue_depth - total;
2994| }
2995| num_allocated = lpfc_new_scsi_buf(vport, num_to_alloc);
2996| if (num_to_alloc != num_allocated) {
2997| do { { if (((0x00000040) & (vport)->cfg_log_verbose) || ("<4>"[1] <= '3')) dev_printk("<4>", &((vport)->phba->pcidev)->dev, "%d:(%d):" "0708 Allocation request of %d " "command buffers did not succeed. " "Allocated %d buffers.\n", (vport)->phba->brd_no, vport->vpi, num_to_alloc, num_allocated); } } while (0)
2998|
2999|
3000|
3001| ;
3002| }
3003| if (num_allocated > 0)
3004| phba->total_scsi_bufs += num_allocated;
3005| return 0;
3006|}
3007|static int
3008|lpfc_slave_configure(struct scsi_device *sdev)
3009|{
3010| struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
3011| struct lpfc_hba *phba = vport->phba;
3012|
3013| if (sdev->tagged_supported)
3014| scsi_activate_tcq(sdev, vport->cfg_lun_queue_depth);
3015| else
3016| scsi_deactivate_tcq(sdev, vport->cfg_lun_queue_depth);
3017|
3018| if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
3019| lpfc_sli_handle_fast_ring_event(phba,
3020| &phba->sli.ring[0], 0x00000001);
3021| if (phba->cfg_poll & DISABLE_FCP_RING_INT)
3022| lpfc_poll_rearm_timer(phba);
3023| }
3024|
3025| return 0;
3026|}
3027|
3028|
3029|
3030|
3031|
3032|
3033|
3034|static void
3035|lpfc_slave_destroy(struct scsi_device *sdev)
3036|{
3037| struct lpfc_vport *vport = (struct lpfc_vport *) sdev->host->hostdata;
3038| struct lpfc_hba *phba = vport->phba;
3039| atomic_dec(&phba->sdev_cnt);
3040| sdev->hostdata = ((void *)0);
3041| return;
3042|}
3043|
3044|
3045|struct scsi_host_template lpfc_template = {
3046| .module = (&__this_module),
3047| .name = "lpfc",
3048| .info = lpfc_info,
3049| .queuecommand = lpfc_queuecommand,
3050| .eh_abort_handler = lpfc_abort_handler,
3051| .eh_device_reset_handler = lpfc_device_reset_handler,
3052| .eh_target_reset_handler = lpfc_target_reset_handler,
3053| .eh_bus_reset_handler = lpfc_bus_reset_handler,
3054| .slave_alloc = lpfc_slave_alloc,
3055| .slave_configure = lpfc_slave_configure,
3056| .slave_destroy = lpfc_slave_destroy,
3057| .scan_finished = lpfc_scan_finished,
3058| .this_id = -1,
3059| .sg_tablesize = 64,
3060| .cmd_per_lun = 3,
3061| .use_clustering = 1,
3062| .shost_attrs = lpfc_hba_attrs,
3063| .max_sectors = 0xFFFF,
3064| .vendor_id = (((__u64)0x01 << 56) | 0x10df),
3065| .change_queue_depth = lpfc_change_queue_depth,
3066|};
3067|
3068|struct scsi_host_template lpfc_vport_template = {
3069| .module = (&__this_module),
3070| .name = "lpfc",
3071| .info = lpfc_info,
3072| .queuecommand = lpfc_queuecommand,
3073| .eh_abort_handler = lpfc_abort_handler,
3074| .eh_device_reset_handler = lpfc_device_reset_handler,
3075| .eh_target_reset_handler = lpfc_target_reset_handler,
3076| .eh_bus_reset_handler = lpfc_bus_reset_handler,
3077| .slave_alloc = lpfc_slave_alloc,
3078| .slave_configure = lpfc_slave_configure,
3079| .slave_destroy = lpfc_slave_destroy,
3080| .scan_finished = lpfc_scan_finished,
3081| .this_id = -1,
3082| .sg_tablesize = 64,
3083| .cmd_per_lun = 3,
3084| .use_clustering = 1,
3085| .shost_attrs = lpfc_vport_attrs,
3086| .max_sectors = 0xFFFF,
3087| .change_queue_depth = lpfc_change_queue_depth,
3088|};