From e34ca8c567859cab6da6d92f2835ebf8a1713ed0 Mon Sep 17 00:00:00 2001 From: dizzyofcrn Date: Sat, 2 May 2015 15:01:14 +0000 Subject: [PATCH] Use sense data to detect the presence of media. This stops the driver from constantly mounting and unmounting the drive. This requires further scrutiny as AROS does not recognise ejected boot cd/dvd when reinserted, I have not tested what happens if the media is not the boot media. Aros did not recognise the reinserted media with the previous version, so this is not a regression with this diff. git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@50579 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- rom/devs/ahci/ahci_cam_aros.c | 50 +++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/rom/devs/ahci/ahci_cam_aros.c b/rom/devs/ahci/ahci_cam_aros.c index c0861327ae..d432cbd3aa 100644 --- a/rom/devs/ahci/ahci_cam_aros.c +++ b/rom/devs/ahci/ahci_cam_aros.c @@ -57,38 +57,60 @@ static void ahci_PortMonitor(struct Task *parent, struct Device *device, struct D(bug("%s %d: Monitoring\n", ((struct Node *)device)->ln_Name, unit->sim_Unit)); do { - BOOL is_present; - + /* Issue a dummy read and gather sense data as we wish to get the current sense and not the previous */ io->io_Command = HD_SCSICMD; io->io_Flags = 0; io->io_Error = 0; IOStdReq(io)->io_Data = &scsi; IOStdReq(io)->io_Length = sizeof(scsi); IOStdReq(io)->io_Actual = 0; + scsi.scsi_Data = NULL; + scsi.scsi_Length = 0; scsi.scsi_Command = (UBYTE *)&test_unit_ready; scsi.scsi_CmdLength = sizeof(test_unit_ready); scsi.scsi_Actual = 0; scsi.scsi_Status = 0; - scsi.scsi_Flags = SCSIF_AUTOSENSE; + scsi.scsi_Flags = SCSIF_READ|SCSIF_AUTOSENSE|0x80; scsi.scsi_SenseData = (UBYTE *)&sense; scsi.scsi_SenseLength = sizeof(sense); scsi.scsi_SenseActual = 0; DoIO(io); - is_present = (io->io_Error == 0) && (scsi.scsi_Status == SCSI_GOOD); - // TODO: Check sense for additional information + if((io->io_Error == 0)) { + if((scsi.scsi_Status != SCSI_GOOD)) { + if((sense.flags & SSD_KEY) == SSD_KEY_NOT_READY) { + /* Medium is not present and tray is either closed or open (when additional sense code is 0x3a) */ + if(sense.add_sense_code == 0x3a) { + media_present = FALSE; + /* + if(sense.add_sense_qual == 1) { + // medium not present - tray closed + } + if(sense.add_sense_qual == 2) { + // medium not present - tray open + } + */ + } - ObtainSemaphore(&unit->sim_Lock); - if (is_present) - unit->sim_Flags |= SIMF_MediaPresent; - else - unit->sim_Flags &= ~SIMF_MediaPresent; - if (is_present != media_present) + } + } else { + /* When status returns GOOD, sense key is not applicable -> assume media to be present */ + media_present = TRUE; + } + } + + /* Presence of media has changed */ + if((unit->sim_Flags |= SIMF_MediaPresent) != (media_present)) { + ObtainSemaphore(&unit->sim_Lock); + if (media_present) { + unit->sim_Flags |= SIMF_MediaPresent; + } else { + unit->sim_Flags &= ~SIMF_MediaPresent; + } unit->sim_ChangeNum++; - ReleaseSemaphore(&unit->sim_Lock); + ReleaseSemaphore(&unit->sim_Lock); - if (is_present != media_present) { struct IORequest *msg; D(bug("%s: Media change detected on ahci.device %d (%s => %s)\n", __func__, unit->sim_Unit, media_present ? "TRUE" : "FALSE", is_present ? "TRUE" : "FALSE")); @@ -102,8 +124,8 @@ static void ahci_PortMonitor(struct Task *parent, struct Device *device, struct } } Permit(); + } - media_present = is_present; /* Wait 1s to the next scan */ } while ((ahci_WaitTO(tmr, 1, 0, SIGF_DOS) & SIGF_DOS) == 0); -- 2.11.4.GIT