]> Git Repo - qemu.git/blobdiff - hw/spapr_vscsi.c
scsi-disk: support DVD profile in GET CONFIGURATION
[qemu.git] / hw / spapr_vscsi.c
index 1c901ef6ebfb78fc56e102d7d9cfc03a9d76dde6..e8426d7c5e9ace9366811e81392cab484f71d367 100644 (file)
@@ -80,7 +80,6 @@ typedef struct vscsi_req {
     int                     active;
     long                    data_len;
     int                     writing;
-    int                     sensing;
     int                     senselen;
     uint8_t                 sense[SCSI_SENSE_BUF_SIZE];
 
@@ -121,7 +120,7 @@ static struct vscsi_req *vscsi_get_req(VSCSIState *s)
     return NULL;
 }
 
-static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
+static void vscsi_put_req(vscsi_req *req)
 {
     if (req->sreq != NULL) {
         scsi_req_unref(req->sreq);
@@ -130,15 +129,6 @@ static void vscsi_put_req(VSCSIState *s, vscsi_req *req)
     req->active = 0;
 }
 
-static vscsi_req *vscsi_find_req(VSCSIState *s, SCSIRequest *req)
-{
-    uint32_t tag = req->tag;
-    if (tag >= VSCSI_REQ_LIMIT || !s->reqs[tag].active) {
-        return NULL;
-    }
-    return &s->reqs[tag];
-}
-
 static void vscsi_decode_id_lun(uint64_t srp_lun, int *id, int *lun)
 {
     /* XXX Figure that one out properly ! This is crackpot */
@@ -445,45 +435,11 @@ static int vscsi_preprocess_desc(vscsi_req *req)
     return 0;
 }
 
-static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req)
-{
-    uint8_t *cdb = req->iu.srp.cmd.cdb;
-    int n;
-
-    n = scsi_req_get_sense(req->sreq, req->sense, sizeof(req->sense));
-    if (n) {
-        req->senselen = n;
-        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
-        vscsi_put_req(s, req);
-        return;
-    }
-
-    dprintf("VSCSI: Got CHECK_CONDITION, requesting sense...\n");
-    cdb[0] = 3;
-    cdb[1] = 0;
-    cdb[2] = 0;
-    cdb[3] = 0;
-    cdb[4] = 96;
-    cdb[5] = 0;
-    req->sensing = 1;
-    n = scsi_req_enqueue(req->sreq, cdb);
-    dprintf("VSCSI: Queued request sense tag 0x%x\n", req->qtag);
-    if (n < 0) {
-        fprintf(stderr, "VSCSI: REQUEST_SENSE wants write data !?!?!?\n");
-        vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
-        scsi_req_abort(req->sreq, CHECK_CONDITION);
-        return;
-    } else if (n == 0) {
-        return;
-    }
-    scsi_req_continue(req->sreq);
-}
-
 /* Callback to indicate that the SCSI layer has completed a transfer.  */
 static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
 {
     VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
-    vscsi_req *req = vscsi_find_req(s, sreq);
+    vscsi_req *req = sreq->hba_private;
     uint8_t *buf;
     int rc = 0;
 
@@ -494,23 +450,6 @@ static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
         return;
     }
 
-    if (req->sensing) {
-        uint8_t *buf = scsi_req_get_buf(sreq);
-
-        len = MIN(len, SCSI_SENSE_BUF_SIZE);
-        dprintf("VSCSI: Sense data, %d bytes:\n", len);
-        dprintf("       %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
-                buf[0], buf[1], buf[2], buf[3],
-                buf[4], buf[5], buf[6], buf[7]);
-        dprintf("       %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
-                buf[8], buf[9], buf[10], buf[11],
-                buf[12], buf[13], buf[14], buf[15]);
-        memcpy(req->sense, buf, len);
-        req->senselen = len;
-        scsi_req_continue(req->sreq);
-        return;
-    }
-
     if (len) {
         buf = scsi_req_get_buf(sreq);
         rc = vscsi_srp_transfer_data(s, req, req->writing, buf, len);
@@ -531,7 +470,7 @@ static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
 static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status)
 {
     VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
-    vscsi_req *req = vscsi_find_req(s, sreq);
+    vscsi_req *req = sreq->hba_private;
     int32_t res_in = 0, res_out = 0;
 
     dprintf("VSCSI: SCSI cmd complete, r=0x%x tag=0x%x status=0x%x, req=%p\n",
@@ -541,37 +480,38 @@ static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status)
         return;
     }
 
