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