Commit 4d611c9a2f4c5d9080d8b6a6f0d7431233cd56f9

Authored by pbrook
1 parent 4ca9c76f

SCSI and USB async IO support.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2107 c046a42c-6fe2-441c-8c8c-71466251a162
hw/esp.c
... ... @@ -62,6 +62,11 @@ struct ESPState {
62 62 uint8_t cmdbuf[TI_BUFSZ];
63 63 int cmdlen;
64 64 int do_cmd;
  65 +
  66 + uint32_t dma_left;
  67 + uint8_t async_buf[TARGET_PAGE_SIZE];
  68 + uint32_t async_ptr;
  69 + uint32_t async_len;
65 70 };
66 71  
67 72 #define STAT_DO 0x00
... ... @@ -72,6 +77,8 @@ struct ESPState {
72 77 #define STAT_MO 0x07
73 78  
74 79 #define STAT_TC 0x10
  80 +#define STAT_PE 0x20
  81 +#define STAT_GE 0x40
75 82 #define STAT_IN 0x80
76 83  
77 84 #define INTR_FC 0x08
... ... @@ -195,26 +202,85 @@ static void write_response(ESPState *s)
195 202  
196 203 }
197 204  
198   -static void esp_command_complete(void *opaque, uint32_t tag, int sense)
  205 +static void esp_do_dma(ESPState *s)
  206 +{
  207 + uint32_t dmaptr, minlen, len, from, to;
  208 + int to_device;
  209 + dmaptr = iommu_translate(s->espdmaregs[1]);
  210 + to_device = (s->espdmaregs[0] & DMA_WRITE_MEM) == 0;
  211 + from = s->espdmaregs[1];
  212 + minlen = s->dma_left;
  213 + to = from + minlen;
  214 + dmaptr = iommu_translate(s->espdmaregs[1]);
  215 + if ((from & TARGET_PAGE_MASK) != (to & TARGET_PAGE_MASK)) {
  216 + len = TARGET_PAGE_SIZE - (from & ~TARGET_PAGE_MASK);
  217 + } else {
  218 + len = to - from;
  219 + }
  220 + DPRINTF("DMA address p %08x v %08x len %08x, from %08x, to %08x\n", dmaptr, s->espdmaregs[1], len, from, to);
  221 + s->espdmaregs[1] += len;
  222 + if (s->do_cmd) {
  223 + s->ti_size -= len;
  224 + DPRINTF("command len %d + %d\n", s->cmdlen, len);
  225 + cpu_physical_memory_read(dmaptr, &s->cmdbuf[s->cmdlen], len);
  226 + s->ti_size = 0;
  227 + s->cmdlen = 0;
  228 + s->do_cmd = 0;
  229 + do_cmd(s, s->cmdbuf);
  230 + return;
  231 + } else {
  232 + s->async_len = len;
  233 + s->dma_left -= len;
  234 + if (to_device) {
  235 + s->async_ptr = -1;
  236 + cpu_physical_memory_read(dmaptr, s->async_buf, len);
  237 + scsi_write_data(s->current_dev, s->async_buf, len);
  238 + } else {
  239 + s->async_ptr = dmaptr;
  240 + scsi_read_data(s->current_dev, s->async_buf, len);
  241 + }
  242 + }
  243 +}
  244 +
  245 +static void esp_command_complete(void *opaque, uint32_t reason, int sense)
