svn commit: r189179 - in projects/jbuild/sys/dev/ata: . chipsets

John Birrell jb at FreeBSD.org
Sat Feb 28 09:55:33 PST 2009


Author: jb
Date: Sat Feb 28 17:55:32 2009
New Revision: 189179
URL: http://svn.freebsd.org/changeset/base/189179

Log:
  MFC

Added:
  projects/jbuild/sys/dev/ata/ata-raid-ddf.h
     - copied unchanged from r189173, head/sys/dev/ata/ata-raid-ddf.h
Replaced:
  projects/jbuild/sys/dev/ata/ata-usb.c
     - copied unchanged from r189173, head/sys/dev/ata/ata-usb.c
Modified:
  projects/jbuild/sys/dev/ata/ata-all.c
  projects/jbuild/sys/dev/ata/ata-all.h
  projects/jbuild/sys/dev/ata/ata-card.c
  projects/jbuild/sys/dev/ata/ata-cbus.c
  projects/jbuild/sys/dev/ata/ata-disk.c
  projects/jbuild/sys/dev/ata/ata-dma.c
  projects/jbuild/sys/dev/ata/ata-isa.c
  projects/jbuild/sys/dev/ata/ata-pci.c
  projects/jbuild/sys/dev/ata/ata-pci.h
  projects/jbuild/sys/dev/ata/ata-queue.c
  projects/jbuild/sys/dev/ata/ata-raid.c
  projects/jbuild/sys/dev/ata/ata-raid.h
  projects/jbuild/sys/dev/ata/ata-sata.c
  projects/jbuild/sys/dev/ata/atapi-cam.c
  projects/jbuild/sys/dev/ata/atapi-cd.c
  projects/jbuild/sys/dev/ata/atapi-fd.c
  projects/jbuild/sys/dev/ata/atapi-tape.c
  projects/jbuild/sys/dev/ata/chipsets/ata-acard.c
  projects/jbuild/sys/dev/ata/chipsets/ata-acerlabs.c
  projects/jbuild/sys/dev/ata/chipsets/ata-ahci.c
  projects/jbuild/sys/dev/ata/chipsets/ata-highpoint.c
  projects/jbuild/sys/dev/ata/chipsets/ata-intel.c
  projects/jbuild/sys/dev/ata/chipsets/ata-jmicron.c
  projects/jbuild/sys/dev/ata/chipsets/ata-marvell.c
  projects/jbuild/sys/dev/ata/chipsets/ata-netcell.c
  projects/jbuild/sys/dev/ata/chipsets/ata-nvidia.c
  projects/jbuild/sys/dev/ata/chipsets/ata-promise.c
  projects/jbuild/sys/dev/ata/chipsets/ata-serverworks.c
  projects/jbuild/sys/dev/ata/chipsets/ata-siliconimage.c
  projects/jbuild/sys/dev/ata/chipsets/ata-sis.c
  projects/jbuild/sys/dev/ata/chipsets/ata-via.c

Modified: projects/jbuild/sys/dev/ata/ata-all.c
==============================================================================
--- projects/jbuild/sys/dev/ata/ata-all.c	Sat Feb 28 17:54:59 2009	(r189178)
+++ projects/jbuild/sys/dev/ata/ata-all.c	Sat Feb 28 17:55:32 2009	(r189179)
@@ -61,7 +61,7 @@ static struct cdevsw ata_cdevsw = {
 
 /* prototypes */
 static void ata_boot_attach(void);
-static device_t ata_add_child(device_t, struct ata_device *, int);
+static void ata_conn_event(void *, int);
 static void bswap(int8_t *, int);
 static void btrim(int8_t *, int);
 static void bpack(int8_t *, int8_t *, int);
@@ -127,6 +127,7 @@ ata_attach(device_t dev)
     bzero(&ch->queue_mtx, sizeof(struct mtx));
     mtx_init(&ch->queue_mtx, "ATA queue lock", NULL, MTX_DEF);
     TAILQ_INIT(&ch->ata_queue);
+    TASK_INIT(&ch->conntask, 0, ata_conn_event, dev);
 
     /* reset the controller HW, the channel and device(s) */
     while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit)
@@ -147,7 +148,7 @@ ata_attach(device_t dev)
 	return ENXIO;
     }
     if ((error = bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, NULL,
-				(driver_intr_t *)ata_interrupt, ch, &ch->ih))) {
+				ata_interrupt, ch, &ch->ih))) {
 	device_printf(dev, "unable to setup interrupt\n");
 	return error;
     }
@@ -178,19 +179,33 @@ ata_detach(device_t dev)
     if (!device_get_children(dev, &children, &nchildren)) {
 	for (i = 0; i < nchildren; i++)
 	    if (children[i])
-		device_delete_child(dev, children[i]);
+		ata_delete_child(dev, children[i]);
 	free(children, M_TEMP);
     } 
