2 * Copyright 2014 Cisco Systems, Inc. All rights reserved.
4 * This program is free software; you may redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
9 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
10 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
11 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
12 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
13 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 #include <linux/errno.h>
19 #include <linux/mempool.h>
21 #include <scsi/scsi_tcq.h>
23 #include "snic_disc.h"
28 /* snic target types */
29 static const char * const snic_tgt_type_str
[] = {
30 [SNIC_TGT_DAS
] = "DAS",
31 [SNIC_TGT_SAN
] = "SAN",
34 static inline const char *
35 snic_tgt_type_to_str(int typ
)
37 return ((typ
> SNIC_TGT_NONE
&& typ
<= SNIC_TGT_SAN
) ?
38 snic_tgt_type_str
[typ
] : "Unknown");
41 static const char * const snic_tgt_state_str
[] = {
42 [SNIC_TGT_STAT_INIT
] = "INIT",
43 [SNIC_TGT_STAT_ONLINE
] = "ONLINE",
44 [SNIC_TGT_STAT_OFFLINE
] = "OFFLINE",
45 [SNIC_TGT_STAT_DEL
] = "DELETION IN PROGRESS",
49 snic_tgt_state_to_str(int state
)
51 return ((state
>= SNIC_TGT_STAT_INIT
&& state
<= SNIC_TGT_STAT_DEL
) ?
52 snic_tgt_state_str
[state
] : "UNKNOWN");
56 * Initiate report_tgt req desc
59 snic_report_tgt_init(struct snic_host_req
*req
, u32 hid
, u8
*buf
, u32 len
,
60 dma_addr_t rsp_buf_pa
, ulong ctx
)
62 struct snic_sg_desc
*sgd
= NULL
;
65 snic_io_hdr_enc(&req
->hdr
, SNIC_REQ_REPORT_TGTS
, 0, SCSI_NO_TAG
, hid
,
68 req
->u
.rpt_tgts
.sg_cnt
= cpu_to_le16(1);
69 sgd
= req_to_sgl(req
);
70 sgd
[0].addr
= cpu_to_le64(rsp_buf_pa
);
71 sgd
[0].len
= cpu_to_le32(len
);
73 req
->u
.rpt_tgts
.sg_addr
= cpu_to_le64((ulong
)sgd
);
77 * snic_queue_report_tgt_req: Queues report target request.
80 snic_queue_report_tgt_req(struct snic
*snic
)
82 struct snic_req_info
*rqi
= NULL
;
83 u32 ntgts
, buf_len
= 0;
88 rqi
= snic_req_init(snic
, 1);
94 if (snic
->fwinfo
.max_tgts
)
95 ntgts
= min_t(u32
, snic
->fwinfo
.max_tgts
, snic
->shost
->max_id
);
97 ntgts
= snic
->shost
->max_id
;
99 /* Allocate Response Buffer */
100 SNIC_BUG_ON(ntgts
== 0);
101 buf_len
= ntgts
* sizeof(struct snic_tgt_id
) + SNIC_SG_DESC_ALIGN
;
103 buf
= kzalloc(buf_len
, GFP_KERNEL
|GFP_DMA
);
105 snic_req_free(snic
, rqi
);
106 SNIC_HOST_ERR(snic
->shost
, "Resp Buf Alloc Failed.\n");
112 SNIC_BUG_ON((((unsigned long)buf
) % SNIC_SG_DESC_ALIGN
) != 0);
114 pa
= pci_map_single(snic
->pdev
, buf
, buf_len
, PCI_DMA_FROMDEVICE
);
115 if (pci_dma_mapping_error(snic
->pdev
, pa
)) {
117 snic_req_free(snic
, rqi
);
118 SNIC_HOST_ERR(snic
->shost
,
119 "Rpt-tgt rspbuf %p: PCI DMA Mapping Failed\n",
127 SNIC_BUG_ON(pa
== 0);
128 rqi
->sge_va
= (ulong
) buf
;
130 snic_report_tgt_init(rqi
->req
,
137 snic_handle_untagged_req(snic
, rqi
);
139 ret
= snic_queue_wq_desc(snic
, rqi
->req
, rqi
->req_len
);
141 pci_unmap_single(snic
->pdev
, pa
, buf_len
, PCI_DMA_FROMDEVICE
);
144 snic_release_untagged_req(snic
, rqi
);
145 SNIC_HOST_ERR(snic
->shost
, "Queuing Report Tgts Failed.\n");
150 SNIC_DISC_DBG(snic
->shost
, "Report Targets Issued.\n");
155 SNIC_HOST_ERR(snic
->shost
,
156 "Queuing Report Targets Failed, err = %d\n",
159 } /* end of snic_queue_report_tgt_req */
163 snic_scsi_scan_tgt(struct work_struct
*work
)
165 struct snic_tgt
*tgt
= container_of(work
, struct snic_tgt
, scan_work
);
166 struct Scsi_Host
*shost
= dev_to_shost(&tgt
->dev
);
169 SNIC_HOST_INFO(shost
, "Scanning Target id 0x%x\n", tgt
->id
);
170 scsi_scan_target(&tgt
->dev
,
176 spin_lock_irqsave(shost
->host_lock
, flags
);
177 tgt
->flags
&= ~SNIC_TGT_SCAN_PENDING
;
178 spin_unlock_irqrestore(shost
->host_lock
, flags
);
179 } /* end of snic_scsi_scan_tgt */
184 static struct snic_tgt
*
185 snic_tgt_lookup(struct snic
*snic
, struct snic_tgt_id
*tgtid
)
187 struct list_head
*cur
, *nxt
;
188 struct snic_tgt
*tgt
= NULL
;
190 list_for_each_safe(cur
, nxt
, &snic
->disc
.tgt_list
) {
191 tgt
= list_entry(cur
, struct snic_tgt
, list
);
192 if (tgt
->id
== le32_to_cpu(tgtid
->tgt_id
))
198 } /* end of snic_tgt_lookup */
201 * snic_tgt_dev_release : Called on dropping last ref for snic_tgt object
204 snic_tgt_dev_release(struct device
*dev
)
206 struct snic_tgt
*tgt
= dev_to_tgt(dev
);
208 SNIC_HOST_INFO(snic_tgt_to_shost(tgt
),
209 "Target Device ID %d (%s) Permanently Deleted.\n",
213 SNIC_BUG_ON(!list_empty(&tgt
->list
));
218 * snic_tgt_del : work function to delete snic_tgt
221 snic_tgt_del(struct work_struct
*work
)
223 struct snic_tgt
*tgt
= container_of(work
, struct snic_tgt
, del_work
);
224 struct Scsi_Host
*shost
= snic_tgt_to_shost(tgt
);
226 if (tgt
->flags
& SNIC_TGT_SCAN_PENDING
)
227 scsi_flush_work(shost
);
229 /* Block IOs on child devices, stops new IOs */
230 scsi_target_block(&tgt
->dev
);
233 snic_tgt_scsi_abort_io(tgt
);
235 /* Unblock IOs now, to flush if there are any. */
236 scsi_target_unblock(&tgt
->dev
, SDEV_TRANSPORT_OFFLINE
);
238 /* Delete SCSI Target and sdevs */
239 scsi_remove_target(&tgt
->dev
); /* ?? */
240 device_del(&tgt
->dev
);
241 put_device(&tgt
->dev
);
242 } /* end of snic_tgt_del */
244 /* snic_tgt_create: checks for existence of snic_tgt, if it doesn't
247 static struct snic_tgt
*
248 snic_tgt_create(struct snic
*snic
, struct snic_tgt_id
*tgtid
)
250 struct snic_tgt
*tgt
= NULL
;
254 tgt
= snic_tgt_lookup(snic
, tgtid
);
256 /* update the information if required */
260 tgt
= kzalloc(sizeof(*tgt
), GFP_KERNEL
);
262 SNIC_HOST_ERR(snic
->shost
, "Failure to allocate snic_tgt.\n");
268 INIT_LIST_HEAD(&tgt
->list
);
269 tgt
->id
= le32_to_cpu(tgtid
->tgt_id
);
272 SNIC_BUG_ON(le16_to_cpu(tgtid
->tgt_type
) > SNIC_TGT_SAN
);
273 tgt
->tdata
.typ
= le16_to_cpu(tgtid
->tgt_type
);
276 * Plugging into SML Device Tree
278 tgt
->tdata
.disc_id
= 0;
279 tgt
->state
= SNIC_TGT_STAT_INIT
;
280 device_initialize(&tgt
->dev
);
281 tgt
->dev
.parent
= get_device(&snic
->shost
->shost_gendev
);
282 tgt
->dev
.release
= snic_tgt_dev_release
;
283 INIT_WORK(&tgt
->scan_work
, snic_scsi_scan_tgt
);
284 INIT_WORK(&tgt
->del_work
, snic_tgt_del
);
285 switch (tgt
->tdata
.typ
) {
287 dev_set_name(&tgt
->dev
, "snic_das_tgt:%d:%d-%d",
288 snic
->shost
->host_no
, tgt
->channel
, tgt
->id
);
292 dev_set_name(&tgt
->dev
, "snic_san_tgt:%d:%d-%d",
293 snic
->shost
->host_no
, tgt
->channel
, tgt
->id
);
297 SNIC_HOST_INFO(snic
->shost
, "Target type Unknown Detected.\n");
298 dev_set_name(&tgt
->dev
, "snic_das_tgt:%d:%d-%d",
299 snic
->shost
->host_no
, tgt
->channel
, tgt
->id
);
303 spin_lock_irqsave(snic
->shost
->host_lock
, flags
);
304 list_add_tail(&tgt
->list
, &snic
->disc
.tgt_list
);
305 tgt
->scsi_tgt_id
= snic
->disc
.nxt_tgt_id
++;
306 tgt
->state
= SNIC_TGT_STAT_ONLINE
;
307 spin_unlock_irqrestore(snic
->shost
->host_lock
, flags
);
309 SNIC_HOST_INFO(snic
->shost
,
310 "Tgt %d, type = %s detected. Adding..\n",
311 tgt
->id
, snic_tgt_type_to_str(tgt
->tdata
.typ
));
313 ret
= device_add(&tgt
->dev
);
315 SNIC_HOST_ERR(snic
->shost
,
316 "Snic Tgt: device_add, with err = %d\n",
319 put_device(&snic
->shost
->shost_gendev
);
326 SNIC_HOST_INFO(snic
->shost
, "Scanning %s.\n", dev_name(&tgt
->dev
));
328 scsi_queue_work(snic
->shost
, &tgt
->scan_work
);
331 } /* end of snic_tgt_create */
333 /* Handler for discovery */
335 snic_handle_tgt_disc(struct work_struct
*work
)
337 struct snic
*snic
= container_of(work
, struct snic
, tgt_work
);
338 struct snic_tgt_id
*tgtid
= NULL
;
339 struct snic_tgt
*tgt
= NULL
;
343 spin_lock_irqsave(&snic
->snic_lock
, flags
);
344 if (snic
->in_remove
) {
345 spin_unlock_irqrestore(&snic
->snic_lock
, flags
);
346 kfree(snic
->disc
.rtgt_info
);
350 spin_unlock_irqrestore(&snic
->snic_lock
, flags
);
352 mutex_lock(&snic
->disc
.mutex
);
353 /* Discover triggered during disc in progress */
354 if (snic
->disc
.req_cnt
) {
355 snic
->disc
.state
= SNIC_DISC_DONE
;
356 snic
->disc
.req_cnt
= 0;
357 mutex_unlock(&snic
->disc
.mutex
);
358 kfree(snic
->disc
.rtgt_info
);
359 snic
->disc
.rtgt_info
= NULL
;
361 SNIC_HOST_INFO(snic
->shost
, "tgt_disc: Discovery restart.\n");
362 /* Start Discovery Again */
363 snic_disc_start(snic
);
368 tgtid
= (struct snic_tgt_id
*)snic
->disc
.rtgt_info
;
370 SNIC_BUG_ON(snic
->disc
.rtgt_cnt
== 0 || tgtid
== NULL
);
372 for (i
= 0; i
< snic
->disc
.rtgt_cnt
; i
++) {
373 tgt
= snic_tgt_create(snic
, &tgtid
[i
]);
375 int buf_sz
= snic
->disc
.rtgt_cnt
* sizeof(*tgtid
);
377 SNIC_HOST_ERR(snic
->shost
, "Failed to create tgt.\n");
378 snic_hex_dump("rpt_tgt_rsp", (char *)tgtid
, buf_sz
);
383 snic
->disc
.rtgt_info
= NULL
;
384 snic
->disc
.state
= SNIC_DISC_DONE
;
385 mutex_unlock(&snic
->disc
.mutex
);
387 SNIC_HOST_INFO(snic
->shost
, "Discovery Completed.\n");
390 } /* end of snic_handle_tgt_disc */
394 snic_report_tgt_cmpl_handler(struct snic
*snic
, struct snic_fw_req
*fwreq
)
398 u32 cmnd_id
, hid
, tgt_cnt
= 0;
400 struct snic_req_info
*rqi
= NULL
;
401 struct snic_tgt_id
*tgtid
;
404 snic_io_hdr_dec(&fwreq
->hdr
, &typ
, &cmpl_stat
, &cmnd_id
, &hid
, &ctx
);
405 rqi
= (struct snic_req_info
*) ctx
;
406 tgtid
= (struct snic_tgt_id
*) rqi
->sge_va
;
408 tgt_cnt
= le32_to_cpu(fwreq
->u
.rpt_tgts_cmpl
.tgt_cnt
);
410 SNIC_HOST_ERR(snic
->shost
, "No Targets Found on this host.\n");
416 /* printing list of targets here */
417 SNIC_HOST_INFO(snic
->shost
, "Target Count = %d\n", tgt_cnt
);
419 SNIC_BUG_ON(tgt_cnt
> snic
->fwinfo
.max_tgts
);
421 for (i
= 0; i
< tgt_cnt
; i
++)
422 SNIC_HOST_INFO(snic
->shost
,
424 le32_to_cpu(tgtid
[i
].tgt_id
));
427 * Queue work for further processing,
428 * Response Buffer Memory is freed after creating targets
430 snic
->disc
.rtgt_cnt
= tgt_cnt
;
431 snic
->disc
.rtgt_info
= (u8
*) tgtid
;
432 queue_work(snic_glob
->event_q
, &snic
->tgt_work
);
436 /* Unmap Response Buffer */
437 snic_pci_unmap_rsp_buf(snic
, rqi
);
442 snic_release_untagged_req(snic
, rqi
);
445 } /* end of snic_report_tgt_cmpl_handler */
447 /* Discovery init fn */
449 snic_disc_init(struct snic_disc
*disc
)
451 INIT_LIST_HEAD(&disc
->tgt_list
);
452 mutex_init(&disc
->mutex
);
454 disc
->nxt_tgt_id
= 0;
455 disc
->state
= SNIC_DISC_INIT
;
458 disc
->rtgt_info
= NULL
;
460 } /* end of snic_disc_init */
462 /* Discovery, uninit fn */
464 snic_disc_term(struct snic
*snic
)
466 struct snic_disc
*disc
= &snic
->disc
;
468 mutex_lock(&disc
->mutex
);
471 SNIC_SCSI_DBG(snic
->shost
, "Terminating Discovery.\n");
473 mutex_unlock(&disc
->mutex
);
477 * snic_disc_start: Discovery Start ...
480 snic_disc_start(struct snic
*snic
)
482 struct snic_disc
*disc
= &snic
->disc
;
485 SNIC_SCSI_DBG(snic
->shost
, "Discovery Start.\n");
487 mutex_lock(&disc
->mutex
);
488 if (disc
->state
== SNIC_DISC_PENDING
) {
490 mutex_unlock(&disc
->mutex
);
494 disc
->state
= SNIC_DISC_PENDING
;
495 mutex_unlock(&disc
->mutex
);
497 ret
= snic_queue_report_tgt_req(snic
);
499 SNIC_HOST_INFO(snic
->shost
, "Discovery Failed, err=%d.\n", ret
);
502 } /* end of snic_disc_start */
508 snic_handle_disc(struct work_struct
*work
)
510 struct snic
*snic
= container_of(work
, struct snic
, disc_work
);
513 SNIC_HOST_INFO(snic
->shost
, "disc_work: Discovery\n");
515 ret
= snic_disc_start(snic
);
520 SNIC_HOST_ERR(snic
->shost
,
521 "disc_work: Discovery Failed w/ err = %d\n",
523 } /* end of snic_disc_work */
526 * snic_tgt_del_all : cleanup all snic targets
527 * Called on unbinding the interface
530 snic_tgt_del_all(struct snic
*snic
)
532 struct snic_tgt
*tgt
= NULL
;
533 struct list_head
*cur
, *nxt
;
536 mutex_lock(&snic
->disc
.mutex
);
537 spin_lock_irqsave(snic
->shost
->host_lock
, flags
);
539 list_for_each_safe(cur
, nxt
, &snic
->disc
.tgt_list
) {
540 tgt
= list_entry(cur
, struct snic_tgt
, list
);
541 tgt
->state
= SNIC_TGT_STAT_DEL
;
542 list_del_init(&tgt
->list
);
543 SNIC_HOST_INFO(snic
->shost
, "Tgt %d q'ing for del\n", tgt
->id
);
544 queue_work(snic_glob
->event_q
, &tgt
->del_work
);
547 spin_unlock_irqrestore(snic
->shost
->host_lock
, flags
);
549 scsi_flush_work(snic
->shost
);
550 mutex_unlock(&snic
->disc
.mutex
);
551 } /* end of snic_tgt_del_all */