Commit 985a03b0ce38275c2ea355bf29b6d6b5779dbb56

Authored by ths
1 parent 1b088995

Real SCSI device passthrough (v4), by Laurent Vivier.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3851 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
@@ -56,6 +56,7 @@ OBJS+=irq.o @@ -56,6 +56,7 @@ OBJS+=irq.o
56 OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o 56 OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o
57 OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o 57 OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o
58 OBJS+=scsi-disk.o cdrom.o 58 OBJS+=scsi-disk.o cdrom.o
  59 +OBJS+=scsi-generic.o
59 OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o 60 OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o
60 OBJS+=sd.o ssi-sd.o 61 OBJS+=sd.o ssi-sd.o
61 62
block-raw-posix.c
@@ -151,7 +151,7 @@ static int raw_pread(BlockDriverState *bs, int64_t offset, @@ -151,7 +151,7 @@ static int raw_pread(BlockDriverState *bs, int64_t offset,
151 if (ret < 0) 151 if (ret < 0)
152 return ret; 152 return ret;
153 153
154 - if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) { 154 + if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
155 ++(s->lseek_err_cnt); 155 ++(s->lseek_err_cnt);
156 if(s->lseek_err_cnt <= 10) { 156 if(s->lseek_err_cnt <= 10) {
157 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 157 DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
@@ -204,7 +204,7 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset, @@ -204,7 +204,7 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset,
204 if (ret < 0) 204 if (ret < 0)
205 return ret; 205 return ret;
206 206
207 - if (lseek(s->fd, offset, SEEK_SET) == (off_t)-1) { 207 + if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
208 ++(s->lseek_err_cnt); 208 ++(s->lseek_err_cnt);
209 if(s->lseek_err_cnt) { 209 if(s->lseek_err_cnt) {
210 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" 210 DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
@@ -276,8 +276,8 @@ void qemu_aio_init(void) @@ -276,8 +276,8 @@ void qemu_aio_init(void)
276 seems to fix the problem. */ 276 seems to fix the problem. */
277 struct aioinit ai; 277 struct aioinit ai;
278 memset(&ai, 0, sizeof(ai)); 278 memset(&ai, 0, sizeof(ai));
279 - ai.aio_threads = 1;  
280 - ai.aio_num = 1; 279 + ai.aio_threads = 16;
  280 + ai.aio_num = 16;
281 ai.aio_idle_time = 365 * 100000; 281 ai.aio_idle_time = 365 * 100000;
282 aio_init(&ai); 282 aio_init(&ai);
283 } 283 }
@@ -387,7 +387,10 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs, @@ -387,7 +387,10 @@ static RawAIOCB *raw_aio_setup(BlockDriverState *bs,
387 acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num; 387 acb->aiocb.aio_sigevent.sigev_signo = aio_sig_num;
388 acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; 388 acb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
389 acb->aiocb.aio_buf = buf; 389 acb->aiocb.aio_buf = buf;
390 - acb->aiocb.aio_nbytes = nb_sectors * 512; 390 + if (nb_sectors < 0)
  391 + acb->aiocb.aio_nbytes = -nb_sectors;
  392 + else
  393 + acb->aiocb.aio_nbytes = nb_sectors * 512;
391 acb->aiocb.aio_offset = sector_num * 512; 394 acb->aiocb.aio_offset = sector_num * 512;
392 acb->next = first_aio; 395 acb->next = first_aio;
393 first_aio = acb; 396 first_aio = acb;
@@ -679,6 +682,8 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) @@ -679,6 +682,8 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
679 s->fd_open_flags = open_flags; 682 s->fd_open_flags = open_flags;
680 /* open will not fail even if no floppy is inserted */ 683 /* open will not fail even if no floppy is inserted */
681 open_flags |= O_NONBLOCK; 684 open_flags |= O_NONBLOCK;
  685 + } else if (strstart(filename, "/dev/sg", NULL)) {
  686 + bs->sg = 1;
682 } 687 }
683 #endif 688 #endif
684 fd = open(filename, open_flags, 0644); 689 fd = open(filename, open_flags, 0644);
@@ -858,6 +863,12 @@ static int raw_set_locked(BlockDriverState *bs, int locked) @@ -858,6 +863,12 @@ static int raw_set_locked(BlockDriverState *bs, int locked)
858 return 0; 863 return 0;
859 } 864 }
860 865
  866 +static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
  867 +{
  868 + BDRVRawState *s = bs->opaque;
  869 +
  870 + return ioctl(s->fd, req, buf);
  871 +}
861 #else 872 #else
862 873
863 static int raw_is_inserted(BlockDriverState *bs) 874 static int raw_is_inserted(BlockDriverState *bs)
@@ -880,6 +891,10 @@ static int raw_set_locked(BlockDriverState *bs, int locked) @@ -880,6 +891,10 @@ static int raw_set_locked(BlockDriverState *bs, int locked)
880 return -ENOTSUP; 891 return -ENOTSUP;
881 } 892 }
882 893
  894 +static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
  895 +{
  896 + return -ENOTSUP;
  897 +}
