1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
14 * Copyright 2022 RackTop Systems, Inc.
15 */
16
17 #include "vioscsi.h"
18
19 static char vioscsi_ident[] = "VIRTIO SCSI driver";
20
21 static uint_t vioscsi_ctl_handler(caddr_t arg1, caddr_t arg2);
22 static uint_t vioscsi_evt_handler(caddr_t arg1, caddr_t arg2);
23 static uint_t vioscsi_cmd_handler(caddr_t arg1, caddr_t arg2);
24
25 static int vioscsi_tran_getcap(struct scsi_address *, char *, int);
26 static int vioscsi_tran_setcap(struct scsi_address *, char *, int, int);
27 static int vioscsi_tran_reset(struct scsi_address *, int);
28
29 static int vioscsi_tran_start(struct scsi_address *, struct scsi_pkt *);
30 static int vioscsi_tran_abort(struct scsi_address *, struct scsi_pkt *);
31
32 static int vioscsi_iport_attach(dev_info_t *);
33 static int vioscsi_iport_detach(dev_info_t *);
34
35 static int vioscsi_req_init(vioscsi_softc_t *, vioscsi_request_t *,
36 virtio_queue_t *, int);
37 static void vioscsi_req_fini(vioscsi_request_t *);
38 static boolean_t vioscsi_req_abort(vioscsi_softc_t *, vioscsi_request_t *);
39 static void vioscsi_lun_changed(vioscsi_softc_t *sc, uint8_t target);
40 static void vioscsi_discover(void *);
41
42 /*
43 * DMA attributes. We support a linked list, but most of our uses require a
44 * single aligned buffer. The HBA buffers will use a copy of this adjusted for
45 * the actual virtio limits.
46 */
47 static ddi_dma_attr_t virtio_dma_attr = {
48 .dma_attr_version = DMA_ATTR_V0,
49 .dma_attr_addr_lo = 0,
50 .dma_attr_addr_hi = 0xFFFFFFFFFFFFFFFFull,
51 .dma_attr_count_max = 0x00000000FFFFFFFFull,
52 .dma_attr_align = 1,
53 .dma_attr_burstsizes = 1,
54 .dma_attr_minxfer = 1,
55 .dma_attr_maxxfer = 0xFFFFFFFFull,
56 .dma_attr_seg = 0xFFFFFFFFFFFFFFFFull,
57 .dma_attr_sgllen = 1,
58 .dma_attr_granular = 1,
59 .dma_attr_flags = 0,
60 };
61
62 /*
63 * this avoids calls to drv_usectohz that might be expensive:
64 */
65 static clock_t vioscsi_hz;
66
67 static boolean_t
vioscsi_poll_until(vioscsi_softc_t * sc,vioscsi_request_t * req,ddi_intr_handler_t func,clock_t until)68 vioscsi_poll_until(vioscsi_softc_t *sc, vioscsi_request_t *req,
69 ddi_intr_handler_t func, clock_t until)
70 {
71 until *= 1000000; /* convert to usec */
72 while (until > 0) {
73 (void) func((caddr_t)sc, NULL);
74 if (req->vr_done) {
75 return (B_TRUE);
76 }
77 drv_usecwait(10);
78 until -= 10;
79 }
80 atomic_or_8(&req->vr_expired, 1);
81 return (B_FALSE);
82 }
83
84 static boolean_t
vioscsi_tmf(vioscsi_softc_t * sc,uint32_t func,uint8_t target,uint16_t lun,vioscsi_request_t * task)85 vioscsi_tmf(vioscsi_softc_t *sc, uint32_t func, uint8_t target, uint16_t lun,
86 vioscsi_request_t *task)
87 {
88 vioscsi_request_t req;
89 vioscsi_tmf_res_t *res;
90 vioscsi_tmf_req_t *tmf;
91
92 bzero(&req, sizeof (req));
93
94 if (vioscsi_req_init(sc, &req, sc->vs_ctl_vq, KM_NOSLEEP) != 0) {
95 return (B_FALSE);
96 }
97
98 tmf = &req.vr_req->tmf;
99 res = &req.vr_res->tmf;
100
101 tmf->type = VIRTIO_SCSI_T_TMF;
102 tmf->subtype = func;
103 tmf->lun[0] = 1;
104 tmf->lun[1] = target;
105 tmf->lun[2] = 0x40 | (lun >> 8);
106 tmf->lun[3] = lun & 0xff;
107 tmf->tag = (uint64_t)task;
108
109 virtio_chain_clear(req.vr_vic);
110 if (virtio_chain_append(req.vr_vic, req.vr_req_pa, sizeof (*tmf),
111 VIRTIO_DIR_DEVICE_READS) != DDI_SUCCESS) {
112 return (B_FALSE);
113 }
114
115 if (virtio_chain_append(req.vr_vic, req.vr_res_pa, sizeof (*res),
116 VIRTIO_DIR_DEVICE_WRITES) != DDI_SUCCESS) {
117 return (B_FALSE);
118 }
119
120 /*
121 * Make sure the device can see our request:
122 */
123 virtio_dma_sync(req.vr_dma, DDI_DMA_SYNC_FORDEV);
124
125 /*
126 * Push chain into the queue:
127 */
128 virtio_chain_submit(req.vr_vic, B_TRUE);
129
130 /*
131 * Wait for it to complete -- these should always complete in a tiny
132 * amount of time. Give it 5 seconds to be sure.
133 */
134 if (!vioscsi_poll_until(sc, &req, vioscsi_ctl_handler, 5)) {
135 /*
136 * We timed out -- this should *NEVER* happen!
137 * There is no safe way to deal with this if it occurs, so we
138 * just warn and leak the resources. Plan for a reboot soon.
139 */
140 dev_err(sc->vs_dip, CE_WARN,
141 "task mgmt timeout! (target %d lun %d)", target, lun);
142 return (B_FALSE);
143 }
144
145 vioscsi_req_fini(&req);
146
147 switch (res->response) {
148 case VIRTIO_SCSI_S_OK:
149 case VIRTIO_SCSI_S_FUNCTION_SUCCEEDED:
150 break;
151 default:
152 return (B_FALSE);
153 }
154 return (B_TRUE);
155 }
156
157 static boolean_t
vioscsi_lun_reset(vioscsi_softc_t * sc,uint8_t target,uint16_t lun)158 vioscsi_lun_reset(vioscsi_softc_t *sc, uint8_t target, uint16_t lun)
159 {
160 return (vioscsi_tmf(sc, VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET,
161 target, lun, NULL));
162 }
163
164 static boolean_t
vioscsi_target_reset(vioscsi_softc_t * sc,uint8_t target)165 vioscsi_target_reset(vioscsi_softc_t *sc, uint8_t target)
166 {
167 return (vioscsi_tmf(sc, VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET,
168 target, 0, NULL));
169 }
170
171 static boolean_t
vioscsi_req_abort(vioscsi_softc_t * sc,vioscsi_request_t * req)172 vioscsi_req_abort(vioscsi_softc_t *sc, vioscsi_request_t *req)
173 {
174 return (vioscsi_tmf(sc, VIRTIO_SCSI_T_TMF_ABORT_TASK,
175 req->vr_target, req->vr_lun, req));
176 }
177
178 static void
vioscsi_dev_abort(vioscsi_dev_t * vd)179 vioscsi_dev_abort(vioscsi_dev_t *vd)
180 {
181 vioscsi_request_t *req;
182 list_t *l = &vd->vd_reqs;
183
184 mutex_enter(&vd->vd_lock);
185 for (req = list_head(l); req != NULL; req = list_next(l, req)) {
186 (void) vioscsi_tmf(vd->vd_sc, VIRTIO_SCSI_T_TMF_ABORT_TASK,
187 req->vr_target, req->vr_lun, req);
188 }
189 mutex_exit(&vd->vd_lock);
190 }
191
192 static void
vioscsi_dev_timeout(void * arg)193 vioscsi_dev_timeout(void *arg)
194 {
195 vioscsi_dev_t *vd = arg;
196 vioscsi_softc_t *sc = vd->vd_sc;
197 vioscsi_request_t *req;
198 timeout_id_t tid;
199 clock_t now;
200 list_t *l;
201
202 mutex_enter(&vd->vd_lock);
203 if ((tid = vd->vd_timeout) == 0) {
204 /*
205 * We are shutting down, stop and do not reschedule.
206 */
207 mutex_exit(&vd->vd_lock);
208 return;
209 }
210 vd->vd_timeout = 0;
211
212 now = ddi_get_lbolt();
213 l = &vd->vd_reqs;
214
215 for (req = list_head(l); req != NULL; req = list_next(l, req)) {
216 /*
217 * The list is sorted by expiration time, so if we reach an
218 * item that hasn't expired yet, we're done.
219 */
220 if (now < req->vr_expire) {
221 break;
222 }
223 atomic_or_8(&req->vr_expired, 1);
224
225 /*
226 * This command timed out, so send an abort.
227 */
228 dev_err(sc->vs_dip, CE_WARN, "cmd timed out (%ds)",
229 (int)req->vr_time);
230 (void) vioscsi_req_abort(sc, req);
231 }
232
233 if (!list_is_empty(l)) {
234 /*
235 * Check again in a second.
236 * If these wake ups are too expensive, we could
237 * calculate other timeouts, but that would require
238 * doing untimeout if we want to wake up earlier.
239 * This is probably cheaper, and certainly simpler.
240 */
241 vd->vd_timeout = timeout(vioscsi_dev_timeout, vd, vioscsi_hz);
242 }
243 mutex_exit(&vd->vd_lock);
244 }
245
246 static void
vioscsi_poll(vioscsi_softc_t * sc,vioscsi_request_t * req)247 vioscsi_poll(vioscsi_softc_t *sc, vioscsi_request_t *req)
248 {
249 if (vioscsi_poll_until(sc, req, vioscsi_cmd_handler, req->vr_time)) {
250 return;
251 }
252
253 /*
254 * Try a "gentle" task abort -- timeouts may be quasi-normal for some
255 * types of requests and devices.
256 */
257 if (vioscsi_req_abort(sc, req) &&
258 vioscsi_poll_until(sc, req, vioscsi_cmd_handler, 1)) {
259 return;
260 }
261
262 /*
263 * A little more forceful with a lun reset:
264 */
265 if (vioscsi_lun_reset(sc, req->vr_target, req->vr_lun) &&
266 vioscsi_poll_until(sc, req, vioscsi_cmd_handler, 1)) {
267 return;
268 }
269
270 /*
271 * If all else fails, reset the target, and keep trying.
272 * This can wind up blocking forever, but if it does it means we are in
273 * a very bad situation (and the virtio device is busted).
274 * We may also be leaking request structures at this point, but only at
275 * the maximum rate of one per minute.
276 */
277 for (;;) {
278 dev_err(sc->vs_dip, CE_WARN, "request stuck, resetting target");
279 (void) vioscsi_target_reset(sc, req->vr_target);
280 if (vioscsi_poll_until(sc, req, vioscsi_cmd_handler, 60)) {
281 return;
282 }
283 }
284 }
285
286 static void
vioscsi_start(vioscsi_softc_t * sc,vioscsi_request_t * req)287 vioscsi_start(vioscsi_softc_t *sc, vioscsi_request_t *req)
288 {
289 vioscsi_cmd_req_t *cmd = &req->vr_req->cmd;
290
291 req->vr_done = 0;
292 req->vr_expired = 0;
293 cmd->lun[0] = 1;
294 cmd->lun[1] = req->vr_target;
295 cmd->lun[2] = 0x40 | ((req->vr_lun >> 8) & 0xff);
296 cmd->lun[3] = req->vr_lun & 0xff;
297 cmd->lun[4] = 0;
298 cmd->lun[5] = 0;
299 cmd->lun[6] = 0;
300 cmd->lun[7] = 0;
301 cmd->tag = (uint64_t)req;
302 cmd->prio = 0;
303 cmd->crn = 0;
304 cmd->task_attr = req->vr_task_attr;
305
306 /*
307 * Make sure the device can see our CDB data:
308 */
309 virtio_dma_sync(req->vr_dma, DDI_DMA_SYNC_FORDEV);
310
311 /*
312 * Determine whether we expect to poll before submitting (because we
313 * cannot touch the request after submission if we are not polling).
314 */
315 if (req->vr_poll) {
316 /*
317 * Push chain into the queue:
318 */
319 virtio_chain_submit(req->vr_vic, B_TRUE);
320
321 /*
322 * NB: Interrupts may be enabled, or might not be. It is fine
323 * either way.
324 */
325 vioscsi_poll(sc, req);
326 } else {
327 /*
328 * Push chain into the queue:
329 */
330 virtio_chain_submit(req->vr_vic, B_TRUE);
331 }
332 }
333
334 static int
vioscsi_tran_start(struct scsi_address * ap,struct scsi_pkt * pkt)335 vioscsi_tran_start(struct scsi_address *ap, struct scsi_pkt *pkt)
336 {
337 struct scsi_device *sd = scsi_address_device(ap);
338 vioscsi_dev_t *vd = scsi_device_hba_private_get(sd);
339 vioscsi_request_t *req = pkt->pkt_ha_private;
340 virtio_chain_t *vic = req->vr_vic;
341 vioscsi_cmd_req_t *cmd = &req->vr_req->cmd;
342 vioscsi_cmd_res_t *res = &req->vr_res->cmd;
343
344 if (pkt->pkt_cdbp == NULL) {
345 return (TRAN_BADPKT);
346 }
347
348 bzero(cmd, sizeof (*cmd));
349 bcopy(pkt->pkt_cdbp, cmd->cdb, pkt->pkt_cdblen);
350
351 /*
352 * Default expiration is 10 seconds, clip at an hour.
353 * (order of operations here is to avoid wrapping, if run in a 32-bit
354 * kernel)
355 */
356 req->vr_time = min(pkt->pkt_time ? pkt->pkt_time : 10, 3600);
357 req->vr_dev = vd;
358 req->vr_poll = ((pkt->pkt_flags & FLAG_NOINTR) != 0);
359 req->vr_target = vd->vd_target;
360 req->vr_lun = vd->vd_lun;
361 req->vr_start = ddi_get_lbolt();
362 req->vr_expire = req->vr_start + req->vr_time * vioscsi_hz;
363
364 /*
365 * Configure task queuing behavior:
366 */
367 if (pkt->pkt_flags & (FLAG_HTAG|FLAG_HEAD)) {
368 req->vr_task_attr = VIRTIO_SCSI_S_HEAD;
369 } else if (pkt->pkt_flags & FLAG_OTAG) {
370 req->vr_task_attr = VIRTIO_SCSI_S_ORDERED;
371 } else if (pkt->pkt_flags & FLAG_SENSING) {
372 req->vr_task_attr = VIRTIO_SCSI_S_ACA;
373 } else { /* FLAG_STAG is also our default */
374 req->vr_task_attr = VIRTIO_SCSI_S_SIMPLE;
375 }
376
377 /*
378 * Make sure we start with a clear chain:
379 */
380 virtio_chain_clear(vic);
381
382 /*
383 * The KVM SCSI emulation requires that all outgoing buffers are added
384 * first with the request header being the first entry. After the
385 * outgoing have been added then the incoming buffers with the response
386 * buffer being the first of the incoming. This requirement is
387 * independent of using chained ring entries or one ring entry with
388 * indirect buffers.
389 */
390
391 /*
392 * Add request header:
393 */
394 if (virtio_chain_append(vic, req->vr_req_pa, sizeof (*cmd),
395 VIRTIO_DIR_DEVICE_READS) != DDI_SUCCESS) {
396 return (TRAN_BUSY);
397 }
398
399 /*
400 * Add write buffers:
401 */
402 if (pkt->pkt_dma_flags & DDI_DMA_WRITE) {
403 for (int i = 0; i < pkt->pkt_numcookies; i++) {
404 if (virtio_chain_append(vic,
405 pkt->pkt_cookies[i].dmac_laddress,
406 pkt->pkt_cookies[i].dmac_size,
407 VIRTIO_DIR_DEVICE_READS) != DDI_SUCCESS) {
408 return (TRAN_BUSY);
409 }
410 }
411 }
412
413 /*
414 * Add response header:
415 */
416 if (virtio_chain_append(vic, req->vr_res_pa, sizeof (*res),
417 VIRTIO_DIR_DEVICE_WRITES) != DDI_SUCCESS) {
418 return (TRAN_BUSY);
419 }
420
421 /*
422 * Add read buffers:
423 */
424 if (pkt->pkt_dma_flags & DDI_DMA_READ) {
425 for (int i = 0; i < pkt->pkt_numcookies; i++) {
426 if (virtio_chain_append(vic,
427 pkt->pkt_cookies[i].dmac_laddress,
428 pkt->pkt_cookies[i].dmac_size,
429 VIRTIO_DIR_DEVICE_WRITES) != DDI_SUCCESS) {
430 return (TRAN_BUSY);
431 }
432 }
433 }
434
435 /*
436 * Check for queue depth, and add to the timeout list:
437 */
438 mutex_enter(&vd->vd_lock);
439 if (vd->vd_num_cmd >= vd->vd_max_cmd) {
440 mutex_exit(&vd->vd_lock);
441 return (TRAN_BUSY);
442 }
443 vd->vd_num_cmd++;
444
445 if (!req->vr_poll) {
446 /*
447 * Add the request to the timeout list.
448 *
449 * In order to minimize the work done during timeout handling,
450 * we keep requests sorted. This assumes that requests mostly
451 * have the same timeout, and requests with long timeouts are
452 * infrequent.
453 */
454 list_t *l = &vd->vd_reqs;
455 vioscsi_request_t *r;
456
457 for (r = list_tail(l); r != NULL; r = list_prev(l, r)) {
458 /*
459 * Avoids wrapping lbolt:
460 */
461 if ((req->vr_expire - r->vr_expire) >= 0) {
462 list_insert_after(l, r, req);
463 break;
464 }
465 }
466 if (r == NULL) {
467 /*
468 * List empty, or this one expires before others:
469 */
470 list_insert_head(l, req);
471 }
472 if (vd->vd_timeout == 0) {
473 vd->vd_timeout = timeout(vioscsi_dev_timeout, vd,
474 vioscsi_hz);
475 }
476 }
477
478 mutex_exit(&vd->vd_lock);
479
480 vioscsi_start(vd->vd_sc, req);
481 return (TRAN_ACCEPT);
482 }
483
484 static int
vioscsi_tran_abort(struct scsi_address * ap,struct scsi_pkt * pkt)485 vioscsi_tran_abort(struct scsi_address *ap, struct scsi_pkt *pkt)
486 {
487 struct scsi_device *sd;
488 vioscsi_dev_t *vd;
489 vioscsi_request_t *req;
490
491 if ((ap == NULL) ||
492 ((sd = scsi_address_device(ap)) == NULL) ||
493 ((vd = scsi_device_hba_private_get(sd)) == NULL)) {
494 return (0);
495 }
496 if (pkt == NULL) {
497 /*
498 * Abort all requests for the LUN.
499 */
500 vioscsi_dev_abort(vd);
501 return (1);
502 }
503 if ((req = pkt->pkt_ha_private) != NULL) {
504 return (vioscsi_req_abort(vd->vd_sc, req) ? 1 : 0);
505 }
506
507 return (0);
508 }
509
510 static void
vioscsi_req_fini(vioscsi_request_t * req)511 vioscsi_req_fini(vioscsi_request_t *req)
512 {
513 if (req->vr_dma != NULL) {
514 virtio_dma_free(req->vr_dma);
515 req->vr_dma = NULL;
516 }
517 if (req->vr_vic != NULL) {
518 virtio_chain_free(req->vr_vic);
519 req->vr_vic = NULL;
520 }
521 }
522
523 static int
vioscsi_req_init(vioscsi_softc_t * sc,vioscsi_request_t * req,virtio_queue_t * vq,int sleep)524 vioscsi_req_init(vioscsi_softc_t *sc, vioscsi_request_t *req,
525 virtio_queue_t *vq, int sleep)
526 {
527 uint64_t pa;
528
529 bzero(req, sizeof (*req));
530 list_link_init(&req->vr_node);
531 req->vr_vq = vq;
532 req->vr_dma = virtio_dma_alloc(sc->vs_virtio, sizeof (vioscsi_op_t),
533 &virtio_dma_attr, DDI_DMA_STREAMING | DDI_DMA_READ | DDI_DMA_WRITE,
534 sleep);
535 req->vr_vic = virtio_chain_alloc(vq, sleep);
536 if ((req->vr_dma == NULL) || (req->vr_vic == NULL)) {
537 return (-1);
538 }
539 virtio_chain_data_set(req->vr_vic, req);
540 req->vr_req = virtio_dma_va(req->vr_dma, VIOSCSI_REQ_OFFSET);
541 req->vr_res = virtio_dma_va(req->vr_dma, VIOSCSI_RES_OFFSET);
542 pa = virtio_dma_cookie_pa(req->vr_dma, 0);
543 req->vr_req_pa = pa + VIOSCSI_REQ_OFFSET;
544 req->vr_res_pa = pa + VIOSCSI_RES_OFFSET;
545 return (0);
546 }
547
548 static void
vioscsi_tran_pkt_destructor(struct scsi_pkt * pkt,scsi_hba_tran_t * tran)549 vioscsi_tran_pkt_destructor(struct scsi_pkt *pkt, scsi_hba_tran_t *tran)
550 {
551 vioscsi_request_t *req = pkt->pkt_ha_private;
552
553 vioscsi_req_fini(req);
554 }
555
556 static int
vioscsi_tran_pkt_constructor(struct scsi_pkt * pkt,scsi_hba_tran_t * tran,int sleep)557 vioscsi_tran_pkt_constructor(struct scsi_pkt *pkt, scsi_hba_tran_t *tran,
558 int sleep)
559 {
560 vioscsi_softc_t *sc = tran->tran_hba_private;
561 vioscsi_request_t *req = pkt->pkt_ha_private;
562
563 if (vioscsi_req_init(sc, req, sc->vs_cmd_vq, sleep) != 0) {
564 vioscsi_req_fini(req);
565 return (-1);
566 }
567 req->vr_pkt = pkt;
568 return (0);
569 }
570
571 static int
vioscsi_tran_setup_pkt(struct scsi_pkt * pkt,int (* cb)(caddr_t),caddr_t arg)572 vioscsi_tran_setup_pkt(struct scsi_pkt *pkt, int (*cb)(caddr_t), caddr_t arg)
573 {
574 if ((pkt->pkt_dma_flags & DDI_DMA_RDWR) == DDI_DMA_RDWR) {
575 /*
576 * We can do read, or write, but not both.
577 */
578 return (-1);
579 }
580
581 return (0);
582 }
583
584 static void
vioscsi_tran_teardown_pkt(struct scsi_pkt * pkt)585 vioscsi_tran_teardown_pkt(struct scsi_pkt *pkt)
586 {
587 vioscsi_request_t *req = pkt->pkt_ha_private;
588 virtio_chain_t *vic = req->vr_vic;
589
590 virtio_chain_clear(vic);
591 }
592
593 static int
vioscsi_tran_getcap(struct scsi_address * ap,char * cap,int whom)594 vioscsi_tran_getcap(struct scsi_address *ap, char *cap, int whom)
595 {
596 int rval = 0;
597 vioscsi_softc_t *sc = ap->a_hba_tran->tran_hba_private;
598
599 if (cap == NULL)
600 return (-1);
601
602 switch (scsi_hba_lookup_capstr(cap)) {
603 case SCSI_CAP_CDB_LEN:
604 rval = sc->vs_cdb_size;
605 break;
606
607 case SCSI_CAP_ARQ:
608 case SCSI_CAP_LUN_RESET:
609 case SCSI_CAP_TAGGED_QING:
610 case SCSI_CAP_UNTAGGED_QING:
611 rval = 1;
612 break;
613
614 default:
615 rval = -1;
616 }
617 return (rval);
618 }
619
620 static int
vioscsi_tran_setcap(struct scsi_address * ap,char * cap,int value,int whom)621 vioscsi_tran_setcap(struct scsi_address *ap, char *cap, int value, int whom)
622 {
623 int rval = 1;
624
625 if (cap == NULL || whom == 0) {
626 return (-1);
627 }
628
629 switch (scsi_hba_lookup_capstr(cap)) {
630 default:
631 rval = 1;
632 }
633 return (rval);
634 }
635
636 static int
vioscsi_tran_reset(struct scsi_address * ap,int level)637 vioscsi_tran_reset(struct scsi_address *ap, int level)
638 {
639 struct scsi_device *sd;
640 vioscsi_dev_t *vd;
641
642 if ((ap == NULL) ||
643 ((sd = scsi_address_device(ap)) == NULL) ||
644 ((vd = scsi_device_hba_private_get(sd)) == NULL)) {
645 return (0);
646 }
647
648 switch (level) {
649 case RESET_LUN:
650 if (vioscsi_lun_reset(vd->vd_sc, vd->vd_target, vd->vd_lun)) {
651 return (1);
652 }
653 break;
654 case RESET_TARGET:
655 if (vioscsi_target_reset(vd->vd_sc, vd->vd_target)) {
656 return (1);
657 }
658 break;
659 case RESET_ALL:
660 default:
661 break;
662 }
663 return (0);
664 }
665
666 static boolean_t
vioscsi_parse_unit_address(const char * ua,int * tgt,int * lun)667 vioscsi_parse_unit_address(const char *ua, int *tgt, int *lun)
668 {
669 long num;
670 char *end;
671
672 if ((ddi_strtol(ua, &end, 16, &num) != 0) ||
673 ((*end != ',') && (*end != 0))) {
674 return (B_FALSE);
675 }
676 *tgt = (int)num;
677 if (*end == 0) {
678 *lun = 0;
679 return (B_TRUE);
680 }
681 end++; /* skip comma */
682 if ((ddi_strtol(end, &end, 16, &num) != 0) || (*end != 0)) {
683 return (B_FALSE);
684 }
685 *lun = (int)num;
686 return (B_TRUE);
687 }
688
689 uint_t
vioscsi_ctl_handler(caddr_t arg1,caddr_t arg2)690 vioscsi_ctl_handler(caddr_t arg1, caddr_t arg2)
691 {
692 vioscsi_softc_t *sc = (vioscsi_softc_t *)arg1;
693 virtio_chain_t *vic;
694
695 while ((vic = virtio_queue_poll(sc->vs_ctl_vq)) != NULL) {
696 vioscsi_request_t *req;
697
698 if ((req = virtio_chain_data(vic)) == NULL) {
699 dev_err(sc->vs_dip, CE_WARN, "missing ctl chain data");
700 continue;
701 }
702 atomic_or_8(&req->vr_done, 1);
703 }
704 return (DDI_INTR_CLAIMED);
705 }
706
707 uint_t
vioscsi_evt_handler(caddr_t arg1,caddr_t arg2)708 vioscsi_evt_handler(caddr_t arg1, caddr_t arg2)
709 {
710 vioscsi_softc_t *sc = (vioscsi_softc_t *)arg1;
711 virtio_chain_t *vic;
712 boolean_t missed = B_FALSE;
713
714 while ((vic = virtio_queue_poll(sc->vs_evt_vq)) != NULL) {
715 vioscsi_evt_t *evt;
716 vioscsi_event_t *ve;
717 uint8_t target;
718
719 if ((ve = virtio_chain_data(vic)) == NULL) {
720 /*
721 * This should never occur, it's a bug if it does.
722 */
723 dev_err(sc->vs_dip, CE_WARN, "missing evt chain data");
724 continue;
725 }
726 evt = ve->ve_evt;
727
728 virtio_dma_sync(ve->ve_dma, DDI_DMA_SYNC_FORKERNEL);
729
730 target = evt->lun[1];
731 switch (evt->event & 0x7FFFFFFF) {
732 case VIRTIO_SCSI_T_TRANSPORT_RESET:
733 switch (evt->reason) {
734 case VIRTIO_SCSI_EVT_RESET_HARD:
735 /*
736 * We could reset-notify, but this doesn't seem
737 * to get fired for targets initiated from
738 * host.
739 */
740 break;
741 case VIRTIO_SCSI_EVT_RESET_REMOVED:
742 case VIRTIO_SCSI_EVT_RESET_RESCAN:
743 /*
744 * We can treat these the same for the target,
745 * and not worry about the actual LUN id here.
746 */
747 vioscsi_lun_changed(sc, target);
748 break;
749 default:
750 /*
751 * Some other event we don't know about.
752 */
753 break;
754 }
755 break;
756 case VIRTIO_SCSI_T_NO_EVENT:
757 /*
758 * If this happens, we missed some event(s).
759 */
760 missed = B_TRUE;
761 break;
762 case VIRTIO_SCSI_T_ASYNC_NOTIFY:
763 /*
764 * We don't register for these, so we don't expect
765 * them.
766 */
767 break;
768 }
769
770 if (evt->event & VIRTIO_SCSI_T_EVENTS_MISSED) {
771 missed = B_TRUE;
772 }
773
774 /*
775 * Resubmit the chain for the next event.
776 */
777 virtio_chain_submit(vic, B_TRUE);
778 }
779
780 if (missed) {
781 (void) ddi_taskq_dispatch(sc->vs_tq, vioscsi_discover, sc,
782 DDI_NOSLEEP);
783 }
784
785 return (DDI_INTR_CLAIMED);
786 }
787
788 uint_t
vioscsi_cmd_handler(caddr_t arg1,caddr_t arg2)789 vioscsi_cmd_handler(caddr_t arg1, caddr_t arg2)
790 {
791 vioscsi_softc_t *sc = (vioscsi_softc_t *)arg1;
792 virtio_chain_t *vic;
793
794 while ((vic = virtio_queue_poll(sc->vs_cmd_vq)) != NULL) {
795
796 vioscsi_request_t *req;
797 vioscsi_dev_t *vd;
798 struct scsi_pkt *pkt;
799 struct virtio_scsi_cmd_resp *res;
800
801 if ((req = virtio_chain_data(vic)) == NULL) {
802 /*
803 * This should never occur, it's a bug if it does.
804 */
805 dev_err(sc->vs_dip, CE_WARN, "missing cmd chain data");
806 continue;
807 }
808
809 virtio_dma_sync(req->vr_dma, DDI_DMA_SYNC_FORKERNEL);
810 res = &req->vr_res->cmd;
811 pkt = req->vr_pkt;
812
813 if (pkt == NULL) {
814 /*
815 * This is an internal request (from discovery), and
816 * doesn't have an associated SCSI pkt structure. In
817 * this case, the notification we've done is
818 * sufficient, and the submitter will examine the
819 * response field directly.
820 */
821 if (req->vr_poll) {
822 atomic_or_8(&req->vr_done, 1);
823 }
824 continue;
825 }
826
827 if ((vd = req->vr_dev) != NULL) {
828 mutex_enter(&vd->vd_lock);
829 vd->vd_num_cmd--;
830 list_remove(&vd->vd_reqs, req);
831 mutex_exit(&vd->vd_lock);
832 }
833
834 switch (res->response) {
835
836 case VIRTIO_SCSI_S_OK:
837 /*
838 * Request processed successfully, check SCSI status.
839 */
840 pkt->pkt_scbp[0] = res->status;
841 pkt->pkt_resid = 0;
842 pkt->pkt_reason = CMD_CMPLT;
843 pkt->pkt_state =
844 STATE_GOT_BUS | STATE_GOT_TARGET |
845 STATE_SENT_CMD | STATE_GOT_STATUS;
846 if ((pkt->pkt_numcookies > 0) &&
847 (pkt->pkt_cookies[0].dmac_size > 0)) {
848 pkt->pkt_state |= STATE_XFERRED_DATA;
849 }
850
851 /*
852 * For CHECK_CONDITION, fill out the ARQ details:
853 */
854 if (res->status == STATUS_CHECK) {
855 /*
856 * ARQ status and arq structure:
857 */
858 pkt->pkt_state |= STATE_ARQ_DONE;
859 pkt->pkt_scbp[1] = STATUS_GOOD;
860 struct scsi_arq_status *ars =
861 (void *)pkt->pkt_scbp;
862 ars->sts_rqpkt_reason = CMD_CMPLT;
863 ars->sts_rqpkt_resid = 0;
864 ars->sts_rqpkt_state =
865 STATE_GOT_BUS | STATE_GOT_TARGET |
866 STATE_GOT_STATUS | STATE_SENT_CMD |
867 STATE_XFERRED_DATA;
868 bcopy(res->sense, &ars->sts_sensedata,
869 res->sense_len);
870 }
871 break;
872
873 case VIRTIO_SCSI_S_BAD_TARGET:
874 case VIRTIO_SCSI_S_INCORRECT_LUN:
875 pkt->pkt_reason = CMD_DEV_GONE;
876 break;
877
878 case VIRTIO_SCSI_S_OVERRUN:
879 dev_err(sc->vs_dip, CE_WARN, "OVERRUN");
880 pkt->pkt_reason = CMD_DATA_OVR;
881 break;
882
883 case VIRTIO_SCSI_S_RESET:
884 pkt->pkt_reason = CMD_RESET;
885 pkt->pkt_statistics |= STAT_DEV_RESET;
886 break;
887
888 case VIRTIO_SCSI_S_ABORTED:
889 if (req->vr_expired) {
890 pkt->pkt_statistics |= STAT_TIMEOUT;
891 pkt->pkt_reason = CMD_TIMEOUT;
892 } else {
893 pkt->pkt_reason = CMD_ABORTED;
894 pkt->pkt_statistics |= STAT_ABORTED;
895 }
896 break;
897
898 case VIRTIO_SCSI_S_BUSY:
899 /*
900 * Busy, should have been caught at submission:
901 */
902 pkt->pkt_reason = CMD_TRAN_ERR;
903 break;
904
905 default:
906 dev_err(sc->vs_dip, CE_WARN, "Unknown response: 0x%x",
907 res->response);
908 pkt->pkt_reason = CMD_TRAN_ERR;
909 break;
910 }
911
912
913 if (!req->vr_poll) {
914 scsi_hba_pkt_comp(pkt);
915 } else {
916 atomic_or_8(&req->vr_done, 1);
917 }
918 }
919 return (DDI_INTR_CLAIMED);
920 }
921
922 static int
vioscsi_tran_tgt_init(dev_info_t * hdip,dev_info_t * tdip,scsi_hba_tran_t * tran,struct scsi_device * sd)923 vioscsi_tran_tgt_init(dev_info_t *hdip, dev_info_t *tdip, scsi_hba_tran_t *tran,
924 struct scsi_device *sd)
925 {
926 const char *ua;
927 vioscsi_softc_t *sc;
928 int target;
929 int lun;
930 vioscsi_dev_t *vd;
931
932 if (scsi_hba_iport_unit_address(hdip) == NULL) {
933 return (DDI_FAILURE); /* only iport has targets */
934 }
935 if ((sc = tran->tran_hba_private) == NULL) {
936 return (DDI_FAILURE);
937 }
938
939 if (((ua = scsi_device_unit_address(sd)) == NULL) ||
940 (!vioscsi_parse_unit_address(ua, &target, &lun))) {
941 return (DDI_FAILURE);
942 }
943
944 vd = kmem_zalloc(sizeof (*vd), KM_SLEEP);
945 list_create(&vd->vd_reqs, sizeof (vioscsi_request_t),
946 offsetof(vioscsi_request_t, vr_node));
947 mutex_init(&vd->vd_lock, NULL, MUTEX_DRIVER,
948 virtio_intr_pri(sc->vs_virtio));
949
950 vd->vd_target = (uint8_t)target;
951 vd->vd_lun = (uint16_t)lun;
952 vd->vd_sc = sc;
953 vd->vd_sd = sd;
954 vd->vd_max_cmd = sc->vs_cmd_per_lun;
955 vd->vd_num_cmd = 0;
956
957 scsi_device_hba_private_set(sd, vd);
958
959 mutex_enter(&sc->vs_lock);
960 list_insert_tail(&sc->vs_devs, vd);
961 mutex_exit(&sc->vs_lock);
962
963 return (DDI_SUCCESS);
964 }
965
966 static void
vioscsi_tran_tgt_free(dev_info_t * hdip,dev_info_t * tdip,scsi_hba_tran_t * tran,struct scsi_device * sd)967 vioscsi_tran_tgt_free(dev_info_t *hdip, dev_info_t *tdip, scsi_hba_tran_t *tran,
968 struct scsi_device *sd)
969 {
970 vioscsi_dev_t *vd = scsi_device_hba_private_get(sd);
971 vioscsi_softc_t *sc = vd->vd_sc;
972 timeout_id_t tid;
973
974 scsi_device_hba_private_set(sd, NULL);
975
976 mutex_enter(&vd->vd_lock);
977 tid = vd->vd_timeout;
978 vd->vd_timeout = 0;
979 mutex_exit(&vd->vd_lock);
980
981 if (tid != 0) {
982 (void) untimeout(tid);
983 }
984
985 mutex_enter(&sc->vs_lock);
986 list_remove(&sc->vs_devs, vd);
987 mutex_exit(&sc->vs_lock);
988
989 list_destroy(&vd->vd_reqs);
990 mutex_destroy(&vd->vd_lock);
991 kmem_free(vd, sizeof (*vd));
992 }
993
994 /*
995 * vioscsi_probe_target probes for existence of a valid target (LUN 0).
996 * It utilizes the supplied request, and sends TEST UNIT READY.
997 * (This command is used because it requires no data.)
998 * It returns 1 if the target is found, 0 if not, and -1 on error.
999 * It is expected additional LUNs will be discovered by the HBA framework using
1000 * REPORT LUNS on LUN 0.
1001 */
1002 static int
vioscsi_probe_target(vioscsi_softc_t * sc,vioscsi_request_t * req,uint8_t target)1003 vioscsi_probe_target(vioscsi_softc_t *sc, vioscsi_request_t *req,
1004 uint8_t target)
1005 {
1006 struct virtio_scsi_cmd_req *cmd = &req->vr_req->cmd;
1007 struct virtio_scsi_cmd_resp *res = &req->vr_res->cmd;
1008
1009 bzero(cmd, sizeof (*cmd));
1010 cmd->cdb[0] = SCMD_TEST_UNIT_READY;
1011
1012 virtio_chain_clear(req->vr_vic);
1013 if (virtio_chain_append(req->vr_vic, req->vr_req_pa,
1014 sizeof (*cmd), VIRTIO_DIR_DEVICE_READS) != DDI_SUCCESS) {
1015 return (-1);
1016 }
1017 if (virtio_chain_append(req->vr_vic, req->vr_res_pa,
1018 sizeof (*res), VIRTIO_DIR_DEVICE_WRITES) != DDI_SUCCESS) {
1019 return (-1);
1020 }
1021 req->vr_poll = B_TRUE;
1022 req->vr_start = ddi_get_lbolt();
1023 req->vr_time = 10; /* seconds */
1024 req->vr_target = target;
1025 req->vr_lun = 0;
1026 req->vr_task_attr = VIRTIO_SCSI_S_HEAD;
1027 vioscsi_start(sc, req);
1028 switch (res->response) {
1029 case VIRTIO_SCSI_S_OK:
1030 return (1);
1031 case VIRTIO_SCSI_S_INCORRECT_LUN:
1032 case VIRTIO_SCSI_S_BAD_TARGET:
1033 return (0);
1034 default:
1035 return (-1);
1036 }
1037 }
1038
1039 static void
vioscsi_rescan_luns(void * arg)1040 vioscsi_rescan_luns(void *arg)
1041 {
1042 vioscsi_softc_t *sc = arg;
1043 vioscsi_dev_t *vd;
1044 scsi_hba_tgtmap_t *tm = sc->vs_tgtmap;
1045 list_t *l;
1046 char addr[16];
1047
1048 l = &sc->vs_devs;
1049 mutex_enter(&sc->vs_lock);
1050 for (vd = list_head(l); vd != NULL; vd = list_next(l, vd)) {
1051 if (!vd->vd_rescan) {
1052 continue;
1053 }
1054
1055 vd->vd_rescan = B_FALSE;
1056 (void) snprintf(addr, sizeof (addr), "%x", vd->vd_target);
1057 scsi_hba_tgtmap_scan_luns(tm, addr);
1058 }
1059 mutex_exit(&sc->vs_lock);
1060 }
1061
1062 static void
vioscsi_lun_changed(vioscsi_softc_t * sc,uint8_t target)1063 vioscsi_lun_changed(vioscsi_softc_t *sc, uint8_t target)
1064 {
1065 vioscsi_dev_t *vd;
1066 list_t *l = &sc->vs_devs;
1067 boolean_t found = B_FALSE;
1068
1069 mutex_enter(&sc->vs_lock);
1070 for (vd = list_head(l); vd != NULL; vd = list_next(l, vd)) {
1071 if ((vd->vd_target == target) && (vd->vd_lun == 0)) {
1072 vd->vd_rescan = B_TRUE;
1073 found = B_TRUE;
1074 break;
1075 }
1076 }
1077 mutex_exit(&sc->vs_lock);
1078
1079 if (found) {
1080 /*
1081 * We have lun 0 already, so report luns changed:
1082 */
1083 (void) ddi_taskq_dispatch(sc->vs_tq, vioscsi_rescan_luns,
1084 sc, DDI_NOSLEEP);
1085 } else {
1086 /*
1087 * We didn't find lun 0, so issue a new discovery:
1088 */
1089 (void) ddi_taskq_dispatch(sc->vs_tq, vioscsi_discover,
1090 sc, DDI_NOSLEEP);
1091 }
1092 }
1093
1094 /*
1095 * vioscsi_discover is our task function for performing target and lun
1096 * discovery. This is done using active SCSI probes.
1097 */
1098 static void
vioscsi_discover(void * arg)1099 vioscsi_discover(void *arg)
1100 {
1101 vioscsi_softc_t *sc = arg;
1102 scsi_hba_tgtmap_t *tm = sc->vs_tgtmap;
1103 vioscsi_request_t req;
1104
1105 if (vioscsi_req_init(sc, &req, sc->vs_cmd_vq, KM_SLEEP) != 0) {
1106 vioscsi_req_fini(&req);
1107 return;
1108 }
1109
1110 if (scsi_hba_tgtmap_set_begin(tm) != DDI_SUCCESS) {
1111 vioscsi_req_fini(&req);
1112 return;
1113 }
1114 for (uint8_t target = 0; target < sc->vs_max_target; target++) {
1115 char ua[10];
1116 switch (vioscsi_probe_target(sc, &req, target)) {
1117 case 1:
1118 (void) snprintf(ua, sizeof (ua), "%x", target);
1119 if (scsi_hba_tgtmap_set_add(tm, SCSI_TGT_SCSI_DEVICE,
1120 ua, NULL) != DDI_SUCCESS) {
1121 (void) scsi_hba_tgtmap_set_flush(tm);
1122 vioscsi_req_fini(&req);
1123 return;
1124 }
1125 break;
1126 case 0:
1127 continue;
1128 case -1:
1129 (void) scsi_hba_tgtmap_set_flush(tm);
1130 vioscsi_req_fini(&req);
1131 return;
1132 }
1133 }
1134 (void) scsi_hba_tgtmap_set_end(tm, 0);
1135 vioscsi_req_fini(&req);
1136 }
1137
1138 static void
vioscsi_teardown(vioscsi_softc_t * sc,boolean_t failed)1139 vioscsi_teardown(vioscsi_softc_t *sc, boolean_t failed)
1140 {
1141 if (sc->vs_virtio != NULL) {
1142 virtio_fini(sc->vs_virtio, failed);
1143 }
1144
1145 /*
1146 * Free up the event resources:
1147 */
1148 for (int i = 0; i < VIOSCSI_NUM_EVENTS; i++) {
1149 vioscsi_event_t *ve = &sc->vs_events[i];
1150 if (ve->ve_vic != NULL) {
1151 virtio_chain_free(ve->ve_vic);
1152 }
1153 if (ve->ve_dma != NULL) {
1154 virtio_dma_free(ve->ve_dma);
1155 }
1156 }
1157
1158 if (sc->vs_tran != NULL) {
1159 scsi_hba_tran_free(sc->vs_tran);
1160 }
1161 if (sc->vs_tq != NULL) {
1162 ddi_taskq_destroy(sc->vs_tq);
1163 }
1164 if (sc->vs_intr_pri != NULL) {
1165 mutex_destroy(&sc->vs_lock);
1166 }
1167 kmem_free(sc, sizeof (*sc));
1168 }
1169
1170 static int
vioscsi_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)1171 vioscsi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1172 {
1173 scsi_hba_tran_t *tran = NULL;
1174 vioscsi_softc_t *sc;
1175 virtio_t *vio;
1176 ddi_dma_attr_t attr;
1177
1178 if (cmd != DDI_ATTACH) { /* no suspend/resume support */
1179 return (DDI_FAILURE);
1180 }
1181
1182 if (scsi_hba_iport_unit_address(dip) != NULL) {
1183 return (vioscsi_iport_attach(dip));
1184 }
1185
1186 sc = kmem_zalloc(sizeof (*sc), KM_SLEEP);
1187 sc->vs_dip = dip;
1188
1189 list_create(&sc->vs_devs, sizeof (vioscsi_dev_t),
1190 offsetof(vioscsi_dev_t, vd_node));
1191
1192 tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);
1193 sc->vs_tran = tran;
1194
1195 tran->tran_hba_len = sizeof (vioscsi_request_t);
1196 tran->tran_hba_private = sc;
1197
1198 /*
1199 * We don't use WWN addressing, so advertise parallel. The underlying
1200 * device might still be using a different transport, even in a
1201 * pass-through, but we cannot discriminate that at this layer.
1202 */
1203 tran->tran_interconnect_type = INTERCONNECT_PARALLEL;
1204
1205 tran->tran_start = vioscsi_tran_start;
1206 tran->tran_abort = vioscsi_tran_abort;
1207 tran->tran_reset = vioscsi_tran_reset;
1208 tran->tran_getcap = vioscsi_tran_getcap;
1209 tran->tran_setcap = vioscsi_tran_setcap;
1210
1211 tran->tran_tgt_init = vioscsi_tran_tgt_init;
1212 tran->tran_tgt_free = vioscsi_tran_tgt_free;
1213
1214 tran->tran_setup_pkt = vioscsi_tran_setup_pkt;
1215 tran->tran_teardown_pkt = vioscsi_tran_teardown_pkt;
1216 tran->tran_pkt_constructor = vioscsi_tran_pkt_constructor;
1217 tran->tran_pkt_destructor = vioscsi_tran_pkt_destructor;
1218
1219 /*
1220 * We need to determine some device settings here, so we initialize the
1221 * virtio in order to access those values. The rest of the setup we do
1222 * in the iport attach. Note that this driver cannot support
1223 * reattaching a child iport once it is removed -- the entire driver
1224 * will need to be reset for that.
1225 */
1226 vio = virtio_init(dip, VIOSCSI_WANTED_FEATURES, B_TRUE);
1227 if ((sc->vs_virtio = vio) == NULL) {
1228 dev_err(dip, CE_WARN, "failed to init virtio");
1229 vioscsi_teardown(sc, B_TRUE);
1230 return (DDI_FAILURE);
1231 }
1232
1233 /*
1234 * Get virtio parameters:
1235 */
1236 sc->vs_max_target = virtio_dev_get16(vio, VIRTIO_SCSI_CFG_MAX_TARGET);
1237 sc->vs_max_lun = virtio_dev_get32(vio, VIRTIO_SCSI_CFG_MAX_LUN);
1238 sc->vs_cdb_size = virtio_dev_get32(vio, VIRTIO_SCSI_CFG_CDB_SIZE);
1239 sc->vs_max_seg = virtio_dev_get32(vio, VIRTIO_SCSI_CFG_SEG_MAX);
1240 sc->vs_cmd_per_lun = virtio_dev_get32(vio, VIRTIO_SCSI_CFG_CMD_PER_LUN);
1241
1242 /*
1243 * Adjust operating parameters to functional limits:
1244 */
1245 sc->vs_max_target = min(VIOSCSI_MAX_TARGET, sc->vs_max_target);
1246 sc->vs_cmd_per_lun = max(1, sc->vs_max_target);
1247 sc->vs_max_seg = max(VIOSCSI_MIN_SEGS, sc->vs_max_seg);
1248
1249 /*
1250 * Allocate queues:
1251 */
1252 sc->vs_ctl_vq = virtio_queue_alloc(vio, 0, "ctl",
1253 vioscsi_ctl_handler, sc, B_FALSE, sc->vs_max_seg);
1254 sc->vs_evt_vq = virtio_queue_alloc(vio, 1, "evt",
1255 vioscsi_evt_handler, sc, B_FALSE, sc->vs_max_seg);
1256 sc->vs_cmd_vq = virtio_queue_alloc(vio, 2, "cmd",
1257 vioscsi_cmd_handler, sc, B_FALSE, sc->vs_max_seg);
1258
1259 if ((sc->vs_ctl_vq == NULL) || (sc->vs_evt_vq == NULL) ||
1260 (sc->vs_cmd_vq == NULL)) {
1261 dev_err(dip, CE_WARN, "failed allocating queue(s)");
1262 vioscsi_teardown(sc, B_TRUE);
1263 return (DDI_FAILURE);
1264 }
1265
1266 if (virtio_init_complete(vio, VIRTIO_ANY_INTR_TYPE) != DDI_SUCCESS) {
1267 dev_err(dip, CE_WARN, "virtio_init_complete failed");
1268 vioscsi_teardown(sc, B_TRUE);
1269 return (DDI_FAILURE);
1270 }
1271
1272 /*
1273 * We cannot initialize this mutex before virtio_init_complete:
1274 */
1275 sc->vs_intr_pri = virtio_intr_pri(vio);
1276 mutex_init(&sc->vs_lock, NULL, MUTEX_DRIVER, sc->vs_intr_pri);
1277
1278 /*
1279 * Allocate events, but do not submit yet:
1280 */
1281 for (int i = 0; i < VIOSCSI_NUM_EVENTS; i++) {
1282 vioscsi_event_t *ve = &sc->vs_events[i];
1283 ve->ve_vic = virtio_chain_alloc(sc->vs_evt_vq, KM_SLEEP);
1284 ve->ve_dma = virtio_dma_alloc(sc->vs_virtio,
1285 sizeof (vioscsi_evt_t), &virtio_dma_attr,
1286 DDI_DMA_STREAMING | DDI_DMA_READ, KM_SLEEP);
1287 if ((ve->ve_vic == NULL) || (ve->ve_dma == NULL)) {
1288 vioscsi_teardown(sc, B_TRUE);
1289 return (DDI_FAILURE);
1290 }
1291 if (virtio_chain_append(ve->ve_vic,
1292 virtio_dma_cookie_pa(ve->ve_dma, 0), sizeof (*ve->ve_evt),
1293 VIRTIO_DIR_DEVICE_WRITES) != DDI_SUCCESS) {
1294 vioscsi_teardown(sc, B_TRUE);
1295 return (DDI_FAILURE);
1296 }
1297 ve->ve_evt = virtio_dma_va(ve->ve_dma, 0);
1298 virtio_chain_data_set(ve->ve_vic, ve);
1299 }
1300
1301 sc->vs_tq = ddi_taskq_create(dip, "task", 1, TASKQ_DEFAULTPRI, 0);
1302 if (sc->vs_tq == NULL) {
1303 dev_err(dip, CE_WARN, "failed to create taskq");
1304 vioscsi_teardown(sc, B_TRUE);
1305 return (DDI_FAILURE);
1306 }
1307
1308 /*
1309 * Maximum number of segments, subtract two needed for headers:
1310 */
1311 attr = virtio_dma_attr;
1312 attr.dma_attr_sgllen = sc->vs_max_seg - 2;
1313
1314 if (scsi_hba_attach_setup(dip, &attr, tran,
1315 SCSI_HBA_ADDR_COMPLEX | SCSI_HBA_HBA |
1316 SCSI_HBA_TRAN_CDB | SCSI_HBA_TRAN_SCB) !=
1317 DDI_SUCCESS) {
1318 vioscsi_teardown(sc, B_TRUE);
1319 return (DDI_FAILURE);
1320 }
1321
1322 if (scsi_hba_iport_register(dip, "iport0") != DDI_SUCCESS) {
1323 vioscsi_teardown(sc, B_TRUE);
1324 return (DDI_FAILURE);
1325 }
1326
1327 ddi_report_dev(dip);
1328
1329 return (DDI_SUCCESS);
1330 }
1331
1332 static void
vioscsi_iport_teardown(vioscsi_softc_t * sc)1333 vioscsi_iport_teardown(vioscsi_softc_t *sc)
1334 {
1335 /*
1336 * Stop the taskq -- ensures we don't try to access resources from a
1337 * task while we are tearing down.
1338 */
1339 ddi_taskq_suspend(sc->vs_tq);
1340 ddi_taskq_wait(sc->vs_tq);
1341
1342 /*
1343 * Shutdown all interrupts and device transfers:
1344 */
1345 virtio_interrupts_disable(sc->vs_virtio);
1346 virtio_shutdown(sc->vs_virtio);
1347
1348 /*
1349 * Common resources:
1350 */
1351 if (sc->vs_tgtmap != NULL) {
1352 scsi_hba_tgtmap_destroy(sc->vs_tgtmap);
1353 sc->vs_tgtmap = NULL;
1354 }
1355 }
1356
1357 /*
1358 * vioscsi_iport_attach implements the attach of the iport. We do the final
1359 * set up of interrupts, and posting of event buffers here, as we do not want
1360 * any activity unless the iport is attached. This matches detach, and makes
1361 * teardown safer.
1362 */
1363 static int
vioscsi_iport_attach(dev_info_t * dip)1364 vioscsi_iport_attach(dev_info_t *dip)
1365 {
1366 const char *ua = scsi_hba_iport_unit_address(dip);
1367 scsi_hba_tran_t *tran;
1368 vioscsi_softc_t *sc;
1369
1370 /*
1371 * We only support a single iport -- all disks are virtual and all
1372 * disks use target/lun addresses.
1373 */
1374 if ((ua == NULL) || (strcmp(ua, "iport0") != 0)) {
1375 return (DDI_FAILURE);
1376 }
1377
1378 /*
1379 * Get our parent's tran, and look up the sc from that:
1380 */
1381 tran = ddi_get_driver_private(ddi_get_parent(dip));
1382 if ((tran == NULL) ||
1383 ((sc = tran->tran_hba_private) == NULL)) {
1384 return (DDI_FAILURE);
1385 }
1386
1387 /*
1388 * Save a copy of the soft state in our tran private area.
1389 * (The framework clears this after cloning from parent.)
1390 */
1391 tran = ddi_get_driver_private(dip);
1392 tran->tran_hba_private = sc;
1393
1394 /*
1395 * We don't want interrupts on the control queue -- strictly polled
1396 * (however if this handler is called from an interrupt, it should
1397 * still be absolutely fine).
1398 */
1399 virtio_queue_no_interrupt(sc->vs_ctl_vq, B_TRUE);
1400
1401 if (scsi_hba_tgtmap_create(dip, SCSI_TM_FULLSET, MICROSEC,
1402 2 * MICROSEC, sc, NULL, NULL, &sc->vs_tgtmap) != DDI_SUCCESS) {
1403 vioscsi_iport_teardown(sc);
1404 return (DDI_FAILURE);
1405 }
1406
1407 /*
1408 * Post events:
1409 */
1410 for (int i = 0; i < VIOSCSI_NUM_EVENTS; i++) {
1411 virtio_chain_submit(sc->vs_events[i].ve_vic, B_FALSE);
1412 }
1413 virtio_queue_flush(sc->vs_evt_vq);
1414
1415 /*
1416 * Start interrupts going now:
1417 */
1418 if (virtio_interrupts_enable(sc->vs_virtio) != DDI_SUCCESS) {
1419 vioscsi_iport_teardown(sc);
1420 return (DDI_FAILURE);
1421 }
1422
1423 /*
1424 * Start a discovery:
1425 */
1426 (void) ddi_taskq_dispatch(sc->vs_tq, vioscsi_discover, sc, DDI_SLEEP);
1427
1428 return (DDI_SUCCESS);
1429 }
1430
1431 static int
vioscsi_quiesce(dev_info_t * dip)1432 vioscsi_quiesce(dev_info_t *dip)
1433 {
1434 vioscsi_softc_t *sc;
1435 scsi_hba_tran_t *tran;
1436
1437 if (((tran = ddi_get_driver_private(dip)) == NULL) ||
1438 ((sc = tran->tran_hba_private) == NULL)) {
1439 return (DDI_FAILURE);
1440 }
1441 if (sc->vs_virtio == NULL) {
1442 return (DDI_SUCCESS); /* not initialized yet */
1443 }
1444
1445 return (virtio_quiesce(sc->vs_virtio));
1446 }
1447
1448 /*
1449 * vioscsi_iport_detach is used to perform the detach of the iport. It
1450 * disables interrupts and the device, but does not free resources, other than
1451 * the target map. Note that due to lack of a way to start virtio after
1452 * virtio_shutdown(), it is not possible to reattach the iport after this is
1453 * called, unless the underlying HBA is also detached and then re-attached.
1454 */
1455 static int
vioscsi_iport_detach(dev_info_t * dip)1456 vioscsi_iport_detach(dev_info_t *dip)
1457 {
1458 const char *ua = scsi_hba_iport_unit_address(dip);
1459 vioscsi_softc_t *sc;
1460 scsi_hba_tran_t *tran;
1461
1462 if ((ua == NULL) || (strcmp(ua, "iport0") != 0)) {
1463 return (DDI_FAILURE);
1464 }
1465
1466 if (((tran = ddi_get_driver_private(dip)) == NULL) ||
1467 ((sc = tran->tran_hba_private) == NULL)) {
1468 return (DDI_FAILURE);
1469 }
1470
1471 mutex_enter(&sc->vs_lock);
1472 if (!list_is_empty(&sc->vs_devs)) {
1473 /*
1474 * Cannot detach while we have target children.
1475 */
1476 mutex_exit(&sc->vs_lock);
1477 return (DDI_FAILURE);
1478 }
1479
1480 vioscsi_iport_teardown(sc);
1481
1482 return (DDI_SUCCESS);
1483 }
1484
1485 static int
vioscsi_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)1486 vioscsi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1487 {
1488 vioscsi_softc_t *sc;
1489 scsi_hba_tran_t *tran;
1490
1491 if (cmd != DDI_DETACH) {
1492 return (DDI_FAILURE);
1493 }
1494
1495 if (scsi_hba_iport_unit_address(dip) != NULL) {
1496 return (vioscsi_iport_detach(dip));
1497 }
1498
1499 if (((tran = ddi_get_driver_private(dip)) == NULL) ||
1500 ((sc = tran->tran_hba_private) == NULL)) {
1501 return (DDI_FAILURE);
1502 }
1503
1504 if (scsi_hba_detach(dip) != DDI_SUCCESS) {
1505 return (DDI_FAILURE);
1506 }
1507 vioscsi_teardown(sc, B_FALSE);
1508
1509 return (DDI_SUCCESS);
1510 }
1511
1512 static struct dev_ops vioscsi_dev_ops = {
1513 .devo_rev = DEVO_REV,
1514 .devo_refcnt = 0,
1515 .devo_getinfo = nodev,
1516 .devo_identify = nulldev,
1517 .devo_probe = nulldev,
1518 .devo_attach = vioscsi_attach,
1519 .devo_detach = vioscsi_detach,
1520 .devo_reset = nodev,
1521 .devo_cb_ops = NULL,
1522 .devo_bus_ops = NULL,
1523 .devo_power = NULL,
1524 .devo_quiesce = vioscsi_quiesce,
1525 };
1526
1527 static struct modldrv modldrv = {
1528 .drv_modops = &mod_driverops,
1529 .drv_linkinfo = vioscsi_ident,
1530 .drv_dev_ops = &vioscsi_dev_ops,
1531 };
1532
1533 static struct modlinkage modlinkage = {
1534 .ml_rev = MODREV_1,
1535 .ml_linkage = { &modldrv, NULL, },
1536 };
1537
1538
1539 int
_init(void)1540 _init(void)
1541 {
1542 int err;
1543
1544 /*
1545 * Initialize this unconditionally:
1546 */
1547 vioscsi_hz = drv_usectohz(1000000);
1548
1549 if ((err = scsi_hba_init(&modlinkage)) != 0) {
1550 return (err);
1551 }
1552
1553 if ((err = mod_install(&modlinkage)) != 0) {
1554 scsi_hba_fini(&modlinkage);
1555 return (err);
1556 }
1557
1558 return (err);
1559 }
1560
1561 int
_fini(void)1562 _fini(void)
1563 {
1564 int err;
1565
1566 if ((err = mod_remove(&modlinkage)) != 0) {
1567 return (err);
1568 }
1569
1570 scsi_hba_fini(&modlinkage);
1571
1572 return (DDI_SUCCESS);
1573 }
1574
1575 int
_info(struct modinfo * modinfop)1576 _info(struct modinfo *modinfop)
1577 {
1578 return (mod_info(&modlinkage, modinfop));
1579 }
1580