Commit 8ccc2ace5628720347017c98a43b47b2ba23cf15

Authored by ths
1 parent cf6d9118

SCSI cleanup, by Laurent Vivier.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3797 c046a42c-6fe2-441c-8c8c-71466251a162
hw/esp.c
@@ -165,7 +165,7 @@ static int get_cmd(ESPState *s, uint8_t *buf) @@ -165,7 +165,7 @@ static int get_cmd(ESPState *s, uint8_t *buf)
165 165
166 if (s->current_dev) { 166 if (s->current_dev) {
167 /* Started a new command before the old one finished. Cancel it. */ 167 /* Started a new command before the old one finished. Cancel it. */
168 - scsi_cancel_io(s->current_dev, 0); 168 + s->current_dev->cancel_io(s->current_dev, 0);
169 s->async_len = 0; 169 s->async_len = 0;
170 } 170 }
171 171
@@ -188,7 +188,7 @@ static void do_cmd(ESPState *s, uint8_t *buf) @@ -188,7 +188,7 @@ static void do_cmd(ESPState *s, uint8_t *buf)
188 188
189 DPRINTF("do_cmd: busid 0x%x\n", buf[0]); 189 DPRINTF("do_cmd: busid 0x%x\n", buf[0]);
190 lun = buf[0] & 7; 190 lun = buf[0] & 7;
191 - datalen = scsi_send_command(s->current_dev, 0, &buf[1], lun); 191 + datalen = s->current_dev->send_command(s->current_dev, 0, &buf[1], lun);
192 s->ti_size = datalen; 192 s->ti_size = datalen;
193 if (datalen != 0) { 193 if (datalen != 0) {
194 s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC; 194 s->rregs[ESP_RSTAT] = STAT_IN | STAT_TC;
@@ -196,10 +196,10 @@ static void do_cmd(ESPState *s, uint8_t *buf) @@ -196,10 +196,10 @@ static void do_cmd(ESPState *s, uint8_t *buf)
196 s->dma_counter = 0; 196 s->dma_counter = 0;
197 if (datalen > 0) { 197 if (datalen > 0) {
198 s->rregs[ESP_RSTAT] |= STAT_DI; 198 s->rregs[ESP_RSTAT] |= STAT_DI;
199 - scsi_read_data(s->current_dev, 0); 199 + s->current_dev->read_data(s->current_dev, 0);
200 } else { 200 } else {
201 s->rregs[ESP_RSTAT] |= STAT_DO; 201 s->rregs[ESP_RSTAT] |= STAT_DO;
202 - scsi_write_data(s->current_dev, 0); 202 + s->current_dev->write_data(s->current_dev, 0);
203 } 203 }
204 } 204 }
205 s->rregs[ESP_RINTR] = INTR_BS | INTR_FC; 205 s->rregs[ESP_RINTR] = INTR_BS | INTR_FC;
@@ -298,9 +298,9 @@ static void esp_do_dma(ESPState *s) @@ -298,9 +298,9 @@ static void esp_do_dma(ESPState *s)
298 if (s->async_len == 0) { 298 if (s->async_len == 0) {
299 if (to_device) { 299 if (to_device) {
300 // ti_size is negative 300 // ti_size is negative
301 - scsi_write_data(s->current_dev, 0); 301 + s->current_dev->write_data(s->current_dev, 0);
302 } else { 302 } else {
303 - scsi_read_data(s->current_dev, 0); 303 + s->current_dev->read_data(s->current_dev, 0);
304 /* If there is still data to be read from the device then 304 /* If there is still data to be read from the device then
305 complete the DMA operation immeriately. Otherwise defer 305 complete the DMA operation immeriately. Otherwise defer
306 until the scsi layer has completed. */ 306 until the scsi layer has completed. */
@@ -335,7 +335,7 @@ static void esp_command_complete(void *opaque, int reason, uint32_t tag, @@ -335,7 +335,7 @@ static void esp_command_complete(void *opaque, int reason, uint32_t tag,
335 } else { 335 } else {
336 DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size); 336 DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
337 s->async_len = arg; 337 s->async_len = arg;
338 - s->async_buf = scsi_get_buf(s->current_dev, 0); 338 + s->async_buf = s->current_dev->get_buf(s->current_dev, 0);
339 if (s->dma_left) { 339 if (s->dma_left) {
340 esp_do_dma(s); 340 esp_do_dma(s);
341 } else if (s->dma_counter != 0 && s->ti_size <= 0) { 341 } else if (s->dma_counter != 0 && s->ti_size <= 0) {
@@ -611,7 +611,7 @@ void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id) @@ -611,7 +611,7 @@ void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id)
611 } 611 }
612 if (s->scsi_dev[id]) { 612 if (s->scsi_dev[id]) {
613 DPRINTF("Destroying device %d\n", id); 613 DPRINTF("Destroying device %d\n", id);
614 - scsi_disk_destroy(s->scsi_dev[id]); 614 + s->scsi_dev[id]->destroy(s->scsi_dev[id]);
615 } 615 }
616 DPRINTF("Attaching block device %d\n", id); 616 DPRINTF("Attaching block device %d\n", id);
617 /* Command queueing is not implemented. */ 617 /* Command queueing is not implemented. */
hw/lsi53c895a.c
@@ -187,6 +187,7 @@ typedef struct { @@ -187,6 +187,7 @@ typedef struct {
187 /* The tag is a combination of the device ID and the SCSI tag. */ 187 /* The tag is a combination of the device ID and the SCSI tag. */
188 uint32_t current_tag; 188 uint32_t current_tag;
189 uint32_t current_dma_len; 189 uint32_t current_dma_len;
  190 + int command_complete;
190 uint8_t *dma_buf; 191 uint8_t *dma_buf;
191 lsi_queue *queue; 192 lsi_queue *queue;
192 int queue_len; 193 int queue_len;
@@ -465,7 +466,8 @@ static void lsi_do_dma(LSIState *s, int out) @@ -465,7 +466,8 @@ static void lsi_do_dma(LSIState *s, int out)
465 s->dbc -= count; 466 s->dbc -= count;
466 467
467 if (s->dma_buf == NULL) { 468 if (s->dma_buf == NULL) {
468 - s->dma_buf = scsi_get_buf(s->current_dev, s->current_tag); 469 + s->dma_buf = s->current_dev->get_buf(s->current_dev,
  470 + s->current_tag);
469 } 471 }
470 472
471 /* ??? Set SFBR to first data byte. */ 473 /* ??? Set SFBR to first data byte. */
@@ -479,10 +481,10 @@ static void lsi_do_dma(LSIState *s, int out) @@ -479,10 +481,10 @@ static void lsi_do_dma(LSIState *s, int out)
479 s->dma_buf = NULL; 481 s->dma_buf = NULL;
480 if (out) { 482 if (out) {
481 /* Write the data. */ 483 /* Write the data. */
482 - scsi_write_data(s->current_dev, s->current_tag); 484 + s->current_dev->write_data(s->current_dev, s->current_tag);
483 } else { 485 } else {
484 /* Request any remaining data. */ 486 /* Request any remaining data. */
485 - scsi_read_data(s->current_dev, s->current_tag); 487 + s->current_dev->read_data(s->current_dev, s->current_tag);
486 } 488 }
487 } else { 489 } else {
488 s->dma_buf += count; 490 s->dma_buf += count;
@@ -596,6 +598,7 @@ static void lsi_command_complete(void *opaque, int reason, uint32_t tag, @@ -596,6 +598,7 @@ static void lsi_command_complete(void *opaque, int reason, uint32_t tag,
596 if (reason == SCSI_REASON_DONE) { 598 if (reason == SCSI_REASON_DONE) {
597 DPRINTF("Command complete sense=%d\n", (int)arg); 599 DPRINTF("Command complete sense=%d\n", (int)arg);
598 s->sense = arg; 600 s->sense = arg;
  601 + s->command_complete = 2;
599 if (s->waiting && s->dbc != 0) { 602 if (s->waiting && s->dbc != 0) {
600 /* Raise phase mismatch for short transfers. */ 603 /* Raise phase mismatch for short transfers. */
601 lsi_bad_phase(s, out, PHASE_ST); 604 lsi_bad_phase(s, out, PHASE_ST);
@@ -612,6 +615,7 @@ static void lsi_command_complete(void *opaque, int reason, uint32_t tag, @@ -612,6 +615,7 @@ static void lsi_command_complete(void *opaque, int reason, uint32_t tag,
612 } 615 }
613 DPRINTF("Data ready tag=0x%x len=%d\n", tag, arg); 616 DPRINTF("Data ready tag=0x%x len=%d\n", tag, arg);
614 s->current_dma_len = arg; 617 s->current_dma_len = arg;
  618 + s->command_complete = 1;
615 if (!s->waiting) 619 if (!s->waiting)
616 return; 620 return;
617 if (s->waiting == 1 || s->dbc == 0) { 621 if (s->waiting == 1 || s->dbc == 0) {
@@ -631,21 +635,30 @@ static void lsi_do_command(LSIState *s) @@ -631,21 +635,30 @@ static void lsi_do_command(LSIState *s)
631 s->dbc = 16; 635 s->dbc = 16;
632 cpu_physical_memory_read(s->dnad, buf, s->dbc); 636 cpu_physical_memory_read(s->dnad, buf, s->dbc);
633 s->sfbr = buf[0]; 637 s->sfbr = buf[0];
634 - n = scsi_send_command(s->current_dev, s->current_tag, buf, s->current_lun); 638 + s->command_complete = 0;
  639 + n = s->current_dev->send_command(s->current_dev, s->current_tag, buf,
  640 + s->current_lun);
635 if (n > 0) { 641 if (n > 0) {
636 lsi_set_phase(s, PHASE_DI); 642 lsi_set_phase(s, PHASE_DI);
637 - scsi_read_data(s->current_dev, s->current_tag); 643 + s->current_dev->read_data(s->current_dev, s->current_tag);
638 } else if (n < 0) { 644 } else if (n < 0) {
639 lsi_set_phase(s, PHASE_DO); 645 lsi_set_phase(s, PHASE_DO);
640 - scsi_write_data(s->current_dev, s->current_tag); 646 + s->current_dev->write_data(s->current_dev, s->current_tag);
641 } 647 }
642 - if (n && s->current_dma_len == 0) {  
643 - /* Command did not complete immediately so disconnect. */  
644 - lsi_add_msg_byte(s, 2); /* SAVE DATA POINTER */  
645 - lsi_add_msg_byte(s, 4); /* DISCONNECT */  
646 - lsi_set_phase(s, PHASE_MI);  
647 - s->msg_action = 1;  
648 - lsi_queue_command(s); 648 +
  649 + if (!s->command_complete) {
  650 + if (n) {
  651 + /* Command did not complete immediately so disconnect. */
  652 + lsi_add_msg_byte(s, 2); /* SAVE DATA POINTER */
  653 + lsi_add_msg_byte(s, 4); /* DISCONNECT */
  654 + /* wait data */
  655 + lsi_set_phase(s, PHASE_MI);
  656 + s->msg_action = 1;
  657 + lsi_queue_command(s);
  658 + } else {
  659 + /* wait command complete */
  660 + lsi_set_phase(s, PHASE_DI);
  661 + }
649 } 662 }
650 } 663 }
651 664
@@ -1822,7 +1835,7 @@ void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id) @@ -1822,7 +1835,7 @@ void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id)
1822 } 1835 }
1823 if (s->scsi_dev[id]) { 1836 if (s->scsi_dev[id]) {
1824 DPRINTF("Destroying device %d\n", id); 1837 DPRINTF("Destroying device %d\n", id);
1825 - scsi_disk_destroy(s->scsi_dev[id]); 1838 + s->scsi_dev[id]->destroy(s->scsi_dev[id]);
1826 } 1839 }
1827 DPRINTF("Attaching block device %d\n", id); 1840 DPRINTF("Attaching block device %d\n", id);
1828 s->scsi_dev[id] = scsi_disk_init(bd, 1, lsi_command_complete, s); 1841 s->scsi_dev[id] = scsi_disk_init(bd, 1, lsi_command_complete, s);
hw/scsi-disk.c
@@ -37,7 +37,7 @@ do { fprintf(stderr, &quot;scsi-disk: &quot; fmt , ##args); } while (0) @@ -37,7 +37,7 @@ do { fprintf(stderr, &quot;scsi-disk: &quot; fmt , ##args); } while (0)
37 #define SCSI_DMA_BUF_SIZE 65536 37 #define SCSI_DMA_BUF_SIZE 65536
38 38
39 typedef struct SCSIRequest { 39 typedef struct SCSIRequest {
40 - SCSIDevice *dev; 40 + SCSIDeviceState *dev;
41 uint32_t tag; 41 uint32_t tag;
42 /* ??? We should probably keep track of whether the data trasfer is 42 /* ??? We should probably keep track of whether the data trasfer is
43 a read or a write. Currently we rely on the host getting it right. */ 43 a read or a write. Currently we rely on the host getting it right. */
@@ -51,7 +51,7 @@ typedef struct SCSIRequest { @@ -51,7 +51,7 @@ typedef struct SCSIRequest {
51 struct SCSIRequest *next; 51 struct SCSIRequest *next;
52 } SCSIRequest; 52 } SCSIRequest;
53 53
54 -struct SCSIDevice 54 +struct SCSIDeviceState
55 { 55 {
56 BlockDriverState *bdrv; 56 BlockDriverState *bdrv;
57 SCSIRequest *requests; 57 SCSIRequest *requests;
@@ -69,7 +69,7 @@ struct SCSIDevice @@ -69,7 +69,7 @@ struct SCSIDevice
69 /* Global pool of SCSIRequest structures. */ 69 /* Global pool of SCSIRequest structures. */
70 static SCSIRequest *free_requests = NULL; 70 static SCSIRequest *free_requests = NULL;
71 71
72 -static SCSIRequest *scsi_new_request(SCSIDevice *s, uint32_t tag) 72 +static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
73 { 73 {
74 SCSIRequest *r; 74 SCSIRequest *r;
75 75
@@ -93,7 +93,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *s, uint32_t tag) @@ -93,7 +93,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *s, uint32_t tag)
93 static void scsi_remove_request(SCSIRequest *r) 93 static void scsi_remove_request(SCSIRequest *r)
94 { 94 {
95 SCSIRequest *last; 95 SCSIRequest *last;
96 - SCSIDevice *s = r->dev; 96 + SCSIDeviceState *s = r->dev;
97 97
98 if (s->requests == r) { 98 if (s->requests == r) {
99 s->requests = r->next; 99 s->requests = r->next;
@@ -111,7 +111,7 @@ static void scsi_remove_request(SCSIRequest *r) @@ -111,7 +111,7 @@ static void scsi_remove_request(SCSIRequest *r)
111 free_requests = r; 111 free_requests = r;
112 } 112 }
113 113
114 -static SCSIRequest *scsi_find_request(SCSIDevice *s, uint32_t tag) 114 +static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
115 { 115 {
116 SCSIRequest *r; 116 SCSIRequest *r;
117 117
@@ -125,7 +125,7 @@ static SCSIRequest *scsi_find_request(SCSIDevice *s, uint32_t tag) @@ -125,7 +125,7 @@ static SCSIRequest *scsi_find_request(SCSIDevice *s, uint32_t tag)
125 /* Helper function for command completion. */ 125 /* Helper function for command completion. */
126 static void scsi_command_complete(SCSIRequest *r, int sense) 126 static void scsi_command_complete(SCSIRequest *r, int sense)
127 { 127 {
128 - SCSIDevice *s = r->dev; 128 + SCSIDeviceState *s = r->dev;
129 uint32_t tag; 129 uint32_t tag;
130 DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense); 130 DPRINTF("Command complete tag=0x%x sense=%d\n", r->tag, sense);
131 s->sense = sense; 131 s->sense = sense;
@@ -135,8 +135,9 @@ static void scsi_command_complete(SCSIRequest *r, int sense) @@ -135,8 +135,9 @@ static void scsi_command_complete(SCSIRequest *r, int sense)
135 } 135 }
136 136
137 /* Cancel a pending data transfer. */ 137 /* Cancel a pending data transfer. */
138 -void scsi_cancel_io(SCSIDevice *s, uint32_t tag) 138 +static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
139 { 139 {
  140 + SCSIDeviceState *s = d->state;
140 SCSIRequest *r; 141 SCSIRequest *r;
141 DPRINTF("Cancel tag=0x%x\n", tag); 142 DPRINTF("Cancel tag=0x%x\n", tag);
142 r = scsi_find_request(s, tag); 143 r = scsi_find_request(s, tag);
@@ -151,7 +152,7 @@ void scsi_cancel_io(SCSIDevice *s, uint32_t tag) @@ -151,7 +152,7 @@ void scsi_cancel_io(SCSIDevice *s, uint32_t tag)
151 static void scsi_read_complete(void * opaque, int ret) 152 static void scsi_read_complete(void * opaque, int ret)
152 { 153 {
153 SCSIRequest *r = (SCSIRequest *)opaque; 154 SCSIRequest *r = (SCSIRequest *)opaque;
154 - SCSIDevice *s = r->dev; 155 + SCSIDeviceState *s = r->dev;
155 156
156 if (ret) { 157 if (ret) {
157 DPRINTF("IO error\n"); 158 DPRINTF("IO error\n");
@@ -164,8 +165,9 @@ static void scsi_read_complete(void * opaque, int ret) @@ -164,8 +165,9 @@ static void scsi_read_complete(void * opaque, int ret)
164 } 165 }
165 166
166 /* Read more data from scsi device into buffer. */ 167 /* Read more data from scsi device into buffer. */
167 -void scsi_read_data(SCSIDevice *s, uint32_t tag) 168 +static void scsi_read_data(SCSIDevice *d, uint32_t tag)
168 { 169 {
  170 + SCSIDeviceState *s = d->state;
169 SCSIRequest *r; 171 SCSIRequest *r;
170 uint32_t n; 172 uint32_t n;
171 173
@@ -204,7 +206,7 @@ void scsi_read_data(SCSIDevice *s, uint32_t tag) @@ -204,7 +206,7 @@ void scsi_read_data(SCSIDevice *s, uint32_t tag)
204 static void scsi_write_complete(void * opaque, int ret) 206 static void scsi_write_complete(void * opaque, int ret)
205 { 207 {
206 SCSIRequest *r = (SCSIRequest *)opaque; 208 SCSIRequest *r = (SCSIRequest *)opaque;
207 - SCSIDevice *s = r->dev; 209 + SCSIDeviceState *s = r->dev;
208 uint32_t len; 210 uint32_t len;
209 211
210 if (ret) { 212 if (ret) {
@@ -228,8 +230,9 @@ static void scsi_write_complete(void * opaque, int ret) @@ -228,8 +230,9 @@ static void scsi_write_complete(void * opaque, int ret)
228 230
229 /* Write data to a scsi device. Returns nonzero on failure. 231 /* Write data to a scsi device. Returns nonzero on failure.
230 The transfer may complete asynchronously. */ 232 The transfer may complete asynchronously. */
231 -int scsi_write_data(SCSIDevice *s, uint32_t tag) 233 +static int scsi_write_data(SCSIDevice *d, uint32_t tag)
232 { 234 {
  235 + SCSIDeviceState *s = d->state;
233 SCSIRequest *r; 236 SCSIRequest *r;
234 uint32_t n; 237 uint32_t n;
235 238
@@ -259,8 +262,9 @@ int scsi_write_data(SCSIDevice *s, uint32_t tag) @@ -259,8 +262,9 @@ int scsi_write_data(SCSIDevice *s, uint32_t tag)
259 } 262 }
260 263
261 /* Return a pointer to the data buffer. */ 264 /* Return a pointer to the data buffer. */
262 -uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag) 265 +static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
263 { 266 {
  267 + SCSIDeviceState *s = d->state;
264 SCSIRequest *r; 268 SCSIRequest *r;
265 269
266 r = scsi_find_request(s, tag); 270 r = scsi_find_request(s, tag);
@@ -276,8 +280,10 @@ uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag) @@ -276,8 +280,10 @@ uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag)
276 (eg. disk reads), negative for transfers to the device (eg. disk writes), 280 (eg. disk reads), negative for transfers to the device (eg. disk writes),
277 and zero if the command does not transfer any data. */ 281 and zero if the command does not transfer any data. */
278 282
279 -int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun) 283 +static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
  284 + uint8_t *buf, int lun)
280 { 285 {
  286 + SCSIDeviceState *s = d->state;
281 int64_t nb_sectors; 287 int64_t nb_sectors;
282 uint32_t lba; 288 uint32_t lba;
283 uint32_t len; 289 uint32_t len;
@@ -291,7 +297,7 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun) @@ -291,7 +297,7 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
291 r = scsi_find_request(s, tag); 297 r = scsi_find_request(s, tag);
292 if (r) { 298 if (r) {
293 BADF("Tag 0x%x already in use\n", tag); 299 BADF("Tag 0x%x already in use\n", tag);
294 - scsi_cancel_io(s, tag); 300 + scsi_cancel_io(d, tag);
295 } 301 }
296 /* ??? Tags are not unique for different luns. We only implement a 302 /* ??? Tags are not unique for different luns. We only implement a
297 single lun, so this should not matter. */ 303 single lun, so this should not matter. */
@@ -576,19 +582,19 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun) @@ -576,19 +582,19 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
576 } 582 }
577 } 583 }
578 584
579 -void scsi_disk_destroy(SCSIDevice *s) 585 +static void scsi_destroy(SCSIDevice *d)
580 { 586 {
581 - qemu_free(s); 587 + qemu_free(d->state);
  588 + qemu_free(d);
582 } 589 }
583 590
584 -SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,  
585 - int tcq,  
586 - scsi_completionfn completion,  
587 - void *opaque) 591 +SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
  592 + scsi_completionfn completion, void *opaque)
588 { 593 {
589 - SCSIDevice *s; 594 + SCSIDevice *d;
  595 + SCSIDeviceState *s;
590 596
591 - s = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice)); 597 + s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
592 s->bdrv = bdrv; 598 s->bdrv = bdrv;
593 s->tcq = tcq; 599 s->tcq = tcq;
594 s->completion = completion; 600 s->completion = completion;
@@ -599,6 +605,14 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, @@ -599,6 +605,14 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
599 s->cluster_size = 1; 605 s->cluster_size = 1;
600 } 606 }
601 607
602 - return s;  
603 -} 608 + d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
  609 + d->state = s;
  610 + d->destroy = scsi_destroy;
  611 + d->send_command = scsi_send_command;
  612 + d->read_data = scsi_read_data;
  613 + d->write_data = scsi_write_data;
  614 + d->cancel_io = scsi_cancel_io;
  615 + d->get_buf = scsi_get_buf;
604 616
  617 + return d;
  618 +}
hw/scsi-disk.h
@@ -7,24 +7,25 @@ enum scsi_reason { @@ -7,24 +7,25 @@ enum scsi_reason {
7 SCSI_REASON_DATA /* Transfer complete, more data required. */ 7 SCSI_REASON_DATA /* Transfer complete, more data required. */
8 }; 8 };
9 9
  10 +typedef struct SCSIDeviceState SCSIDeviceState;
10 typedef struct SCSIDevice SCSIDevice; 11 typedef struct SCSIDevice SCSIDevice;
11 typedef void (*scsi_completionfn)(void *opaque, int reason, uint32_t tag, 12 typedef void (*scsi_completionfn)(void *opaque, int reason, uint32_t tag,
12 uint32_t arg); 13 uint32_t arg);
13 14
14 -SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,  
15 - int tcq,  
16 - scsi_completionfn completion,  
17 - void *opaque);  
18 -void scsi_disk_destroy(SCSIDevice *s); 15 +struct SCSIDevice
  16 +{
  17 + SCSIDeviceState *state;
  18 + void (*destroy)(SCSIDevice *s);
  19 + int32_t (*send_command)(SCSIDevice *s, uint32_t tag, uint8_t *buf,
  20 + int lun);
  21 + void (*read_data)(SCSIDevice *s, uint32_t tag);
  22 + int (*write_data)(SCSIDevice *s, uint32_t tag);
  23 + void (*cancel_io)(SCSIDevice *s, uint32_t tag);
  24 + uint8_t *(*get_buf)(SCSIDevice *s, uint32_t tag);
  25 +};
19 26
20 -int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun);  
21 -/* SCSI data transfers are asynchrnonous. However, unlike the block IO  
22 - layer the completion routine may be called directly by  
23 - scsi_{read,write}_data. */  
24 -void scsi_read_data(SCSIDevice *s, uint32_t tag);  
25 -int scsi_write_data(SCSIDevice *s, uint32_t tag);  
26 -void scsi_cancel_io(SCSIDevice *s, uint32_t tag);  
27 -uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag); 27 +SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
  28 + scsi_completionfn completion, void *opaque);
28 29
29 /* cdrom.c */ 30 /* cdrom.c */
30 int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track); 31 int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
hw/usb-msd.c
@@ -149,9 +149,9 @@ static void usb_msd_copy_data(MSDState *s) @@ -149,9 +149,9 @@ static void usb_msd_copy_data(MSDState *s)
149 s->data_len -= len; 149 s->data_len -= len;
150 if (s->scsi_len == 0) { 150 if (s->scsi_len == 0) {
151 if (s->mode == USB_MSDM_DATAIN) { 151 if (s->mode == USB_MSDM_DATAIN) {
152 - scsi_read_data(s->scsi_dev, s->tag); 152 + s->scsi_dev->read_data(s->scsi_dev, s->tag);
153 } else if (s->mode == USB_MSDM_DATAOUT) { 153 } else if (s->mode == USB_MSDM_DATAOUT) {
154 - scsi_write_data(s->scsi_dev, s->tag); 154 + s->scsi_dev->write_data(s->scsi_dev, s->tag);
155 } 155 }
156 } 156 }
157 } 157 }
@@ -204,7 +204,7 @@ static void usb_msd_command_complete(void *opaque, int reason, uint32_t tag, @@ -204,7 +204,7 @@ static void usb_msd_command_complete(void *opaque, int reason, uint32_t tag,
204 return; 204 return;
205 } 205 }
206 s->scsi_len = arg; 206 s->scsi_len = arg;
207 - s->scsi_buf = scsi_get_buf(s->scsi_dev, tag); 207 + s->scsi_buf = s->scsi_dev->get_buf(s->scsi_dev, tag);
208 if (p) { 208 if (p) {
209 usb_msd_copy_data(s); 209 usb_msd_copy_data(s);
210 if (s->usb_len == 0) { 210 if (s->usb_len == 0) {
@@ -342,7 +342,7 @@ static int usb_msd_handle_control(USBDevice *dev, int request, int value, @@ -342,7 +342,7 @@ static int usb_msd_handle_control(USBDevice *dev, int request, int value,
342 static void usb_msd_cancel_io(USBPacket *p, void *opaque) 342 static void usb_msd_cancel_io(USBPacket *p, void *opaque)
343 { 343 {
344 MSDState *s = opaque; 344 MSDState *s = opaque;
345 - scsi_cancel_io(s->scsi_dev, s->tag); 345 + s->scsi_dev->cancel_io(s->scsi_dev, s->tag);
346 s->packet = NULL; 346 s->packet = NULL;
347 s->scsi_len = 0; 347 s->scsi_len = 0;
348 } 348 }
@@ -390,14 +390,14 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) @@ -390,14 +390,14 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
390 DPRINTF("Command tag 0x%x flags %08x len %d data %d\n", 390 DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
391 s->tag, cbw.flags, cbw.cmd_len, s->data_len); 391 s->tag, cbw.flags, cbw.cmd_len, s->data_len);
392 s->residue = 0; 392 s->residue = 0;
393 - scsi_send_command(s->scsi_dev, s->tag, cbw.cmd, 0); 393 + s->scsi_dev->send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
394 /* ??? Should check that USB and SCSI data transfer 394 /* ??? Should check that USB and SCSI data transfer
395 directions match. */ 395 directions match. */
396 if (s->residue == 0) { 396 if (s->residue == 0) {
397 if (s->mode == USB_MSDM_DATAIN) { 397 if (s->mode == USB_MSDM_DATAIN) {
398 - scsi_read_data(s->scsi_dev, s->tag); 398 + s->scsi_dev->read_data(s->scsi_dev, s->tag);
399 } else if (s->mode == USB_MSDM_DATAOUT) { 399 } else if (s->mode == USB_MSDM_DATAOUT) {
400 - scsi_write_data(s->scsi_dev, s->tag); 400 + s->scsi_dev->write_data(s->scsi_dev, s->tag);
401 } 401 }
402 } 402 }
403 ret = len; 403 ret = len;
@@ -508,7 +508,7 @@ static void usb_msd_handle_destroy(USBDevice *dev) @@ -508,7 +508,7 @@ static void usb_msd_handle_destroy(USBDevice *dev)
508 { 508 {
509 MSDState *s = (MSDState *)dev; 509 MSDState *s = (MSDState *)dev;
510 510
511 - scsi_disk_destroy(s->scsi_dev); 511 + s->scsi_dev->destroy(s->scsi_dev);
512 bdrv_delete(s->bs); 512 bdrv_delete(s->bs);
513 qemu_free(s); 513 qemu_free(s);
514 } 514 }