883 #endif /* !linux */ 898 #endif /* !linux */
884 899
885 BlockDriver bdrv_host_device = { 900 BlockDriver bdrv_host_device = {
@@ -906,4 +921,6 @@ BlockDriver bdrv_host_device = { @@ -906,4 +921,6 @@ BlockDriver bdrv_host_device = {
906 .bdrv_media_changed = raw_media_changed, 921 .bdrv_media_changed = raw_media_changed,
907 .bdrv_eject = raw_eject, 922 .bdrv_eject = raw_eject,
908 .bdrv_set_locked = raw_set_locked, 923 .bdrv_set_locked = raw_set_locked,
  924 + /* generic scsi device */
  925 + .bdrv_ioctl = raw_ioctl,
909 }; 926 };
@@ -786,6 +786,11 @@ int bdrv_is_read_only(BlockDriverState *bs) @@ -786,6 +786,11 @@ int bdrv_is_read_only(BlockDriverState *bs)
786 return bs->read_only; 786 return bs->read_only;
787 } 787 }
788 788
  789 +int bdrv_is_sg(BlockDriverState *bs)
  790 +{
  791 + return bs->sg;
  792 +}
  793 +
789 /* XXX: no longer used */ 794 /* XXX: no longer used */
790 void bdrv_set_change_cb(BlockDriverState *bs, 795 void bdrv_set_change_cb(BlockDriverState *bs,
791 void (*change_cb)(void *opaque), void *opaque) 796 void (*change_cb)(void *opaque), void *opaque)
@@ -1394,3 +1399,14 @@ void bdrv_set_locked(BlockDriverState *bs, int locked) @@ -1394,3 +1399,14 @@ void bdrv_set_locked(BlockDriverState *bs, int locked)
1394 drv->bdrv_set_locked(bs, locked); 1399 drv->bdrv_set_locked(bs, locked);
1395 } 1400 }
1396 } 1401 }
  1402 +
  1403 +/* needed for generic scsi interface */
  1404 +
  1405 +int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
  1406 +{
  1407 + BlockDriver *drv = bs->drv;
  1408 +
  1409 + if (drv && drv->bdrv_ioctl)
  1410 + return drv->bdrv_ioctl(bs, req, buf);
  1411 + return -ENOTSUP;
  1412 +}
@@ -119,6 +119,7 @@ int bdrv_get_type_hint(BlockDriverState *bs); @@ -119,6 +119,7 @@ int bdrv_get_type_hint(BlockDriverState *bs);
119 int bdrv_get_translation_hint(BlockDriverState *bs); 119 int bdrv_get_translation_hint(BlockDriverState *bs);
120 int bdrv_is_removable(BlockDriverState *bs); 120 int bdrv_is_removable(BlockDriverState *bs);
121 int bdrv_is_read_only(BlockDriverState *bs); 121 int bdrv_is_read_only(BlockDriverState *bs);
  122 +int bdrv_is_sg(BlockDriverState *bs);
122 int bdrv_is_inserted(BlockDriverState *bs); 123 int bdrv_is_inserted(BlockDriverState *bs);
123 int bdrv_media_changed(BlockDriverState *bs); 124 int bdrv_media_changed(BlockDriverState *bs);
124 int bdrv_is_locked(BlockDriverState *bs); 125 int bdrv_is_locked(BlockDriverState *bs);
@@ -148,6 +149,7 @@ int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id); @@ -148,6 +149,7 @@ int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
148 int bdrv_snapshot_list(BlockDriverState *bs, 149 int bdrv_snapshot_list(BlockDriverState *bs,
149 QEMUSnapshotInfo **psn_info); 150 QEMUSnapshotInfo **psn_info);
150 char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn); 151 char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
  152 +int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf);
