OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
eject mounted CD after resume

From: Alexey Vatchenko (avvmail.zp.ua)
Date: Sun Jul 16 2006 - 07:49:21 CDT


Hi!

On my laptop, i'm able to eject mounted CD after resume... Attached is
the patch that eliminates this problem (or
http://psytech.h10.ru/patches/cd.diff.txt).

--
Alexey V. Vatchenko
http://psytech.h10.ru
JID: avvjabber.zp.ua
ICQ: 162799204
Index: sys/scsi/cd.c
===================================================================
RCS file: /cvs/src/sys/scsi/cd.c,v
retrieving revision 1.104
diff -u -r1.104 cd.c
--- sys/scsi/cd.c 21 Jan 2006 12:18:49 -0000 1.104
+++ sys/scsi/cd.c 15 Jul 2006 11:57:12 -0000
-133,6 +133,8
 int dvd_read_manufact(struct cd_softc *, union dvd_struct *);
 int dvd_read_struct(struct cd_softc *, union dvd_struct *);
 
+void cd_powerhook(int why, void *arg);
+
 struct cfattach cd_ca = {
         sizeof(struct cd_softc), cdmatch, cdattach,
         cddetach, cdactivate
-222,6 +224,13
             (sa->sa_inqbuf->version & SID_ANSII) == 0)
                 cd->flags |= CDF_ANCIENT;
 
+ /*
+ * XXX - Establish a shutdown hook so that we can
+ * relock mounted CD after RESUME.
+ */
+ if ((cd->sc_cdpwrhook = powerhook_establish(cd_powerhook, cd)) == NULL)
+ printf("%s: WARNING: unable to establish power hook\n",
+ cd->sc_dev.dv_xname);
         printf("\n");
 }
 
-277,6 +286,10
                 if (cdevsw[cmaj].d_open == cdopen)
                         vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR);
 
+ /* Get rid of the power hook. */
+ if (sc->sc_cdpwrhook != NULL)
+ powerhook_disestablish(sc->sc_cdpwrhook);
+
         /* Detach disk. */
         disk_detach(&sc->sc_dk);
 
-355,6 +368,7
                     SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
                 if (error)
                         goto bad;
+ cd->flags |= CDF_LOCKED;
 
                 /* Load the physical device parameters. */
                 sc_link->flags |= SDEV_MEDIA_LOADED;
-396,6 +410,7
         if (cd->sc_dk.dk_openmask == 0) {
                 scsi_prevent(sc_link, PR_ALLOW,
                     SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
+ cd->flags &= ~CDF_LOCKED;
                 sc_link->flags &= ~(SDEV_OPEN | SDEV_MEDIA_LOADED);
         }
 
-442,6 +457,7
 
                 scsi_prevent(cd->sc_link, PR_ALLOW,
                     SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);
+ cd->flags &= ~CDF_LOCKED;
                 cd->sc_link->flags &= ~(SDEV_OPEN | SDEV_MEDIA_LOADED);
 
                 if (cd->sc_link->flags & SDEV_EJECTING) {
-777,6 +793,7
         struct cd_softc *cd;
         int part = CDPART(dev);
         int error = 0;
+ int prevent;
 
         cd = cdlookup(CDUNIT(dev));
         if (cd == NULL)
-1098,16 +1115,28
         case DIOCEJECT:
                 cd->sc_link->flags |= SDEV_EJECTING;
                 break;
- case CDIOCALLOW:
- error = scsi_prevent(cd->sc_link, PR_ALLOW, 0);
- break;
- case CDIOCPREVENT:
- error = scsi_prevent(cd->sc_link, PR_PREVENT, 0);
- break;
+
+ case CDIOCALLOW:/* FALLTHROUGH */
+ case CDIOCPREVENT:/* FALLTHROUGH */
         case DIOCLOCK:
- error = scsi_prevent(cd->sc_link,
- (*(int *)addr) ? PR_PREVENT : PR_ALLOW, 0);
+ if (cmd == CDIOCALLOW)
+ prevent = PR_ALLOW;
+ else if (cmd == CDIOCPREVENT)
+ prevent = PR_PREVENT;
+ else if (cmd == DIOCLOCK && *(int *)addr != 0)
+ prevent = PR_PREVENT;
+ else
+ prevent = PR_ALLOW;
+
+ error = scsi_prevent(cd->sc_link, prevent, 0);
+ if (error == 0) {
+ if (prevent == PR_PREVENT)
+ cd->flags |= CDF_LOCKED;
+ else
+ cd->flags &= ~CDF_LOCKED;
+ }
                 break;
+
         case CDIOCSETDEBUG:
                 cd->sc_link->flags |= (SDEV_DB1 | SDEV_DB2);
                 break;
-1996,4 +2025,14
         default:
                 return (EINVAL);
         }
+}
+
+void
+cd_powerhook(int why, void *arg)
+{
+ struct cd_softc *cd = arg;
+
+ /* Try to relock CD after resume */
+ if (why == PWR_RESUME && (cd->flags & CDF_LOCKED) != 0)
+ (void) scsi_prevent(cd->sc_link, PR_PREVENT, 0);
 }
Index: sys/scsi/cd.h
===================================================================
RCS file: /cvs/src/sys/scsi/cd.h,v
retrieving revision 1.9
diff -u -r1.9 cd.h
--- sys/scsi/cd.h 3 Aug 2005 23:37:07 -0000 1.9
+++ sys/scsi/cd.h 15 Jul 2006 11:57:12 -0000
-252,6 +252,7
         struct cd_parms orig_params; /* filled in when CD-DA mode starts */
 #endif
         struct buf buf_queue;
+ void *sc_cdpwrhook; /* our power hook */
 
 #if NRND > 0
         rndsource_element_t rnd_source;