+    taskqueue_drain(taskqueue_thread, &ch->conntask);
 
     /* release resources */
     bus_teardown_intr(dev, ch->r_irq, ch->ih);
     bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
     ch->r_irq = NULL;
+
+    /* free DMA resources if DMA HW present*/
+    if (ch->dma.free)
+	ch->dma.free(dev);
+
     mtx_destroy(&ch->state_mtx);
     mtx_destroy(&ch->queue_mtx);
     return 0;
 }
 
+static void
+ata_conn_event(void *context, int dummy)
+{
+    device_t dev = (device_t)context;
+
+    ata_reinit(dev);
+}
+
 int
 ata_reinit(device_t dev)
 {
@@ -212,6 +227,11 @@ ata_reinit(device_t dev)
 
     /* catch eventual request in ch->running */
     mtx_lock(&ch->state_mtx);
+    if (ch->state & ATA_STALL_QUEUE) {
+	/* Recursive reinits and reinits during detach prohobited. */
+	mtx_unlock(&ch->state_mtx);
+	return (ENXIO);
+    }
     if ((request = ch->running))
 	callout_stop(&request->callout);
     ch->running = NULL;
@@ -244,7 +264,7 @@ ata_reinit(device_t dev)
 			    ata_finish(request);
 		    request = NULL;
 		}
-		device_delete_child(dev, children[i]);
+		ata_delete_child(dev, children[i]);
 	    }
 	}
 	free(children, M_TEMP);
@@ -269,6 +289,9 @@ ata_reinit(device_t dev)
     mtx_unlock(&ch->state_mtx);
     ATA_LOCKING(dev, ATA_LF_UNLOCK);
 
+    /* Add new children. */
+    ata_identify(dev);
+
     if (bootverbose)
 	device_printf(dev, "reinit done ..\n");
 
@@ -304,11 +327,10 @@ ata_suspend(device_t dev)
 int
 ata_resume(device_t dev)
 {
-    struct ata_channel *ch;
     int error;
 
     /* check for valid device */
-    if (!dev || !(ch = device_get_softc(dev)))
+    if (!dev || !device_get_softc(dev))
 	return ENXIO;
 
     /* reinit the devices, we dont know what mode/state they are in */
@@ -319,7 +341,7 @@ ata_resume(device_t dev)
     return error;
 }
 
-int
+void
 ata_interrupt(void *data)
 {
     struct ata_channel *ch = (struct ata_channel *)data;
@@ -354,11 +376,10 @@ ata_interrupt(void *data)
 	    mtx_unlock(&ch->state_mtx);
 	    ATA_LOCKING(ch->dev, ATA_LF_UNLOCK);
 	    ata_finish(request);
-	    return 1;
+	    return;
 	}
     } while (0);
     mtx_unlock(&ch->state_mtx);
-    return 0;
 }
 
 /*
@@ -382,30 +403,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));
@@ -566,19 +589,44 @@ ata_boot_attach(void)
 /*
  * misc support functions
  */