-    if (!req->sensing && status == CHECK_CONDITION) {
-        vscsi_send_request_sense(s, req);
-        return;
+    if (status == CHECK_CONDITION) {
+        req->senselen = scsi_req_get_sense(req->sreq, req->sense,
+                                           sizeof(req->sense));
+        dprintf("VSCSI: Sense data, %d bytes:\n", len);
+        dprintf("       %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
+                req->sense[0], req->sense[1], req->sense[2], req->sense[3],
+                req->sense[4], req->sense[5], req->sense[6], req->sense[7]);
+        dprintf("       %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
+                req->sense[8], req->sense[9], req->sense[10], req->sense[11],
+                req->sense[12], req->sense[13], req->sense[14], req->sense[15]);
     }
 
-    if (req->sensing) {
-        dprintf("VSCSI: Sense done !\n");
-        status = CHECK_CONDITION;
-    } else {
-        dprintf("VSCSI: Command complete err=%d\n", status);
-        if (status == 0) {
-            /* We handle overflows, not underflows for normal commands,
-             * but hopefully nobody cares
-             */
-            if (req->writing) {
-                res_out = req->data_len;
-            } else {
-                res_in = req->data_len;
-            }
+    dprintf("VSCSI: Command complete err=%d\n", status);
+    if (status == 0) {
+        /* We handle overflows, not underflows for normal commands,
+         * but hopefully nobody cares
+         */
+        if (req->writing) {
+            res_out = req->data_len;
+        } else {
+            res_in = req->data_len;
         }
     }
-    vscsi_send_rsp(s, req, 0, res_in, res_out);
-    vscsi_put_req(s, req);
+    vscsi_send_rsp(s, req, status, res_in, res_out);
+    vscsi_put_req(req);
 }
 
 static void vscsi_request_cancelled(SCSIRequest *sreq)
 {
-    VSCSIState *s = DO_UPCAST(VSCSIState, vdev.qdev, sreq->bus->qbus.parent);
-    vscsi_req *req = vscsi_find_req(s, sreq);
+    vscsi_req *req = sreq->hba_private;
 
-    vscsi_put_req(s, req);
+    vscsi_put_req(req);
 }
 
 static void vscsi_process_login(VSCSIState *s, vscsi_req *req)
@@ -659,8 +599,8 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
     }
 
     req->lun = lun;
-    req->sreq = scsi_req_new(sdev, req->qtag, lun);
-    n = scsi_req_enqueue(req->sreq, srp->cmd.cdb);
+    req->sreq = scsi_req_new(sdev, req->qtag, lun, srp->cmd.cdb, req);
+    n = scsi_req_enqueue(req->sreq);
 
     dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n",
             req->qtag, srp->cmd.cdb[0], id, lun, n);
@@ -847,7 +787,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
     if (spapr_tce_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->iu,
                            crq->s.IU_length)) {
         fprintf(stderr, "vscsi_got_payload: DMA read failure !\n");
-        qemu_free(req);
+        g_free(req);
     }
     memcpy(&req->crq, crq, sizeof(vscsi_crq));
 
@@ -858,7 +798,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
     }
 
     if (done) {
-        vscsi_put_req(s, req);
+        vscsi_put_req(req);
     }
 }
 
@@ -952,20 +892,14 @@ static int spapr_vscsi_init(VIOsPAPRDevice *dev)
     return 0;
 }
 
-void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg,
-                        qemu_irq qirq, uint32_t vio_irq_num)
+void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg)
 {
     DeviceState *dev;
-    VIOsPAPRDevice *sdev;
 
     dev = qdev_create(&bus->bus, "spapr-vscsi");
     qdev_prop_set_uint32(dev, "reg", reg);
 
     qdev_init_nofail(dev);
-
-    sdev = (VIOsPAPRDevice *)dev;
-    sdev->qirq = qirq;
-    sdev->vio_irq_num = vio_irq_num;
 }
 
 static int spapr_vscsi_devnode(VIOsPAPRDevice *dev, void *fdt, int node_off)
@@ -995,9 +929,7 @@ static VIOsPAPRDeviceInfo spapr_vscsi = {
     .qdev.name = "spapr-vscsi",
     .qdev.size = sizeof(VSCSIState),
     .qdev.props = (Property[]) {
-        DEFINE_PROP_UINT32("reg", VIOsPAPRDevice, reg, 0x2000),
-        DEFINE_PROP_UINT32("dma-window", VIOsPAPRDevice,
-                           rtce_window_size, 0x10000000),
+        DEFINE_SPAPR_PROPERTIES(VSCSIState, vdev, 0x2000, 0x10000000),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
This page took 0.032292 seconds and 4 git commands to generate.