From owner-svn-src-projects@FreeBSD.ORG Sat Feb 28 17:55:32 2009 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E823D10656D9; Sat, 28 Feb 2009 17:55:32 +0000 (UTC) (envelope-from jb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D44DA8FC23; Sat, 28 Feb 2009 17:55:32 +0000 (UTC) (envelope-from jb@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n1SHtW0Z016957; Sat, 28 Feb 2009 17:55:32 GMT (envelope-from jb@svn.freebsd.org) Received: (from jb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n1SHtWGf016946; Sat, 28 Feb 2009 17:55:32 GMT (envelope-from jb@svn.freebsd.org) Message-Id: <200902281755.n1SHtWGf016946@svn.freebsd.org> From: John Birrell Date: Sat, 28 Feb 2009 17:55:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r189179 - in projects/jbuild/sys/dev/ata: . chipsets X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Feb 2009 17:55:33 -0000 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 /* 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 ***