-static device_t
-ata_add_child(device_t parent, struct ata_device *atadev, int unit)
+device_t
+ata_add_child(device_t parent, int unit, int atapi)
 {
+    struct ata_device *atadev;
     device_t child;
+    int dev_unit = -1;
 
-    if ((child = device_add_child(parent, NULL, unit))) {
+#ifdef ATA_STATIC_ID
+    if (!atapi)
+	dev_unit = (device_get_unit(parent) << 1) + unit;
+#endif
+    if ((child = device_add_child(parent, NULL, dev_unit))) {
+	if (!(atadev = malloc(sizeof(struct ata_device),
+			  M_ATA, M_NOWAIT | M_ZERO))) {
+	    device_printf(parent, "out of memory\n");
+	    device_delete_child(parent, child);
+	    return (NULL);
+	}
 	device_set_softc(child, atadev);
 	device_quiet(child);
 	atadev->dev = child;
+	atadev->unit = unit;
+	atadev->type = atapi ? ATA_T_ATAPI : ATA_T_ATA;
 	atadev->max_iosize = DEV_BSIZE;
 	atadev->mode = ATA_PIO_MAX;
     }
-    return child;
+    return (child);
+}
+
+int
+ata_delete_child(device_t parent, device_t child)
+{
+    struct ata_device *atadev = device_get_softc(child);
+    int res;
+
+    res = device_delete_child(parent, child);
+    free(atadev, M_ATA);
+    return (res);
 }
 
 int
@@ -589,11 +637,11 @@ ata_getparam(struct ata_device *atadev, 
     u_int8_t command = 0;
     int error = ENOMEM, retries = 2;
 
-    if (ch->devices & (ATA_ATA_MASTER << atadev->unit))
+    if (atadev->type == ATA_T_ATA)
 	command = ATA_ATA_IDENTIFY;
-    if (ch->devices & (ATA_ATAPI_MASTER << atadev->unit))
+    else if (atadev->type == ATA_T_ATAPI)
 	command = ATA_ATAPI_IDENTIFY;
-    if (!command)
+    else
 	return ENXIO;
 
     while (retries-- > 0 && error) {
@@ -603,7 +651,9 @@ ata_getparam(struct ata_device *atadev, 
 	request->timeout = 1;
 	request->retries = 0;
 	request->u.ata.command = command;
-	request->flags = (ATA_R_READ|ATA_R_AT_HEAD|ATA_R_DIRECT|ATA_R_QUIET);
+	request->flags = (ATA_R_READ|ATA_R_AT_HEAD|ATA_R_THREAD);
+	if (!bootverbose)
+	    request->flags |= ATA_R_QUIET;
 	request->data = (void *)&atadev->param;
 	request->bytecount = sizeof(struct ata_params);
 	request->donecount = 0;
@@ -637,17 +687,18 @@ ata_getparam(struct ata_device *atadev, 
 	btrim(atacap->serial, sizeof(atacap->serial));
 	bpack(atacap->serial, atacap->serial, sizeof(atacap->serial));
 
-	if (bootverbose)
-	    printf("ata%d-%s: pio=%s wdma=%s udma=%s cable=%s wire\n",
+	if (init) {
+	    char buffer[64];
+
+	    if (bootverbose) {
+		printf("ata%d-%s: pio=%s wdma=%s udma=%s cable=%s wire\n",
 		   device_get_unit(ch->dev),
 		   ata_unit2str(atadev),
 		   ata_mode2str(ata_pmode(atacap)),
 		   ata_mode2str(ata_wmode(atacap)),
 		   ata_mode2str(ata_umode(atacap)),
 		   (atacap->hwres & ATA_CABLE_ID) ? "80":"40");
-
-	if (init) {
-	    char buffer[64];
+	    }
 
 	    sprintf(buffer, "%.40s/%.8s", atacap->model, atacap->revision);
 	    device_set_desc_copy(atadev->dev, buffer);
@@ -679,38 +730,36 @@ ata_identify(device_t dev)
 {
     struct ata_channel *ch = device_get_softc(dev);
     struct ata_device *atadev;
-    device_t child;
-    int i;
+    device_t *children;
+    int nchildren, i, n = ch->devices;
 
     if (bootverbose)
-	device_printf(dev, "identify ch->devices=%08x\n", ch->devices);
-
-    for (i = 0; i < ATA_PM; ++i) {
-	if (ch->devices & (((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << i))) {
-	    int unit = -1;
+	device_printf(dev, "Identifying devices: %08x\n", ch->devices);
 
-	    if (!(atadev = malloc(sizeof(struct ata_device),
-				  M_ATA, M_NOWAIT | M_ZERO))) {
-		device_printf(dev, "out of memory\n");
-		return ENOMEM;
-	    }
-	    atadev->unit = i;
-#ifdef ATA_STATIC_ID
-	    if (ch->devices & ((ATA_ATA_MASTER << i)))
-		unit = (device_get_unit(dev) << 1) + i;
-#endif
-	    if ((child = ata_add_child(dev, atadev, unit))) {
-		if (ata_getparam(atadev, 1)) {
-		    device_delete_child(dev, child);
-		    free(atadev, M_ATA);
-		}
-	    }
-	    else
-		free(atadev, M_ATA);
+    mtx_lock(&Giant);
+    /* Skip existing devices. */
+    if (!device_get_children(dev, &children, &nchildren)) {
+	for (i = 0; i < nchildren; i++) {
+	    if (children[i] && (atadev = device_get_softc(children[i])))
+		n &= ~((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << atadev->unit);
 	}
+	free(children, M_TEMP);
+    }
+    if (bootverbose)
+	device_printf(dev, "New devices: %08x\n", n);
+    if (n == 0) {
+	mtx_unlock(&Giant);
+	return (0);
     }
+    /* Create new devices. */
+    for (i = 0; i < ATA_PM; ++i) {
+	if (n & (((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << i)))
+	    ata_add_child(dev, i, n & (ATA_ATAPI_MASTER << i));
+    }
+
     bus_generic_probe(dev);
     bus_generic_attach(dev);
+    mtx_unlock(&Giant);
     return 0;
 }
 
@@ -894,8 +943,7 @@ ata_atapi(device_t dev)
     struct ata_channel *ch = device_get_softc(device_get_parent(dev));
     struct ata_device *atadev = device_get_softc(dev);
 
-    return ((atadev->unit == ATA_MASTER && ch->devices & ATA_ATAPI_MASTER) ||
-            (atadev->unit == ATA_SLAVE && ch->devices & ATA_ATAPI_SLAVE));
+    return (ch->devices & (ATA_ATAPI_MASTER << atadev->unit));
 }
 
 int

Modified: projects/jbuild/sys/dev/ata/ata-all.h
==============================================================================
--- projects/jbuild/sys/dev/ata/ata-all.h	Sat Feb 28 17:54:59 2009	(r189178)
+++ projects/jbuild/sys/dev/ata/ata-all.h	Sat Feb 28 17:55:32 2009	(r189179)
@@ -212,7 +212,7 @@
 #define         ATA_AHCI_P_CMD_NOOP     0x00000000
 #define         ATA_AHCI_P_CMD_ACTIVE   0x10000000
 #define         ATA_AHCI_P_CMD_PARTIAL  0x20000000
-#define         ATA_AHCI_P_CMD_SLUMPER  0x60000000
+#define         ATA_AHCI_P_CMD_SLUMBER  0x60000000
 
 #define ATA_AHCI_P_TFD                  0x120
 #define ATA_AHCI_P_SIG                  0x124
@@ -367,7 +367,6 @@ struct ata_request {
 #define         ATA_R_AT_HEAD           0x00000200
 #define         ATA_R_REQUEUE           0x00000400
 #define         ATA_R_THREAD            0x00000800
-#define         ATA_R_DIRECT            0x00001000
 
 #define         ATA_R_DEBUG             0x10000000
 #define         ATA_R_DANGER1           0x20000000
@@ -411,6 +410,10 @@ struct ata_device {
 #define         ATA_MASTER              0x00
 #define         ATA_SLAVE               0x01
 #define         ATA_PM                  0x0f
+    int                         type;           /* device type */
+#define         ATA_T_ATA               0x00
+#define         ATA_T_ATAPI             0x01
+#define         ATA_T_ATAPI_CAM         0x02
 
     struct ata_params           param;          /* ata param structure */
     int                         mode;           /* current transfermode */
@@ -423,6 +426,8 @@ struct ata_device {
 #define         ATA_D_MEDIA_CHANGED     0x0002
 #define         ATA_D_ENC_PRESENT       0x0004
 #define         ATA_D_48BIT_ACTIVE      0x0008
+#define         ATA_D_PROBED            0x0010
+#define         ATA_D_VALID             0x0020
 };
 
 /* structure for holding DMA Physical Region Descriptors (PRD) entries */
@@ -500,6 +505,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 */
@@ -529,6 +535,7 @@ struct ata_channel {
     TAILQ_HEAD(, ata_request)   ata_queue;      /* head of ATA queue */
     struct ata_request          *freezepoint;   /* composite freezepoint */
     struct ata_request          *running;       /* currently running request */
+    struct task			conntask;	/* PHY events handling task */
 };
 
 /* disk bay/enclosure related */
@@ -554,10 +561,12 @@ int ata_detach(device_t dev);
 int ata_reinit(device_t dev);
 int ata_suspend(device_t dev);
 int ata_resume(device_t dev);
-int ata_interrupt(void *data);
+void ata_interrupt(void *data);
 int ata_device_ioctl(device_t dev, u_long cmd, caddr_t data);
 int ata_getparam(struct ata_device *atadev, int init);
 int ata_identify(device_t dev);
+device_t ata_add_child(device_t, int, int);
+int ata_delete_child(device_t , device_t);
 void ata_default_registers(device_t dev);
 void ata_modify_if_48bit(struct ata_request *request);
 void ata_udelay(int interval);

Modified: projects/jbuild/sys/dev/ata/ata-card.c
==============================================================================
--- projects/jbuild/sys/dev/ata/ata-card.c	Sat Feb 28 17:54:59 2009	(r189178)
+++ projects/jbuild/sys/dev/ata/ata-card.c	Sat Feb 28 17:55:32 2009	(r189179)
@@ -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: projects/jbuild/sys/dev/ata/ata-cbus.c
==============================================================================
--- projects/jbuild/sys/dev/ata/ata-cbus.c	Sat Feb 28 17:54:59 2009	(r189178)
+++ projects/jbuild/sys/dev/ata/ata-cbus.c	Sat Feb 28 17:55:32 2009	(r189179)
@@ -106,7 +106,8 @@ static int
 ata_cbus_attach(device_t dev)
 {
     struct ata_cbus_controller *ctlr = device_get_softc(dev);
-    int rid;
+    device_t child;
+    int rid, unit;
 
     /* allocate resources */
     rid = ATA_IOADDR_RID;
@@ -159,12 +160,16 @@ ata_cbus_attach(device_t dev)
     ctlr->locked_bank = -1;
     ctlr->restart_bank = -1;
 
-    if (!device_add_child(dev, "ata", 0))
-	return ENOMEM;
-    if (!device_add_child(dev, "ata", 1))
-	return ENOMEM;
+    for (unit = 0; unit < 2; unit++) {
+	child = device_add_child(dev, "ata", unit);
+	if (child == NULL)
+	    device_printf(dev, "failed to add ata child device\n");
+	else
+	    device_set_ivars(child, (void *)(intptr_t)unit);
+    }
 
-    return bus_generic_attach(dev);
+    bus_generic_attach(dev);
+    return (0);
 }
 
 static struct resource *
@@ -259,19 +264,26 @@ DRIVER_MODULE(atacbus, isa, ata_cbus_dri
 static int
 ata_cbuschannel_probe(device_t dev)
 {
+    char buffer[32];
+
+    sprintf(buffer, "ATA channel %d", (int)(intptr_t)device_get_ivars(dev));
+    device_set_desc_copy(dev, buffer);
+
+    return ata_probe(dev);
+}
+
+static int
+ata_cbuschannel_attach(device_t dev)
+{
     struct ata_cbus_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
-    device_t *children;
-    int count, i;
+    int i;
 
-    /* find channel number on this controller */
-    device_get_children(device_get_parent(dev), &children, &count);
-    for (i = 0; i < count; i++) {
-	if (children[i] == dev) 
-	    ch->unit = i;
-    }
-    free(children, M_TEMP);
+    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 ++) {
 	ch->r_io[i].res = ctlr->io;
@@ -285,7 +297,20 @@ ata_cbuschannel_probe(device_t dev)
     /* initialize softc for this channel */
     ch->flags |= ATA_USE_16BIT;
     ata_generic_hw(dev);
-    return ata_probe(dev);
+
+    return ata_attach(dev);
+}
+
+static int
+ata_cbuschannel_detach(device_t dev)
+{
+    struct ata_channel *ch = device_get_softc(dev);
+
+    if (!ch->attached)
+	return (0);
+    ch->attached = 0;
+
+    return ata_detach(dev);
 }
 
 static int
@@ -333,8 +358,8 @@ ata_cbuschannel_banking(device_t dev, in
 static device_method_t ata_cbuschannel_methods[] = {
     /* device interface */
     DEVMETHOD(device_probe,     ata_cbuschannel_probe),
-    DEVMETHOD(device_attach,    ata_attach),
-    DEVMETHOD(device_detach,    ata_detach),
+    DEVMETHOD(device_attach,    ata_cbuschannel_attach),
+    DEVMETHOD(device_detach,    ata_cbuschannel_detach),
     DEVMETHOD(device_suspend,   ata_suspend),
     DEVMETHOD(device_resume,    ata_resume),
 

Modified: projects/jbuild/sys/dev/ata/ata-disk.c
==============================================================================
--- projects/jbuild/sys/dev/ata/ata-disk.c	Sat Feb 28 17:54:59 2009	(r189178)
+++ projects/jbuild/sys/dev/ata/ata-disk.c	Sat Feb 28 17:55:32 2009	(r189179)
@@ -79,6 +79,18 @@ ad_probe(device_t dev)
 {
     struct ata_device *atadev = device_get_softc(dev);
 
+    if (atadev->type != ATA_T_ATA)
+	return (ENXIO);
+
+    if (!(atadev->flags & ATA_D_PROBED)) {
+	atadev->flags |= ATA_D_PROBED;
+	if (ata_getparam(atadev, 1) == 0)
+	    atadev->flags |= ATA_D_VALID;
+    }
+
+    if (!(atadev->flags & ATA_D_VALID))
+	return (ENXIO);
+
     if (!(atadev->param.config & ATA_PROTO_ATAPI) ||
 	(atadev->param.config == ATA_CFA_MAGIC1) ||
 	(atadev->param.config == ATA_CFA_MAGIC2) ||
@@ -182,13 +194,14 @@ ad_detach(device_t dev)
     return 0;
 }
 
-static void
+static int
 ad_shutdown(device_t dev)
 {
     struct ata_device *atadev = device_get_softc(dev);
 
     if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE)
 	ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0);
+    return 0;
 }
 
 static int
@@ -198,10 +211,9 @@ ad_reinit(device_t dev)
     struct ata_device *atadev = device_get_softc(dev);
 
     /* if detach pending, return error */
-    if (((atadev->unit == ATA_MASTER) && !(ch->devices & ATA_ATA_MASTER)) ||
-	((atadev->unit == ATA_SLAVE) && !(ch->devices & ATA_ATA_SLAVE))) {
+    if (!(ch->devices & (ATA_ATA_MASTER << atadev->unit)))
 	return 1;
-    }
+
     ad_init(dev);
     return 0;
 }

Modified: projects/jbuild/sys/dev/ata/ata-dma.c
==============================================================================
--- projects/jbuild/sys/dev/ata/ata-dma.c	Sat Feb 28 17:54:59 2009	(r189178)
+++ projects/jbuild/sys/dev/ata/ata-dma.c	Sat Feb 28 17:55:32 2009	(r189179)
@@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$");
 #include <dev/ata/ata-pci.h>
 
 /* prototypes */
-static void ata_dmafini(device_t dev);
 static void ata_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
 static void ata_dmaalloc(device_t dev);
 static void ata_dmafree(device_t dev);

Modified: projects/jbuild/sys/dev/ata/ata-isa.c
==============================================================================
--- projects/jbuild/sys/dev/ata/ata-isa.c	Sat Feb 28 17:54:59 2009	(r189178)
+++ projects/jbuild/sys/dev/ata/ata-isa.c	Sat Feb 28 17:55:32 2009	(r189179)
@@ -60,15 +60,53 @@ static struct isa_pnp_id ata_ids[] = {
 static int
 ata_isa_probe(device_t dev)
 {
-    struct ata_channel *ch = device_get_softc(dev);
     struct resource *io = NULL, *ctlio = NULL;
     u_long tmp;
-    int i, rid;
+    int rid;
 
     /* check isapnp ids */
     if (ISA_PNP_PROBE(device_get_parent(dev), dev, ata_ids) == ENXIO)
 	return ENXIO;
-    
+
+    /* allocate the io port range */
+    rid = ATA_IOADDR_RID;
+    if (!(io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
+				  ATA_IOSIZE, RF_ACTIVE)))
+	return ENXIO;
+
+    /* set the altport range */
+    if (bus_get_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, &tmp, &tmp)) {
+	bus_set_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID,
+			 rman_get_start(io) + ATA_CTLOFFSET, ATA_CTLIOSIZE);
+    }
+
+    /* allocate the altport range */
+    rid = ATA_CTLADDR_RID; 
+    if (!(ctlio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
+				     ATA_CTLIOSIZE, RF_ACTIVE))) {
+	bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io);
+	return ENXIO;
+    }
+
+    /* Release resources to reallocate on attach. */
+    bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID, ctlio);
+    bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io);
+
+    return (ata_probe(dev));
+}
+
+static int
+ata_isa_attach(device_t dev)
+{
+    struct ata_channel *ch = device_get_softc(dev);
+    struct resource *io = NULL, *ctlio = NULL;
+    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,
@@ -103,13 +141,33 @@ ata_isa_probe(device_t dev)
     ch->unit = 0;
     ch->flags |= ATA_USE_16BIT;
     ata_generic_hw(dev);
-    return ata_probe(dev);
+    return ata_attach(dev);
+}
+
+static int
+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,
+	ch->r_io[ATA_CONTROL].res);
+    bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID,
+	ch->r_io[ATA_IDX_ADDR].res);
+    return (error);
 }
 
 static device_method_t ata_isa_methods[] = {
     /* device interface */
     DEVMETHOD(device_probe,     ata_isa_probe),
-    DEVMETHOD(device_attach,    ata_attach),
+    DEVMETHOD(device_attach,    ata_isa_attach),
+    DEVMETHOD(device_detach,    ata_isa_detach),
     DEVMETHOD(device_suspend,   ata_suspend),
     DEVMETHOD(device_resume,    ata_resume),
 

Modified: projects/jbuild/sys/dev/ata/ata-pci.c
==============================================================================
--- projects/jbuild/sys/dev/ata/ata-pci.c	Sat Feb 28 17:54:59 2009	(r189178)
+++ projects/jbuild/sys/dev/ata/ata-pci.c	Sat Feb 28 17:55:32 2009	(r189179)
@@ -88,6 +88,7 @@ int
 ata_pci_attach(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
+    device_t child;
     u_int32_t cmd;
     int unit;
 
@@ -97,8 +98,9 @@ ata_pci_attach(device_t dev)
 	ctlr->channels = 2;
     else
 	ctlr->channels = 1;
-    ctlr->allocate = ata_pci_allocate;
-    ctlr->dmainit = ata_pci_dmainit;
+    ctlr->ichannels = -1;
+    ctlr->ch_attach = ata_pci_ch_attach;
+    ctlr->ch_detach = ata_pci_ch_detach;
     ctlr->dev = dev;
 
     /* if needed try to enable busmastering */
@@ -121,11 +123,15 @@ ata_pci_attach(device_t dev)
 
     /* attach all channels on this controller */
     for (unit = 0; unit < ctlr->channels; unit++) {
-	if ((unit == 0 || unit == 1) && ctlr->legacy) {
-	    device_add_child(dev, "ata", unit);
+	if ((ctlr->ichannels & (1 << unit)) == 0)
 	    continue;
-	}
-	device_add_child(dev, "ata", devclass_find_free_unit(ata_devclass, 2));
+	child = device_add_child(dev, "ata",
+	    ((unit == 0 || unit == 1) && ctlr->legacy) ?
+	    unit : devclass_find_free_unit(ata_devclass, 2));
+	if (child == NULL)
+	    device_printf(dev, "failed to add ata child device\n");
+	else
+	    device_set_ivars(child, (void *)(intptr_t)unit);
     }
     bus_generic_attach(dev);
     return 0;
@@ -147,7 +153,9 @@ ata_pci_detach(device_t dev)
 
     if (ctlr->r_irq) {
 	bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle);
-	bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ctlr->r_irq);
+	bus_release_resource(dev, SYS_RES_IRQ, ctlr->r_irq_rid, ctlr->r_irq);
+	if (ctlr->r_irq_rid != ATA_IRQ_RID)
+	    pci_release_msi(dev);
     }
     if (ctlr->r_res2)
 	bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, ctlr->r_res2);
@@ -336,7 +344,7 @@ ata_generic_chipinit(device_t dev)
 }
 
 int
-ata_pci_allocate(device_t dev)
+ata_pci_ch_attach(device_t dev)
 {
     struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
@@ -353,6 +361,8 @@ ata_pci_allocate(device_t dev)
 	return ENXIO;
     }
 
+    ata_pci_dmainit(dev);
+
     for (i = ATA_DATA; i <= ATA_COMMAND; i ++) {
 	ch->r_io[i].res = io;
 	ch->r_io[i].offset = i;
@@ -373,6 +383,21 @@ ata_pci_allocate(device_t dev)
 }
 
 int
+ata_pci_ch_detach(device_t dev)
+{
+    struct ata_channel *ch = device_get_softc(dev);
+
+    ata_pci_dmafini(dev);
+
+    bus_release_resource(dev, SYS_RES_IOPORT, ATA_CTLADDR_RID,
+	ch->r_io[ATA_CONTROL].res);
+    bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID,
+	ch->r_io[ATA_IDX_ADDR].res);
+
+    return (0);
+}
+
+int
 ata_pci_status(device_t dev)
 {
     struct ata_pci_controller *controller =
@@ -468,6 +493,12 @@ ata_pci_dmainit(device_t dev)
     ch->dma.reset = ata_pci_dmareset;
 }
 
+void
+ata_pci_dmafini(device_t dev)
+{
+
+    ata_dmafini(dev);
+}
 
 static device_method_t ata_pci_methods[] = {
     /* device interface */
@@ -504,23 +535,9 @@ MODULE_DEPEND(atapci, ata, 1, 1, 1);
 static int
 ata_pcichannel_probe(device_t dev)
 {
-    struct ata_channel *ch = device_get_softc(dev);
-    device_t *children;
-    int count, i;
     char buffer[32];
 
-    /* take care of green memory */
-    bzero(ch, sizeof(struct ata_channel));
-
-    /* find channel number on this controller */
-    device_get_children(device_get_parent(dev), &children, &count);
-    for (i = 0; i < count; i++) {
-	if (children[i] == dev)
-	    ch->unit = i;
-    }
-    free(children, M_TEMP);
-
-    sprintf(buffer, "ATA channel %d", ch->unit);
+    sprintf(buffer, "ATA channel %d", (int)(intptr_t)device_get_ivars(dev));
     device_set_desc_copy(dev, buffer);
 
     return ata_probe(dev);
@@ -530,12 +547,16 @@ static int
 ata_pcichannel_attach(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 (ctlr->dmainit)
-	ctlr->dmainit(dev);
+    if (ch->attached)
+	return (0);
+    ch->attached = 1;
+
+    ch->unit = (intptr_t)device_get_ivars(dev);
 
-    if ((error = ctlr->allocate(dev)))
+    if ((error = ctlr->ch_attach(dev)))
 	return error;
 
     return ata_attach(dev);
@@ -544,17 +565,21 @@ ata_pcichannel_attach(device_t dev)
 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;
 
-    ch->dma.free(dev);
+    if (ctlr->ch_detach)
+	return (ctlr->ch_detach(dev));
 
-    /* XXX SOS free resources for io and ctlio ?? */
-
-    return 0;
+    return (0);
 }
 
 static int
@@ -658,11 +683,19 @@ int
 ata_setup_interrupt(device_t dev, void *intr_func)
 {
     struct ata_pci_controller *ctlr = device_get_softc(dev);
-    int rid = ATA_IRQ_RID;
+    int i, msi = 0;
 
     if (!ctlr->legacy) {
-	if (!(ctlr->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
-						   RF_SHAREABLE | RF_ACTIVE))) {
+	if (resource_int_value(device_get_name(dev),
+		device_get_unit(dev), "msi", &i) == 0 && i != 0)
+	    msi = 1;
+	if (msi && pci_msi_count(dev) > 0 && pci_alloc_msi(dev, &msi) == 0) {
+	    ctlr->r_irq_rid = 0x1;
+	} else {
+	    ctlr->r_irq_rid = ATA_IRQ_RID;
+	}
+	if (!(ctlr->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+		&ctlr->r_irq_rid, RF_SHAREABLE | RF_ACTIVE))) {
 	    device_printf(dev, "unable to map interrupt\n");
 	    return ENXIO;
 	}

Modified: projects/jbuild/sys/dev/ata/ata-pci.h
==============================================================================
--- projects/jbuild/sys/dev/ata/ata-pci.h	Sat Feb 28 17:54:59 2009	(r189178)
+++ projects/jbuild/sys/dev/ata/ata-pci.h	Sat Feb 28 17:55:32 2009	(r189179)
@@ -45,18 +45,20 @@ struct ata_pci_controller {
     int                 r_type2;
     int                 r_rid2;
     struct resource     *r_res2;
+    int                 r_irq_rid;
     struct resource     *r_irq;
     void                *handle;
     struct ata_chip_id  *chip;
     int			legacy;
     int                 channels;
+    int			ichannels;
     int                 (*chipinit)(device_t);
     int                 (*suspend)(device_t);
     int                 (*resume)(device_t);
-    int                 (*allocate)(device_t);
+    int                 (*ch_attach)(device_t);
+    int                 (*ch_detach)(device_t);
     int                 (*locking)(device_t, int);
     void                (*reset)(device_t);
-    void                (*dmainit)(device_t);
     void                (*setmode)(device_t, int);
     struct {
     void                (*function)(void *);
@@ -64,15 +66,6 @@ struct ata_pci_controller {
     } interrupt[8];     /* XXX SOS max ch# for now */
 };
 
-/* structure for SATA connection update hotplug/hotswap support */
-struct ata_connect_task {
-    struct task task;
-    device_t    dev;  
-    int         action;
-#define ATA_C_ATTACH    1
-#define ATA_C_DETACH    2
-};
-
 /* defines for known chipset PCI id's */
 #define ATA_ACARD_ID            0x1191
 #define ATA_ATP850              0x00021191
@@ -256,8 +249,32 @@ struct ata_connect_task {
 #define ATA_NFORCE_MCP61_S2     0x03f610de
 #define ATA_NFORCE_MCP61_S3     0x03f710de
 #define ATA_NFORCE_MCP65        0x044810de
+#define ATA_NFORCE_MCP67_A0     0x055010de
+#define ATA_NFORCE_MCP67_A1     0x055110de
+#define ATA_NFORCE_MCP67_A2     0x055210de
+#define ATA_NFORCE_MCP67_A3     0x055310de
+#define ATA_NFORCE_MCP67_A4     0x055410de
+#define ATA_NFORCE_MCP67_A5     0x055510de
+#define ATA_NFORCE_MCP67_A6     0x055610de
+#define ATA_NFORCE_MCP67_A7     0x055710de
+#define ATA_NFORCE_MCP67_A8     0x055810de
+#define ATA_NFORCE_MCP67_A9     0x055910de
+#define ATA_NFORCE_MCP67_AA     0x055A10de
+#define ATA_NFORCE_MCP67_AB     0x055B10de
 #define ATA_NFORCE_MCP67        0x056010de
 #define ATA_NFORCE_MCP73        0x056c10de
+#define ATA_NFORCE_MCP73_A0     0x07f010de
+#define ATA_NFORCE_MCP73_A1     0x07f110de
+#define ATA_NFORCE_MCP73_A2     0x07f210de
+#define ATA_NFORCE_MCP73_A3     0x07f310de
+#define ATA_NFORCE_MCP73_A4     0x07f410de
+#define ATA_NFORCE_MCP73_A5     0x07f510de
+#define ATA_NFORCE_MCP73_A6     0x07f610de
+#define ATA_NFORCE_MCP73_A7     0x07f710de
+#define ATA_NFORCE_MCP73_A8     0x07f810de
+#define ATA_NFORCE_MCP73_A9     0x07f910de
+#define ATA_NFORCE_MCP73_AA     0x07fa10de
+#define ATA_NFORCE_MCP73_AB     0x07fb10de
 #define ATA_NFORCE_MCP77        0x075910de
 
 #define ATA_PROMISE_ID          0x105a
@@ -407,10 +424,12 @@ struct resource * ata_pci_alloc_resource
 int ata_pci_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r);
 int ata_pci_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_filter_t *filter, driver_intr_t *function, void *argument, void **cookiep);
  int ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie);
-int ata_pci_allocate(device_t dev);
+int ata_pci_ch_attach(device_t dev);
+int ata_pci_ch_detach(device_t dev);
 int ata_pci_status(device_t dev);
 void ata_pci_hw(device_t dev);
 void ata_pci_dmainit(device_t dev);
+void ata_pci_dmafini(device_t dev);
 char *ata_pcivendor2str(device_t dev);
 int ata_legacy(device_t);
 void ata_generic_intr(void *data);
@@ -423,7 +442,6 @@ int ata_check_80pin(device_t dev, int mo
 int ata_mode2idx(int mode);
 
 /* global prototypes ata-sata.c */
-void ata_sata_phy_event(void *context, int dummy);
 void ata_sata_phy_check_events(device_t dev);
 int ata_sata_phy_reset(device_t dev);
 void ata_sata_setmode(device_t dev, int mode);
@@ -432,14 +450,15 @@ void ata_pm_identify(device_t dev);
 
 /* global prototypes from chipsets/ata-*.c */
 int ata_ahci_chipinit(device_t);
-int ata_ahci_allocate(device_t dev);
+int ata_ahci_ch_attach(device_t dev);
+int ata_ahci_ch_detach(device_t dev);
 void ata_ahci_reset(device_t dev);
-void ata_ahci_dmainit(device_t dev);
 int ata_marvell_edma_chipinit(device_t);
 int ata_sii_chipinit(device_t);
 

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list