tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

drvctl rescan for atabus



Hi,

I'm interested in feedback on and testing of a patch that implements
rescaning of atabus.  A patch should be attached.

Usage is rather straightforward:

detach:
drvctl -d (wdX|atapibusX)

rescan/reattach:
drvctl -r -a ata_hl atabusX

        Jonathan Kollasch
Index: sys/dev/ata/ata.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata.c,v
retrieving revision 1.107
diff -u -r1.107 ata.c
--- sys/dev/ata/ata.c   13 Sep 2009 18:45:10 -0000      1.107
+++ sys/dev/ata/ata.c   2 Oct 2009 21:23:59 -0000
@@ -110,6 +110,7 @@
 
 extern struct cfdriver atabus_cd;
 
+static int  atabus_rescan(device_t, const char *, const int *);
 static void atabus_childdetached(device_t, device_t);
 static bool atabus_resume(device_t PMF_FN_PROTO);
 static bool atabus_suspend(device_t PMF_FN_PROTO);
@@ -384,6 +385,10 @@
                if (chp->ch_flags & ATACH_SHUTDOWN) {
                        break;
                }
+               if (chp->ch_flags & ATACH_TH_RESCAN) {
+                       atabusconfig(sc);
+                       chp->ch_flags &= ~ATACH_TH_RESCAN;
+               }
                if (chp->ch_flags & ATACH_TH_RESET) {
                        /*
                         * ata_reset_channel() will freeze 2 times, so
@@ -605,6 +610,43 @@
        return (error);
 }
 
+static int
+atabus_rescan(device_t self, const char *ifattr, const int *locators)
+{
+       struct atabus_softc *sc = device_private(self);
+       struct ata_channel *chp = sc->sc_chan;
+       struct atabus_initq *initq;
+       int i;
+       int s;
+
+       /* fail if there's anything attached already */
+
+       if (chp->atapibus != NULL)
+               return EBUSY;
+
+       for (i = 0; i < ATA_MAXDRIVES; i++) {
+               if (chp->ata_drives[i] != NULL)
+                       return EBUSY;
+       }
+
+       /* reset drive flags */
+       s = splbio();
+       for (i = 0; i < ATA_MAXDRIVES; i++) {
+               chp->ch_drive[i].drive_flags = 0;
+       }
+       splx(s);
+
+       initq = malloc(sizeof(*initq), M_DEVBUF, M_WAITOK);
+       initq->atabus_sc = sc;
+       TAILQ_INSERT_TAIL(&atabus_initq_head, initq, atabus_initq);
+       config_pending_incr();
+
+       chp->ch_flags |= ATACH_TH_RESCAN;
+       wakeup(&chp->ch_thread);
+
+       return 0;
+}
+
 void
 atabus_childdetached(device_t self, device_t child)
 {
@@ -643,7 +685,7 @@
 }
 
 CFATTACH_DECL3_NEW(atabus, sizeof(struct atabus_softc),
-    atabus_match, atabus_attach, atabus_detach, atabus_activate, NULL,
+    atabus_match, atabus_attach, atabus_detach, atabus_activate, atabus_rescan,
     atabus_childdetached, DVF_DETACH_SHUTDOWN);
 
 /*****************************************************************************
Index: sys/dev/ata/atavar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/atavar.h,v
retrieving revision 1.79
diff -u -r1.79 atavar.h
--- sys/dev/ata/atavar.h        12 May 2009 14:16:53 -0000      1.79
+++ sys/dev/ata/atavar.h        2 Oct 2009 21:23:59 -0000
@@ -342,6 +342,7 @@
 #define        ATACH_DISABLED 0x80     /* channel is disabled */
 #define ATACH_TH_RUN   0x100   /* the kernel thread is working */
 #define ATACH_TH_RESET 0x200   /* someone ask the thread to reset */
+#define ATACH_TH_RESCAN 0x400  /* someone ask the thread to rescan */
        u_int8_t ch_status;     /* copy of status register */
        u_int8_t ch_error;      /* copy of error register */
 


Home | Main Index | Thread Index | Old Index