SCSI lun probing fix.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1945 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
pbrook 2006-05-26 21:53:41 +00:00
parent cac782d496
commit 0fc5c15a4f
4 changed files with 23 additions and 19 deletions

View File

@ -55,6 +55,7 @@ struct ESPState {
uint32_t ti_size; uint32_t ti_size;
uint32_t ti_rptr, ti_wptr; uint32_t ti_rptr, ti_wptr;
uint8_t ti_buf[TI_BUFSZ]; uint8_t ti_buf[TI_BUFSZ];
int sense;
int dma; int dma;
SCSIDevice *scsi_dev[MAX_DISKS]; SCSIDevice *scsi_dev[MAX_DISKS];
SCSIDevice *current_dev; SCSIDevice *current_dev;
@ -84,6 +85,7 @@ static void handle_satn(ESPState *s)
uint32_t dmaptr, dmalen; uint32_t dmaptr, dmalen;
int target; int target;
int32_t datalen; int32_t datalen;
int lun;
dmalen = s->wregs[0] | (s->wregs[1] << 8); dmalen = s->wregs[0] | (s->wregs[1] << 8);
target = s->wregs[4] & 7; target = s->wregs[4] & 7;
@ -98,6 +100,8 @@ static void handle_satn(ESPState *s)
memcpy(&buf[1], s->ti_buf, dmalen); memcpy(&buf[1], s->ti_buf, dmalen);
dmalen++; dmalen++;
} }
DPRINTF("busid 0x%x\n", buf[0]);
lun = buf[0] & 7;
s->ti_size = 0; s->ti_size = 0;
s->ti_rptr = 0; s->ti_rptr = 0;
@ -113,7 +117,7 @@ static void handle_satn(ESPState *s)
return; return;
} }
s->current_dev = s->scsi_dev[target]; 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) { if (datalen == 0) {
s->ti_size = 0; s->ti_size = 0;
} else { } else {
@ -132,34 +136,33 @@ static void handle_satn(ESPState *s)
pic_set_irq(s->irq, 1); 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; 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) { if (s->dma) {
dmaptr = iommu_translate(s->espdmaregs[1]); dmaptr = iommu_translate(s->espdmaregs[1]);
DPRINTF("DMA Direction: %c\n", DPRINTF("DMA Direction: %c\n",
s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r'); 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[4] = STAT_IN | STAT_TC | STAT_ST;
s->rregs[5] = INTR_BS | INTR_FC; s->rregs[5] = INTR_BS | INTR_FC;
s->rregs[6] = SEQ_CD; s->rregs[6] = SEQ_CD;
} else { } else {
memcpy(s->ti_buf, buf, len); s->ti_size = 2;
s->ti_size = len;
s->ti_rptr = 0; s->ti_rptr = 0;
s->ti_wptr = 0; s->ti_wptr = 0;
s->rregs[7] = len; s->rregs[7] = 2;
} }
s->espdmaregs[0] |= DMA_INTR; s->espdmaregs[0] |= DMA_INTR;
pic_set_irq(s->irq, 1); pic_set_irq(s->irq, 1);
} }
static const uint8_t okbuf[] = {0, 0}; static void esp_command_complete(void *opaque, uint32_t tag, int sense)
static void esp_command_complete(void *opaque, uint32_t tag, int fail)
{ {
ESPState *s = (ESPState *)opaque; 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) if (s->ti_size != 0)
DPRINTF("SCSI command completed unexpectedly\n"); DPRINTF("SCSI command completed unexpectedly\n");
s->ti_size = 0; s->ti_size = 0;
/* ??? Report failures. */ if (sense)
if (fail)
DPRINTF("Command failed\n"); DPRINTF("Command failed\n");
s->sense = sense;
s->rregs[4] = STAT_IN | STAT_TC | STAT_ST; 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; break;
case 0x11: case 0x11:
DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val); DPRINTF("Initiator Command Complete Sequence (%2.2x)\n", val);
dma_write(s, okbuf, 2); write_response(s);
break; break;
case 0x12: case 0x12:
DPRINTF("Message Accepted (%2.2x)\n", val); DPRINTF("Message Accepted (%2.2x)\n", val);
dma_write(s, okbuf, 2); write_response(s);
s->rregs[5] = INTR_DC; s->rregs[5] = INTR_DC;
s->rregs[6] = 0; s->rregs[6] = 0;
break; break;

View File

@ -53,7 +53,7 @@ struct SCSIDevice
static void scsi_command_complete(SCSIDevice *s, int sense) static void scsi_command_complete(SCSIDevice *s, int sense)
{ {
s->sense = 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. */ /* 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), (eg. disk reads), negative for transfers to the device (eg. disk writes),
and zero if the command does not transfer any data. */ 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; int64_t nb_sectors;
uint32_t lba; uint32_t lba;
@ -225,8 +225,9 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf)
printf("\n"); printf("\n");
} }
#endif #endif
if (buf[1] >> 5) { if (lun || buf[1] >> 5) {
/* Only LUN 0 supported. */ /* Only LUN 0 supported. */
DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
goto fail; goto fail;
} }
switch (s->command) { switch (s->command) {

View 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", DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
s->tag, cbw.flags, cbw.cmd_len, s->data_len); 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; ret = len;
break; break;

2
vl.h
View File

@ -1044,7 +1044,7 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
void *opaque); void *opaque);
void scsi_disk_destroy(SCSIDevice *s); 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_read_data(SCSIDevice *s, uint8_t *data, uint32_t len);
int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len); int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len);