Commit 42550fde7e16ac040fbd391bb2c65c3f5fa08d60

Authored by ths
1 parent 62ee0211

SCSI emulation improvements, by Chuck Brazie.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2265 c046a42c-6fe2-441c-8c8c-71466251a162
... ... @@ -688,23 +688,21 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
688 688 if (i440fx_state) {
689 689 i440fx_init_memory_mappings(i440fx_state);
690 690 }
691   -#if 0
692   - /* ??? Need to figure out some way for the user to
693   - specify SCSI devices. */
694 691 if (pci_enabled) {
695 692 void *scsi;
696   - BlockDriverState *bdrv;
697   -
698   - scsi = lsi_scsi_init(pci_bus, -1);
699   - bdrv = bdrv_new("scsidisk");
700   - bdrv_open(bdrv, "scsi_disk.img", 0);
701   - lsi_scsi_attach(scsi, bdrv, -1);
702   - bdrv = bdrv_new("scsicd");
703   - bdrv_open(bdrv, "scsi_cd.iso", 0);
704   - bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
705   - lsi_scsi_attach(scsi, bdrv, -1);
  693 +
  694 + if (scsi_hba_lsi > 0) {
  695 + if (!(scsi = lsi_scsi_init(pci_bus, -1))) {
  696 + exit(1);
  697 + }
  698 + for(i = 0; i < MAX_SCSI_DISKS; i++) {
  699 + if (scsi_disks_info[i].adapter == SCSI_LSI_53C895A &&
  700 + scsi_disks_info[i].device_type != SCSI_NONE) {
  701 + lsi_scsi_attach(scsi, bs_scsi_table[i], scsi_disks_info[i].id);
  702 + }
  703 + }
  704 + }
706 705 }
707   -#endif
708 706 }
709 707  
710 708 static void pc_init_pci(int ram_size, int vga_ram_size, int boot_device,
... ...
qemu-doc.texi
... ... @@ -223,10 +223,16 @@ using @file{/dev/cdrom} as filename (@pxref{host_drives}).
223 223 Boot on floppy (a), hard disk (c) or CD-ROM (d). Hard disk boot is
224 224 the default.
225 225  
  226 +@item -disk ide,img=file[,hdx=a..dd][,type=disk|cdrom]
  227 +Use @var{file} as the IDE disk/CD-ROM image. The defaults are: hdx=a,type=disk
  228 +
  229 +@item -disk scsi,img=file[,sdx=a..g][,type=disk|cdrom][,id=n]
  230 +Use @var{file} as the SCSI disk/CD-ROM image. The defaults are: sdx=a,type=disk,id='auto assign'
  231 +
226 232 @item -snapshot
227 233 Write to temporary files instead of disk image files. In this case,
228 234 the raw disk image you use is not written back. You can however force
229   -the write back by pressing @key{C-a s} (@pxref{disk_images}).
  235 +the write back by pressing @key{C-a s} (@pxref{disk_images}).
230 236  
231 237 @item -no-fd-bootchk
232 238 Disable boot signature checking for floppy disks in Bochs BIOS. It may
... ...
... ... @@ -109,6 +109,8 @@
109 109 /* XXX: use a two level table to limit memory usage */
110 110 #define MAX_IOPORTS 65536
111 111  
  112 +#define DISK_OPTIONS_SIZE 256
  113 +
112 114 const char *bios_dir = CONFIG_QEMU_SHAREDIR;
113 115 char phys_ram_file[1024];
114 116 void *ioport_opaque[MAX_IOPORTS];
... ... @@ -119,6 +121,9 @@ IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
119 121 BlockDriverState *bs_table[MAX_DISKS + 1], *fd_table[MAX_FD];
120 122 /* point to the block driver where the snapshots are managed */
121 123 BlockDriverState *bs_snapshots;
  124 +BlockDriverState *bs_scsi_table[MAX_SCSI_DISKS];
  125 +SCSIDiskInfo scsi_disks_info[MAX_SCSI_DISKS];
  126 +int scsi_hba_lsi; /* Count of scsi disks/cdrom using this lsi adapter */
122 127 int vga_ram_size;
123 128 int bios_size;
124 129 static DisplayState display_state;
... ... @@ -3814,7 +3819,172 @@ void do_info_network(void)
3814 3819 term_printf(" %s\n", vc->info_str);
3815 3820 }
3816 3821 }
3817   -
  3822 +
  3823 +/* Parse IDE and SCSI disk options */
  3824 +static int disk_options_init(int num_ide_disks,
  3825 + char ide_disk_options[][DISK_OPTIONS_SIZE],
  3826 + int snapshot,
  3827 + int num_scsi_disks,
  3828 + char scsi_disk_options[][DISK_OPTIONS_SIZE],
  3829 + int cdrom_index,
  3830 + int cyls,
  3831 + int heads,
  3832 + int secs,
  3833 + int translation)
  3834 +{
  3835 + char buf[256];
  3836 + char dev_name[64];
  3837 + int id, i, j;
  3838 + int cdrom_device;
  3839 + int ide_cdrom_created = 0;
  3840 + int scsi_index;
  3841 + scsi_host_adapters temp_adapter;
  3842 +
  3843 + /* Process any IDE disks/cdroms */
  3844 + for (i=0; i< num_ide_disks; i++) {
  3845 + for (j=0; j<MAX_DISKS; j++) {
  3846 + if (ide_disk_options[j][0] == '\0')
  3847 + continue;
  3848 +
  3849 + if (get_param_value(buf, sizeof(buf),"type",ide_disk_options[j])) {
  3850 + if (!strcmp(buf, "disk")) {
  3851 + cdrom_device = 0;
  3852 + } else if (!strcmp(buf, "cdrom")) {
  3853 + cdrom_device = 1;
  3854 + ide_cdrom_created = 1;
  3855 + } else {
  3856 + fprintf(stderr, "qemu: invalid IDE disk type= value: %s\n", buf);
  3857 + return -1;
  3858 + }
  3859 + } else {
  3860 + cdrom_device = 0;
  3861 + }
  3862 +
  3863 + if (cdrom_device) {
  3864 + snprintf(dev_name, sizeof(dev_name), "cdrom%c", i);
  3865 + } else {
  3866 + snprintf(dev_name, sizeof(dev_name), "hd%c", i + 'a');
  3867 + }
  3868 +
  3869 + if (!(get_param_value(buf, sizeof(buf),"img",ide_disk_options[j]))) {
  3870 + fprintf(stderr, "qemu: missing IDE disk img= value.\n");
  3871 + return -1;
  3872 + }
  3873 +
  3874 + if (!(bs_table[i] = bdrv_new(dev_name))) {
  3875 + fprintf(stderr, "qemu: unable to create new block device for:%s\n",dev_name);
  3876 + return -1;
  3877 + }
  3878 +
  3879 + if (cdrom_device) {
  3880 + bdrv_set_type_hint(bs_table[i], BDRV_TYPE_CDROM);
  3881 + }
  3882 +
  3883 + if (bdrv_open(bs_table[i], buf, snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
  3884 + fprintf(stderr, "qemu: could not open hard disk image: '%s'\n",
  3885 + buf);
  3886 + return -1;
  3887 + }
  3888 + if (i == 0 && cyls != 0) {
  3889 + bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
  3890 + bdrv_set_translation_hint(bs_table[i], translation);
  3891 + }
  3892 + ide_disk_options[j][0] = '\0';
  3893 +
  3894 + if (i == cdrom_index) {
  3895 + cdrom_index = -1;
  3896 + }
  3897 + break; /* finished with this IDE device*/
  3898 + }
  3899 + }
  3900 +
  3901 + if (cdrom_index >= 0 && (!ide_cdrom_created)) {
  3902 + bs_table[cdrom_index] = bdrv_new("cdrom");
  3903 + bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
  3904 + }
  3905 +
  3906 + for(i = 0; i < num_scsi_disks; i++) {
  3907 +
  3908 + temp_adapter = SCSI_LSI_53C895A;
  3909 + scsi_hba_lsi++;
  3910 +
  3911 + /*Check for sdx= parameter */
  3912 + if (get_param_value(buf, sizeof(buf), "sdx", scsi_disk_options[i])) {
  3913 + if (buf[0] >= 'a' && buf[0] <= 'g') {
  3914 + scsi_index = buf[0] - 'a';
  3915 + } else{
  3916 + fprintf(stderr, "qemu: sdx= option for SCSI must be one letter from a-g. %s \n",buf);
  3917 + exit(1);
  3918 + }
  3919 + } else {
  3920 + scsi_index = 0;
  3921 + }
  3922 +
  3923 + /* Check for SCSI id specified. */
  3924 + if (get_param_value(buf, sizeof(buf),"id",scsi_disk_options[i])) {
  3925 + id = strtol(buf, NULL, 0);
  3926 + if (id < 0 || id > 6) {
  3927 + fprintf(stderr, "qemu: SCSI id must be from 0-6: %d\n", id);
  3928 + return -1;
  3929 + }
  3930 + /* Check if id already used */
  3931 + for(j = 0; j < MAX_SCSI_DISKS; j++) {
  3932 + if (scsi_disks_info[j].device_type != SCSI_NONE &&
  3933 + j != i &&
  3934 + scsi_disks_info[j].adapter == temp_adapter &&
  3935 + scsi_disks_info[j].id == id ) {
  3936 + fprintf(stderr, "qemu: SCSI id already used: %u\n", id);
  3937 + return -1;
  3938 + }
  3939 + }
  3940 + } else {
  3941 + id = -1;
  3942 + }
  3943 + scsi_disks_info[i].adapter = temp_adapter;
  3944 + scsi_disks_info[i].id = id;
  3945 +
  3946 + if (get_param_value(buf, sizeof(buf),"type",scsi_disk_options[i])) {
  3947 + if (!strcmp(buf, "disk")) {
  3948 + cdrom_device = 0;
  3949 + } else if (!strcmp(buf, "cdrom")) {
  3950 + cdrom_device = 1;
  3951 + } else {
  3952 + fprintf(stderr, "qemu: invalid SCSI disk type= value: %s\n", buf);
  3953 + return -1;
  3954 + }
  3955 + } else {
  3956 + cdrom_device = 0;
  3957 + }
  3958 +
  3959 + if (cdrom_device) {
  3960 + snprintf(dev_name, sizeof(buf), "cdrom%c", scsi_index);
  3961 + scsi_disks_info[scsi_index].device_type = SCSI_CDROM;
  3962 + } else {
  3963 + snprintf(dev_name, sizeof(buf), "sd%c", scsi_index + 'a');
  3964 + scsi_disks_info[scsi_index].device_type = SCSI_DISK;
  3965 + }
  3966 +
  3967 + if (!(bs_scsi_table[scsi_index] = bdrv_new(dev_name))) {
  3968 + fprintf(stderr, "qemu: unable to create new block device for:%s\n",dev_name);
  3969 + return -1;
  3970 + }
  3971 +
  3972 + /* Get image filename from options and then try to open it */
  3973 + if (get_param_value(buf, sizeof(buf),"img",scsi_disk_options[i])) {
  3974 + if (bdrv_open(bs_scsi_table[scsi_index], buf, 0) < 0) {
  3975 + fprintf(stderr, "qemu: could not open SCSI disk image img='%s'\n",buf);
  3976 + return -1;
  3977 + }
  3978 + } else {
  3979 + fprintf(stderr, "qemu: SCSI disk image not specified for sd%c \n", i + 'a');
  3980 + return -1;
  3981 + }
  3982 + }
  3983 +
  3984 + return 0;
  3985 +}
  3986 +
  3987 +
3818 3988 /***********************************************************/
3819 3989 /* USB devices */
3820 3990  
... ... @@ -5923,6 +6093,10 @@ void help(void)
5923 6093 "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
5924 6094 "-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
5925 6095 "-boot [a|c|d] boot on floppy (a), hard disk (c) or CD-ROM (d)\n"
  6096 + "-disk ide,img=file[,hdx=a..dd][,type=disk|cdrom] \n"
  6097 + " defaults are: hdx=a,type=disk \n"
  6098 + "-disk scsi,img=file[,sdx=a..g][,type=disk|cdrom][,id=n] \n"
  6099 + " defaults are: sdx=a,type=disk,id='auto assign' \n"
5926 6100 "-snapshot write to temporary files instead of disk image files\n"
5927 6101 #ifdef CONFIG_SDL
5928 6102 "-no-quit disable SDL window close capability\n"
... ... @@ -6103,6 +6277,7 @@ enum {
6103 6277 QEMU_OPTION_no_acpi,
6104 6278 QEMU_OPTION_no_reboot,
6105 6279 QEMU_OPTION_daemonize,
  6280 + QEMU_OPTION_disk,
6106 6281 };
6107 6282  
6108 6283 typedef struct QEMUOption {
... ... @@ -6177,6 +6352,7 @@ const QEMUOption qemu_options[] = {
6177 6352 { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
6178 6353 { "smp", HAS_ARG, QEMU_OPTION_smp },
6179 6354 { "vnc", HAS_ARG, QEMU_OPTION_vnc },
  6355 + { "disk", HAS_ARG, QEMU_OPTION_disk },
6180 6356  
6181 6357 /* temporary options */
6182 6358 { "usb", 0, QEMU_OPTION_usb },
... ... @@ -6395,7 +6571,11 @@ int main(int argc, char **argv)
6395 6571 int i, cdrom_index;
6396 6572 int snapshot, linux_boot;
6397 6573 const char *initrd_filename;
6398   - const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
  6574 + const char *fd_filename[MAX_FD];
  6575 + char scsi_options[MAX_SCSI_DISKS] [DISK_OPTIONS_SIZE];
  6576 + char ide_options[MAX_DISKS] [DISK_OPTIONS_SIZE];
  6577 + int num_ide_disks;
  6578 + int num_scsi_disks;
6399 6579 const char *kernel_filename, *kernel_cmdline;
6400 6580 DisplayState *ds = &display_state;
6401 6581 int cyls, heads, secs, translation;
... ... @@ -6450,10 +6630,19 @@ int main(int argc, char **argv)
6450 6630 register_machines();
6451 6631 machine = first_machine;
6452 6632 initrd_filename = NULL;
  6633 + for(i = 0; i < MAX_SCSI_DISKS; i++) {
  6634 + scsi_disks_info[i].device_type = SCSI_NONE;
  6635 + bs_scsi_table[i] = NULL;
  6636 + }
  6637 +
  6638 + num_ide_disks = 0;
  6639 + num_scsi_disks = 0;
  6640 +
6453 6641 for(i = 0; i < MAX_FD; i++)
6454 6642 fd_filename[i] = NULL;
6455   - for(i = 0; i < MAX_DISKS; i++)
6456   - hd_filename[i] = NULL;
  6643 + for(i = 0; i < MAX_DISKS; i++) {
  6644 + ide_options[i][0] = '\0';
  6645 + }
6457 6646 ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
6458 6647 vga_ram_size = VGA_RAM_SIZE;
6459 6648 bios_size = BIOS_SIZE;
... ... @@ -6497,7 +6686,16 @@ int main(int argc, char **argv)
6497 6686 break;
6498 6687 r = argv[optind];
6499 6688 if (r[0] != '-') {
6500   - hd_filename[0] = argv[optind++];
  6689 +
  6690 + /* Build new disk IDE syntax string */
  6691 + pstrcpy(ide_options[0],
  6692 + 14,
  6693 + "hdx=a,img=");
  6694 + /*Add on image filename */
  6695 + pstrcpy(&(ide_options[0][13]),
  6696 + sizeof(ide_options[0])-13,
  6697 + argv[optind++]);
  6698 + num_ide_disks++;
6501 6699 } else {
6502 6700 const QEMUOption *popt;
6503 6701  
... ... @@ -6547,10 +6745,75 @@ int main(int argc, char **argv)
6547 6745 case QEMU_OPTION_hdd:
6548 6746 {
6549 6747 int hd_index;
  6748 + const char newIDE_DiskSyntax [][10] = {
  6749 + "hdx=a,img=", "hdx=b,img=", "hdx=c,img=", "hdx=d,img=" };
  6750 +
6550 6751 hd_index = popt->index - QEMU_OPTION_hda;
6551   - hd_filename[hd_index] = optarg;
6552   - if (hd_index == cdrom_index)
6553   - cdrom_index = -1;
  6752 + if (num_ide_disks >= MAX_DISKS){
  6753 + fprintf(stderr, "qemu: too many IDE disks defined.\n");
  6754 + exit(1);
  6755 + }
  6756 + /* Build new disk IDE syntax string */
  6757 + pstrcpy(ide_options[hd_index],
  6758 + 11,
  6759 + newIDE_DiskSyntax[hd_index]);
  6760 + /* Add on image filename */
  6761 + pstrcpy(&(ide_options[hd_index][10]),
  6762 + sizeof(ide_options[0])-10,
  6763 + optarg);
  6764 + num_ide_disks++;
  6765 + }
  6766 + break;
  6767 + case QEMU_OPTION_disk: /*Combined IDE and SCSI, for disk and CDROM */
  6768 + {
  6769 + const char *p_input_char;
  6770 + char *p_output_string;
  6771 + char device[64];
  6772 + int disk_index;
  6773 +
  6774 + p_input_char = optarg;
  6775 + p_output_string = device;
  6776 + while (*p_input_char != '\0' && *p_input_char != ',') {
  6777 + if ((p_output_string - device) < sizeof(device) - 1)
  6778 + *p_output_string++ = *p_input_char;
  6779 + p_input_char++;
  6780 + }
  6781 + *p_output_string = '\0';
  6782 + if (*p_input_char == ',')
  6783 + p_input_char++;
  6784 +
  6785 + if (!strcmp(device, "scsi")) {
  6786 + if (num_scsi_disks >= MAX_SCSI_DISKS) {
  6787 + fprintf(stderr, "qemu: too many SCSI disks defined.\n");
  6788 + exit(1);
  6789 + }
  6790 + pstrcpy(scsi_options[num_scsi_disks],
  6791 + sizeof(scsi_options[0]),
  6792 + p_input_char);
  6793 + num_scsi_disks++;
  6794 + } else if (!strcmp(device,"ide")) {
  6795 + if (num_ide_disks >= MAX_DISKS) {
  6796 + fprintf(stderr, "qemu: too many IDE disks/cdroms defined.\n");
  6797 + exit(1);
  6798 + }
  6799 + disk_index = 0; /* default is hda */
  6800 + if (get_param_value(device, sizeof(device),"hdx",p_input_char)) {
  6801 + if (device[0] >= 'a' && device[0] <= 'd') {
  6802 + disk_index = device[0] - 'a';
  6803 + } else {
  6804 + fprintf(stderr, "qemu: invalid IDE disk hdx= value: %s\n", device);
  6805 + return -1;
  6806 + }
  6807 + }
  6808 + else disk_index=0;
  6809 + pstrcpy(ide_options[disk_index],
  6810 + sizeof(ide_options[0]),
  6811 + p_input_char);
  6812 + num_ide_disks++;
  6813 + } else {
  6814 + fprintf(stderr, "qemu: -disk option must specify IDE or SCSI: %s \n",device);
  6815 + exit(1);
  6816 + }
6554 6817 }
6555 6818 break;
6556 6819 case QEMU_OPTION_snapshot:
... ... @@ -6604,8 +6867,22 @@ int main(int argc, char **argv)
6604 6867 kernel_cmdline = optarg;
6605 6868 break;
6606 6869 case QEMU_OPTION_cdrom:
6607   - if (cdrom_index >= 0) {
6608   - hd_filename[cdrom_index] = optarg;
  6870 + {
  6871 + char buf[24];
  6872 + if (num_ide_disks >= MAX_DISKS) {
  6873 + fprintf(stderr, "qemu: too many IDE disks/cdroms defined.\n");
  6874 + exit(1);
  6875 + }
  6876 + snprintf(buf, sizeof(buf), "type=cdrom,hdx=%c,img=", cdrom_index + 'a');
  6877 + /* Build new disk IDE syntax string */
  6878 + pstrcpy(ide_options[cdrom_index],
  6879 + 25,
  6880 + buf);
  6881 + /* Add on image filename */
  6882 + pstrcpy(&(ide_options[cdrom_index][24]),
  6883 + sizeof(ide_options[0])-24,
  6884 + optarg);
  6885 + num_ide_disks++;
6609 6886 }
6610 6887 break;
6611 6888 case QEMU_OPTION_boot:
... ... @@ -6893,20 +7170,11 @@ int main(int argc, char **argv)
6893 7170 kqemu_allowed = 0;
6894 7171 #endif
6895 7172 linux_boot = (kernel_filename != NULL);
6896   -
6897   - if (!linux_boot &&
6898   - hd_filename[0] == '\0' &&
6899   - (cdrom_index >= 0 && hd_filename[cdrom_index] == '\0') &&
  7173 +
  7174 + if (!linux_boot &&
  7175 + num_ide_disks == 0 &&
6900 7176 fd_filename[0] == '\0')
6901 7177 help();
6902   -
6903   - /* boot to cd by default if no hard disk */
6904   - if (hd_filename[0] == '\0' && boot_device == 'c') {
6905   - if (fd_filename[0] != '\0')
6906   - boot_device = 'a';
6907   - else
6908   - boot_device = 'd';
6909   - }
6910 7178  
6911 7179 setvbuf(stdout, NULL, _IOLBF, 0);
6912 7180  
... ... @@ -6942,31 +7210,22 @@ int main(int argc, char **argv)
6942 7210 exit(1);
6943 7211 }
6944 7212  
6945   - /* we always create the cdrom drive, even if no disk is there */
6946 7213 bdrv_init();
6947   - if (cdrom_index >= 0) {
6948   - bs_table[cdrom_index] = bdrv_new("cdrom");
6949   - bdrv_set_type_hint(bs_table[cdrom_index], BDRV_TYPE_CDROM);
  7214 +
  7215 + /* open the virtual block devices, disks or CDRoms */
  7216 + if (disk_options_init(num_ide_disks,ide_options,snapshot,
  7217 + num_scsi_disks,scsi_options,
  7218 + cdrom_index,
  7219 + cyls, heads, secs, translation)){
  7220 + exit(1);
6950 7221 }
6951 7222  
6952   - /* open the virtual block devices */
6953   - for(i = 0; i < MAX_DISKS; i++) {
6954   - if (hd_filename[i]) {
6955   - if (!bs_table[i]) {
6956   - char buf[64];
6957   - snprintf(buf, sizeof(buf), "hd%c", i + 'a');
6958   - bs_table[i] = bdrv_new(buf);
6959   - }
6960   - if (bdrv_open(bs_table[i], hd_filename[i], snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
6961   - fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
6962   - hd_filename[i]);
6963   - exit(1);
6964   - }
6965   - if (i == 0 && cyls != 0) {
6966   - bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
6967   - bdrv_set_translation_hint(bs_table[i], translation);
6968   - }
6969   - }
  7223 + /* boot to floppy or default cd if no hard disk */
  7224 + if (num_ide_disks == 0 && boot_device == 'c') {
  7225 + if (fd_filename[0] != '\0')
  7226 + boot_device = 'a';
  7227 + else
  7228 + boot_device = 'd';
6970 7229 }
6971 7230  
6972 7231 /* we always create at least one floppy disk */
... ...
... ... @@ -1222,9 +1222,30 @@ int scsi_write_data(SCSIDevice *s, uint32_t tag);
1222 1222 void scsi_cancel_io(SCSIDevice *s, uint32_t tag);
1223 1223 uint8_t *scsi_get_buf(SCSIDevice *s, uint32_t tag);
1224 1224  
  1225 +enum scsi_host_adapters {
  1226 + SCSI_LSI_53C895A
  1227 +};
  1228 +enum scsi_devices {
  1229 + SCSI_CDROM,
  1230 + SCSI_DISK,
  1231 + SCSI_NONE
  1232 +};
  1233 +typedef enum scsi_host_adapters scsi_host_adapters;
  1234 +typedef enum scsi_devices scsi_devices;
  1235 +typedef struct SCSIDiskInfo {
  1236 + scsi_host_adapters adapter;
  1237 + int id;
  1238 + scsi_devices device_type;
  1239 +} SCSIDiskInfo;
  1240 +
  1241 +#define MAX_SCSI_DISKS 7
  1242 +extern BlockDriverState *bs_scsi_table[MAX_SCSI_DISKS];
  1243 +extern SCSIDiskInfo scsi_disks_info[MAX_SCSI_DISKS];
  1244 +
1225 1245 /* lsi53c895a.c */
1226 1246 void lsi_scsi_attach(void *opaque, BlockDriverState *bd, int id);
1227 1247 void *lsi_scsi_init(PCIBus *bus, int devfn);
  1248 +extern int scsi_hba_lsi; // Count of scsi disks/cdrom using this lsi adapter
1228 1249  
1229 1250 /* integratorcp.c */
1230 1251 extern QEMUMachine integratorcp926_machine;
... ...