199 246 {
200 247 ESPState *s = (ESPState *)opaque;
201 248  
202   - DPRINTF("SCSI Command complete\n");
203   - if (s->ti_size != 0)
204   - DPRINTF("SCSI command completed unexpectedly\n");
205   - s->ti_size = 0;
206   - if (sense)
207   - DPRINTF("Command failed\n");
208   - s->sense = sense;
209   - s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
  249 + s->ti_size -= s->async_len;
  250 + s->espdmaregs[1] += s->async_len;
  251 + if (s->async_ptr != (uint32_t)-1) {
  252 + cpu_physical_memory_write(s->async_ptr, s->async_buf, s->async_len);
  253 + }
  254 + if (reason == SCSI_REASON_DONE) {
  255 + DPRINTF("SCSI Command complete\n");
  256 + if (s->ti_size != 0)
  257 + DPRINTF("SCSI command completed unexpectedly\n");
  258 + s->ti_size = 0;
  259 + if (sense)
  260 + DPRINTF("Command failed\n");
  261 + s->sense = sense;
  262 + } else {
  263 + DPRINTF("transfer %d/%d\n", s->dma_left, s->ti_size);
  264 + }
  265 + if (s->dma_left) {
  266 + esp_do_dma(s);
  267 + } else {
  268 + if (s->ti_size) {
  269 + s->rregs[4] |= STAT_IN | STAT_TC;
  270 + } else {
  271 + s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
  272 + }
  273 + s->rregs[5] = INTR_BS;
  274 + s->rregs[6] = 0;
  275 + s->rregs[7] = 0;
  276 + s->espdmaregs[0] |= DMA_INTR;
  277 + pic_set_irq(s->irq, 1);
  278 + }
210 279 }
211 280  
212 281 static void handle_ti(ESPState *s)
213 282 {
214   - uint32_t dmaptr, dmalen, minlen, len, from, to;
215   - unsigned int i;
216   - int to_device;
217   - uint8_t buf[TARGET_PAGE_SIZE];
  283 + uint32_t dmalen, minlen;
218 284  
219 285 dmalen = s->wregs[0] | (s->wregs[1] << 8);
220 286 if (dmalen==0) {
... ... @@ -227,47 +293,9 @@ static void handle_ti(ESPState *s)
227 293 minlen = (dmalen < s->ti_size) ? dmalen : s->ti_size;
228 294 DPRINTF("Transfer Information len %d\n", minlen);
229 295 if (s->dma) {
230   - dmaptr = iommu_translate(s->espdmaregs[1]);
231   - /* Check if the transfer writes to to reads from the device. */
232   - to_device = (s->espdmaregs[0] & DMA_WRITE_MEM) == 0;
233   - DPRINTF("DMA Direction: %c, addr 0x%8.8x %08x\n",
234   - to_device ? 'r': 'w', dmaptr, s->ti_size);
235   - from = s->espdmaregs[1];
236   - to = from + minlen;
237   - for (i = 0; i < minlen; i += len, from += len) {
238   - dmaptr = iommu_translate(s->espdmaregs[1] + i);
239   - if ((from & TARGET_PAGE_MASK) != (to & TARGET_PAGE_MASK)) {
240   - len = TARGET_PAGE_SIZE - (from & ~TARGET_PAGE_MASK);
241   - } else {
242   - len = to - from;
243   - }
244   - DPRINTF("DMA address p %08x v %08x len %08x, from %08x, to %08x\n", dmaptr, s->espdmaregs[1] + i, len, from, to);
245   - s->ti_size -= len;
246   - if (s->do_cmd) {
247   - DPRINTF("command len %d + %d\n", s->cmdlen, len);
248   - cpu_physical_memory_read(dmaptr, &s->cmdbuf[s->cmdlen], len);
249   - s->ti_size = 0;
250   - s->cmdlen = 0;
251   - s->do_cmd = 0;
252   - do_cmd(s, s->cmdbuf);
253   - return;
254   - } else {
255   - if (to_device) {
256   - cpu_physical_memory_read(dmaptr, buf, len);
257   - scsi_write_data(s->current_dev, buf, len);
258   - } else {
259   - scsi_read_data(s->current_dev, buf, len);
260   - cpu_physical_memory_write(dmaptr, buf, len);
261   - }
262   - }
263   - }
264   - if (s->ti_size) {
265   - s->rregs[4] = STAT_IN | STAT_TC | (to_device ? STAT_DO : STAT_DI);
266   - }
267   - s->rregs[5] = INTR_BS;
268   - s->rregs[6] = 0;
269   - s->rregs[7] = 0;
270   - s->espdmaregs[0] |= DMA_INTR;
  296 + s->dma_left = minlen;
  297 + s->rregs[4] &= ~STAT_TC;
  298 + esp_do_dma(s);
271 299 } else if (s->do_cmd) {
272 300 DPRINTF("command len %d\n", s->cmdlen);
273 301 s->ti_size = 0;
... ... @@ -276,7 +304,6 @@ static void handle_ti(ESPState *s)
276 304 do_cmd(s, s->cmdbuf);
277 305 return;
278 306 }
279   - pic_set_irq(s->irq, 1);
280 307 }
281 308  
282 309 static void esp_reset(void *opaque)
... ... @@ -320,8 +347,8 @@ static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
320 347 break;
321 348 case 5:
322 349 // interrupt
323   - // Clear status bits except TC
324   - s->rregs[4] &= STAT_TC;
  350 + // Clear interrupt/error status bits
  351 + s->rregs[4] &= ~(STAT_IN | STAT_GE | STAT_PE);
325 352 pic_set_irq(s->irq, 0);
326 353 s->espdmaregs[0] &= ~DMA_INTR;
327 354 break;
... ... @@ -342,6 +369,7 @@ static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
342 369 case 0:
343 370 case 1:
344 371 s->rregs[saddr] = val;
  372 + s->rregs[4] &= ~STAT_TC;
345 373 break;
346 374 case 2:
347 375 // FIFO
... ...
hw/lsi53c895a.c
... ... @@ -152,6 +152,9 @@ do { fprintf(stderr, &quot;lsi_scsi: &quot; fmt , ##args); } while (0)
152 152 /* The HBA is ID 7, so for simplicitly limit to 7 devices. */
153 153 #define LSI_MAX_DEVS 7
154 154  
  155 +/* Size of internal DMA buffer for async IO requests. */
  156 +#define LSI_DMA_BLOCK_SIZE 0x10000
  157 +
155 158 typedef struct {
156 159 PCIDevice pci_dev;
157 160 int mmio_io_addr;
... ... @@ -162,7 +165,9 @@ typedef struct {
162 165 int carry; /* ??? Should this be an a visible register somewhere? */
163 166 int sense;
164 167 uint8_t msg;
165   - /* Nonzero if a Wait Reselect instruction has been issued. */
  168 + /* 0 if SCRIPTS are running or stopped.
  169 + * 1 if a Wait Reselect instruction has been issued.
  170 + * 2 if a DMA operation is in progress. */
166 171 int waiting;
167 172 SCSIDevice *scsi_dev[LSI_MAX_DEVS];
168 173 SCSIDevice *current_dev;
... ... @@ -226,6 +231,7 @@ typedef struct {
226 231 uint32_t csbc;
227 232 uint32_t scratch[13]; /* SCRATCHA-SCRATCHR */
228 233  
  234 + uint8_t dma_buf[LSI_DMA_BLOCK_SIZE];
229 235 /* Script ram is stored as 32-bit words in host byteorder. */
230 236 uint32_t script_ram[2048];
231 237 } LSIState;
... ... @@ -295,6 +301,7 @@ static void lsi_soft_reset(LSIState *s)
295 301  
296 302 static uint8_t lsi_reg_readb(LSIState *s, int offset);
297 303 static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val);
  304 +static void lsi_execute_script(LSIState *s);
298 305  
299 306 static inline uint32_t read_dword(LSIState *s, uint32_t addr)
300 307 {
... ... @@ -402,21 +409,20 @@ static void lsi_bad_phase(LSIState *s, int out, int new_phase)
402 409 lsi_set_phase(s, new_phase);
403 410 }
404 411  
  412 +/* Initiate a SCSI layer data transfer. */
405 413 static void lsi_do_dma(LSIState *s, int out)
406 414 {
407   - uint8_t buf[TARGET_PAGE_SIZE];
408   - uint32_t addr;
409 415 uint32_t count;
410   - int n;
411 416  
412 417 count = s->dbc;
413   - addr = s->dnad;
414   - DPRINTF("DMA %s addr=0x%08x len=%d avail=%d\n", out ? "out" : "in",
  418 + if (count > LSI_DMA_BLOCK_SIZE)
  419 + count = LSI_DMA_BLOCK_SIZE;
  420 + DPRINTF("DMA addr=0x%08x len=%d avail=%d\n",
415 421 addr, count, s->data_len);
416 422 /* ??? Too long transfers are truncated. Don't know if this is the
417 423 correct behavior. */
418 424 if (count > s->data_len) {
419   - /* If the DMA length is greater then the device data length then
  425 + /* If the DMA length is greater than the device data length then
420 426 a phase mismatch will occur. */
421 427 count = s->data_len;
422 428 s->dbc = count;
... ... @@ -426,20 +432,47 @@ static void lsi_do_dma(LSIState *s, int out)
426 432 s->csbc += count;
427 433  
428 434 /* ??? Set SFBR to first data byte. */
429   - while (count) {
430   - n = (count > TARGET_PAGE_SIZE) ? TARGET_PAGE_SIZE : count;
431   - if (out) {
432   - cpu_physical_memory_read(addr, buf, n);
433   - scsi_write_data(s->current_dev, buf, n);
434   - } else {
435   - scsi_read_data(s->current_dev, buf, n);
436   - cpu_physical_memory_write(addr, buf, n);
437   - }
438   - addr += n;
439   - count -= n;
  435 + if ((s->sstat1 & PHASE_MASK) == PHASE_DO) {
  436 + cpu_physical_memory_read(s->dnad, s->dma_buf, count);
  437 + scsi_write_data(s->current_dev, s->dma_buf, count);
  438 + } else {
  439 + scsi_read_data(s->current_dev, s->dma_buf, count);
440 440 }
  441 + /* If the DMA did not complete then suspend execution. */
  442 + if (s->dbc)
  443 + s->waiting = 2;
441 444 }
442 445  
  446 +/* Callback to indicate that the SCSI layer has completed a transfer. */
  447 +static void lsi_command_complete(void *opaque, uint32_t reason, int sense)
  448 +{
  449 + LSIState *s = (LSIState *)opaque;
  450 + uint32_t count;
  451 + int out;
  452 +
  453 + out = ((s->sstat1 & PHASE_MASK) == PHASE_DO);
  454 + count = s->dbc;
  455 + if (count > LSI_DMA_BLOCK_SIZE)
  456 + count = LSI_DMA_BLOCK_SIZE;
  457 + if (!out)
  458 + cpu_physical_memory_write(s->dnad, s->dma_buf, count);
  459 + s->dnad += count;
  460 + s->dbc -= count;
  461 +
  462 + if (reason == SCSI_REASON_DONE) {
  463 + DPRINTF("Command complete sense=%d\n", sense);
  464 + s->sense = sense;
  465 + lsi_set_phase(s, PHASE_ST);
  466 + }
  467 +
  468 + if (s->dbc) {
  469 + lsi_do_dma(s, out);
  470 + } else if (s->waiting == 2) {
  471 + /* Restart SCRIPTS execution. */
  472 + s->waiting = 0;
  473 + lsi_execute_script(s);
  474 + }
  475 +}
443 476  
444 477 static void lsi_do_command(LSIState *s)
445 478 {
... ... @@ -461,15 +494,6 @@ static void lsi_do_command(LSIState *s)
461 494 }
462 495 }
463 496  
464   -static void lsi_command_complete(void *opaque, uint32_t tag, int sense)
465   -{
466   - LSIState *s = (LSIState *)opaque;
467   -
468   - DPRINTF("Command complete sense=%d\n", sense);
469   - s->sense = sense;
470   - lsi_set_phase(s, PHASE_ST);
471   -}
472   -
473 497 static void lsi_do_status(LSIState *s)
474 498 {
475 499 DPRINTF("Get status len=%d sense=%d\n", s->dbc, s->sense);
... ... @@ -1134,7 +1158,7 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
1134 1158 s->istat0 &= ~LSI_ISTAT0_INTF;
1135 1159 lsi_update_irq(s);
1136 1160 }
1137   - if (s->waiting && val & LSI_ISTAT0_SIGP) {
  1161 + if (s->waiting == 1 && val & LSI_ISTAT0_SIGP) {
1138 1162 DPRINTF("Woken by SIGP\n");
1139 1163 s->waiting = 0;
1140 1164 s->dsp = s->dnad;
... ...
hw/scsi-disk.c
... ... @@ -25,6 +25,7 @@ do { fprintf(stderr, &quot;scsi-disk: &quot; fmt , ##args); } while (0)
25 25  
26 26 #define SENSE_NO_SENSE 0
27 27 #define SENSE_NOT_READY 2
  28 +#define SENSE_HARDWARE_ERROR 4
28 29 #define SENSE_ILLEGAL_REQUEST 5
29 30  
30 31 struct SCSIDevice
... ... @@ -46,7 +47,13 @@ struct SCSIDevice
46 47 int buf_pos;
47 48 int buf_len;
48 49 int sense;
  50 + BlockDriverAIOCB *aiocb;
  51 + /* Data still to be transfered after this request completes. */
  52 + uint8_t *aiodata;
  53 + uint32_t aiolen;
49 54 char buf[512];
  55 + /* Completion functions may be called from either scsi_{read,write}_data
  56 + or from the AIO completion routines. */
50 57 scsi_completionfn completion;
51 58 void *opaque;
52 59 };
... ... @@ -54,10 +61,49 @@ struct SCSIDevice
54 61 static void scsi_command_complete(SCSIDevice *s, int sense)
55 62 {
56 63 s->sense = sense;
57   - s->completion(s->opaque, s->tag, sense);
  64 + s->completion(s->opaque, SCSI_REASON_DONE, sense);
58 65 }
59 66  
60   -/* Read data from a scsi device. Returns nonzero on failure. */
  67 +static void scsi_transfer_complete(SCSIDevice *s)
  68 +{
  69 + s->completion(s->opaque, SCSI_REASON_DATA, 0);
  70 + s->aiocb = NULL;
  71 +}
  72 +
  73 +static void scsi_read_complete(void * opaque, int ret)
  74 +{
  75 + SCSIDevice *s = (SCSIDevice *)opaque;
  76 +
  77 + if (ret) {
  78 + DPRINTF("IO error\n");
  79 + scsi_command_complete(s, SENSE_HARDWARE_ERROR);
  80 + }
  81 +
  82 + if (s->aiolen) {
  83 + /* Read the remaining data. Full and partial sectors are transferred
  84 + separately. */
  85 + scsi_read_data(s, s->aiodata, s->aiolen);
  86 + } else {
  87 + if (s->buf_len == 0 && s->sector_count == 0)
  88 + scsi_command_complete(s, SENSE_NO_SENSE);
  89 + else
  90 + scsi_transfer_complete(s);
  91 + }
  92 +}
  93 +
  94 +/* Cancel a pending data transfer. */
  95 +void scsi_cancel_io(SCSIDevice *s)
  96 +{
  97 + if (!s->aiocb) {
  98 + BADF("Cancel with no pending IO\n");
  99 + return;
  100 + }
  101 + bdrv_aio_cancel(s->aiocb);
  102 + s->aiocb = NULL;
  103 +}
  104 +
  105 +/* Read data from a scsi device. Returns nonzero on failure.
  106 + The transfer may complete asynchronously. */
61 107 int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len)
62 108 {
63 109 uint32_t n;
... ... @@ -84,14 +130,19 @@ int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len)
84 130 n = s->sector_count;
85 131  
86 132 if (n != 0) {
87   - bdrv_read(s->bdrv, s->sector, data, n);
88   - data += n * 512;
89   - len -= n * 512;
  133 + s->aiolen = len - n * 512;
  134 + s->aiodata = data + n * 512;
  135 + s->aiocb = bdrv_aio_read(s->bdrv, s->sector, data, n,
  136 + scsi_read_complete, s);
  137 + if (s->aiocb == NULL)
  138 + scsi_command_complete(s, SENSE_HARDWARE_ERROR);
90 139 s->sector += n;
91 140 s->sector_count -= n;
  141 + return 0;
92 142 }
93 143  
94 144 if (len && s->sector_count) {
  145 + /* TODO: Make this use AIO. */
95 146 bdrv_read(s->bdrv, s->sector, s->buf, 1);
96 147 s->sector++;
97 148 s->sector_count--;
... ... @@ -106,11 +157,53 @@ int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len)
106 157  
107 158 if (s->buf_len == 0 && s->sector_count == 0)
108 159 scsi_command_complete(s, SENSE_NO_SENSE);
  160 + else
  161 + scsi_transfer_complete(s);
109 162  
110 163 return 0;
111 164 }
112 165  
113   -/* Read data to a scsi device. Returns nonzero on failure. */
  166 +static void scsi_write_complete(void * opaque, int ret)
  167 +{
  168 + SCSIDevice *s = (SCSIDevice *)opaque;
  169 +
  170 + if (ret) {
  171 + fprintf(stderr, "scsi-disc: IO write error\n");
  172 + exit(1);
  173 + }
  174 +
  175 + if (s->sector_count == 0)
  176 + scsi_command_complete(s, SENSE_NO_SENSE);
  177 + else
  178 + scsi_transfer_complete(s);
  179 +}
  180 +
  181 +static uint32_t scsi_write_partial_sector(SCSIDevice *s, uint8_t *data,
  182 + uint32_t len)
  183 +{
  184 + int n;
  185 +
  186 + n = 512 - s->buf_len;
  187 + if (n > len)
  188 + n = len;
  189 +
  190 + memcpy(s->buf + s->buf_len, data, n);
  191 + data += n;
  192 + s->buf_len += n;
  193 + len -= n;
  194 + if (s->buf_len == 512) {
  195 + /* A full sector has been accumulated. Write it to disk. */
  196 + /* TODO: Make this use async IO. */
  197 + bdrv_write(s->bdrv, s->sector, s->buf, 1);
  198 + s->buf_len = 0;
  199 + s->sector++;
  200 + s->sector_count--;
  201 + }
  202 + return n;
  203 +}
  204 +
  205 +/* Write data to a scsi device. Returns nonzero on failure.
  206 + The transfer may complete asynchronously. */
114 207 int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len)
115 208 {
116 209 uint32_t n;
... ... @@ -125,48 +218,39 @@ int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len)
125 218 return 1;
126 219  
127 220 if (s->buf_len != 0 || len < 512) {
128   - n = 512 - s->buf_len;
129   - if (n > len)
130   - n = len;
131   -
132   - memcpy(s->buf + s->buf_len, data, n);
133   - data += n;
134   - s->buf_len += n;
  221 + n = scsi_write_partial_sector(s, data, len);
135 222 len -= n;
136   - if (s->buf_len == 512) {
137   - /* A full sector has been accumulated. Write it to disk. */
138   - bdrv_write(s->bdrv, s->sector, s->buf, 1);
139   - s->buf_len = 0;
140   - s->sector++;
141   - s->sector_count--;
142   - }
  223 + data += n;
143 224 }
144 225  
145 226 n = len / 512;
146 227 if (n > s->sector_count)
147   - n = s->sector_count;
  228 + return 1;
148 229  
149 230 if (n != 0) {
150   - bdrv_write(s->bdrv, s->sector, data, n);
  231 + s->aiocb = bdrv_aio_write(s->bdrv, s->sector, data, n,
  232 + scsi_write_complete, s);
  233 + if (s->aiocb == NULL)
  234 + scsi_command_complete(s, SENSE_HARDWARE_ERROR);
151 235 data += n * 512;
152 236 len -= n * 512;
153 237 s->sector += n;
154 238 s->sector_count -= n;
155 239 }
156 240  
157   - if (len >= 512)
158   - return 1;
159   -
160   - if (len && s->sector_count) {
161   - /* Recurse to complete the partial write. */
162   - return scsi_write_data(s, data, len);
  241 + if (len) {
  242 + if (s->sector_count == 0)
  243 + return 1;
  244 + /* Complete a partial write. */
  245 + scsi_write_partial_sector(s, data, len);
  246 + }
  247 + if (n == 0) {
  248 + /* Transfer completes immediately. */
  249 + if (s->sector_count == 0)
  250 + scsi_command_complete(s, SENSE_NO_SENSE);
  251 + else
  252 + scsi_transfer_complete(s);
163 253 }
164   -
165   - if (len != 0)
166   - return 1;
167   -
168   - if (s->sector_count == 0)
169   - scsi_command_complete(s, SENSE_NO_SENSE);
170 254  
171 255 return 0;
172 256 }
... ...
hw/usb-hid.c
... ... @@ -474,19 +474,18 @@ static int usb_mouse_handle_control(USBDevice *dev, int request, int value,
474 474 return ret;
475 475 }
476 476  
477   -static int usb_mouse_handle_data(USBDevice *dev, int pid,
478   - uint8_t devep, uint8_t *data, int len)
  477 +static int usb_mouse_handle_data(USBDevice *dev, USBPacket *p)
479 478 {
480 479 USBMouseState *s = (USBMouseState *)dev;
481 480 int ret = 0;
482 481  
483   - switch(pid) {
  482 + switch(p->pid) {
484 483 case USB_TOKEN_IN:
485   - if (devep == 1) {
  484 + if (p->devep == 1) {
486 485 if (s->kind == USB_MOUSE)
487   - ret = usb_mouse_poll(s, data, len);
  486 + ret = usb_mouse_poll(s, p->data, p->len);
488 487 else if (s->kind == USB_TABLET)
489   - ret = usb_tablet_poll(s, data, len);
  488 + ret = usb_tablet_poll(s, p->data, p->len);
490 489 } else {
491 490 goto fail;
492 491 }
... ...
hw/usb-hub.c
... ... @@ -180,8 +180,7 @@ static void usb_hub_attach(USBPort *port1, USBDevice *dev)
180 180 port->wPortStatus &= ~PORT_STAT_LOW_SPEED;
181 181 port->port.dev = dev;
182 182 /* send the attach message */
183   - dev->handle_packet(dev,
184   - USB_MSG_ATTACH, 0, 0, NULL, 0);
  183 + usb_send_msg(dev, USB_MSG_ATTACH);
185 184 } else {
186 185 dev = port->port.dev;
187 186 if (dev) {
... ... @@ -192,8 +191,7 @@ static void usb_hub_attach(USBPort *port1, USBDevice *dev)
192 191 port->wPortChange |= PORT_STAT_C_ENABLE;
193 192 }
194 193 /* send the detach message */
195   - dev->handle_packet(dev,
196   - USB_MSG_DETACH, 0, 0, NULL, 0);
  194 + usb_send_msg(dev, USB_MSG_DETACH);
197 195 port->port.dev = NULL;
198 196 }
199 197 }
... ... @@ -349,8 +347,7 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value,
349 347 break;
350 348 case PORT_RESET:
351 349 if (dev) {
352   - dev->handle_packet(dev,
353   - USB_MSG_RESET, 0, 0, NULL, 0);
  350 + usb_send_msg(dev, USB_MSG_RESET);
354 351 port->wPortChange |= PORT_STAT_C_RESET;
355 352 /* set enable bit */
356 353 port->wPortStatus |= PORT_STAT_ENABLE;
... ... @@ -434,22 +431,21 @@ static int usb_hub_handle_control(USBDevice *dev, int request, int value,
434 431 return ret;
435 432 }
436 433  
437   -static int usb_hub_handle_data(USBDevice *dev, int pid,
438   - uint8_t devep, uint8_t *data, int len)
  434 +static int usb_hub_handle_data(USBDevice *dev, USBPacket *p)
439 435 {
440 436 USBHubState *s = (USBHubState *)dev;
441 437 int ret;
442 438  
443   - switch(pid) {
  439 + switch(p->pid) {
444 440 case USB_TOKEN_IN:
445   - if (devep == 1) {
  441 + if (p->devep == 1) {
446 442 USBHubPort *port;
447 443 unsigned int status;
448 444 int i, n;
449 445 n = (s->nb_ports + 1 + 7) / 8;
450   - if (len == 1) { /* FreeBSD workaround */
  446 + if (p->len == 1) { /* FreeBSD workaround */
451 447 n = 1;
452   - } else if (n > len) {
  448 + } else if (n > p->len) {
453 449 return USB_RET_BABBLE;
454 450 }
455 451 status = 0;
... ... @@ -460,7 +456,7 @@ static int usb_hub_handle_data(USBDevice *dev, int pid,
460 456 }
461 457 if (status != 0) {
462 458 for(i = 0; i < n; i++) {
463   - data[i] = status >> (8 * i);
  459 + p->data[i] = status >> (8 * i);
464 460 }
465 461 ret = n;
466 462 } else {
... ... @@ -479,9 +475,7 @@ static int usb_hub_handle_data(USBDevice *dev, int pid,
479 475 return ret;
480 476 }
481 477  
482   -static int usb_hub_broadcast_packet(USBHubState *s, int pid,
483   - uint8_t devaddr, uint8_t devep,
484   - uint8_t *data, int len)
  478 +static int usb_hub_broadcast_packet(USBHubState *s, USBPacket *p)
485 479 {
486 480 USBHubPort *port;
487 481 USBDevice *dev;
... ... @@ -491,9 +485,7 @@ static int usb_hub_broadcast_packet(USBHubState *s, int pid,
491 485 port = &s->ports[i];
492 486 dev = port->port.dev;
493 487 if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) {
494   - ret = dev->handle_packet(dev, pid,
495   - devaddr, devep,
496   - data, len);
  488 + ret = dev->handle_packet(dev, p);
497 489 if (ret != USB_RET_NODEV) {
498 490 return ret;
499 491 }
... ... @@ -502,9 +494,7 @@ static int usb_hub_broadcast_packet(USBHubState *s, int pid,
502 494 return USB_RET_NODEV;
503 495 }
504 496  
505   -static int usb_hub_handle_packet(USBDevice *dev, int pid,
506   - uint8_t devaddr, uint8_t devep,
507   - uint8_t *data, int len)
  497 +static int usb_hub_handle_packet(USBDevice *dev, USBPacket *p)
508 498 {
509 499 USBHubState *s = (USBHubState *)dev;
510 500  
... ... @@ -513,14 +503,14 @@ static int usb_hub_handle_packet(USBDevice *dev, int pid,
513 503 #endif
514 504 if (dev->state == USB_STATE_DEFAULT &&
515 505 dev->addr != 0 &&
516   - devaddr != dev->addr &&
517   - (pid == USB_TOKEN_SETUP ||
518   - pid == USB_TOKEN_OUT ||
519   - pid == USB_TOKEN_IN)) {
  506 + p->devaddr != dev->addr &&
  507 + (p->pid == USB_TOKEN_SETUP ||
  508 + p->pid == USB_TOKEN_OUT ||
  509 + p->pid == USB_TOKEN_IN)) {
520 510 /* broadcast the packet to the devices */
521   - return usb_hub_broadcast_packet(s, pid, devaddr, devep, data, len);
  511 + return usb_hub_broadcast_packet(s, p);
522 512 }
523   - return usb_generic_handle_packet(dev, pid, devaddr, devep, data, len);
  513 + return usb_generic_handle_packet(dev, p);
524 514 }
525 515  
526 516 static void usb_hub_handle_destroy(USBDevice *dev)
... ...
hw/usb-msd.c
... ... @@ -33,9 +33,12 @@ typedef struct {
33 33 USBDevice dev;
34 34 enum USBMSDMode mode;
35 35 uint32_t data_len;
  36 + uint32_t transfer_len;
36 37 uint32_t tag;
37 38 SCSIDevice *scsi_dev;
38 39 int result;
  40 + /* For async completion. */
  41 + USBPacket *packet;
39 42 } MSDState;
40 43  
41 44 static const uint8_t qemu_msd_dev_descriptor[] = {
... ... @@ -103,13 +106,27 @@ static const uint8_t qemu_msd_config_descriptor[] = {
103 106 0x00 /* u8 ep_bInterval; */
104 107 };
105 108  
106   -static void usb_msd_command_complete(void *opaque, uint32_t tag, int fail)
  109 +static void usb_msd_command_complete(void *opaque, uint32_t reason, int fail)
107 110 {
108 111 MSDState *s = (MSDState *)opaque;
109   -
110   - DPRINTF("Command complete\n");
111   - s->result = fail;
112   - s->mode = USB_MSDM_CSW;
  112 + USBPacket *p;
  113 +
  114 + s->data_len -= s->transfer_len;
  115 + s->transfer_len = 0;
  116 + if (reason == SCSI_REASON_DONE) {
  117 + DPRINTF("Command complete %d\n", fail);
  118 + s->result = fail;
  119 + s->mode = USB_MSDM_CSW;
  120 + }
  121 + if (s->packet) {
  122 + /* Set s->packet to NULL before calling usb_packet_complete because
  123 + annother request may be issues before usb_packet_complete returns.
  124 + */
  125 + DPRINTF("Packet complete %p\n", p);
  126 + p = s->packet;
  127 + s->packet = NULL;
  128 + usb_packet_complete(p);
  129 + }
113 130 }
114 131  
115 132 static void usb_msd_handle_reset(USBDevice *dev)
... ... @@ -250,15 +267,24 @@ struct usb_msd_csw {
250 267 uint8_t status;
251 268 };
252 269  
253   -static int usb_msd_handle_data(USBDevice *dev, int pid, uint8_t devep,
254   - uint8_t *data, int len)
  270 +static void usb_msd_cancel_io(USBPacket *p, void *opaque)
  271 +{
  272 + MSDState *s = opaque;
  273 + scsi_cancel_io(s->scsi_dev);
  274 + s->packet = NULL;
  275 +}
  276 +
  277 +static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
255 278 {
256 279 MSDState *s = (MSDState *)dev;
257 280 int ret = 0;
258 281 struct usb_msd_cbw cbw;
259 282 struct usb_msd_csw csw;
  283 + uint8_t devep = p->devep;
  284 + uint8_t *data = p->data;
  285 + int len = p->len;
260 286  
261   - switch (pid) {
  287 + switch (p->pid) {
262 288 case USB_TOKEN_OUT:
263 289 if (devep != 2)
264 290 goto fail;
... ... @@ -300,13 +326,18 @@ static int usb_msd_handle_data(USBDevice *dev, int pid, uint8_t devep,
300 326 if (len > s->data_len)
301 327 goto fail;
302 328  
  329 + s->transfer_len = len;
303 330 if (scsi_write_data(s->scsi_dev, data, len))
304 331 goto fail;
305 332  
306   - s->data_len -= len;
307   - if (s->data_len == 0)
308   - s->mode = USB_MSDM_CSW;
309   - ret = len;
  333 + if (s->transfer_len == 0) {
  334 + ret = len;
  335 + } else {
  336 + DPRINTF("Deferring packet %p\n", p);
  337 + usb_defer_packet(p, usb_msd_cancel_io, s);
  338 + s->packet = p;
  339 + ret = USB_RET_ASYNC;
  340 + }
310 341 break;
311 342  
312 343 default:
... ... @@ -340,13 +371,18 @@ static int usb_msd_handle_data(USBDevice *dev, int pid, uint8_t devep,
340 371 if (len > s->data_len)
341 372 len = s->data_len;
342 373  
  374 + s->transfer_len = len;
343 375 if (scsi_read_data(s->scsi_dev, data, len))
344 376 goto fail;
345 377  
346   - s->data_len -= len;
347   - if (s->data_len == 0)
348   - s->mode = USB_MSDM_CSW;
349   - ret = len;
  378 + if (s->transfer_len == 0) {
  379 + ret = len;
  380 + } else {
  381 + DPRINTF("Deferring packet %p\n", p);
  382 + usb_defer_packet(p, usb_msd_cancel_io, s);
  383 + s->packet = p;
  384 + ret = USB_RET_ASYNC;
  385 + }
350 386 break;
351 387  
352 388 default:
... ...
hw/usb-ohci.c
... ... @@ -89,6 +89,14 @@ typedef struct {
89 89 uint32_t rhdesc_a, rhdesc_b;
90 90 uint32_t rhstatus;
91 91 OHCIPort rhport[OHCI_MAX_PORTS];
  92 +
  93 + /* Active packets. */
  94 + uint32_t old_ctl;
  95 + USBPacket usb_packet;
  96 + uint8_t usb_buf[8192];
  97 + uint32_t async_td;
  98 + int async_complete;
  99 +
92 100 } OHCIState;
93 101  
94 102 /* Host Controller Communications Area */
... ... @@ -288,8 +296,7 @@ static void ohci_attach(USBPort *port1, USBDevice *dev)
288 296 port->ctrl &= ~OHCI_PORT_LSDA;
289 297 port->port.dev = dev;
290 298 /* send the attach message */
291   - dev->handle_packet(dev,
292   - USB_MSG_ATTACH, 0, 0, NULL, 0);
  299 + usb_send_msg(dev, USB_MSG_ATTACH);
293 300 dprintf("usb-ohci: Attached port %d\n", port1->index);
294 301 } else {
295 302 /* set connect status */
... ... @@ -305,8 +312,7 @@ static void ohci_attach(USBPort *port1, USBDevice *dev)
305 312 dev = port->port.dev;
306 313 if (dev) {
307 314 /* send the detach message */
308   - dev->handle_packet(dev,
309   - USB_MSG_DETACH, 0, 0, NULL, 0);
  315 + usb_send_msg(dev, USB_MSG_DETACH);
310 316 }
311 317 port->port.dev = NULL;
312 318 dprintf("usb-ohci: Detached port %d\n", port1->index);
... ... @@ -323,6 +329,7 @@ static void ohci_reset(OHCIState *ohci)
323 329 int i;
324 330  
325 331 ohci->ctl = 0;
  332 + ohci->old_ctl = 0;
326 333 ohci->status = 0;
327 334 ohci->intr_status = 0;
328 335 ohci->intr = OHCI_INTR_MIE;
... ... @@ -356,6 +363,10 @@ static void ohci_reset(OHCIState *ohci)
356 363 if (port->port.dev)
357 364 ohci_attach(&port->port, port->port.dev);
358 365 }
  366 + if (ohci->async_td) {
  367 + usb_cancel_packet(&ohci->usb_packet);
  368 + ohci->async_td = 0;
  369 + }
359 370 dprintf("usb-ohci: Reset %s\n", ohci->pci_dev.name);
360 371 }
361 372  
... ... @@ -423,6 +434,18 @@ static void ohci_copy_td(struct ohci_td *td, uint8_t *buf, int len, int write)
423 434 cpu_physical_memory_rw(ptr, buf, len - n, write);
424 435 }
425 436  
  437 +static void ohci_process_lists(OHCIState *ohci);
  438 +
  439 +static void ohci_async_complete_packet(USBPacket * packet, void *opaque)
  440 +{
  441 + OHCIState *ohci = opaque;
  442 +#ifdef DEBUG_PACKET
  443 + dprintf("Async packet complete\n");
  444 +#endif
  445 + ohci->async_complete = 1;
  446 + ohci_process_lists(ohci);
  447 +}
  448 +
426 449 /* Service a transport descriptor.
427 450 Returns nonzero to terminate processing of this endpoint. */
428 451  
... ... @@ -430,7 +453,6 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
430 453 {
431 454 int dir;
432 455 size_t len = 0;
433   - uint8_t buf[8192];
434 456 char *str = NULL;
435 457 int pid;
436 458 int ret;
... ... @@ -439,8 +461,17 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
439 461 struct ohci_td td;
440 462 uint32_t addr;
441 463 int flag_r;
  464 + int completion;
442 465  
443 466 addr = ed->head & OHCI_DPTR_MASK;
  467 + /* See if this TD has already been submitted to the device. */
  468 + completion = (addr == ohci->async_td);
  469 + if (completion && !ohci->async_complete) {
  470 +#ifdef DEBUG_PACKET
  471 + dprintf("Skipping async TD\n");
  472 +#endif
  473 + return 1;
  474 + }
444 475 if (!ohci_read_td(addr, &td)) {
445 476 fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);
446 477 return 0;
... ... @@ -481,8 +512,8 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
481 512 len = (td.be - td.cbp) + 1;
482 513 }
483 514  
484   - if (len && dir != OHCI_TD_DIR_IN) {
485   - ohci_copy_td(&td, buf, len, 0);
  515 + if (len && dir != OHCI_TD_DIR_IN && !completion) {
  516 + ohci_copy_td(&td, ohci->usb_buf, len, 0);
486 517 }
487 518 }
488 519  
... ... @@ -494,31 +525,58 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
494 525 if (len >= 0 && dir != OHCI_TD_DIR_IN) {
495 526 dprintf(" data:");
496 527 for (i = 0; i < len; i++)
497   - printf(" %.2x", buf[i]);
  528 + printf(" %.2x", ohci->usb_buf[i]);
498 529 dprintf("\n");
499 530 }
500 531 #endif
501   - ret = USB_RET_NODEV;
502   - for (i = 0; i < ohci->num_ports; i++) {
503   - dev = ohci->rhport[i].port.dev;
504   - if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
505   - continue;
506   -
507   - ret = dev->handle_packet(dev, pid, OHCI_BM(ed->flags, ED_FA),
508   - OHCI_BM(ed->flags, ED_EN), buf, len);
509   - if (ret != USB_RET_NODEV)
510   - break;
511   - }
  532 + if (completion) {
  533 + ret = ohci->usb_packet.len;
  534 + ohci->async_td = 0;
  535 + ohci->async_complete = 0;
  536 + } else {
  537 + ret = USB_RET_NODEV;
  538 + for (i = 0; i < ohci->num_ports; i++) {
  539 + dev = ohci->rhport[i].port.dev;
  540 + if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0)
  541 + continue;
  542 +
  543 + if (ohci->async_td) {
  544 + /* ??? The hardware should allow one active packet per
  545 + endpoint. We only allow one active packet per controller.
  546 + This should be sufficient as long as devices respond in a
  547 + timely manner.
  548 + */
512 549 #ifdef DEBUG_PACKET
513   - dprintf("ret=%d\n", ret);
  550 + dprintf("Too many pending packets\n");
514 551 #endif
  552 + return 1;
  553 + }
  554 + ohci->usb_packet.pid = pid;
  555 + ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA);
  556 + ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN);
  557 + ohci->usb_packet.data = ohci->usb_buf;
  558 + ohci->usb_packet.len = len;
  559 + ohci->usb_packet.complete_cb = ohci_async_complete_packet;
  560 + ohci->usb_packet.complete_opaque = ohci;
  561 + ret = dev->handle_packet(dev, &ohci->usb_packet);
  562 + if (ret != USB_RET_NODEV)
  563 + break;
  564 + }
  565 +#ifdef DEBUG_PACKET
  566 + dprintf("ret=%d\n", ret);
  567 +#endif
  568 + if (ret == USB_RET_ASYNC) {
  569 + ohci->async_td = addr;
  570 + return 1;
  571 + }
  572 + }
515 573 if (ret >= 0) {
516 574 if (dir == OHCI_TD_DIR_IN) {
517   - ohci_copy_td(&td, buf, ret, 1);
  575 + ohci_copy_td(&td, ohci->usb_buf, ret, 1);
518 576 #ifdef DEBUG_PACKET
519 577 dprintf(" data:");
520 578 for (i = 0; i < ret; i++)
521   - printf(" %.2x", buf[i]);
  579 + printf(" %.2x", ohci->usb_buf[i]);
522 580 dprintf("\n");
523 581 #endif
524 582 } else {
... ... @@ -608,8 +666,16 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head)
608 666  
609 667 next_ed = ed.next & OHCI_DPTR_MASK;
610 668  
611   - if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K))
  669 + if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
  670 + uint32_t addr;
  671 + /* Cancel pending packets for ED that have been paused. */
  672 + addr = ed.head & OHCI_DPTR_MASK;
  673 + if (ohci->async_td && addr == ohci->async_td) {
  674 + usb_cancel_packet(&ohci->usb_packet);
  675 + ohci->async_td = 0;
  676 + }
612 677 continue;
  678 + }
613 679  
614 680 /* Skip isochronous endpoints. */
615 681 if (ed.flags & OHCI_ED_F)
... ... @@ -646,6 +712,26 @@ static void ohci_sof(OHCIState *ohci)
646 712 ohci_set_interrupt(ohci, OHCI_INTR_SF);
647 713 }
648 714  
  715 +/* Process Control and Bulk lists. */
  716 +static void ohci_process_lists(OHCIState *ohci)
  717 +{
  718 + if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) {
  719 + if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head)
  720 + dprintf("usb-ohci: head %x, cur %x\n", ohci->ctrl_head, ohci->ctrl_cur);
  721 + if (!ohci_service_ed_list(ohci, ohci->ctrl_head)) {
  722 + ohci->ctrl_cur = 0;
  723 + ohci->status &= ~OHCI_STATUS_CLF;
  724 + }
  725 + }
  726 +
  727 + if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) {
  728 + if (!ohci_service_ed_list(ohci, ohci->bulk_head)) {
  729 + ohci->bulk_cur = 0;
  730 + ohci->status &= ~OHCI_STATUS_BLF;
  731 + }
  732 + }
  733 +}
  734 +
649 735 /* Do frame processing on frame boundary */
650 736 static void ohci_frame_boundary(void *opaque)
651 737 {
... ... @@ -661,21 +747,15 @@ static void ohci_frame_boundary(void *opaque)
661 747 n = ohci->frame_number & 0x1f;
662 748 ohci_service_ed_list(ohci, le32_to_cpu(hcca.intr[n]));
663 749 }
664   - if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) {
665   - if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head)
666   - dprintf("usb-ohci: head %x, cur %x\n", ohci->ctrl_head, ohci->ctrl_cur);
667   - if (!ohci_service_ed_list(ohci, ohci->ctrl_head)) {
668   - ohci->ctrl_cur = 0;
669   - ohci->status &= ~OHCI_STATUS_CLF;
670   - }
671   - }
672 750  
673   - if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) {
674   - if (!ohci_service_ed_list(ohci, ohci->bulk_head)) {
675   - ohci->bulk_cur = 0;
676   - ohci->status &= ~OHCI_STATUS_BLF;
677   - }
  751 + /* Cancel all pending packets if either of the lists has been disabled. */
  752 + if (ohci->async_td &&
  753 + ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) {
  754 + usb_cancel_packet(&ohci->usb_packet);
  755 + ohci->async_td = 0;
678 756 }
  757 + ohci->old_ctl = ohci->ctl;
  758 + ohci_process_lists(ohci);
679 759  
680 760 /* Frame boundary, so do EOF stuf here */
681 761 ohci->frt = ohci->fit;
... ... @@ -907,8 +987,7 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val)
907 987  
908 988 if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) {
909 989 dprintf("usb-ohci: port %d: RESET\n", portnum);
910   - port->port.dev->handle_packet(port->port.dev, USB_MSG_RESET,
911   - 0, 0, NULL, 0);
  990 + usb_send_msg(port->port.dev, USB_MSG_RESET);
912 991 port->ctrl &= ~OHCI_PORT_PRS;
913 992 /* ??? Should this also set OHCI_PORT_PESC. */
914 993 port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC;
... ... @@ -1186,5 +1265,6 @@ void usb_ohci_init(struct PCIBus *bus, int num_ports, int devfn)
1186 1265 qemu_register_usb_port(&ohci->rhport[i].port, ohci, i, ohci_attach);
1187 1266 }
1188 1267  
  1268 + ohci->async_td = 0;
1189 1269 ohci_reset(ohci);
1190 1270 }
... ...
hw/usb-uhci.c
... ... @@ -76,6 +76,18 @@ typedef struct UHCIState {
76 76 uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */
77 77 QEMUTimer *frame_timer;
78 78 UHCIPort ports[NB_PORTS];
  79 +
  80 + /* Interrupts that should be raised at the end of the current frame. */
  81 + uint32_t pending_int_mask;
  82 + /* For simplicity of implementation we only allow a single pending USB
  83 + request. This means all usb traffic on this controller is effectively
  84 + suspended until that transfer completes. When the transfer completes
  85 + the next transfer from that queue will be processed. However
  86 + other queues will not be processed until the next frame. The solution
  87 + is to allow multiple pending requests. */
  88 + uint32_t async_qh;
  89 + USBPacket usb_packet;
  90 + uint8_t usb_buf[1280];
79 91 } UHCIState;
80 92  
81 93 typedef struct UHCI_TD {
... ... @@ -188,8 +200,7 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
188 200 port = &s->ports[i];
189 201 dev = port->port.dev;
190 202 if (dev) {
191   - dev->handle_packet(dev,
192   - USB_MSG_RESET, 0, 0, NULL, 0);
  203 + usb_send_msg(dev, USB_MSG_RESET);
193 204 }
194 205 }
195 206 uhci_reset(s);
... ... @@ -232,8 +243,7 @@ static void uhci_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
232 243 /* port reset */
233 244 if ( (val & UHCI_PORT_RESET) &&
234 245 !(port->ctrl & UHCI_PORT_RESET) ) {
235   - dev->handle_packet(dev,
236   - USB_MSG_RESET, 0, 0, NULL, 0);
  246 + usb_send_msg(dev, USB_MSG_RESET);
237 247 }
238 248 }
239 249 port->ctrl = (port->ctrl & 0x01fb) | (val & ~0x01fb);
... ... @@ -336,8 +346,7 @@ static void uhci_attach(USBPort *port1, USBDevice *dev)
336 346 port->ctrl &= ~UHCI_PORT_LSDA;
337 347 port->port.dev = dev;
338 348 /* send the attach message */
339   - dev->handle_packet(dev,
340   - USB_MSG_ATTACH, 0, 0, NULL, 0);
  349 + usb_send_msg(dev, USB_MSG_ATTACH);
341 350 } else {
342 351 /* set connect status */
343 352 if (port->ctrl & UHCI_PORT_CCS) {
... ... @@ -352,16 +361,13 @@ static void uhci_attach(USBPort *port1, USBDevice *dev)
352 361 dev = port->port.dev;
353 362 if (dev) {
354 363 /* send the detach message */
355   - dev->handle_packet(dev,
356   - USB_MSG_DETACH, 0, 0, NULL, 0);
  364 + usb_send_msg(dev, USB_MSG_DETACH);
357 365 }
358 366 port->port.dev = NULL;
359 367 }
360 368 }
361 369  
362   -static int uhci_broadcast_packet(UHCIState *s, uint8_t pid,
363   - uint8_t devaddr, uint8_t devep,
364   - uint8_t *data, int len)
  370 +static int uhci_broadcast_packet(UHCIState *s, USBPacket *p)
365 371 {
366 372 UHCIPort *port;
367 373 USBDevice *dev;
... ... @@ -370,18 +376,18 @@ static int uhci_broadcast_packet(UHCIState *s, uint8_t pid,
370 376 #ifdef DEBUG_PACKET
371 377 {
372 378 const char *pidstr;
373   - switch(pid) {
  379 + switch(p->pid) {
374 380 case USB_TOKEN_SETUP: pidstr = "SETUP"; break;
375 381 case USB_TOKEN_IN: pidstr = "IN"; break;
376 382 case USB_TOKEN_OUT: pidstr = "OUT"; break;
377 383 default: pidstr = "?"; break;
378 384 }
379 385 printf("frame %d: pid=%s addr=0x%02x ep=%d len=%d\n",
380   - s->frnum, pidstr, devaddr, devep, len);
381   - if (pid != USB_TOKEN_IN) {
  386 + s->frnum, pidstr, p->devaddr, p->devep, p->len);
  387 + if (p->pid != USB_TOKEN_IN) {
382 388 printf(" data_out=");
383   - for(i = 0; i < len; i++) {
384   - printf(" %02x", data[i]);
  389 + for(i = 0; i < p->len; i++) {
  390 + printf(" %02x", p->data[i]);
385 391 }
386 392 printf("\n");
387 393 }
... ... @@ -391,17 +397,17 @@ static int uhci_broadcast_packet(UHCIState *s, uint8_t pid,
391 397 port = &s->ports[i];
392 398 dev = port->port.dev;
393 399 if (dev && (port->ctrl & UHCI_PORT_EN)) {
394   - ret = dev->handle_packet(dev, pid,
395   - devaddr, devep,
396   - data, len);
  400 + ret = dev->handle_packet(dev, p);
397 401 if (ret != USB_RET_NODEV) {
398 402 #ifdef DEBUG_PACKET
399   - {
  403 + if (ret == USB_RET_ASYNC) {
  404 + printf("usb-uhci: Async packet\n");
  405 + } else {
400 406 printf(" ret=%d ", ret);
401   - if (pid == USB_TOKEN_IN && ret > 0) {
  407 + if (p->pid == USB_TOKEN_IN && ret > 0) {
402 408 printf("data_in=");
403 409 for(i = 0; i < ret; i++) {
404   - printf(" %02x", data[i]);
  410 + printf(" %02x", p->data[i]);
405 411 }
406 412 }
407 413 printf("\n");
... ... @@ -414,6 +420,8 @@ static int uhci_broadcast_packet(UHCIState *s, uint8_t pid,
414 420 return USB_RET_NODEV;
415 421 }
416 422  
  423 +static void uhci_async_complete_packet(USBPacket * packet, void *opaque);
  424 +
417 425 /* return -1 if fatal error (frame must be stopped)
418 426 0 if TD successful
419 427 1 if TD unsuccessful or inactive
... ... @@ -421,9 +429,9 @@ static int uhci_broadcast_packet(UHCIState *s, uint8_t pid,
421 429 static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
422 430 {
423 431 uint8_t pid;
424   - uint8_t buf[1280];
425 432 int len, max_len, err, ret;
426 433  
  434 + /* ??? This is wrong for async completion. */
427 435 if (td->ctrl & TD_CTRL_IOC) {
428 436 *int_mask |= 0x01;
429 437 }
... ... @@ -434,21 +442,8 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
434 442 /* TD is active */
435 443 max_len = ((td->token >> 21) + 1) & 0x7ff;
436 444 pid = td->token & 0xff;
437   - switch(pid) {
438   - case USB_TOKEN_OUT:
439   - case USB_TOKEN_SETUP:
440   - cpu_physical_memory_read(td->buffer, buf, max_len);
441   - ret = uhci_broadcast_packet(s, pid,
442   - (td->token >> 8) & 0x7f,
443   - (td->token >> 15) & 0xf,
444   - buf, max_len);
445   - len = max_len;
446   - break;
447   - case USB_TOKEN_IN:
448   - ret = uhci_broadcast_packet(s, pid,
449   - (td->token >> 8) & 0x7f,
450   - (td->token >> 15) & 0xf,
451   - buf, max_len);
  445 + if (s->async_qh) {
  446 + ret = s->usb_packet.len;
452 447 if (ret >= 0) {
453 448 len = ret;
454 449 if (len > max_len) {
... ... @@ -457,17 +452,52 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
457 452 }
458 453 if (len > 0) {
459 454 /* write the data back */
460   - cpu_physical_memory_write(td->buffer, buf, len);
  455 + cpu_physical_memory_write(td->buffer, s->usb_buf, len);
461 456 }
462 457 } else {
463 458 len = 0;
464 459 }
465   - break;
466   - default:
467   - /* invalid pid : frame interrupted */
468   - s->status |= UHCI_STS_HCPERR;
469   - uhci_update_irq(s);
470   - return -1;
  460 + s->async_qh = 0;
  461 + } else {
  462 + s->usb_packet.pid = pid;
  463 + s->usb_packet.devaddr = (td->token >> 8) & 0x7f;
  464 + s->usb_packet.devep = (td->token >> 15) & 0xf;
  465 + s->usb_packet.data = s->usb_buf;
  466 + s->usb_packet.len = max_len;
  467 + s->usb_packet.complete_cb = uhci_async_complete_packet;
  468 + s->usb_packet.complete_opaque = s;
  469 + switch(pid) {
  470 + case USB_TOKEN_OUT:
  471 + case USB_TOKEN_SETUP:
  472 + cpu_physical_memory_read(td->buffer, s->usb_buf, max_len);
  473 + ret = uhci_broadcast_packet(s, &s->usb_packet);
  474 + len = max_len;
  475 + break;
  476 + case USB_TOKEN_IN:
  477 + ret = uhci_broadcast_packet(s, &s->usb_packet);
  478 + if (ret >= 0) {
  479 + len = ret;
  480 + if (len > max_len) {
  481 + len = max_len;
  482 + ret = USB_RET_BABBLE;
  483 + }
  484 + if (len > 0) {
  485 + /* write the data back */
  486 + cpu_physical_memory_write(td->buffer, s->usb_buf, len);
  487 + }
  488 + } else {
  489 + len = 0;
  490 + }
  491 + break;
  492 + default:
  493 + /* invalid pid : frame interrupted */
  494 + s->status |= UHCI_STS_HCPERR;
  495 + uhci_update_irq(s);
  496 + return -1;
  497 + }
  498 + }
  499 + if (ret == USB_RET_ASYNC) {
  500 + return 2;
471 501 }
472 502 if (td->ctrl & TD_CTRL_IOS)
473 503 td->ctrl &= ~TD_CTRL_ACTIVE;
... ... @@ -520,6 +550,61 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
520 550 }
521 551 }
522 552  
  553 +static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
  554 +{
  555 + UHCIState *s = opaque;
  556 + UHCI_QH qh;
  557 + UHCI_TD td;
  558 + uint32_t link;
  559 + uint32_t old_td_ctrl;
  560 + uint32_t val;
  561 + int ret;
  562 +
  563 + link = s->async_qh;
  564 + if (!link) {
  565 + /* This should never happen. It means a TD somehow got removed
  566 + without cancelling the associated async IO request. */
  567 + return;
  568 + }
  569 + cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
  570 + le32_to_cpus(&qh.link);
  571 + le32_to_cpus(&qh.el_link);
  572 + /* Re-process the queue containing the async packet. */
  573 + while (1) {
  574 + cpu_physical_memory_read(qh.el_link & ~0xf,
  575 + (uint8_t *)&td, sizeof(td));
  576 + le32_to_cpus(&td.link);
  577 + le32_to_cpus(&td.ctrl);
  578 + le32_to_cpus(&td.token);
  579 + le32_to_cpus(&td.buffer);
  580 + old_td_ctrl = td.ctrl;
  581 + ret = uhci_handle_td(s, &td, &s->pending_int_mask);
  582 + /* update the status bits of the TD */
  583 + if (old_td_ctrl != td.ctrl) {
  584 + val = cpu_to_le32(td.ctrl);
  585 + cpu_physical_memory_write((qh.el_link & ~0xf) + 4,
  586 + (const uint8_t *)&val,
  587 + sizeof(val));
  588 + }
  589 + if (ret < 0)
  590 + break; /* interrupted frame */
  591 + if (ret == 2) {
  592 + s->async_qh = link;
  593 + break;
  594 + } else if (ret == 0) {
  595 + /* update qh element link */
  596 + qh.el_link = td.link;
  597 + val = cpu_to_le32(qh.el_link);
  598 + cpu_physical_memory_write((link & ~0xf) + 4,
  599 + (const uint8_t *)&val,
  600 + sizeof(val));
  601 + if (!(qh.el_link & 4))
  602 + break;
  603 + }
  604 + break;
  605 + }
  606 +}
  607 +
523 608 static void uhci_frame_timer(void *opaque)
524 609 {
525 610 UHCIState *s = opaque;
... ... @@ -528,6 +613,7 @@ static void uhci_frame_timer(void *opaque)
528 613 int int_mask, cnt, ret;
529 614 UHCI_TD td;
530 615 UHCI_QH qh;
  616 + uint32_t old_async_qh;
531 617  
532 618 if (!(s->cmd & UHCI_CMD_RS)) {
533 619 qemu_del_timer(s->frame_timer);
... ... @@ -535,6 +621,14 @@ static void uhci_frame_timer(void *opaque)
535 621 s->status |= UHCI_STS_HCHALTED;
536 622 return;
537 623 }
  624 + /* Complete the previous frame. */
  625 + s->frnum = (s->frnum + 1) & 0x7ff;
  626 + if (s->pending_int_mask) {
  627 + s->status2 |= s->pending_int_mask;
  628 + s->status |= UHCI_STS_USBINT;
  629 + uhci_update_irq(s);
  630 + }
  631 + old_async_qh = s->async_qh;
538 632 frame_addr = s->fl_base_addr + ((s->frnum & 0x3ff) << 2);
539 633 cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
540 634 le32_to_cpus(&link);
... ... @@ -546,6 +640,12 @@ static void uhci_frame_timer(void *opaque)
546 640 /* valid frame */
547 641 if (link & 2) {
548 642 /* QH */
  643 + if (link == s->async_qh) {
  644 + /* We've found a previously issues packet.
  645 + Nothing else to do. */
  646 + old_async_qh = 0;
  647 + break;
  648 + }
549 649 cpu_physical_memory_read(link & ~0xf, (uint8_t *)&qh, sizeof(qh));
550 650 le32_to_cpus(&qh.link);
551 651 le32_to_cpus(&qh.el_link);
... ... @@ -556,6 +656,10 @@ static void uhci_frame_timer(void *opaque)
556 656 } else if (qh.el_link & 2) {
557 657 /* QH */
558 658 link = qh.el_link;
  659 + } else if (s->async_qh) {
  660 + /* We can only cope with one pending packet. Keep looking
  661 + for the previously issued packet. */
  662 + link = qh.link;
559 663 } else {
560 664 /* TD */
561 665 if (--cnt == 0)
... ... @@ -577,7 +681,9 @@ static void uhci_frame_timer(void *opaque)
577 681 }
578 682 if (ret < 0)
579 683 break; /* interrupted frame */
580   - if (ret == 0) {
  684 + if (ret == 2) {
  685 + s->async_qh = link;
  686 + } else if (ret == 0) {
581 687 /* update qh element link */
582 688 qh.el_link = td.link;
583 689 val = cpu_to_le32(qh.el_link);
... ... @@ -599,25 +705,41 @@ static void uhci_frame_timer(void *opaque)
599 705 le32_to_cpus(&td.ctrl);
600 706 le32_to_cpus(&td.token);
601 707 le32_to_cpus(&td.buffer);
602   - old_td_ctrl = td.ctrl;
603   - ret = uhci_handle_td(s, &td, &int_mask);
604   - /* update the status bits of the TD */
605   - if (old_td_ctrl != td.ctrl) {
606   - val = cpu_to_le32(td.ctrl);
607   - cpu_physical_memory_write((link & ~0xf) + 4,
608   - (const uint8_t *)&val,
609   - sizeof(val));
  708 + /* Ignore isochonous transfers while there is an async packet
  709 + pending. This is wrong, but we don't implement isochronous
  710 + transfers anyway. */
  711 + if (s->async_qh == 0) {
  712 + old_td_ctrl = td.ctrl;
  713 + ret = uhci_handle_td(s, &td, &int_mask);
  714 + /* update the status bits of the TD */
  715 + if (old_td_ctrl != td.ctrl) {
  716 + val = cpu_to_le32(td.ctrl);
  717 + cpu_physical_memory_write((link & ~0xf) + 4,
  718 + (const uint8_t *)&val,
  719 + sizeof(val));
  720 + }
  721 + if (ret < 0)
  722 + break; /* interrupted frame */
  723 + if (ret == 2) {
  724 + /* We can't handle async isochronous transfers.
  725 + Cancel The packet. */
  726 + fprintf(stderr, "usb-uhci: Unimplemented async packet\n");
  727 + usb_cancel_packet(&s->usb_packet);
  728 + }
610 729 }
611   - if (ret < 0)
612   - break; /* interrupted frame */
613 730 link = td.link;
614 731 }
615 732 }
616   - s->frnum = (s->frnum + 1) & 0x7ff;
617   - if (int_mask) {
618   - s->status2 |= int_mask;
619   - s->status |= UHCI_STS_USBINT;
620   - uhci_update_irq(s);
  733 + s->pending_int_mask = int_mask;
  734 + if (old_async_qh) {
  735 + /* A previously started transfer has disappeared from the transfer
  736 + list. There's nothing useful we can do with it now, so just
  737 + discard the packet and hope it wasn't too important. */
  738 +#ifdef DEBUG
  739 + printf("Discarding USB packet\n");
  740 +#endif
  741 + usb_cancel_packet(&s->usb_packet);
  742 + s->async_qh = 0;
621 743 }
622 744 /* prepare the timer for the next frame */
623 745 expire_time = qemu_get_clock(vm_clock) +
... ...
hw/usb.c
... ... @@ -38,13 +38,13 @@ void usb_attach(USBPort *port, USBDevice *dev)
38 38 #define SETUP_STATE_DATA 1
39 39 #define SETUP_STATE_ACK 2
40 40  
41   -int usb_generic_handle_packet(USBDevice *s, int pid,
42   - uint8_t devaddr, uint8_t devep,
43   - uint8_t *data, int len)
  41 +int usb_generic_handle_packet(USBDevice *s, USBPacket *p)
44 42 {
45 43 int l, ret = 0;
  44 + int len = p->len;
  45 + uint8_t *data = p->data;
46 46  
47   - switch(pid) {
  47 + switch(p->pid) {
48 48 case USB_MSG_ATTACH:
49 49 s->state = USB_STATE_ATTACHED;
50 50 break;
... ... @@ -58,7 +58,7 @@ int usb_generic_handle_packet(USBDevice *s, int pid,
58 58 s->handle_reset(s);
59 59 break;
60 60 case USB_TOKEN_SETUP:
61   - if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
  61 + if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
62 62 return USB_RET_NODEV;
63 63 if (len != 8)
64 64 goto fail;
... ... @@ -85,9 +85,9 @@ int usb_generic_handle_packet(USBDevice *s, int pid,
85 85 }
86 86 break;
87 87 case USB_TOKEN_IN:
88   - if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
  88 + if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
89 89 return USB_RET_NODEV;
90   - switch(devep) {
  90 + switch(p->devep) {
91 91 case 0:
92 92 switch(s->setup_state) {
93 93 case SETUP_STATE_ACK:
... ... @@ -125,14 +125,14 @@ int usb_generic_handle_packet(USBDevice *s, int pid,
125 125 }
126 126 break;
127 127 default:
128   - ret = s->handle_data(s, pid, devep, data, len);
  128 + ret = s->handle_data(s, p);
129 129 break;
130 130 }
131 131 break;
132 132 case USB_TOKEN_OUT:
133   - if (s->state < USB_STATE_DEFAULT || devaddr != s->addr)
  133 + if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr)
134 134 return USB_RET_NODEV;
135   - switch(devep) {
  135 + switch(p->devep) {
136 136 case 0:
137 137 switch(s->setup_state) {
138 138 case SETUP_STATE_ACK:
... ... @@ -163,7 +163,7 @@ int usb_generic_handle_packet(USBDevice *s, int pid,
163 163 }
164 164 break;
165 165 default:
166   - ret = s->handle_data(s, pid, devep, data, len);
  166 + ret = s->handle_data(s, p);
167 167 break;
168 168 }
169 169 break;
... ... @@ -191,3 +191,13 @@ int set_usb_string(uint8_t *buf, const char *str)
191 191 }
192 192 return q - buf;
193 193 }
  194 +
  195 +/* Send an internal message to a USB device. */
  196 +void usb_send_msg(USBDevice *dev, int msg)
  197 +{
  198 + USBPacket p;
  199 + memset(&p, 0, sizeof(p));
  200 + p.pid = msg;
  201 + dev->handle_packet(dev, &p);
  202 +}
  203 +
... ...
hw/usb.h
... ... @@ -34,6 +34,7 @@
34 34 #define USB_RET_NAK (-2)
35 35 #define USB_RET_STALL (-3)
36 36 #define USB_RET_BABBLE (-4)
  37 +#define USB_RET_ASYNC (-5)
37 38  
38 39 #define USB_SPEED_LOW 0
39 40 #define USB_SPEED_FULL 1
... ... @@ -109,13 +110,12 @@
109 110  
110 111 typedef struct USBPort USBPort;
111 112 typedef struct USBDevice USBDevice;
  113 +typedef struct USBPacket USBPacket;
112 114  
113 115 /* definition of a USB device */
114 116 struct USBDevice {
115 117 void *opaque;
116   - int (*handle_packet)(USBDevice *dev, int pid,
117   - uint8_t devaddr, uint8_t devep,
118   - uint8_t *data, int len);
  118 + int (*handle_packet)(USBDevice *dev, USBPacket *p);
119 119 void (*handle_destroy)(USBDevice *dev);
120 120  
121 121 int speed;
... ... @@ -126,8 +126,7 @@ struct USBDevice {
126 126 void (*handle_reset)(USBDevice *dev);
127 127 int (*handle_control)(USBDevice *dev, int request, int value,
128 128 int index, int length, uint8_t *data);
129   - int (*handle_data)(USBDevice *dev, int pid, uint8_t devep,
130   - uint8_t *data, int len);
  129 + int (*handle_data)(USBDevice *dev, USBPacket *p);
131 130 uint8_t addr;
132 131 char devname[32];
133 132  
... ... @@ -151,11 +150,54 @@ struct USBPort {
151 150 struct USBPort *next; /* Used internally by qemu. */
152 151 };
153 152  
  153 +typedef void USBCallback(USBPacket * packet, void *opaque);
  154 +
  155 +/* Structure used to hold information about an active USB packet. */
  156 +struct USBPacket {
  157 + /* Data fields for use by the driver. */
  158 + int pid;
  159 + uint8_t devaddr;
  160 + uint8_t devep;
  161 + uint8_t *data;
  162 + int len;
  163 + /* Internal use by the USB layer. */
  164 + USBCallback *complete_cb;
  165 + void *complete_opaque;
  166 + USBCallback *cancel_cb;
  167 + void * *cancel_opaque;
  168 +};
  169 +
  170 +/* Defer completion of a USB packet. The hadle_packet routine should then
  171 + return USB_RET_ASYNC. Packets that complete immediately (before
  172 + handle_packet returns) should not call this method. */
  173 +static inline void usb_defer_packet(USBPacket *p, USBCallback *cancel,
  174 + void * opaque)
  175 +{
  176 + p->cancel_cb = cancel;
  177 + p->cancel_opaque = opaque;
  178 +}
  179 +
  180 +/* Notify the controller that an async packet is complete. This should only
  181 + be called for packets previously deferred with usb_defer_packet, and
  182 + should never be called from within handle_packet. */
  183 +static inline void usb_packet_complete(USBPacket *p)
  184 +{
  185 + p->complete_cb(p, p->complete_opaque);
  186 +}
  187 +
  188 +/* Cancel an active packet. The packed must have been deferred with
  189 + usb_defer_packet, and not yet completed. */
  190 +static inline void usb_cancel_packet(USBPacket * p)
  191 +{
  192 + p->cancel_cb(p, p->cancel_opaque);
  193 +}
  194 +
154 195 void usb_attach(USBPort *port, USBDevice *dev);
155   -int usb_generic_handle_packet(USBDevice *s, int pid,
156   - uint8_t devaddr, uint8_t devep,
157   - uint8_t *data, int len);
  196 +int usb_generic_handle_packet(USBDevice *s, USBPacket *p);
158 197 int set_usb_string(uint8_t *buf, const char *str);
  198 +void usb_send_msg(USBDevice *dev, int msg);
  199 +
  200 +void usb_packet_complete(USBPacket *p);
159 201  
160 202 /* usb hub */
161 203 USBDevice *usb_hub_init(int nb_ports);
... ...
pc-bios/openbios-esp.diff 0 → 100644
  1 +The ESP SCSI driver currently doesn't check whether a DMA requests has
  2 +completed before checking its status. On older qemu versions this works ok
  3 +because DMA happens instantly. On never qemu DMA can take an indeterminate
  4 +amount of time ooto complete, just like on real hardware.
  5 +
  6 +The patch below waits for the controller to raise the DMA interrupt after
  7 +initiating a DMA request.
  8 +
  9 +Index: drivers/esp.c
  10 +===================================================================
  11 +--- drivers/esp.c (revision 61)
  12 ++++ drivers/esp.c (working copy)
  13 +@@ -113,6 +113,8 @@ do_command(esp_private_t *esp, sd_privat
  14 + esp->espdma.regs->cond_reg = 0;
  15 + // Set ATN, issue command
  16 + esp->ll->regs[ESP_CMD] = ESP_CMD_SELA | ESP_CMD_DMA;
  17 ++ // Wait for DMA to complete
  18 ++ while ((esp->espdma.regs->cond_reg & DMA_HNDL_INTR) == 0) /* no-op */;
  19 + // Check status
  20 + status = esp->ll->regs[ESP_STATUS];
  21 +
  22 +@@ -129,6 +131,8 @@ do_command(esp_private_t *esp, sd_privat
  23 + esp->espdma.regs->cond_reg = DMA_ST_WRITE;
  24 + // Transfer
  25 + esp->ll->regs[ESP_CMD] = ESP_CMD_TI | ESP_CMD_DMA;
  26 ++ // Wait for DMA to complete
  27 ++ while ((esp->espdma.regs->cond_reg & DMA_HNDL_INTR) == 0) /* no-op */;
  28 + // Check status
  29 + status = esp->ll->regs[ESP_STATUS];
  30 +
... ...
pc-bios/openbios-sparc32
No preview for this file type
usb-linux.c
... ... @@ -114,22 +114,21 @@ static int usb_host_handle_control(USBDevice *dev,
114 114 }
115 115 }
116 116  
117   -static int usb_host_handle_data(USBDevice *dev, int pid,
118   - uint8_t devep,
119   - uint8_t *data, int len)
  117 +static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
120 118 {
121 119 USBHostDevice *s = (USBHostDevice *)dev;
122 120 struct usbdevfs_bulktransfer bt;
123 121 int ret;
  122 + uint8_t devep = p->devep;
124 123  
125 124 /* XXX: optimize and handle all data types by looking at the
126 125 config descriptor */
127   - if (pid == USB_TOKEN_IN)
  126 + if (p->pid == USB_TOKEN_IN)
128 127 devep |= 0x80;
129 128 bt.ep = devep;
130   - bt.len = len;
  129 + bt.len = p->len;
131 130 bt.timeout = 50;
132   - bt.data = data;
  131 + bt.data = p->data;
133 132 ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
134 133 if (ret < 0) {
135 134 switch(errno) {
... ...
... ... @@ -1146,6 +1146,11 @@ void do_usb_del(const char *devname);
1146 1146 void usb_info(void);
1147 1147  
1148 1148 /* scsi-disk.c */
  1149 +enum scsi_reason {
  1150 + SCSI_REASON_DONE, /* Command complete. */
  1151 + SCSI_REASON_DATA /* Transfer complete, more data required. */
  1152 +};
  1153 +
1149 1154 typedef struct SCSIDevice SCSIDevice;
1150 1155 typedef void (*scsi_completionfn)(void *, uint32_t, int);
1151 1156  
... ... @@ -1155,8 +1160,12 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
1155 1160 void scsi_disk_destroy(SCSIDevice *s);
1156 1161  
1157 1162 int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun);
  1163 +/* SCSI data transfers are asynchrnonous. However, unlike the block IO
  1164 + layer the completion routine may be called directly by
  1165 + scsi_{read,write}_data. */
1158 1166 int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len);
1159 1167 int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len);
  1168 +void scsi_cancel_io(SCSIDevice *s);
1160 1169  
1161 1170 /* lsi53c895a.c */
1162 1171 void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id);
... ...