SCSI lun probing fix.
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 26 May 2006 21:53:41 +0000 (21:53 +0000)
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 26 May 2006 21:53:41 +0000 (21:53 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1945 c046a42c-6fe2-441c-8c8c-71466251a162

hw/esp.c
hw/scsi-disk.c
hw/usb-msd.c
vl.h

index 68e15dd..9087679 100644 (file)
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -55,6 +55,7 @@ struct ESPState {
     uint32_t ti_size;
     uint32_t ti_rptr, ti_wptr;
     uint8_t ti_buf[TI_BUFSZ];
+    int sense;
     int dma;
     SCSIDevice *scsi_dev[MAX_DISKS];
     SCSIDevice *current_dev;
@@ -84,6 +85,7 @@ static void handle_satn(ESPState *s)
     uint32_t dmaptr, dmalen;
     int target;
     int32_t datalen;
+    int lun;
 
     dmalen = s->wregs[0] | (s->wregs[1] << 8);
     target = s->wregs[4] & 7;
@@ -98,6 +100,8 @@ static void handle_satn(ESPState *s)
        memcpy(&buf[1], s->ti_buf, dmalen);
        dmalen++;
     }
+    DPRINTF("busid 0x%x\n", buf[0]);
+    lun = buf[0] & 7;
 
     s->ti_size = 0;
     s->ti_rptr = 0;
@@ -113,7 +117,7 @@ static void handle_satn(ESPState *s)
        return;
     }
     s->current_dev = s->scsi_dev[target];
-    datalen = scsi_send_command(s->current_dev, 0, &buf[1]);
+    datalen = scsi_send_command(s->current_dev, 0, &buf[1], lun);
     if (datalen == 0) {
         s->ti_size = 0;
     } else {
@@ -132,34 +136,33 @@ static void handle_satn(ESPState *s)
     pic_set_irq(s->irq, 1);
 }
 
-static void dma_write(ESPState *s, const uint8_t *buf, uint32_t len)
+static void write_response(ESPState *s)
 {
     uint32_t dmaptr;
 
-    DPRINTF("Transfer status len %d\n", len);
+    DPRINTF("Transfer status (sense=%d)\n", s->sense);
+    s->ti_buf[0] = s->sense;
+    s->ti_buf[1] = 0;
     if (s->dma) {
        dmaptr = iommu_translate(s->espdmaregs[1]);
        DPRINTF("DMA Direction: %c\n",
                 s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r');
-       cpu_physical_memory_write(dmaptr, buf, len);
+       cpu_physical_memory_write(dmaptr, s->ti_buf, 2);
        s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
        s->rregs[5] = INTR_BS | INTR_FC;
        s->rregs[6] = SEQ_CD;
     } else {
-       memcpy(s->ti_buf, buf, len);
-       s->ti_size = len;
+       s->ti_size = 2;
        s->ti_rptr = 0;
        s->ti_wptr = 0;
-       s->rregs[7] = len;
+       s->rregs[7] = 2;
     }
     s->espdmaregs[0] |= DMA_INTR;
     pic_set_irq(s->irq, 1);
 
 }
 
-static const uint8_t okbuf[] = {0, 0};
-
-static void esp_command_complete(void *opaque, uint32_t tag, int fail)
+static void esp_command_complete(void *opaque, uint32_t tag, int sense)
 {
     ESPState *s = (ESPState *)opaque;
 
@@ -167,9 +170,9 @@ static void esp_command_complete(void *opaque, uint32_t tag, int fail)
     if (s->ti_size != 0)
         DPRINTF("SCSI command completed unexpectedly\n");
     s->ti_size = 0;
-    /* ??? Report failures.  */
-    if (fail)
+    if (sense)
         DPRINTF("Command failed\n");
+    s->sense = sense;
     s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
 }
 
@@ -333,11 +336,11 @@ static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
            break;
        case 0x11:
            DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
-           dma_write(s, okbuf, 2);
+           write_response(s);
            break;
        case 0x12:
            DPRINTF("Message Accepted (%2.2x)\n", val);
-           dma_write(s, okbuf, 2);
+           write_response(s);
            s->rregs[5] = INTR_DC;
            s->rregs[6] = 0;
            break;
index 9285c18..c15486b 100644 (file)
@@ -53,7 +53,7 @@ struct SCSIDevice
 static void scsi_command_complete(SCSIDevice *s, int sense)
 {
     s->sense = sense;
-    s->completion(s->opaque, s->tag, sense != SENSE_NO_SENSE);
+    s->completion(s->opaque, s->tag, sense);
 }
 
 /* Read data from a scsi device.  Returns nonzero on failure.  */
@@ -175,7 +175,7 @@ int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len)
    (eg. disk reads), negative for transfers to the device (eg. disk writes),
    and zero if the command does not transfer any data.  */
 
-int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf)
+int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
 {
     int64_t nb_sectors;
     uint32_t lba;
@@ -225,8 +225,9 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf)
         printf("\n");
     }
 #endif
-    if (buf[1] >> 5) {
+    if (lun || buf[1] >> 5) {
         /* Only LUN 0 supported.  */
+        DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
         goto fail;
     }
     switch (s->command) {
index 6b4cb81..bcca6d4 100644 (file)
@@ -295,7 +295,7 @@ static int usb_msd_handle_data(USBDevice *dev, int pid, uint8_t devep,
             }
             DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
                     s->tag, cbw.flags, cbw.cmd_len, s->data_len);
-            scsi_send_command(s->scsi_dev, s->tag, cbw.cmd);
+            scsi_send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
             ret = len;
             break;
 
diff --git a/vl.h b/vl.h
index f8414ea..26e009f 100644 (file)
--- a/vl.h
+++ b/vl.h
@@ -1044,7 +1044,7 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
                            void *opaque);
 void scsi_disk_destroy(SCSIDevice *s);
 
-int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf);
+int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun);
 int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len);
 int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len);