| @@ -1,34 +1,34 @@ | | | @@ -1,34 +1,34 @@ |
1 | /* $NetBSD: vioscsi.c,v 1.7 2016/10/04 18:20:49 jdolecek Exp $ */ | | 1 | /* $NetBSD: vioscsi.c,v 1.8 2016/10/04 18:23:24 jdolecek Exp $ */ |
2 | /* $OpenBSD: vioscsi.c,v 1.3 2015/03/14 03:38:49 jsg Exp $ */ | | 2 | /* $OpenBSD: vioscsi.c,v 1.3 2015/03/14 03:38:49 jsg Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (c) 2013 Google Inc. | | 5 | * Copyright (c) 2013 Google Inc. |
6 | * | | 6 | * |
7 | * Permission to use, copy, modify, and distribute this software for any | | 7 | * Permission to use, copy, modify, and distribute this software for any |
8 | * purpose with or without fee is hereby granted, provided that the above | | 8 | * purpose with or without fee is hereby granted, provided that the above |
9 | * copyright notice and this permission notice appear in all copies. | | 9 | * copyright notice and this permission notice appear in all copies. |
10 | * | | 10 | * |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | | 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | | 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | | 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | | 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | | 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | | 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
18 | */ | | 18 | */ |
19 | | | 19 | |
20 | #include <sys/cdefs.h> | | 20 | #include <sys/cdefs.h> |
21 | __KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.7 2016/10/04 18:20:49 jdolecek Exp $"); | | 21 | __KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.8 2016/10/04 18:23:24 jdolecek Exp $"); |
22 | | | 22 | |
23 | #include <sys/param.h> | | 23 | #include <sys/param.h> |
24 | #include <sys/systm.h> | | 24 | #include <sys/systm.h> |
25 | #include <sys/device.h> | | 25 | #include <sys/device.h> |
26 | #include <sys/bus.h> | | 26 | #include <sys/bus.h> |
27 | #include <sys/buf.h> | | 27 | #include <sys/buf.h> |
28 | | | 28 | |
29 | #include <dev/pci/pcidevs.h> | | 29 | #include <dev/pci/pcidevs.h> |
30 | #include <dev/pci/pcireg.h> | | 30 | #include <dev/pci/pcireg.h> |
31 | #include <dev/pci/pcivar.h> | | 31 | #include <dev/pci/pcivar.h> |
32 | | | 32 | |
33 | #include <dev/pci/vioscsireg.h> | | 33 | #include <dev/pci/vioscsireg.h> |
34 | #include <dev/pci/virtiovar.h> | | 34 | #include <dev/pci/virtiovar.h> |
| @@ -209,27 +209,39 @@ vioscsi_scsipi_request(struct scsipi_cha | | | @@ -209,27 +209,39 @@ vioscsi_scsipi_request(struct scsipi_cha |
209 | { | | 209 | { |
210 | struct vioscsi_softc *sc = | | 210 | struct vioscsi_softc *sc = |
211 | device_private(chan->chan_adapter->adapt_dev); | | 211 | device_private(chan->chan_adapter->adapt_dev); |
212 | struct virtio_softc *vsc = device_private(device_parent(sc->sc_dev)); | | 212 | struct virtio_softc *vsc = device_private(device_parent(sc->sc_dev)); |
213 | struct scsipi_xfer *xs; | | 213 | struct scsipi_xfer *xs; |
214 | struct scsipi_periph *periph; | | 214 | struct scsipi_periph *periph; |
215 | struct vioscsi_req *vr; | | 215 | struct vioscsi_req *vr; |
216 | struct virtio_scsi_req_hdr *req; | | 216 | struct virtio_scsi_req_hdr *req; |
217 | struct virtqueue *vq = &sc->sc_vqs[2]; | | 217 | struct virtqueue *vq = &sc->sc_vqs[2]; |
218 | int slot, error; | | 218 | int slot, error; |
219 | | | 219 | |
220 | DPRINTF(("%s: enter\n", __func__)); | | 220 | DPRINTF(("%s: enter\n", __func__)); |
221 | | | 221 | |
222 | if (request != ADAPTER_REQ_RUN_XFER) { | | 222 | switch (request) { |
| | | 223 | case ADAPTER_REQ_RUN_XFER: |
| | | 224 | break; |
| | | 225 | case ADAPTER_REQ_SET_XFER_MODE: |
| | | 226 | { |
| | | 227 | struct scsipi_xfer_mode *xm = arg; |
| | | 228 | xm->xm_mode = PERIPH_CAP_TQING; |
| | | 229 | xm->xm_period = 0; |
| | | 230 | xm->xm_offset = 0; |
| | | 231 | scsipi_async_event(chan, ASYNC_EVENT_XFER_MODE, xm); |
| | | 232 | return; |
| | | 233 | } |
| | | 234 | default: |
223 | DPRINTF(("%s: unhandled %d\n", __func__, request)); | | 235 | DPRINTF(("%s: unhandled %d\n", __func__, request)); |
224 | return; | | 236 | return; |
225 | } | | 237 | } |
226 | | | 238 | |
227 | xs = arg; | | 239 | xs = arg; |
228 | periph = xs->xs_periph; | | 240 | periph = xs->xs_periph; |
229 | | | 241 | |
230 | vr = vioscsi_req_get(sc); | | 242 | vr = vioscsi_req_get(sc); |
231 | /* | | 243 | /* |
232 | * This can happen when we run out of queue slots. | | 244 | * This can happen when we run out of queue slots. |
233 | */ | | 245 | */ |
234 | if (vr == NULL) { | | 246 | if (vr == NULL) { |
235 | xs->error = XS_RESOURCE_SHORTAGE; | | 247 | xs->error = XS_RESOURCE_SHORTAGE; |
| @@ -250,26 +262,49 @@ vioscsi_scsipi_request(struct scsipi_cha | | | @@ -250,26 +262,49 @@ vioscsi_scsipi_request(struct scsipi_cha |
250 | if (periph->periph_target >= 256 || periph->periph_lun >= 16384) { | | 262 | if (periph->periph_target >= 256 || periph->periph_lun >= 16384) { |
251 | DPRINTF(("%s: bad target %u or lun %u\n", __func__, | | 263 | DPRINTF(("%s: bad target %u or lun %u\n", __func__, |
252 | periph->periph_target, periph->periph_lun)); | | 264 | periph->periph_target, periph->periph_lun)); |
253 | goto stuffup; | | 265 | goto stuffup; |
254 | } | | 266 | } |
255 | req->lun[0] = 1; | | 267 | req->lun[0] = 1; |
256 | req->lun[1] = periph->periph_target - 1; | | 268 | req->lun[1] = periph->periph_target - 1; |
257 | req->lun[2] = 0x40 | (periph->periph_lun >> 8); | | 269 | req->lun[2] = 0x40 | (periph->periph_lun >> 8); |
258 | req->lun[3] = periph->periph_lun; | | 270 | req->lun[3] = periph->periph_lun; |
259 | memset(req->lun + 4, 0, 4); | | 271 | memset(req->lun + 4, 0, 4); |
260 | DPRINTF(("%s: command for %u:%u at slot %d\n", __func__, | | 272 | DPRINTF(("%s: command for %u:%u at slot %d\n", __func__, |
261 | periph->periph_target - 1, periph->periph_lun, slot)); | | 273 | periph->periph_target - 1, periph->periph_lun, slot)); |
262 | | | 274 | |
| | | 275 | /* tag */ |
| | | 276 | switch (XS_CTL_TAGTYPE(xs)) { |
| | | 277 | case XS_CTL_HEAD_TAG: |
| | | 278 | req->task_attr = VIRTIO_SCSI_S_HEAD; |
| | | 279 | break; |
| | | 280 | |
| | | 281 | #if 0 /* XXX */ |
| | | 282 | case XS_CTL_ACA_TAG: |
| | | 283 | req->task_attr = VIRTIO_SCSI_S_ACA; |
| | | 284 | break; |
| | | 285 | #endif |
| | | 286 | |
| | | 287 | case XS_CTL_ORDERED_TAG: |
| | | 288 | req->task_attr = VIRTIO_SCSI_S_ORDERED; |
| | | 289 | break; |
| | | 290 | |
| | | 291 | case XS_CTL_SIMPLE_TAG: |
| | | 292 | default: |
| | | 293 | req->task_attr = VIRTIO_SCSI_S_SIMPLE; |
| | | 294 | break; |
| | | 295 | } |
| | | 296 | req->id = (intptr_t)vr; |
| | | 297 | |
263 | if ((size_t)xs->cmdlen > sizeof(req->cdb)) { | | 298 | if ((size_t)xs->cmdlen > sizeof(req->cdb)) { |
264 | DPRINTF(("%s: bad cmdlen %zu > %zu\n", __func__, | | 299 | DPRINTF(("%s: bad cmdlen %zu > %zu\n", __func__, |
265 | (size_t)xs->cmdlen, sizeof(req->cdb))); | | 300 | (size_t)xs->cmdlen, sizeof(req->cdb))); |
266 | goto stuffup; | | 301 | goto stuffup; |
267 | } | | 302 | } |
268 | | | 303 | |
269 | memset(req->cdb, 0, sizeof(req->cdb)); | | 304 | memset(req->cdb, 0, sizeof(req->cdb)); |
270 | memcpy(req->cdb, xs->cmd, xs->cmdlen); | | 305 | memcpy(req->cdb, xs->cmd, xs->cmdlen); |
271 | | | 306 | |
272 | error = bus_dmamap_load(vsc->sc_dmat, vr->vr_data, | | 307 | error = bus_dmamap_load(vsc->sc_dmat, vr->vr_data, |
273 | xs->data, xs->datalen, NULL, XS2DMA(xs)); | | 308 | xs->data, xs->datalen, NULL, XS2DMA(xs)); |
274 | switch (error) { | | 309 | switch (error) { |
275 | case 0: | | 310 | case 0: |