1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright 2013 Nathan Whitehorn
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/param.h>
30 #include <sys/systm.h>
31 #include <sys/kernel.h>
32 #include <sys/malloc.h>
33 #include <sys/module.h>
34 #include <sys/selinfo.h>
35 #include <sys/bus.h>
36 #include <sys/conf.h>
37 #include <sys/eventhandler.h>
38 #include <sys/rman.h>
39 #include <sys/bio.h>
40 #include <sys/ioccom.h>
41 #include <sys/uio.h>
42 #include <sys/proc.h>
43 #include <sys/signalvar.h>
44 #include <sys/sysctl.h>
45 #include <sys/endian.h>
46 #include <sys/vmem.h>
47
48 #include <cam/cam.h>
49 #include <cam/cam_ccb.h>
50 #include <cam/cam_debug.h>
51 #include <cam/cam_periph.h>
52 #include <cam/cam_sim.h>
53 #include <cam/cam_xpt_periph.h>
54 #include <cam/cam_xpt_sim.h>
55 #include <cam/scsi/scsi_all.h>
56 #include <cam/scsi/scsi_message.h>
57
58 #include <dev/ofw/openfirm.h>
59 #include <dev/ofw/ofw_bus.h>
60 #include <dev/ofw/ofw_bus_subr.h>
61
62 #include <machine/bus.h>
63 #include <machine/resource.h>
64
65 #include <powerpc/pseries/phyp-hvcall.h>
66
67 struct vscsi_softc;
68
69 /* VSCSI CRQ format from table 260 of PAPR spec 2.4 (page 760) */
70 struct vscsi_crq {
71 uint8_t valid;
72 uint8_t format;
73 uint8_t reserved;
74 uint8_t status;
75 uint16_t timeout;
76 uint16_t iu_length;
77 uint64_t iu_data;
78 };
79
80 struct vscsi_xfer {
81 TAILQ_ENTRY(vscsi_xfer) queue;
82 struct vscsi_softc *sc;
83 union ccb *ccb;
84 bus_dmamap_t dmamap;
85 uint64_t tag;
86
87 vmem_addr_t srp_iu_offset;
88 vmem_size_t srp_iu_size;
89 };
90
91 TAILQ_HEAD(vscsi_xferq, vscsi_xfer);
92
93 struct vscsi_softc {
94 device_t dev;
95 struct cam_devq *devq;
96 struct cam_sim *sim;
97 struct cam_path *path;
98 struct mtx io_lock;
99
100 cell_t unit;
101 int bus_initialized;
102 int bus_logged_in;
103 int max_transactions;
104
105 int irqid;
106 struct resource *irq;
107 void *irq_cookie;
108
109 bus_dma_tag_t crq_tag;
110 struct vscsi_crq *crq_queue;
111 int n_crqs, cur_crq;
112 bus_dmamap_t crq_map;
113 bus_addr_t crq_phys;
114
115 vmem_t *srp_iu_arena;
116 void *srp_iu_queue;
117 bus_addr_t srp_iu_phys;
118
119 bus_dma_tag_t data_tag;
120
121 struct vscsi_xfer loginxp;
122 struct vscsi_xfer *xfer;
123 struct vscsi_xferq active_xferq;
124 struct vscsi_xferq free_xferq;
125 };
126
127 struct srp_login {
128 uint8_t type;
129 uint8_t reserved[7];
130 uint64_t tag;
131 uint64_t max_cmd_length;
132 uint32_t reserved2;
133 uint16_t buffer_formats;
134 uint8_t flags;
135 uint8_t reserved3[5];
136 uint8_t initiator_port_id[16];
137 uint8_t target_port_id[16];
138 } __packed;
139
140 struct srp_login_rsp {
141 uint8_t type;
142 uint8_t reserved[3];
143 uint32_t request_limit_delta;
144 uint8_t tag;
145 uint32_t max_i_to_t_len;
146 uint32_t max_t_to_i_len;
147 uint16_t buffer_formats;
148 uint8_t flags;
149 /* Some reserved bits follow */
150 } __packed;
151
152 struct srp_cmd {
153 uint8_t type;
154 uint8_t flags1;
155 uint8_t reserved[3];
156 uint8_t formats;
157 uint8_t out_buffer_count;
158 uint8_t in_buffer_count;
159 uint64_t tag;
160 uint32_t reserved2;
161 uint64_t lun;
162 uint8_t reserved3[3];
163 uint8_t additional_cdb;
164 uint8_t cdb[16];
165 uint8_t data_payload[0];
166 } __packed;
167
168 struct srp_rsp {
169 uint8_t type;
170 uint8_t reserved[3];
171 uint32_t request_limit_delta;
172 uint64_t tag;
173 uint16_t reserved2;
174 uint8_t flags;
175 uint8_t status;
176 uint32_t data_out_resid;
177 uint32_t data_in_resid;
178 uint32_t sense_data_len;
179 uint32_t response_data_len;
180 uint8_t data_payload[0];
181 } __packed;
182
183 struct srp_tsk_mgmt {
184 uint8_t type;
185 uint8_t reserved[7];
186 uint64_t tag;
187 uint32_t reserved2;
188 uint64_t lun;
189 uint8_t reserved3[2];
190 uint8_t function;
191 uint8_t reserved4;
192 uint64_t manage_tag;
193 uint64_t reserved5;
194 } __packed;
195
196 /* Message code type */
197 #define SRP_LOGIN_REQ 0x00
198 #define SRP_TSK_MGMT 0x01
199 #define SRP_CMD 0x02
200 #define SRP_I_LOGOUT 0x03
201
202 #define SRP_LOGIN_RSP 0xC0
203 #define SRP_RSP 0xC1
204 #define SRP_LOGIN_REJ 0xC2
205
206 #define SRP_T_LOGOUT 0x80
207 #define SRP_CRED_REQ 0x81
208 #define SRP_AER_REQ 0x82
209
210 #define SRP_CRED_RSP 0x41
211 #define SRP_AER_RSP 0x41
212
213 /* Flags for srp_rsp flags field */
214 #define SRP_RSPVALID 0x01
215 #define SRP_SNSVALID 0x02
216 #define SRP_DOOVER 0x04
217 #define SRP_DOUNDER 0x08
218 #define SRP_DIOVER 0x10
219 #define SRP_DIUNDER 0x20
220
221 #define MAD_SUCESS 0x00
222 #define MAD_NOT_SUPPORTED 0xf1
223 #define MAD_FAILED 0xf7
224
225 #define MAD_EMPTY_IU 0x01
226 #define MAD_ERROR_LOGGING_REQUEST 0x02
227 #define MAD_ADAPTER_INFO_REQUEST 0x03
228 #define MAD_CAPABILITIES_EXCHANGE 0x05
229 #define MAD_PHYS_ADAP_INFO_REQUEST 0x06
230 #define MAD_TAPE_PASSTHROUGH_REQUEST 0x07
231 #define MAD_ENABLE_FAST_FAIL 0x08
232
233 static int vscsi_probe(device_t);
234 static int vscsi_attach(device_t);
235 static int vscsi_detach(device_t);
236 static void vscsi_cam_action(struct cam_sim *, union ccb *);
237 static void vscsi_cam_poll(struct cam_sim *);
238 static void vscsi_intr(void *arg);
239 static void vscsi_check_response_queue(struct vscsi_softc *sc);
240 static void vscsi_setup_bus(struct vscsi_softc *sc);
241
242 static void vscsi_srp_login(struct vscsi_softc *sc);
243 static void vscsi_crq_load_cb(void *, bus_dma_segment_t *, int, int);
244 static void vscsi_scsi_command(void *xxp, bus_dma_segment_t *segs,
245 int nsegs, int err);
246 static void vscsi_task_management(struct vscsi_softc *sc, union ccb *ccb);
247 static void vscsi_srp_response(struct vscsi_xfer *, struct vscsi_crq *);
248
249 static device_method_t vscsi_methods[] = {
250 DEVMETHOD(device_probe, vscsi_probe),
251 DEVMETHOD(device_attach, vscsi_attach),
252 DEVMETHOD(device_detach, vscsi_detach),
253
254 DEVMETHOD_END
255 };
256
257 static driver_t vscsi_driver = {
258 "vscsi",
259 vscsi_methods,
260 sizeof(struct vscsi_softc)
261 };
262
263 DRIVER_MODULE(vscsi, vdevice, vscsi_driver, 0, 0);
264 MALLOC_DEFINE(M_VSCSI, "vscsi", "CAM device queue for VSCSI");
265
266 static int
vscsi_probe(device_t dev)267 vscsi_probe(device_t dev)
268 {
269
270 if (!ofw_bus_is_compatible(dev, "IBM,v-scsi"))
271 return (ENXIO);
272
273 device_set_desc(dev, "POWER Hypervisor Virtual SCSI Bus");
274 return (0);
275 }
276
277 static int
vscsi_attach(device_t dev)278 vscsi_attach(device_t dev)
279 {
280 struct vscsi_softc *sc;
281 struct vscsi_xfer *xp;
282 int error, i;
283
284 sc = device_get_softc(dev);
285 if (sc == NULL)
286 return (EINVAL);
287
288 sc->dev = dev;
289 mtx_init(&sc->io_lock, "vscsi", NULL, MTX_DEF);
290
291 /* Get properties */
292 OF_getencprop(ofw_bus_get_node(dev), "reg", &sc->unit,
293 sizeof(sc->unit));
294
295 /* Setup interrupt */
296 sc->irqid = 0;
297 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
298 RF_ACTIVE);
299
300 if (!sc->irq) {
301 device_printf(dev, "Could not allocate IRQ\n");
302 mtx_destroy(&sc->io_lock);
303 return (ENXIO);
304 }
305
306 bus_setup_intr(dev, sc->irq, INTR_TYPE_CAM | INTR_MPSAFE |
307 INTR_ENTROPY, NULL, vscsi_intr, sc, &sc->irq_cookie);
308
309 /* Data DMA */
310 error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
311 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, BUS_SPACE_MAXSIZE,
312 256, BUS_SPACE_MAXSIZE_32BIT, 0, busdma_lock_mutex, &sc->io_lock,
313 &sc->data_tag);
314
315 TAILQ_INIT(&sc->active_xferq);
316 TAILQ_INIT(&sc->free_xferq);
317
318 /* First XFER for login data */
319 sc->loginxp.sc = sc;
320 bus_dmamap_create(sc->data_tag, 0, &sc->loginxp.dmamap);
321 TAILQ_INSERT_TAIL(&sc->free_xferq, &sc->loginxp, queue);
322
323 /* CRQ area */
324 error = bus_dma_tag_create(bus_get_dma_tag(dev), PAGE_SIZE, 0,
325 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, 8*PAGE_SIZE,
326 1, BUS_SPACE_MAXSIZE, 0, NULL, NULL, &sc->crq_tag);
327 error = bus_dmamem_alloc(sc->crq_tag, (void **)&sc->crq_queue,
328 BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->crq_map);
329 sc->crq_phys = 0;
330 sc->n_crqs = 0;
331 error = bus_dmamap_load(sc->crq_tag, sc->crq_map, sc->crq_queue,
332 8*PAGE_SIZE, vscsi_crq_load_cb, sc, 0);
333
334 mtx_lock(&sc->io_lock);
335 vscsi_setup_bus(sc);
336 sc->xfer = malloc(sizeof(sc->xfer[0])*sc->max_transactions, M_VSCSI,
337 M_NOWAIT);
338 for (i = 0; i < sc->max_transactions; i++) {
339 xp = &sc->xfer[i];
340 xp->sc = sc;
341
342 error = bus_dmamap_create(sc->data_tag, 0, &xp->dmamap);
343 if (error) {
344 device_printf(dev, "Could not create DMA map (%d)\n",
345 error);
346 break;
347 }
348
349 TAILQ_INSERT_TAIL(&sc->free_xferq, xp, queue);
350 }
351 mtx_unlock(&sc->io_lock);
352
353 /* Allocate CAM bits */
354 if ((sc->devq = cam_simq_alloc(sc->max_transactions)) == NULL)
355 return (ENOMEM);
356
357 sc->sim = cam_sim_alloc(vscsi_cam_action, vscsi_cam_poll, "vscsi", sc,
358 device_get_unit(dev), &sc->io_lock,
359 sc->max_transactions, sc->max_transactions,
360 sc->devq);
361 if (sc->sim == NULL) {
362 cam_simq_free(sc->devq);
363 sc->devq = NULL;
364 device_printf(dev, "CAM SIM attach failed\n");
365 return (EINVAL);
366 }
367
368 mtx_lock(&sc->io_lock);
369 if (xpt_bus_register(sc->sim, dev, 0) != 0) {
370 device_printf(dev, "XPT bus registration failed\n");
371 cam_sim_free(sc->sim, FALSE);
372 sc->sim = NULL;
373 cam_simq_free(sc->devq);
374 sc->devq = NULL;
375 mtx_unlock(&sc->io_lock);
376 return (EINVAL);
377 }
378 mtx_unlock(&sc->io_lock);
379
380 return (0);
381 }
382
383 static int
vscsi_detach(device_t dev)384 vscsi_detach(device_t dev)
385 {
386 struct vscsi_softc *sc;
387
388 sc = device_get_softc(dev);
389 if (sc == NULL)
390 return (EINVAL);
391
392 if (sc->sim != NULL) {
393 mtx_lock(&sc->io_lock);
394 xpt_bus_deregister(cam_sim_path(sc->sim));
395 cam_sim_free(sc->sim, FALSE);
396 sc->sim = NULL;
397 mtx_unlock(&sc->io_lock);
398 }
399
400 if (sc->devq != NULL) {
401 cam_simq_free(sc->devq);
402 sc->devq = NULL;
403 }
404
405 mtx_destroy(&sc->io_lock);
406
407 return (0);
408 }
409
410 static void
vscsi_cam_action(struct cam_sim * sim,union ccb * ccb)411 vscsi_cam_action(struct cam_sim *sim, union ccb *ccb)
412 {
413 struct vscsi_softc *sc = cam_sim_softc(sim);
414
415 mtx_assert(&sc->io_lock, MA_OWNED);
416
417 switch (ccb->ccb_h.func_code) {
418 case XPT_PATH_INQ:
419 {
420 struct ccb_pathinq *cpi = &ccb->cpi;
421
422 cpi->version_num = 1;
423 cpi->hba_inquiry = PI_TAG_ABLE;
424 cpi->hba_misc = PIM_EXTLUNS;
425 cpi->target_sprt = 0;
426 cpi->hba_eng_cnt = 0;
427 cpi->max_target = 0;
428 cpi->max_lun = 0;
429 cpi->initiator_id = ~0;
430 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
431 strlcpy(cpi->hba_vid, "IBM", HBA_IDLEN);
432 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
433 cpi->unit_number = cam_sim_unit(sim);
434 cpi->bus_id = cam_sim_bus(sim);
435 cpi->base_transfer_speed = 150000;
436 cpi->transport = XPORT_SRP;
437 cpi->transport_version = 0;
438 cpi->protocol = PROTO_SCSI;
439 cpi->protocol_version = SCSI_REV_SPC4;
440 cpi->ccb_h.status = CAM_REQ_CMP;
441 break;
442 }
443 case XPT_RESET_BUS:
444 ccb->ccb_h.status = CAM_REQ_CMP;
445 break;
446 case XPT_RESET_DEV:
447 ccb->ccb_h.status = CAM_REQ_INPROG;
448 vscsi_task_management(sc, ccb);
449 return;
450 case XPT_GET_TRAN_SETTINGS:
451 ccb->cts.protocol = PROTO_SCSI;
452 ccb->cts.protocol_version = SCSI_REV_SPC4;
453 ccb->cts.transport = XPORT_SRP;
454 ccb->cts.transport_version = 0;
455 ccb->cts.proto_specific.valid = 0;
456 ccb->cts.xport_specific.valid = 0;
457 ccb->ccb_h.status = CAM_REQ_CMP;
458 break;
459 case XPT_SET_TRAN_SETTINGS:
460 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
461 break;
462 case XPT_SCSI_IO:
463 {
464 struct vscsi_xfer *xp;
465
466 ccb->ccb_h.status = CAM_REQ_INPROG;
467
468 xp = TAILQ_FIRST(&sc->free_xferq);
469 if (xp == NULL)
470 panic("SCSI queue flooded");
471 xp->ccb = ccb;
472 TAILQ_REMOVE(&sc->free_xferq, xp, queue);
473 TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue);
474 bus_dmamap_load_ccb(sc->data_tag, xp->dmamap,
475 ccb, vscsi_scsi_command, xp, 0);
476
477 return;
478 }
479 default:
480 ccb->ccb_h.status = CAM_REQ_INVALID;
481 break;
482 }
483
484 xpt_done(ccb);
485 return;
486 }
487
488 static void
vscsi_srp_login(struct vscsi_softc * sc)489 vscsi_srp_login(struct vscsi_softc *sc)
490 {
491 struct vscsi_xfer *xp;
492 struct srp_login *login;
493 struct vscsi_crq crq;
494 int err;
495
496 mtx_assert(&sc->io_lock, MA_OWNED);
497
498 xp = TAILQ_FIRST(&sc->free_xferq);
499 if (xp == NULL)
500 panic("SCSI queue flooded");
501 xp->ccb = NULL;
502 TAILQ_REMOVE(&sc->free_xferq, xp, queue);
503 TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue);
504
505 /* Set up command */
506 xp->srp_iu_size = 64;
507 crq.iu_length = htobe16(xp->srp_iu_size);
508 err = vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size,
509 M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset);
510 if (err)
511 panic("Error during VMEM allocation (%d)", err);
512
513 login = (struct srp_login *)((uint8_t *)xp->sc->srp_iu_queue +
514 (uintptr_t)xp->srp_iu_offset);
515 bzero(login, xp->srp_iu_size);
516 login->type = SRP_LOGIN_REQ;
517 login->tag = (uint64_t)(xp);
518 login->max_cmd_length = htobe64(256);
519 login->buffer_formats = htobe16(0x1 | 0x2); /* Direct and indirect */
520 login->flags = 0;
521
522 /* Create CRQ entry */
523 crq.valid = 0x80;
524 crq.format = 0x01;
525 crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset);
526 bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE);
527
528 err = phyp_hcall(H_SEND_CRQ, xp->sc->unit,
529 be64toh(((uint64_t *)(&crq))[0]),
530 be64toh(((uint64_t *)(&crq))[1]));
531 if (err != 0)
532 panic("CRQ send failure (%d)", err);
533 }
534
535 static void
vscsi_task_management(struct vscsi_softc * sc,union ccb * ccb)536 vscsi_task_management(struct vscsi_softc *sc, union ccb *ccb)
537 {
538 struct srp_tsk_mgmt *cmd;
539 struct vscsi_xfer *xp;
540 struct vscsi_crq crq;
541 int err;
542
543 mtx_assert(&sc->io_lock, MA_OWNED);
544
545 xp = TAILQ_FIRST(&sc->free_xferq);
546 if (xp == NULL)
547 panic("SCSI queue flooded");
548 xp->ccb = ccb;
549 TAILQ_REMOVE(&sc->free_xferq, xp, queue);
550 TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue);
551
552 xp->srp_iu_size = sizeof(*cmd);
553 crq.iu_length = htobe16(xp->srp_iu_size);
554 err = vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size,
555 M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset);
556 if (err)
557 panic("Error during VMEM allocation (%d)", err);
558
559 cmd = (struct srp_tsk_mgmt *)((uint8_t *)xp->sc->srp_iu_queue +
560 (uintptr_t)xp->srp_iu_offset);
561 bzero(cmd, xp->srp_iu_size);
562 cmd->type = SRP_TSK_MGMT;
563 cmd->tag = (uint64_t)xp;
564 cmd->lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
565
566 switch (ccb->ccb_h.func_code) {
567 case XPT_RESET_DEV:
568 cmd->function = 0x08;
569 break;
570 default:
571 panic("Unimplemented code %d", ccb->ccb_h.func_code);
572 break;
573 }
574
575 bus_dmamap_sync(xp->sc->crq_tag, xp->sc->crq_map, BUS_DMASYNC_PREWRITE);
576
577 /* Create CRQ entry */
578 crq.valid = 0x80;
579 crq.format = 0x01;
580 crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset);
581
582 err = phyp_hcall(H_SEND_CRQ, xp->sc->unit,
583 be64toh(((uint64_t *)(&crq))[0]),
584 be64toh(((uint64_t *)(&crq))[1]));
585 if (err != 0)
586 panic("CRQ send failure (%d)", err);
587 }
588
589 static void
vscsi_scsi_command(void * xxp,bus_dma_segment_t * segs,int nsegs,int err)590 vscsi_scsi_command(void *xxp, bus_dma_segment_t *segs, int nsegs, int err)
591 {
592 struct vscsi_xfer *xp = xxp;
593 uint8_t *cdb;
594 union ccb *ccb = xp->ccb;
595 struct srp_cmd *cmd;
596 uint64_t chunk_addr;
597 uint32_t chunk_size;
598 int desc_start, i;
599 struct vscsi_crq crq;
600
601 KASSERT(err == 0, ("DMA error %d\n", err));
602
603 mtx_assert(&xp->sc->io_lock, MA_OWNED);
604
605 cdb = (ccb->ccb_h.flags & CAM_CDB_POINTER) ?
606 ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes;
607
608 /* Command format from Table 20, page 37 of SRP spec */
609 xp->srp_iu_size = 48 + ((nsegs > 1) ? 20 : 16) +
610 ((ccb->csio.cdb_len > 16) ? (ccb->csio.cdb_len - 16) : 0);
611 crq.iu_length = htobe16(xp->srp_iu_size);
612 if (nsegs > 1)
613 xp->srp_iu_size += nsegs*16;
614 xp->srp_iu_size = roundup(xp->srp_iu_size, 16);
615 err = vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size,
616 M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset);
617 if (err)
618 panic("Error during VMEM allocation (%d)", err);
619
620 cmd = (struct srp_cmd *)((uint8_t *)xp->sc->srp_iu_queue +
621 (uintptr_t)xp->srp_iu_offset);
622 bzero(cmd, xp->srp_iu_size);
623 cmd->type = SRP_CMD;
624 if (ccb->csio.cdb_len > 16)
625 cmd->additional_cdb = (ccb->csio.cdb_len - 16) << 2;
626 memcpy(cmd->cdb, cdb, ccb->csio.cdb_len);
627
628 cmd->tag = (uint64_t)(xp); /* Let the responder find this again */
629 cmd->lun = htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
630
631 if (nsegs > 1) {
632 /* Use indirect descriptors */
633 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
634 case CAM_DIR_OUT:
635 cmd->formats = (2 << 4);
636 break;
637 case CAM_DIR_IN:
638 cmd->formats = 2;
639 break;
640 default:
641 panic("Does not support bidirectional commands (%d)",
642 ccb->ccb_h.flags & CAM_DIR_MASK);
643 break;
644 }
645
646 desc_start = ((ccb->csio.cdb_len > 16) ?
647 ccb->csio.cdb_len - 16 : 0);
648 chunk_addr = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset + 20 +
649 desc_start + sizeof(*cmd));
650 chunk_size = htobe32(16*nsegs);
651 memcpy(&cmd->data_payload[desc_start], &chunk_addr, 8);
652 memcpy(&cmd->data_payload[desc_start+12], &chunk_size, 4);
653 chunk_size = 0;
654 for (i = 0; i < nsegs; i++)
655 chunk_size += segs[i].ds_len;
656 chunk_size = htobe32(chunk_size);
657 memcpy(&cmd->data_payload[desc_start+16], &chunk_size, 4);
658 desc_start += 20;
659 for (i = 0; i < nsegs; i++) {
660 chunk_addr = htobe64(segs[i].ds_addr);
661 chunk_size = htobe32(segs[i].ds_len);
662
663 memcpy(&cmd->data_payload[desc_start + 16*i],
664 &chunk_addr, 8);
665 /* Set handle tag to 0 */
666 memcpy(&cmd->data_payload[desc_start + 16*i + 12],
667 &chunk_size, 4);
668 }
669 } else if (nsegs == 1) {
670 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
671 case CAM_DIR_OUT:
672 cmd->formats = (1 << 4);
673 break;
674 case CAM_DIR_IN:
675 cmd->formats = 1;
676 break;
677 default:
678 panic("Does not support bidirectional commands (%d)",
679 ccb->ccb_h.flags & CAM_DIR_MASK);
680 break;
681 }
682
683 /*
684 * Memory descriptor:
685 * 8 byte address
686 * 4 byte handle
687 * 4 byte length
688 */
689
690 chunk_addr = htobe64(segs[0].ds_addr);
691 chunk_size = htobe32(segs[0].ds_len);
692 desc_start = ((ccb->csio.cdb_len > 16) ?
693 ccb->csio.cdb_len - 16 : 0);
694
695 memcpy(&cmd->data_payload[desc_start], &chunk_addr, 8);
696 /* Set handle tag to 0 */
697 memcpy(&cmd->data_payload[desc_start+12], &chunk_size, 4);
698 KASSERT(xp->srp_iu_size >= 48 + ((ccb->csio.cdb_len > 16) ?
699 ccb->csio.cdb_len : 16), ("SRP IU command length"));
700 } else {
701 cmd->formats = 0;
702 }
703 bus_dmamap_sync(xp->sc->crq_tag, xp->sc->crq_map, BUS_DMASYNC_PREWRITE);
704
705 /* Create CRQ entry */
706 crq.valid = 0x80;
707 crq.format = 0x01;
708 crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset);
709
710 err = phyp_hcall(H_SEND_CRQ, xp->sc->unit,
711 be64toh(((uint64_t *)(&crq))[0]),
712 be64toh(((uint64_t *)(&crq))[1]));
713 if (err != 0)
714 panic("CRQ send failure (%d)", err);
715 }
716
717 static void
vscsi_crq_load_cb(void * xsc,bus_dma_segment_t * segs,int nsegs,int err)718 vscsi_crq_load_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int err)
719 {
720 struct vscsi_softc *sc = xsc;
721
722 sc->crq_phys = segs[0].ds_addr;
723 sc->n_crqs = PAGE_SIZE/sizeof(struct vscsi_crq);
724
725 sc->srp_iu_queue = (uint8_t *)(sc->crq_queue);
726 sc->srp_iu_phys = segs[0].ds_addr;
727 sc->srp_iu_arena = vmem_create("VSCSI SRP IU", PAGE_SIZE,
728 segs[0].ds_len - PAGE_SIZE, 16, 0, M_BESTFIT | M_NOWAIT);
729 }
730
731 static void
vscsi_setup_bus(struct vscsi_softc * sc)732 vscsi_setup_bus(struct vscsi_softc *sc)
733 {
734 struct vscsi_crq crq;
735 struct vscsi_xfer *xp;
736 int error;
737
738 struct {
739 uint32_t type;
740 uint16_t status;
741 uint16_t length;
742 uint64_t tag;
743 uint64_t buffer;
744 struct {
745 char srp_version[8];
746 char partition_name[96];
747 uint32_t partition_number;
748 uint32_t mad_version;
749 uint32_t os_type;
750 uint32_t port_max_txu[8];
751 } payload;
752 } mad_adapter_info;
753
754 bzero(&crq, sizeof(crq));
755
756 /* Init message */
757 crq.valid = 0xc0;
758 crq.format = 0x01;
759
760 do {
761 error = phyp_hcall(H_FREE_CRQ, sc->unit);
762 } while (error == H_BUSY);
763
764 /* See initialization sequence page 757 */
765 bzero(sc->crq_queue, sc->n_crqs*sizeof(sc->crq_queue[0]));
766 sc->cur_crq = 0;
767 sc->bus_initialized = 0;
768 sc->bus_logged_in = 0;
769 bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE);
770 error = phyp_hcall(H_REG_CRQ, sc->unit, sc->crq_phys,
771 sc->n_crqs*sizeof(sc->crq_queue[0]));
772 KASSERT(error == 0, ("CRQ registration success"));
773
774 error = phyp_hcall(H_SEND_CRQ, sc->unit,
775 be64toh(((uint64_t *)(&crq))[0]),
776 be64toh(((uint64_t *)(&crq))[1]));
777 if (error != 0)
778 panic("CRQ setup failure (%d)", error);
779
780 while (sc->bus_initialized == 0)
781 vscsi_check_response_queue(sc);
782
783 /* Send MAD adapter info */
784 mad_adapter_info.type = htobe32(MAD_ADAPTER_INFO_REQUEST);
785 mad_adapter_info.status = 0;
786 mad_adapter_info.length = htobe16(sizeof(mad_adapter_info.payload));
787
788 strcpy(mad_adapter_info.payload.srp_version, "16.a");
789 strcpy(mad_adapter_info.payload.partition_name, "UNKNOWN");
790 mad_adapter_info.payload.partition_number = -1;
791 mad_adapter_info.payload.mad_version = htobe32(1);
792 mad_adapter_info.payload.os_type = htobe32(2); /* Claim we are Linux */
793 mad_adapter_info.payload.port_max_txu[0] = 0;
794 /* If this fails, we get the defaults above */
795 OF_getprop(OF_finddevice("/"), "ibm,partition-name",
796 mad_adapter_info.payload.partition_name,
797 sizeof(mad_adapter_info.payload.partition_name));
798 OF_getprop(OF_finddevice("/"), "ibm,partition-no",
799 &mad_adapter_info.payload.partition_number,
800 sizeof(mad_adapter_info.payload.partition_number));
801
802 xp = TAILQ_FIRST(&sc->free_xferq);
803 xp->ccb = NULL;
804 TAILQ_REMOVE(&sc->free_xferq, xp, queue);
805 TAILQ_INSERT_TAIL(&sc->active_xferq, xp, queue);
806 xp->srp_iu_size = sizeof(mad_adapter_info);
807 crq.iu_length = htobe16(xp->srp_iu_size);
808 vmem_alloc(xp->sc->srp_iu_arena, xp->srp_iu_size,
809 M_BESTFIT | M_NOWAIT, &xp->srp_iu_offset);
810 mad_adapter_info.buffer = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset + 24);
811 mad_adapter_info.tag = (uint64_t)xp;
812 memcpy((uint8_t *)xp->sc->srp_iu_queue + (uintptr_t)xp->srp_iu_offset,
813 &mad_adapter_info, sizeof(mad_adapter_info));
814 crq.valid = 0x80;
815 crq.format = 0x02;
816 crq.iu_data = htobe64(xp->sc->srp_iu_phys + xp->srp_iu_offset);
817 bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE);
818 phyp_hcall(H_SEND_CRQ, xp->sc->unit,
819 be64toh(((uint64_t *)(&crq))[0]),
820 be64toh(((uint64_t *)(&crq))[1]));
821
822 while (TAILQ_EMPTY(&sc->free_xferq))
823 vscsi_check_response_queue(sc);
824
825 /* Send SRP login */
826 vscsi_srp_login(sc);
827 while (sc->bus_logged_in == 0)
828 vscsi_check_response_queue(sc);
829
830 error = phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); /* Enable interrupts */
831 }
832
833 static void
vscsi_intr(void * xsc)834 vscsi_intr(void *xsc)
835 {
836 struct vscsi_softc *sc = xsc;
837
838 mtx_lock(&sc->io_lock);
839 vscsi_check_response_queue(sc);
840 mtx_unlock(&sc->io_lock);
841 }
842
843 static void
vscsi_srp_response(struct vscsi_xfer * xp,struct vscsi_crq * crq)844 vscsi_srp_response(struct vscsi_xfer *xp, struct vscsi_crq *crq)
845 {
846 union ccb *ccb = xp->ccb;
847 struct vscsi_softc *sc = xp->sc;
848 struct srp_rsp *rsp;
849 uint32_t sense_len;
850
851 /* SRP response packet in original request */
852 rsp = (struct srp_rsp *)((uint8_t *)sc->srp_iu_queue +
853 (uintptr_t)xp->srp_iu_offset);
854 ccb->csio.scsi_status = rsp->status;
855 if (ccb->csio.scsi_status == SCSI_STATUS_OK)
856 ccb->ccb_h.status = CAM_REQ_CMP;
857 else
858 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
859 #ifdef NOTYET
860 /* Collect fast fail codes */
861 if (crq->status != 0)
862 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
863 #endif
864
865 if (ccb->ccb_h.status != CAM_REQ_CMP) {
866 ccb->ccb_h.status |= CAM_DEV_QFRZN;
867 xpt_freeze_devq(ccb->ccb_h.path, /*count*/ 1);
868 }
869
870 if (!(rsp->flags & SRP_RSPVALID))
871 rsp->response_data_len = 0;
872 if (!(rsp->flags & SRP_SNSVALID))
873 rsp->sense_data_len = 0;
874 if (!(rsp->flags & (SRP_DOOVER | SRP_DOUNDER)))
875 rsp->data_out_resid = 0;
876 if (!(rsp->flags & (SRP_DIOVER | SRP_DIUNDER)))
877 rsp->data_in_resid = 0;
878
879 if (rsp->flags & SRP_SNSVALID) {
880 bzero(&ccb->csio.sense_data, sizeof(struct scsi_sense_data));
881 ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
882 sense_len = min(be32toh(rsp->sense_data_len),
883 ccb->csio.sense_len);
884 memcpy(&ccb->csio.sense_data,
885 &rsp->data_payload[be32toh(rsp->response_data_len)],
886 sense_len);
887 ccb->csio.sense_resid = ccb->csio.sense_len -
888 be32toh(rsp->sense_data_len);
889 }
890
891 switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
892 case CAM_DIR_OUT:
893 ccb->csio.resid = rsp->data_out_resid;
894 break;
895 case CAM_DIR_IN:
896 ccb->csio.resid = rsp->data_in_resid;
897 break;
898 }
899
900 bus_dmamap_sync(sc->data_tag, xp->dmamap, BUS_DMASYNC_POSTREAD);
901 bus_dmamap_unload(sc->data_tag, xp->dmamap);
902 xpt_done(ccb);
903 xp->ccb = NULL;
904 }
905
906 static void
vscsi_login_response(struct vscsi_xfer * xp,struct vscsi_crq * crq)907 vscsi_login_response(struct vscsi_xfer *xp, struct vscsi_crq *crq)
908 {
909 struct vscsi_softc *sc = xp->sc;
910 struct srp_login_rsp *rsp;
911
912 /* SRP response packet in original request */
913 rsp = (struct srp_login_rsp *)((uint8_t *)sc->srp_iu_queue +
914 (uintptr_t)xp->srp_iu_offset);
915 KASSERT(be16toh(rsp->buffer_formats) & 0x3, ("Both direct and indirect "
916 "buffers supported"));
917
918 sc->max_transactions = be32toh(rsp->request_limit_delta);
919 device_printf(sc->dev, "Queue depth %d commands\n",
920 sc->max_transactions);
921 sc->bus_logged_in = 1;
922 }
923
924 static void
vscsi_cam_poll(struct cam_sim * sim)925 vscsi_cam_poll(struct cam_sim *sim)
926 {
927 struct vscsi_softc *sc = cam_sim_softc(sim);
928
929 vscsi_check_response_queue(sc);
930 }
931
932 static void
vscsi_check_response_queue(struct vscsi_softc * sc)933 vscsi_check_response_queue(struct vscsi_softc *sc)
934 {
935 struct vscsi_crq *crq;
936 struct vscsi_xfer *xp;
937 int code;
938
939 mtx_assert(&sc->io_lock, MA_OWNED);
940
941 while (sc->crq_queue[sc->cur_crq].valid != 0) {
942 /* The hypercalls at both ends of this are not optimal */
943 phyp_hcall(H_VIO_SIGNAL, sc->unit, 0);
944 bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_POSTREAD);
945
946 crq = &sc->crq_queue[sc->cur_crq];
947
948 switch (crq->valid) {
949 case 0xc0:
950 if (crq->format == 0x02)
951 sc->bus_initialized = 1;
952 break;
953 case 0x80:
954 /* IU data is set to tag pointer (the XP) */
955 xp = (struct vscsi_xfer *)crq->iu_data;
956
957 switch (crq->format) {
958 case 0x01:
959 code = *((uint8_t *)sc->srp_iu_queue +
960 (uintptr_t)xp->srp_iu_offset);
961 switch (code) {
962 case SRP_RSP:
963 vscsi_srp_response(xp, crq);
964 break;
965 case SRP_LOGIN_RSP:
966 vscsi_login_response(xp, crq);
967 break;
968 default:
969 device_printf(sc->dev, "Unknown SRP "
970 "response code %d\n", code);
971 break;
972 }
973 break;
974 case 0x02:
975 /* Ignore management datagrams */
976 break;
977 default:
978 panic("Unknown CRQ format %d\n", crq->format);
979 break;
980 }
981 vmem_free(sc->srp_iu_arena, xp->srp_iu_offset,
982 xp->srp_iu_size);
983 TAILQ_REMOVE(&sc->active_xferq, xp, queue);
984 TAILQ_INSERT_TAIL(&sc->free_xferq, xp, queue);
985 break;
986 default:
987 device_printf(sc->dev,
988 "Unknown CRQ message type %d\n", crq->valid);
989 break;
990 }
991
992 crq->valid = 0;
993 sc->cur_crq = (sc->cur_crq + 1) % sc->n_crqs;
994
995 bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE);
996 phyp_hcall(H_VIO_SIGNAL, sc->unit, 1);
997 }
998 }
999