| @@ -1,33 +1,34 @@ | | | @@ -1,33 +1,34 @@ |
| | | 1 | /* $NetBSD: vioscsi.c,v 1.7 2016/10/04 18:20:49 jdolecek Exp $ */ |
1 | /* $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 $ */ |
2 | | | 3 | |
3 | /* | | 4 | /* |
4 | * Copyright (c) 2013 Google Inc. | | 5 | * Copyright (c) 2013 Google Inc. |
5 | * | | 6 | * |
6 | * Permission to use, copy, modify, and distribute this software for any | | 7 | * Permission to use, copy, modify, and distribute this software for any |
7 | * 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 |
8 | * copyright notice and this permission notice appear in all copies. | | 9 | * copyright notice and this permission notice appear in all copies. |
9 | * | | 10 | * |
10 | * 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 |
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | | 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 | * 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 |
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | | 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 | * 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 |
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | | 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | | 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 | */ | | 18 | */ |
18 | | | 19 | |
19 | #include <sys/cdefs.h> | | 20 | #include <sys/cdefs.h> |
20 | __KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.6 2015/11/01 08:55:05 pooka Exp $"); | | 21 | __KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.7 2016/10/04 18:20:49 jdolecek Exp $"); |
21 | | | 22 | |
22 | #include <sys/param.h> | | 23 | #include <sys/param.h> |
23 | #include <sys/systm.h> | | 24 | #include <sys/systm.h> |
24 | #include <sys/device.h> | | 25 | #include <sys/device.h> |
25 | #include <sys/bus.h> | | 26 | #include <sys/bus.h> |
26 | #include <sys/buf.h> | | 27 | #include <sys/buf.h> |
27 | | | 28 | |
28 | #include <dev/pci/pcidevs.h> | | 29 | #include <dev/pci/pcidevs.h> |
29 | #include <dev/pci/pcireg.h> | | 30 | #include <dev/pci/pcireg.h> |
30 | #include <dev/pci/pcivar.h> | | 31 | #include <dev/pci/pcivar.h> |
31 | | | 32 | |
32 | #include <dev/pci/vioscsireg.h> | | 33 | #include <dev/pci/vioscsireg.h> |
33 | #include <dev/pci/virtiovar.h> | | 34 | #include <dev/pci/virtiovar.h> |
| @@ -217,36 +218,35 @@ vioscsi_scsipi_request(struct scsipi_cha | | | @@ -217,36 +218,35 @@ vioscsi_scsipi_request(struct scsipi_cha |
217 | int slot, error; | | 218 | int slot, error; |
218 | | | 219 | |
219 | DPRINTF(("%s: enter\n", __func__)); | | 220 | DPRINTF(("%s: enter\n", __func__)); |
220 | | | 221 | |
221 | if (request != ADAPTER_REQ_RUN_XFER) { | | 222 | if (request != ADAPTER_REQ_RUN_XFER) { |
222 | DPRINTF(("%s: unhandled %d\n", __func__, request)); | | 223 | DPRINTF(("%s: unhandled %d\n", __func__, request)); |
223 | return; | | 224 | return; |
224 | } | | 225 | } |
225 | | | 226 | |
226 | xs = arg; | | 227 | xs = arg; |
227 | periph = xs->xs_periph; | | 228 | periph = xs->xs_periph; |
228 | | | 229 | |
229 | vr = vioscsi_req_get(sc); | | 230 | vr = vioscsi_req_get(sc); |
230 | #ifdef DIAGNOSTIC | | | |
231 | /* | | 231 | /* |
232 | * This should never happen as we track the resources | | 232 | * This can happen when we run out of queue slots. |
233 | * in the mid-layer. | | | |
234 | */ | | 233 | */ |
235 | if (vr == NULL) { | | 234 | if (vr == NULL) { |
236 | scsipi_printaddr(xs->xs_periph); | | 235 | xs->error = XS_RESOURCE_SHORTAGE; |
237 | panic("%s: unable to allocate request\n", __func__); | | 236 | scsipi_done(xs); |
| | | 237 | return; |
238 | } | | 238 | } |
239 | #endif | | 239 | |
240 | req = &vr->vr_req; | | 240 | req = &vr->vr_req; |
241 | slot = vr - sc->sc_reqs; | | 241 | slot = vr - sc->sc_reqs; |
242 | | | 242 | |
243 | vr->vr_xs = xs; | | 243 | vr->vr_xs = xs; |
244 | | | 244 | |
245 | /* | | 245 | /* |
246 | * "The only supported format for the LUN field is: first byte set to | | 246 | * "The only supported format for the LUN field is: first byte set to |
247 | * 1, second byte set to target, third and fourth byte representing a | | 247 | * 1, second byte set to target, third and fourth byte representing a |
248 | * single level LUN structure, followed by four zero bytes." | | 248 | * single level LUN structure, followed by four zero bytes." |
249 | */ | | 249 | */ |
250 | if (periph->periph_target >= 256 || periph->periph_lun >= 16384) { | | 250 | if (periph->periph_target >= 256 || periph->periph_lun >= 16384) { |
251 | DPRINTF(("%s: bad target %u or lun %u\n", __func__, | | 251 | DPRINTF(("%s: bad target %u or lun %u\n", __func__, |
252 | periph->periph_target, periph->periph_lun)); | | 252 | periph->periph_target, periph->periph_lun)); |
| @@ -274,27 +274,27 @@ vioscsi_scsipi_request(struct scsipi_cha | | | @@ -274,27 +274,27 @@ vioscsi_scsipi_request(struct scsipi_cha |
274 | switch (error) { | | 274 | switch (error) { |
275 | case 0: | | 275 | case 0: |
276 | break; | | 276 | break; |
277 | case ENOMEM: | | 277 | case ENOMEM: |
278 | case EAGAIN: | | 278 | case EAGAIN: |
279 | xs->error = XS_RESOURCE_SHORTAGE; | | 279 | xs->error = XS_RESOURCE_SHORTAGE; |
280 | goto nomore; | | 280 | goto nomore; |
281 | default: | | 281 | default: |
282 | aprint_error_dev(sc->sc_dev, "error %d loading DMA map\n", | | 282 | aprint_error_dev(sc->sc_dev, "error %d loading DMA map\n", |
283 | error); | | 283 | error); |
284 | stuffup: | | 284 | stuffup: |
285 | xs->error = XS_DRIVER_STUFFUP; | | 285 | xs->error = XS_DRIVER_STUFFUP; |
286 | nomore: | | 286 | nomore: |
287 | // XXX: free req? | | 287 | vioscsi_req_put(sc, vr); |
288 | scsipi_done(xs); | | 288 | scsipi_done(xs); |
289 | return; | | 289 | return; |
290 | } | | 290 | } |
291 | | | 291 | |
292 | int nsegs = VIRTIO_SCSI_MIN_SEGMENTS; | | 292 | int nsegs = VIRTIO_SCSI_MIN_SEGMENTS; |
293 | if ((xs->xs_control & (XS_CTL_DATA_IN|XS_CTL_DATA_OUT)) != 0) | | 293 | if ((xs->xs_control & (XS_CTL_DATA_IN|XS_CTL_DATA_OUT)) != 0) |
294 | nsegs += vr->vr_data->dm_nsegs; | | 294 | nsegs += vr->vr_data->dm_nsegs; |
295 | | | 295 | |
296 | error = virtio_enqueue_reserve(vsc, vq, slot, nsegs); | | 296 | error = virtio_enqueue_reserve(vsc, vq, slot, nsegs); |
297 | if (error) { | | 297 | if (error) { |
298 | DPRINTF(("%s: error reserving %d\n", __func__, error)); | | 298 | DPRINTF(("%s: error reserving %d\n", __func__, error)); |
299 | goto stuffup; | | 299 | goto stuffup; |
300 | } | | 300 | } |