151 153
152 char *get_human_readable_size(char *buf, int buf_size, int64_t size); 154 char *get_human_readable_size(char *buf, int buf_size, int64_t size);
153 int path_is_absolute(const char *path); 155 int path_is_absolute(const char *path);
block_int.h
@@ -82,6 +82,9 @@ struct BlockDriver { @@ -82,6 +82,9 @@ struct BlockDriver {
82 int (*bdrv_eject)(BlockDriverState *bs, int eject_flag); 82 int (*bdrv_eject)(BlockDriverState *bs, int eject_flag);
83 int (*bdrv_set_locked)(BlockDriverState *bs, int locked); 83 int (*bdrv_set_locked)(BlockDriverState *bs, int locked);
84 84
  85 + /* to control generic scsi devices */
  86 + int (*bdrv_ioctl)(BlockDriverState *bs, unsigned long int req, void *buf);
  87 +
85 BlockDriverAIOCB *free_aiocb; 88 BlockDriverAIOCB *free_aiocb;
86 struct BlockDriver *next; 89 struct BlockDriver *next;
87 }; 90 };
@@ -93,6 +96,7 @@ struct BlockDriverState { @@ -93,6 +96,7 @@ struct BlockDriverState {
93 int removable; /* if true, the media can be removed */ 96 int removable; /* if true, the media can be removed */
94 int locked; /* if true, the media cannot temporarily be ejected */ 97 int locked; /* if true, the media cannot temporarily be ejected */
95 int encrypted; /* if true, the media is encrypted */ 98 int encrypted; /* if true, the media is encrypted */
  99 + int sg; /* if true, the device is a /dev/sg* */
96 /* event callback when inserting/removing */ 100 /* event callback when inserting/removing */
97 void (*change_cb)(void *opaque); 101 void (*change_cb)(void *opaque);
98 void *change_opaque; 102 void *change_opaque;
hw/esp.c
@@ -615,7 +615,9 @@ void esp_scsi_attach(void *opaque, BlockDriverState *bd, int id) @@ -615,7 +615,9 @@ void esp_scsi_attach(void *opaque, BlockDriverState *bd, int 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. */
618 - s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s); 618 + s->scsi_dev[id] = scsi_generic_init(bd, 0, esp_command_complete, s);
  619 + if (s->scsi_dev[id] == NULL)
  620 + s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s);
619 } 621 }
620 622
621 void *esp_init(target_phys_addr_t espaddr, 623 void *esp_init(target_phys_addr_t espaddr,
hw/lsi53c895a.c
@@ -1236,6 +1236,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) @@ -1236,6 +1236,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
1236 return s->sdid; 1236 return s->sdid;
1237 case 0x07: /* GPREG0 */ 1237 case 0x07: /* GPREG0 */
1238 return 0x7f; 1238 return 0x7f;
  1239 + case 0x08: /* Revision ID */
  1240 + return 0x00;
1239 case 0xa: /* SSID */ 1241 case 0xa: /* SSID */
1240 return s->ssid; 1242 return s->ssid;
1241 case 0xb: /* SBCL */ 1243 case 0xb: /* SBCL */
@@ -1281,6 +1283,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset) @@ -1281,6 +1283,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
1281 return s->ctest4; 1283 return s->ctest4;
1282 case 0x22: /* CTEST5 */ 1284 case 0x22: /* CTEST5 */
1283 return s->ctest5; 1285 return s->ctest5;
  1286 + case 0x23: /* CTEST6 */
  1287 + return 0;
1284 case 0x24: /* DBC[0:7] */ 1288 case 0x24: /* DBC[0:7] */
1285 return s->dbc & 0xff; 1289 return s->dbc & 0xff;
1286 case 0x25: /* DBC[8:15] */ 1290 case 0x25: /* DBC[8:15] */
@@ -1838,7 +1842,9 @@ void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id) @@ -1838,7 +1842,9 @@ void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id)
1838 s->scsi_dev[id]->destroy(s->scsi_dev[id]); 1842 s->scsi_dev[id]->destroy(s->scsi_dev[id]);
1839 } 1843 }
1840 DPRINTF("Attaching block device %d\n", id); 1844 DPRINTF("Attaching block device %d\n", id);
1841 - s->scsi_dev[id] = scsi_disk_init(bd, 1, lsi_command_complete, s); 1845 + s->scsi_dev[id] = scsi_generic_init(bd, 1, lsi_command_complete, s);
  1846 + if (s->scsi_dev[id] == NULL)
  1847 + s->scsi_dev[id] = scsi_disk_init(bd, 1, lsi_command_complete, s);
1842 } 1848 }
1843 1849
1844 void *lsi_scsi_init(PCIBus *bus, int devfn) 1850 void *lsi_scsi_init(PCIBus *bus, int devfn)
hw/scsi-disk.h
@@ -26,6 +26,8 @@ struct SCSIDevice @@ -26,6 +26,8 @@ struct SCSIDevice
26 26
27 SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq, 27 SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
28 scsi_completionfn completion, void *opaque); 28 scsi_completionfn completion, void *opaque);
  29 +SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
  30 + scsi_completionfn completion, void *opaque);
29 31
30 /* cdrom.c */ 32 /* cdrom.c */
31 int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track); 33 int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);