Commit 0fc5c15a authored by pbrook's avatar pbrook
Browse files

SCSI lun probing fix.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1945 c046a42c-6fe2-441c-8c8c-71466251a162
parent cac782d4
......@@ -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;
......
......@@ -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) {
......
......@@ -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;
......
......@@ -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);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment