svn commit: r188812 - head/sys/dev/ata

Alexander Motin mav at FreeBSD.org
Thu Feb 19 04:47:27 PST 2009


Author: mav
Date: Thu Feb 19 12:47:24 2009
New Revision: 188812
URL: http://svn.freebsd.org/changeset/base/188812

Log:
  Use channel driver's attach/detach routines instead of ata_attach()/
  ata_detach() to implement IOCATAATTACH/IOCATADETACH ioctls.
  This will permit channel drivers to properly shutdown port hardware on channel
  detach and init it on attach.

Modified:
  head/sys/dev/ata/ata-all.c
  head/sys/dev/ata/ata-all.h
  head/sys/dev/ata/ata-card.c
  head/sys/dev/ata/ata-cbus.c
  head/sys/dev/ata/ata-isa.c
  head/sys/dev/ata/ata-pci.c
  head/sys/dev/ata/ata-usb.c

Modified: head/sys/dev/ata/ata-all.c
==============================================================================
--- head/sys/dev/ata/ata-all.c	Thu Feb 19 08:25:29 2009	(r188811)
+++ head/sys/dev/ata/ata-all.c	Thu Feb 19 12:47:24 2009	(r188812)
@@ -385,30 +385,32 @@ ata_ioctl(struct cdev *dev, u_long cmd, 
 
     case IOCATAREINIT:
 	if (*value >= devclass_get_maxunit(ata_devclass) ||
-	    !(device = devclass_get_device(ata_devclass, *value)))
+	    !(device = devclass_get_device(ata_devclass, *value)) ||
+	    !device_is_attached(device))
 	    return ENXIO;
 	error = ata_reinit(device);
 	break;
 
     case IOCATAATTACH:
 	if (*value >= devclass_get_maxunit(ata_devclass) ||
-	    !(device = devclass_get_device(ata_devclass, *value)))
+	    !(device = devclass_get_device(ata_devclass, *value)) ||
+	    !device_is_attached(device))
 	    return ENXIO;
-	/* XXX SOS should enable channel HW on controller */
-	error = ata_attach(device);
+	error = DEVICE_ATTACH(device);
 	break;
 
     case IOCATADETACH:
 	if (*value >= devclass_get_maxunit(ata_devclass) ||
-	    !(device = devclass_get_device(ata_devclass, *value)))
+	    !(device = devclass_get_device(ata_devclass, *value)) ||
+	    !device_is_attached(device))
 	    return ENXIO;
-	error = ata_detach(device);
-	/* XXX SOS should disable channel HW on controller */
+	error = DEVICE_DETACH(device);
 	break;
 
     case IOCATADEVICES:
 	if (devices->channel >= devclass_get_maxunit(ata_devclass) ||
-	    !(device = devclass_get_device(ata_devclass, devices->channel)))
+	    !(device = devclass_get_device(ata_devclass, devices->channel)) ||
+	    !device_is_attached(device))
 	    return ENXIO;
 	bzero(devices->name[0], 32);
 	bzero(&devices->params[0], sizeof(struct ata_params));

Modified: head/sys/dev/ata/ata-all.h
==============================================================================
--- head/sys/dev/ata/ata-all.h	Thu Feb 19 08:25:29 2009	(r188811)
+++ head/sys/dev/ata/ata-all.h	Thu Feb 19 12:47:24 2009	(r188812)
@@ -500,6 +500,7 @@ struct ata_resource {
 struct ata_channel {
     device_t                    dev;            /* device handle */
     int                         unit;           /* physical channel */
+    int                         attached;       /* channel is attached */
     struct ata_resource         r_io[ATA_MAX_RES];/* I/O resources */
     struct resource             *r_irq;         /* interrupt of this channel */
     void                        *ih;            /* interrupt handle */

Modified: head/sys/dev/ata/ata-card.c
==============================================================================
--- head/sys/dev/ata/ata-card.c	Thu Feb 19 08:25:29 2009	(r188811)
+++ head/sys/dev/ata/ata-card.c	Thu Feb 19 12:47:24 2009	(r188812)
@@ -91,6 +91,10 @@ ata_pccard_attach(device_t dev)
     struct resource *io, *ctlio;
     int i, rid, err;
 
+    if (ch->attached)
+	return (0);
+    ch->attached = 1;
+
     /* allocate the io range to get start and length */
     rid = ATA_IOADDR_RID;
     if (!(io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
@@ -142,6 +146,10 @@ ata_pccard_detach(device_t dev)
     struct ata_channel *ch = device_get_softc(dev);
     int i;
 
+    if (!ch->attached)
+	return (0);
+    ch->attached = 0;
+
     ata_detach(dev);
     if (ch->r_io[ATA_CONTROL].res != ch->r_io[ATA_DATA].res)
 	bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID,

Modified: head/sys/dev/ata/ata-cbus.c
==============================================================================
--- head/sys/dev/ata/ata-cbus.c	Thu Feb 19 08:25:29 2009	(r188811)
+++ head/sys/dev/ata/ata-cbus.c	Thu Feb 19 12:47:24 2009	(r188812)
@@ -279,6 +279,10 @@ ata_cbuschannel_attach(device_t dev)
     struct ata_channel *ch = device_get_softc(dev);
     int i;
 
+    if (ch->attached)
+	return (0);
+    ch->attached = 1;
+
     ch->unit = (intptr_t)device_get_ivars(dev);
     /* setup the resource vectors */
     for (i = ATA_DATA; i <= ATA_COMMAND; i ++) {
@@ -298,6 +302,17 @@ ata_cbuschannel_attach(device_t dev)
 }
 
 static int
+ata_cbuschannel_detach(device_t dev)
+{
+
+    if (!ch->attached)
+	return (0);
+    ch->attached = 0;
+
+    return ata_detach(dev);
+}
+
+static int
 ata_cbuschannel_banking(device_t dev, int flags)
 {
     struct ata_cbus_controller *ctlr = device_get_softc(device_get_parent(dev));
@@ -343,7 +358,7 @@ static device_method_t ata_cbuschannel_m
     /* device interface */
     DEVMETHOD(device_probe,     ata_cbuschannel_probe),
     DEVMETHOD(device_attach,    ata_cbuschannel_attach),
-    DEVMETHOD(device_detach,    ata_detach),
+    DEVMETHOD(device_detach,    ata_cbuschannel_detach),
     DEVMETHOD(device_suspend,   ata_suspend),
     DEVMETHOD(device_resume,    ata_resume),
 

Modified: head/sys/dev/ata/ata-isa.c
==============================================================================
--- head/sys/dev/ata/ata-isa.c	Thu Feb 19 08:25:29 2009	(r188811)
+++ head/sys/dev/ata/ata-isa.c	Thu Feb 19 12:47:24 2009	(r188812)
@@ -103,6 +103,10 @@ ata_isa_attach(device_t dev)
     u_long tmp;
     int i, rid;
 
+    if (ch->attached)
+	return (0);
+    ch->attached = 1;
+
     /* allocate the io port range */
     rid = ATA_IOADDR_RID;
     if (!(io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
@@ -146,6 +150,10 @@ ata_isa_detach(device_t dev)
     struct ata_channel *ch = device_get_softc(dev);
     int error;
 
+    if (!ch->attached)
+	return (0);
+    ch->attached = 0;
+
     error = ata_detach(dev);
 
     bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID,

Modified: head/sys/dev/ata/ata-pci.c
==============================================================================
--- head/sys/dev/ata/ata-pci.c	Thu Feb 19 08:25:29 2009	(r188811)
+++ head/sys/dev/ata/ata-pci.c	Thu Feb 19 12:47:24 2009	(r188812)
@@ -550,8 +550,9 @@ ata_pcichannel_attach(device_t dev)
     struct ata_channel *ch = device_get_softc(dev);
     int error;
 
-    /* take care of green memory */
-    bzero(ch, sizeof(struct ata_channel));
+    if (ch->attached)
+	return (0);
+    ch->attached = 1;
 
     ch->unit = (intptr_t)device_get_ivars(dev);
 
@@ -565,8 +566,13 @@ static int
 ata_pcichannel_detach(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
+    struct ata_channel *ch = device_get_softc(dev);
     int error;
 
+    if (!ch->attached)
+	return (0);
+    ch->attached = 0;
+
     if ((error = ata_detach(dev)))
 	return error;
 

Modified: head/sys/dev/ata/ata-usb.c
==============================================================================
--- head/sys/dev/ata/ata-usb.c	Thu Feb 19 08:25:29 2009	(r188811)
+++ head/sys/dev/ata/ata-usb.c	Thu Feb 19 12:47:24 2009	(r188812)
@@ -842,8 +842,9 @@ ata_usbchannel_attach(device_t dev)
 {
     struct ata_channel *ch = device_get_softc(dev);
 
-    /* take care of green memory */
-    bzero(ch, sizeof(struct ata_channel));
+    if (ch->attached)
+	return (0);
+    ch->attached = 1;
 
     /* initialize the softc basics */
     ch->dev = dev;
@@ -876,6 +877,10 @@ ata_usbchannel_detach(device_t dev)
     device_t *children;
     int nchildren, i;
 
+    if (!ch->attached)
+	return (0);
+    ch->attached = 0;
+
     /* detach & delete all children */
     if (!device_get_children(dev, &children, &nchildren)) {
         for (i = 0; i < nchildren; i++)


More information about the svn-src-head mailing list