VirtualBox

Ignore:
Timestamp:
Nov 25, 2019 3:09:28 PM (5 years ago)
Author:
vboxsync
Message:

PC/BIOS: Don't panic when an INQUIRY fails but don't continue with that target, bugref:9440

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/BIOS/virtio.c

    r82180 r82182  
    760760
    761761        rc = virtio_scsi_cmd_data_in(virtio, i, aCDB, 6, buffer, 5, 0, 0);
    762         if (rc != 0)
    763             BX_PANIC("%s: SCSI_INQUIRY failed\n", __func__);
    764 
    765         devcount_scsi = bios_dsk->scsi_devcount;
    766 
    767         /* Check the attached device. */
    768         if (   ((buffer[0] & 0xe0) == 0)
    769             && ((buffer[0] & 0x1f) == 0x00))
     762        if (!rc)
    770763        {
    771             DBG_VIRTIO("%s: Disk detected at %d\n", __func__, i);
    772 
    773             /* We add the disk only if the maximum is not reached yet. */
    774             if (devcount_scsi < BX_MAX_SCSI_DEVICES)
     764            devcount_scsi = bios_dsk->scsi_devcount;
     765
     766            /* Check the attached device. */
     767            if (   ((buffer[0] & 0xe0) == 0)
     768                && ((buffer[0] & 0x1f) == 0x00))
    775769            {
    776                 uint64_t    sectors, t;
    777                 uint32_t    sector_size, cylinders;
    778                 uint16_t    heads, sectors_per_track;
    779                 uint8_t     hdcount;
    780                 uint8_t     cmos_base;
    781 
    782                 /* Issue a read capacity command now. */
    783                 _fmemset(aCDB, 0, sizeof(aCDB));
    784                 aCDB[0] = SCSI_SERVICE_ACT;
    785                 aCDB[1] = SCSI_READ_CAP_16;
    786                 aCDB[13] = 32; /* Allocation length. */
    787 
    788                 rc = virtio_scsi_cmd_data_in(virtio, i, aCDB, 16, buffer, 32, 0, 0);
    789                 if (rc != 0)
    790                     BX_PANIC("%s: SCSI_READ_CAPACITY failed\n", __func__);
    791 
    792                 /* The value returned is the last addressable LBA, not
    793                  * the size, which what "+ 1" is for.
    794                  */
    795                 sectors = swap_64(*(uint64_t *)buffer) + 1;
    796 
    797                 sector_size =   ((uint32_t)buffer[8] << 24)
    798                               | ((uint32_t)buffer[9] << 16)
    799                               | ((uint32_t)buffer[10] << 8)
    800                               | ((uint32_t)buffer[11]);
    801 
    802                 /* We only support the disk if sector size is 512 bytes. */
    803                 if (sector_size != 512)
     770                DBG_VIRTIO("%s: Disk detected at %d\n", __func__, i);
     771
     772                /* We add the disk only if the maximum is not reached yet. */
     773                if (devcount_scsi < BX_MAX_SCSI_DEVICES)
    804774                {
    805                     /* Leave a log entry. */
    806                     BX_INFO("Disk %d has an unsupported sector size of %u\n", i, sector_size);
    807                     continue;
    808                 }
    809 
    810                 /* Get logical CHS geometry. */
    811                 switch (devcount_scsi)
    812                 {
    813                     case 0:
    814                         cmos_base = 0x90;
    815                         break;
    816                     case 1:
    817                         cmos_base = 0x98;
    818                         break;
    819                     case 2:
    820                         cmos_base = 0xA0;
    821                         break;
    822                     case 3:
    823                         cmos_base = 0xA8;
    824                         break;
    825                     default:
    826                         cmos_base = 0;
    827                 }
    828 
    829                 if (cmos_base && inb_cmos(cmos_base + 7))
    830                 {
    831                     /* If provided, grab the logical geometry from CMOS. */
    832                     cylinders         = inb_cmos(cmos_base + 0) + (inb_cmos(cmos_base + 1) << 8);
    833                     heads             = inb_cmos(cmos_base + 2);
    834                     sectors_per_track = inb_cmos(cmos_base + 7);
     775                    uint64_t    sectors, t;
     776                    uint32_t    sector_size, cylinders;
     777                    uint16_t    heads, sectors_per_track;
     778                    uint8_t     hdcount;
     779                    uint8_t     cmos_base;
     780
     781                    /* Issue a read capacity command now. */
     782                    _fmemset(aCDB, 0, sizeof(aCDB));
     783                    aCDB[0] = SCSI_SERVICE_ACT;
     784                    aCDB[1] = SCSI_READ_CAP_16;
     785                    aCDB[13] = 32; /* Allocation length. */
     786
     787                    rc = virtio_scsi_cmd_data_in(virtio, i, aCDB, 16, buffer, 32, 0, 0);
     788                    if (rc != 0)
     789                        BX_PANIC("%s: SCSI_READ_CAPACITY failed\n", __func__);
     790
     791                    /* The value returned is the last addressable LBA, not
     792                     * the size, which what "+ 1" is for.
     793                     */
     794                    sectors = swap_64(*(uint64_t *)buffer) + 1;
     795
     796                    sector_size =   ((uint32_t)buffer[8] << 24)
     797                                  | ((uint32_t)buffer[9] << 16)
     798                                  | ((uint32_t)buffer[10] << 8)
     799                                  | ((uint32_t)buffer[11]);
     800
     801                    /* We only support the disk if sector size is 512 bytes. */
     802                    if (sector_size != 512)
     803                    {
     804                        /* Leave a log entry. */
     805                        BX_INFO("Disk %d has an unsupported sector size of %u\n", i, sector_size);
     806                        continue;
     807                    }
     808
     809                    /* Get logical CHS geometry. */
     810                    switch (devcount_scsi)
     811                    {
     812                        case 0:
     813                            cmos_base = 0x90;
     814                            break;
     815                        case 1:
     816                            cmos_base = 0x98;
     817                            break;
     818                        case 2:
     819                            cmos_base = 0xA0;
     820                            break;
     821                        case 3:
     822                            cmos_base = 0xA8;
     823                            break;
     824                        default:
     825                            cmos_base = 0;
     826                    }
     827
     828                    if (cmos_base && inb_cmos(cmos_base + 7))
     829                    {
     830                        /* If provided, grab the logical geometry from CMOS. */
     831                        cylinders         = inb_cmos(cmos_base + 0) + (inb_cmos(cmos_base + 1) << 8);
     832                        heads             = inb_cmos(cmos_base + 2);
     833                        sectors_per_track = inb_cmos(cmos_base + 7);
     834                    }
     835                    else
     836                    {
     837                        /* Calculate default logical geometry. NB: Very different
     838                         * from default ATA/SATA logical geometry!
     839                         */
     840                        if (sectors >= (uint32_t)4 * 1024 * 1024)
     841                        {
     842                            heads = 255;
     843                            sectors_per_track = 63;
     844                            /* Approximate x / (255 * 63) using shifts */
     845                            t = (sectors >> 6) + (sectors >> 12);
     846                            cylinders = (t >> 8) + (t >> 16);
     847                        }
     848                        else if (sectors >= (uint32_t)2 * 1024 * 1024)
     849                        {
     850                            heads = 128;
     851                            sectors_per_track = 32;
     852                            cylinders = sectors >> 12;
     853                        }
     854                        else
     855                        {
     856                            heads = 64;
     857                            sectors_per_track = 32;
     858                            cylinders = sectors >> 11;
     859                        }
     860                    }
     861
     862                    /* Calculate index into the generic disk table. */
     863                    hd_index = devcount_scsi + BX_MAX_ATA_DEVICES;
     864
     865                    bios_dsk->scsidev[devcount_scsi].target_id = i;
     866                    bios_dsk->devices[hd_index].type        = DSK_TYPE_VIRTIO_SCSI;
     867                    bios_dsk->devices[hd_index].device      = DSK_DEVICE_HD;
     868                    bios_dsk->devices[hd_index].removable   = 0;
     869                    bios_dsk->devices[hd_index].lock        = 0;
     870                    bios_dsk->devices[hd_index].blksize     = sector_size;
     871                    bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_LBA;
     872
     873                    /* Write LCHS/PCHS values. */
     874                    bios_dsk->devices[hd_index].lchs.heads = heads;
     875                    bios_dsk->devices[hd_index].lchs.spt   = sectors_per_track;
     876                    bios_dsk->devices[hd_index].pchs.heads = heads;
     877                    bios_dsk->devices[hd_index].pchs.spt   = sectors_per_track;
     878
     879                    if (cylinders > 1024) {
     880                        bios_dsk->devices[hd_index].lchs.cylinders = 1024;
     881                        bios_dsk->devices[hd_index].pchs.cylinders = 1024;
     882                    } else {
     883                        bios_dsk->devices[hd_index].lchs.cylinders = (uint16_t)cylinders;
     884                        bios_dsk->devices[hd_index].pchs.cylinders = (uint16_t)cylinders;
     885                    }
     886
     887                    BX_INFO("SCSI %d-ID#%d: LCHS=%lu/%u/%u 0x%llx sectors\n", devcount_scsi,
     888                            i, (uint32_t)cylinders, heads, sectors_per_track, sectors);
     889
     890                    bios_dsk->devices[hd_index].sectors = sectors;
     891
     892                    /* Store the id of the disk in the ata hdidmap. */
     893                    hdcount = bios_dsk->hdcount;
     894                    bios_dsk->hdidmap[hdcount] = devcount_scsi + BX_MAX_ATA_DEVICES;
     895                    hdcount++;
     896                    bios_dsk->hdcount = hdcount;
     897
     898                    /* Update hdcount in the BDA. */
     899                    hdcount = read_byte(0x40, 0x75);
     900                    hdcount++;
     901                    write_byte(0x40, 0x75, hdcount);
     902
     903                    devcount_scsi++;
    835904                }
    836905                else
    837906                {
    838                     /* Calculate default logical geometry. NB: Very different
    839                      * from default ATA/SATA logical geometry!
    840                      */
    841                     if (sectors >= (uint32_t)4 * 1024 * 1024)
    842                     {
    843                         heads = 255;
    844                         sectors_per_track = 63;
    845                         /* Approximate x / (255 * 63) using shifts */
    846                         t = (sectors >> 6) + (sectors >> 12);
    847                         cylinders = (t >> 8) + (t >> 16);
    848                     }
    849                     else if (sectors >= (uint32_t)2 * 1024 * 1024)
    850                     {
    851                         heads = 128;
    852                         sectors_per_track = 32;
    853                         cylinders = sectors >> 12;
    854                     }
    855                     else
    856                     {
    857                         heads = 64;
    858                         sectors_per_track = 32;
    859                         cylinders = sectors >> 11;
    860                     }
     907                    /* We reached the maximum of SCSI disks we can boot from. We can quit detecting. */
     908                    break;
    861909                }
    862 
    863                 /* Calculate index into the generic disk table. */
     910            }
     911            else if (   ((buffer[0] & 0xe0) == 0)
     912                     && ((buffer[0] & 0x1f) == 0x05))
     913            {
     914                uint8_t     cdcount;
     915                uint8_t     removable;
     916
     917                BX_INFO("SCSI %d-ID#%d: CD/DVD-ROM\n", devcount_scsi, i);
     918
     919                /* Calculate index into the generic device table. */
    864920                hd_index = devcount_scsi + BX_MAX_ATA_DEVICES;
     921
     922                removable = buffer[1] & 0x80 ? 1 : 0;
    865923
    866924                bios_dsk->scsidev[devcount_scsi].target_id = i;
    867925                bios_dsk->devices[hd_index].type        = DSK_TYPE_VIRTIO_SCSI;
    868                 bios_dsk->devices[hd_index].device      = DSK_DEVICE_HD;
    869                 bios_dsk->devices[hd_index].removable   = 0;
    870                 bios_dsk->devices[hd_index].lock        = 0;
    871                 bios_dsk->devices[hd_index].blksize     = sector_size;
    872                 bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_LBA;
    873 
    874                 /* Write LCHS/PCHS values. */
    875                 bios_dsk->devices[hd_index].lchs.heads = heads;
    876                 bios_dsk->devices[hd_index].lchs.spt   = sectors_per_track;
    877                 bios_dsk->devices[hd_index].pchs.heads = heads;
    878                 bios_dsk->devices[hd_index].pchs.spt   = sectors_per_track;
    879 
    880                 if (cylinders > 1024) {
    881                     bios_dsk->devices[hd_index].lchs.cylinders = 1024;
    882                     bios_dsk->devices[hd_index].pchs.cylinders = 1024;
    883                 } else {
    884                     bios_dsk->devices[hd_index].lchs.cylinders = (uint16_t)cylinders;
    885                     bios_dsk->devices[hd_index].pchs.cylinders = (uint16_t)cylinders;
    886                 }
    887 
    888                 BX_INFO("SCSI %d-ID#%d: LCHS=%lu/%u/%u 0x%llx sectors\n", devcount_scsi,
    889                         i, (uint32_t)cylinders, heads, sectors_per_track, sectors);
    890 
    891                 bios_dsk->devices[hd_index].sectors = sectors;
    892 
    893                 /* Store the id of the disk in the ata hdidmap. */
    894                 hdcount = bios_dsk->hdcount;
    895                 bios_dsk->hdidmap[hdcount] = devcount_scsi + BX_MAX_ATA_DEVICES;
    896                 hdcount++;
    897                 bios_dsk->hdcount = hdcount;
    898 
    899                 /* Update hdcount in the BDA. */
    900                 hdcount = read_byte(0x40, 0x75);
    901                 hdcount++;
    902                 write_byte(0x40, 0x75, hdcount);
     926                bios_dsk->devices[hd_index].device      = DSK_DEVICE_CDROM;
     927                bios_dsk->devices[hd_index].removable   = removable;
     928                bios_dsk->devices[hd_index].blksize     = 2048;
     929                bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_NONE;
     930
     931                /* Store the ID of the device in the BIOS cdidmap. */
     932                cdcount = bios_dsk->cdcount;
     933                bios_dsk->cdidmap[cdcount] = devcount_scsi + BX_MAX_ATA_DEVICES;
     934                cdcount++;
     935                bios_dsk->cdcount = cdcount;
    903936
    904937                devcount_scsi++;
    905938            }
    906939            else
    907             {
    908                 /* We reached the maximum of SCSI disks we can boot from. We can quit detecting. */
    909                 break;
    910             }
    911         }
    912         else if (   ((buffer[0] & 0xe0) == 0)
    913                  && ((buffer[0] & 0x1f) == 0x05))
    914         {
    915             uint8_t     cdcount;
    916             uint8_t     removable;
    917 
    918             BX_INFO("SCSI %d-ID#%d: CD/DVD-ROM\n", devcount_scsi, i);
    919 
    920             /* Calculate index into the generic device table. */
    921             hd_index = devcount_scsi + BX_MAX_ATA_DEVICES;
    922 
    923             removable = buffer[1] & 0x80 ? 1 : 0;
    924 
    925             bios_dsk->scsidev[devcount_scsi].target_id = i;
    926             bios_dsk->devices[hd_index].type        = DSK_TYPE_VIRTIO_SCSI;
    927             bios_dsk->devices[hd_index].device      = DSK_DEVICE_CDROM;
    928             bios_dsk->devices[hd_index].removable   = removable;
    929             bios_dsk->devices[hd_index].blksize     = 2048;
    930             bios_dsk->devices[hd_index].translation = GEO_TRANSLATION_NONE;
    931 
    932             /* Store the ID of the device in the BIOS cdidmap. */
    933             cdcount = bios_dsk->cdcount;
    934             bios_dsk->cdidmap[cdcount] = devcount_scsi + BX_MAX_ATA_DEVICES;
    935             cdcount++;
    936             bios_dsk->cdcount = cdcount;
    937 
    938             devcount_scsi++;
     940                DBG_VIRTIO("%s: No supported device detected at %d\n", __func__, i);
    939941        }
    940942        else
    941             DBG_VIRTIO("%s: No supported device detected at %d\n", __func__, i);
     943            DBG_VIRTIO("%s: INQUIRY failed with %u\n", __func__, rc);
    942944
    943945        bios_dsk->scsi_devcount = devcount_scsi;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette