16 #include <linux/module.h>
17 #include <linux/slab.h>
19 #include <linux/virtio.h>
21 #include <linux/virtio_config.h>
27 #define VIRTIO_SCSI_MEMPOOL_SZ 64
28 #define VIRTIO_SCSI_EVENT_LEN 8
91 static void virtscsi_compute_resid(
struct scsi_cmnd *
sc,
u32 resid)
96 if (!scsi_bidi_cmnd(sc)) {
97 scsi_set_resid(sc, resid);
101 scsi_in(sc)->resid =
min(resid, scsi_in(sc)->
length);
102 scsi_out(sc)->resid = resid - scsi_in(sc)->resid;
110 static void virtscsi_complete_cmd(
void *
buf)
117 "cmd %p response %u status %#02x sense_len %u\n",
121 virtscsi_compute_resid(sc, resp->
resid);
124 set_host_byte(sc,
DID_OK);
171 static void virtscsi_vq_done(
struct virtqueue *vq,
void (*
fn)(
void *buf))
183 static void virtscsi_req_done(
struct virtqueue *vq)
190 virtscsi_vq_done(vq, virtscsi_complete_cmd);
191 spin_unlock_irqrestore(&vscsi->
req_vq.vq_lock, flags);
194 static void virtscsi_complete_free(
void *buf)
204 static void virtscsi_ctrl_done(
struct virtqueue *vq)
211 virtscsi_vq_done(vq, virtscsi_complete_free);
212 spin_unlock_irqrestore(&vscsi->
ctrl_vq.vq_lock, flags);
215 static int virtscsi_kick_event(
struct virtio_scsi *vscsi,
230 spin_unlock_irqrestore(&vscsi->
event_vq.vq_lock, flags);
235 static int virtscsi_kick_event_all(
struct virtio_scsi *vscsi)
241 virtscsi_kick_event(vscsi, &vscsi->
event_list[i]);
247 static void virtscsi_cancel_event_work(
struct virtio_scsi *vscsi)
255 static void virtscsi_handle_transport_reset(
struct virtio_scsi *vscsi,
260 unsigned int target =
event->lun[1];
261 unsigned int lun = (
event->lun[2] << 8) | event->
lun[3];
273 pr_err(
"SCSI device %d 0 %d %d not found\n",
278 pr_info(
"Unsupport virtio scsi event reason %x\n", event->
reason);
282 static void virtscsi_handle_param_change(
struct virtio_scsi *vscsi,
287 unsigned int target =
event->lun[1];
288 unsigned int lun = (
event->lun[2] << 8) | event->
lun[3];
294 pr_err(
"SCSI device %d 0 %d %d not found\n",
319 switch (event->
event) {
323 virtscsi_handle_transport_reset(vscsi, event);
326 virtscsi_handle_param_change(vscsi, event);
329 pr_err(
"Unsupport virtio scsi event %x\n", event->
event);
331 virtscsi_kick_event(vscsi, event_node);
334 static void virtscsi_complete_event(
void *buf)
342 static void virtscsi_event_done(
struct virtqueue *vq)
349 virtscsi_vq_done(vq, virtscsi_complete_event);
350 spin_unlock_irqrestore(&vscsi->
event_vq.vq_lock, flags);
353 static void virtscsi_map_sgl(
struct scatterlist *
sg,
unsigned int *p_idx,
358 unsigned int idx = *p_idx;
362 sg[idx++] = *sg_elem;
380 unsigned *out_num,
unsigned *in_num,
381 size_t req_size,
size_t resp_size)
385 unsigned int idx = 0;
388 sg_set_buf(&sg[idx++], &cmd->req, req_size);
392 virtscsi_map_sgl(sg, &idx, scsi_out(sc));
397 sg_set_buf(&sg[idx++], &cmd->resp, resp_size);
401 virtscsi_map_sgl(sg, &idx, scsi_in(sc));
403 *in_num = idx - *out_num;
409 size_t req_size,
size_t resp_size,
gfp_t gfp)
411 unsigned int out_num, in_num;
416 virtscsi_map_cmd(tgt, cmd, &out_num, &in_num, req_size, resp_size);
424 spin_unlock_irqrestore(&vq->
vq_lock, flags);
445 "cmd %p CDB: %#02x\n", sc, sc->
cmnd[0]);
452 memset(cmd, 0,
sizeof(*cmd));
457 .lun[2] = (sc->
device->lun >> 8) | 0x40,
458 .lun[3] = sc->
device->lun & 0xff,
459 .tag = (
unsigned long)
sc,
468 if (virtscsi_kick_cmd(tgt, &vscsi->
req_vq, cmd,
484 if (virtscsi_kick_cmd(tgt, &vscsi->
ctrl_vq, cmd,
499 static int virtscsi_device_reset(
struct scsi_cmnd *sc)
509 memset(cmd, 0,
sizeof(*cmd));
516 .lun[2] = (sc->
device->lun >> 8) | 0x40,
517 .lun[3] = sc->
device->lun & 0xff,
519 return virtscsi_tmf(vscsi, cmd);
522 static int virtscsi_abort(
struct scsi_cmnd *sc)
532 memset(cmd, 0,
sizeof(*cmd));
539 .lun[2] = (sc->
device->lun >> 8) | 0x40,
540 .lun[3] = sc->
device->lun & 0xff,
541 .tag = (
unsigned long)
sc,
543 return virtscsi_tmf(vscsi, cmd);
548 .name =
"Virtio SCSI HBA",
549 .proc_name =
"virtio_scsi",
550 .queuecommand = virtscsi_queuecommand,
552 .eh_abort_handler = virtscsi_abort,
553 .eh_device_reset_handler = virtscsi_device_reset,
560 #define virtscsi_config_get(vdev, fld) \
562 typeof(((struct virtio_scsi_config *)0)->fld) __val; \
563 vdev->config->get(vdev, \
564 offsetof(struct virtio_scsi_config, fld), \
565 &__val, sizeof(__val)); \
569 #define virtscsi_config_set(vdev, fld, val) \
571 typeof(((struct virtio_scsi_config *)0)->fld) __val = (val); \
572 vdev->config->set(vdev, \
573 offsetof(struct virtio_scsi_config, fld), \
574 &__val, sizeof(__val)); \
581 virtscsi_vq->
vq = vq;
591 tgt =
kmalloc(
sizeof(*tgt) +
sizeof(tgt->
sg[0]) * (sg_elems + 2),
611 struct Scsi_Host *sh = virtio_scsi_host(vdev);
616 vdev->
config->reset(vdev);
619 for (i = 0; i < num_targets; i++) {
624 vdev->
config->del_vqs(vdev);
639 const char *names[] = {
646 err = vdev->
config->find_vqs(vdev, 3, vqs, callbacks, names);
650 virtscsi_init_vq(&vscsi->
ctrl_vq, vqs[0]);
651 virtscsi_init_vq(&vscsi->
event_vq, vqs[1]);
652 virtscsi_init_vq(&vscsi->
req_vq, vqs[2]);
658 virtscsi_kick_event_all(vscsi);
663 for (i = 0; i < num_targets; i++) {
664 vscsi->
tgt[
i] = virtscsi_alloc_tgt(vdev, sg_elems);
665 if (!vscsi->
tgt[i]) {
674 virtscsi_remove_vqs(vdev);
683 u32 sg_elems, num_targets;
697 vscsi = shost_priv(shost);
701 err = virtscsi_init(vdev, vscsi, num_targets);
703 goto virtscsi_init_failed;
713 shost->
max_id = num_targets;
716 err = scsi_add_host(shost, &vdev->
dev);
718 goto scsi_add_host_failed;
725 scsi_add_host_failed:
726 vdev->
config->del_vqs(vdev);
727 virtscsi_init_failed:
734 struct Scsi_Host *shost = virtio_scsi_host(vdev);
738 virtscsi_cancel_event_work(vscsi);
742 virtscsi_remove_vqs(vdev);
749 virtscsi_remove_vqs(vdev);
755 struct Scsi_Host *sh = virtio_scsi_host(vdev);
758 return virtscsi_init(vdev, vscsi, sh->
max_id);
775 .driver.name = KBUILD_MODNAME,
778 .probe = virtscsi_probe,
779 .scan = virtscsi_scan,
781 .freeze = virtscsi_freeze,
782 .restore = virtscsi_restore,
792 if (!virtscsi_cmd_cache) {
794 "virtscsi_cmd_cache failed\n");
802 if (!virtscsi_cmd_pool) {
804 "virtscsi_cmd_pool failed\n");
814 if (virtscsi_cmd_pool) {
816 virtscsi_cmd_pool =
NULL;
818 if (virtscsi_cmd_cache) {
820 virtscsi_cmd_cache =
NULL;
825 static void __exit fini(
void)