From 09274de1f70e0773b95f865ef4980599e51aa67d Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Wed, 22 Jun 2022 11:53:06 +0100 Subject: scsi-disk: add SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE quirk for Macintosh Both MacOS and A/UX make use of vendor-specific MODE SELECT commands with PF=0 to identify SCSI devices: - MacOS sends a MODE SELECT command with PF=0 for the MODE_PAGE_VENDOR_SPECIFIC (0x0) mode page containing 2 bytes before initialising a disk - A/UX (installed on disk) sends a MODE SELECT command with PF=0 during SCSI bus enumeration, and gets stuck in an infinite loop if it fails Add a new SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE quirk to allow both PF=0 MODE SELECT commands and implement a MODE_PAGE_VENDOR_SPECIFIC (0x0) mode page which is compatible with MacOS. Signed-off-by: Mark Cave-Ayland Message-Id: <20220622105314.802852-7-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-disk.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index b1d08bf..2cdbba7 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -1079,6 +1079,7 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, int page_control) { static const int mode_sense_valid[0x3f] = { + [MODE_PAGE_VENDOR_SPECIFIC] = (1 << TYPE_DISK) | (1 << TYPE_ROM), [MODE_PAGE_HD_GEOMETRY] = (1 << TYPE_DISK), [MODE_PAGE_FLEXIBLE_DISK_GEOMETRY] = (1 << TYPE_DISK), [MODE_PAGE_CACHING] = (1 << TYPE_DISK) | (1 << TYPE_ROM), @@ -1244,6 +1245,22 @@ static int mode_sense_page(SCSIDiskState *s, int page, uint8_t **p_outbuf, return -1; } + case MODE_PAGE_VENDOR_SPECIFIC: + if (s->qdev.type == TYPE_DISK && (s->quirks & + (1 << SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE))) { + length = 0x2; + if (page_control == 1) { /* Changeable Values */ + p[0] = 0xff; + p[1] = 0xff; + break; + } + p[0] = 0; + p[1] = 0; + break; + } else { + return -1; + } + default: return -1; } @@ -1570,9 +1587,12 @@ static void scsi_disk_emulate_mode_select(SCSIDiskReq *r, uint8_t *inbuf) int bd_len; int pass; - /* We only support PF=1, SP=0. */ if ((r->req.cmd.buf[1] & 0x11) != 0x10) { - goto invalid_field; + if (!(s->quirks & + (1 << SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE))) { + /* We only support PF=1, SP=0. */ + goto invalid_field; + } } if (len < hdr_len) { @@ -3069,6 +3089,9 @@ static Property scsi_hd_properties[] = { DEFINE_PROP_UINT16("rotation_rate", SCSIDiskState, rotation_rate, 0), DEFINE_PROP_INT32("scsi_version", SCSIDiskState, qdev.default_scsi_version, 5), + DEFINE_PROP_BIT("quirk_mode_page_vendor_specific_apple", SCSIDiskState, + quirks, SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE, + 0), DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf), DEFINE_PROP_END_OF_LIST(), }; @@ -3121,6 +3144,9 @@ static Property scsi_cd_properties[] = { SCSI_DISK_QUIRK_MODE_PAGE_APPLE_VENDOR, 0), DEFINE_PROP_BIT("quirk_mode_sense_rom_use_dbd", SCSIDiskState, quirks, SCSI_DISK_QUIRK_MODE_SENSE_ROM_USE_DBD, 0), + DEFINE_PROP_BIT("quirk_mode_page_vendor_specific_apple", SCSIDiskState, + quirks, SCSI_DISK_QUIRK_MODE_PAGE_VENDOR_SPECIFIC_APPLE, + 0), DEFINE_PROP_END_OF_LIST(), }; -- cgit v1.1