From owner-svn-src-all@FreeBSD.ORG Thu Oct 9 12:56:57 2008 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9FD5D106568E; Thu, 9 Oct 2008 12:56:57 +0000 (UTC) (envelope-from sos@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 894A08FC13; Thu, 9 Oct 2008 12:56:57 +0000 (UTC) (envelope-from sos@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 m99Cuvaf062510; Thu, 9 Oct 2008 12:56:57 GMT (envelope-from sos@svn.freebsd.org) Received: (from sos@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id m99Cuvex062502; Thu, 9 Oct 2008 12:56:57 GMT (envelope-from sos@svn.freebsd.org) Message-Id: <200810091256.m99Cuvex062502@svn.freebsd.org> From: Søren Schmidt Date: Thu, 9 Oct 2008 12:56:57 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r183724 - in head/sys: conf dev/ata dev/ata/chipsets modules/ata modules/ata/ata modules/ata/atacore modules/ata/atadevel modules/ata/atapci modules/ata/atapci/chipsets modules/ata/atap... X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Oct 2008 12:56:57 -0000 Author: sos Date: Thu Oct 9 12:56:57 2008 New Revision: 183724 URL: http://svn.freebsd.org/changeset/base/183724 Log: This is the roumored ATA modulerisation works, and it needs a little explanation. If you just config KERNEL as usual there should be no apparent changes, you'll get all chipset support code compiled in. However there is now a way to only compile in code for chipsets needed on a pr vendor basis. ATA now has the following "device" entries: atacore: ATA core functionality, always needed for any ATA setup atacard: CARDBUS support atacbus: PC98 cbus support ataisa: ISA bus support atapci: PCI bus support only generic chipset support. ataahci: AHCI support, also pulled in by some vendor modules. ataacard, ataacerlabs, ataadaptec, ataamd, ataati, atacenatek, atacypress, atacyrix, atahighpoint, ataintel, ataite, atajmicron, atamarvell, atamicron, atanational, atanetcell, atanvidia, atapromise, ataserverworks, atasiliconimage, atasis, atavia; Vendor support, ie atavia for VIA chipsets atadisk: ATA disk driver ataraid: ATA softraid driver atapicd: ATAPI cd/dvd driver atapifd: ATAPI floppy/flashdisk driver atapist: ATAPI tape driver atausb: ATA<>USB bridge atapicam: ATA<>CAM bridge This makes it possible to config a kernel with just VIA chipset support by having the following ATA lines in the kernel config file: device atacore device atapci device atavia And then you need the atadisk, atapicd etc lines in there just as usual. If you use ATA as modules loaded at boot there is few changes except the rename of the "ata" module to "atacore", things looks just as usual. However under atapci you now have a whole bunch of vendor specific drivers, that you can kldload individually depending on you needs. Drivers have the same names as used in the kernel config explained above. Added: head/sys/dev/ata/ata-sata.c (contents, props changed) head/sys/dev/ata/chipsets/ head/sys/dev/ata/chipsets/ata-acard.c (contents, props changed) head/sys/dev/ata/chipsets/ata-acerlabs.c (contents, props changed) head/sys/dev/ata/chipsets/ata-adaptec.c (contents, props changed) head/sys/dev/ata/chipsets/ata-ahci.c (contents, props changed) head/sys/dev/ata/chipsets/ata-amd.c (contents, props changed) head/sys/dev/ata/chipsets/ata-ati.c (contents, props changed) head/sys/dev/ata/chipsets/ata-cenatek.c (contents, props changed) head/sys/dev/ata/chipsets/ata-cypress.c (contents, props changed) head/sys/dev/ata/chipsets/ata-cyrix.c (contents, props changed) head/sys/dev/ata/chipsets/ata-highpoint.c (contents, props changed) head/sys/dev/ata/chipsets/ata-intel.c (contents, props changed) head/sys/dev/ata/chipsets/ata-ite.c (contents, props changed) head/sys/dev/ata/chipsets/ata-jmicron.c (contents, props changed) head/sys/dev/ata/chipsets/ata-marvell.c (contents, props changed) head/sys/dev/ata/chipsets/ata-micron.c (contents, props changed) head/sys/dev/ata/chipsets/ata-national.c (contents, props changed) head/sys/dev/ata/chipsets/ata-netcell.c (contents, props changed) head/sys/dev/ata/chipsets/ata-nvidia.c (contents, props changed) head/sys/dev/ata/chipsets/ata-promise.c (contents, props changed) head/sys/dev/ata/chipsets/ata-serverworks.c (contents, props changed) head/sys/dev/ata/chipsets/ata-siliconimage.c (contents, props changed) head/sys/dev/ata/chipsets/ata-sis.c (contents, props changed) head/sys/dev/ata/chipsets/ata-via.c (contents, props changed) head/sys/modules/ata/atacore/ head/sys/modules/ata/atacore/Makefile (contents, props changed) head/sys/modules/ata/atadevel/ head/sys/modules/ata/atadevel/Makefile (contents, props changed) head/sys/modules/ata/atadevel/ata-devel.c (contents, props changed) head/sys/modules/ata/atapci/Makefile.inc (contents, props changed) head/sys/modules/ata/atapci/chipsets/ head/sys/modules/ata/atapci/chipsets/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/Makefile.inc (contents, props changed) head/sys/modules/ata/atapci/chipsets/ataacard/ head/sys/modules/ata/atapci/chipsets/ataacard/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/ataacerlabs/ head/sys/modules/ata/atapci/chipsets/ataacerlabs/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/ataadaptec/ head/sys/modules/ata/atapci/chipsets/ataadaptec/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/ataahci/ head/sys/modules/ata/atapci/chipsets/ataahci/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/ataamd/ head/sys/modules/ata/atapci/chipsets/ataamd/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/ataati/ head/sys/modules/ata/atapci/chipsets/ataati/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atacenatek/ head/sys/modules/ata/atapci/chipsets/atacenatek/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atacypress/ head/sys/modules/ata/atapci/chipsets/atacypress/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atacyrix/ head/sys/modules/ata/atapci/chipsets/atacyrix/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atahighpoint/ head/sys/modules/ata/atapci/chipsets/atahighpoint/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/ataintel/ head/sys/modules/ata/atapci/chipsets/ataintel/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/ataite/ head/sys/modules/ata/atapci/chipsets/ataite/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atajmicron/ head/sys/modules/ata/atapci/chipsets/atajmicron/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atamarvell/ head/sys/modules/ata/atapci/chipsets/atamarvell/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atamicron/ head/sys/modules/ata/atapci/chipsets/atamicron/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atanational/ head/sys/modules/ata/atapci/chipsets/atanational/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atanetcell/ head/sys/modules/ata/atapci/chipsets/atanetcell/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atanvidia/ head/sys/modules/ata/atapci/chipsets/atanvidia/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atapromise/ head/sys/modules/ata/atapci/chipsets/atapromise/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/ataserverworks/ head/sys/modules/ata/atapci/chipsets/ataserverworks/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atasiliconimage/ head/sys/modules/ata/atapci/chipsets/atasiliconimage/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atasis/ head/sys/modules/ata/atapci/chipsets/atasis/Makefile (contents, props changed) head/sys/modules/ata/atapci/chipsets/atavia/ head/sys/modules/ata/atapci/chipsets/atavia/Makefile (contents, props changed) Deleted: head/sys/dev/ata/ata-chipset.c head/sys/modules/ata/ata/Makefile Modified: head/sys/conf/files head/sys/dev/ata/ata-all.c head/sys/dev/ata/ata-all.h head/sys/dev/ata/ata-dma.c head/sys/dev/ata/ata-pci.c head/sys/dev/ata/ata-pci.h head/sys/modules/ata/Makefile head/sys/modules/ata/atapci/Makefile Modified: head/sys/conf/files ============================================================================== --- head/sys/conf/files Thu Oct 9 12:25:07 2008 (r183723) +++ head/sys/conf/files Thu Oct 9 12:56:57 2008 (r183724) @@ -459,23 +459,49 @@ dev/an/if_an_isa.c optional an isa dev/an/if_an_pccard.c optional an pccard dev/an/if_an_pci.c optional an pci dev/asr/asr.c optional asr pci -dev/ata/ata_if.m optional ata -dev/ata/ata-all.c optional ata -dev/ata/ata-card.c optional ata pccard -dev/ata/ata-cbus.c optional ata pc98 -dev/ata/ata-chipset.c optional ata pci +# +dev/ata/ata_if.m optional ata | atacore +dev/ata/ata-all.c optional ata | atacore +dev/ata/ata-lowlevel.c optional ata | atacore +dev/ata/ata-queue.c optional ata | atacore +dev/ata/ata-card.c optional ata pccard | atapccard +dev/ata/ata-cbus.c optional ata pc98 | atapc98 +dev/ata/ata-isa.c optional ata isa | ataisa +dev/ata/ata-pci.c optional ata pci | atapci +dev/ata/ata-dma.c optional ata pci | atapci +dev/ata/ata-sata.c optional ata pci | atapci +dev/ata/chipsets/ata-ahci.c optional ata pci | ataahci | ataacerlabs | \ + ataati | ataintel | atajmicron | atavia +dev/ata/chipsets/ata-acard.c optional ata pci | ataacard +dev/ata/chipsets/ata-acerlabs.c optional ata pci | ataacerlabs +dev/ata/chipsets/ata-adaptec.c optional ata pci | ataadaptec +dev/ata/chipsets/ata-amd.c optional ata pci | ataamd +dev/ata/chipsets/ata-ati.c optional ata pci | ataati +dev/ata/chipsets/ata-cenatek.c optional ata pci | atacenatek +dev/ata/chipsets/ata-cypress.c optional ata pci | atacypress +dev/ata/chipsets/ata-cyrix.c optional ata pci | atacyrix +dev/ata/chipsets/ata-highpoint.c optional ata pci | atahighpoint +dev/ata/chipsets/ata-intel.c optional ata pci | ataintel +dev/ata/chipsets/ata-ite.c optional ata pci | ataite +dev/ata/chipsets/ata-jmicron.c optional ata pci | atajmicron +dev/ata/chipsets/ata-marvell.c optional ata pci | atamarvell +dev/ata/chipsets/ata-micron.c optional ata pci | atamicron +dev/ata/chipsets/ata-national.c optional ata pci | atanational +dev/ata/chipsets/ata-netcell.c optional ata pci | atanetcell +dev/ata/chipsets/ata-nvidia.c optional ata pci | atanvidia +dev/ata/chipsets/ata-promise.c optional ata pci | atapromise +dev/ata/chipsets/ata-serverworks.c optional ata pci | ataserverworks +dev/ata/chipsets/ata-siliconimage.c optional ata pci | atasiliconimage +dev/ata/chipsets/ata-sis.c optional ata pci | atasis +dev/ata/chipsets/ata-via.c optional ata pci | atavia dev/ata/ata-disk.c optional atadisk -dev/ata/ata-dma.c optional ata pci -dev/ata/ata-isa.c optional ata isa -dev/ata/ata-lowlevel.c optional ata -dev/ata/ata-pci.c optional ata pci -dev/ata/ata-queue.c optional ata dev/ata/ata-raid.c optional ataraid dev/ata/ata-usb.c optional atausb -dev/ata/atapi-cam.c optional atapicam dev/ata/atapi-cd.c optional atapicd dev/ata/atapi-fd.c optional atapifd dev/ata/atapi-tape.c optional atapist +dev/ata/atapi-cam.c optional atapicam +# dev/ath/ah_osdep.c optional ath_hal \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_rate/amrr/amrr.c optional ath_rate_amrr \ Modified: head/sys/dev/ata/ata-all.c ============================================================================== --- head/sys/dev/ata/ata-all.c Thu Oct 9 12:25:07 2008 (r183723) +++ head/sys/dev/ata/ata-all.c Thu Oct 9 12:56:57 2008 (r183724) @@ -616,7 +616,6 @@ ata_getparam(struct ata_device *atadev, if (!error && (isprint(atadev->param.model[0]) || isprint(atadev->param.model[1]))) { struct ata_params *atacap = &atadev->param; - char buffer[64]; int16_t *ptr; for (ptr = (int16_t *)atacap; @@ -648,6 +647,8 @@ ata_getparam(struct ata_device *atadev, (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); if ((atadev->param.config & ATA_PROTO_ATAPI) && @@ -677,8 +678,8 @@ int ata_identify(device_t dev) { struct ata_channel *ch = device_get_softc(dev); - struct ata_device *devices[ATA_PM]; - device_t childdevs[ATA_PM]; + struct ata_device *atadev; + device_t child; int i; if (bootverbose) @@ -688,33 +689,26 @@ ata_identify(device_t dev) if (ch->devices & (((ATA_ATA_MASTER | ATA_ATAPI_MASTER) << i))) { int unit = -1; - if (!(devices[i] = malloc(sizeof(struct ata_device), - M_ATA, M_NOWAIT | M_ZERO))) { + if (!(atadev = malloc(sizeof(struct ata_device), + M_ATA, M_NOWAIT | M_ZERO))) { device_printf(dev, "out of memory\n"); return ENOMEM; } - devices[i]->unit = i; + atadev->unit = i; #ifdef ATA_STATIC_ID if (ch->devices & ((ATA_ATA_MASTER << i))) unit = (device_get_unit(dev) << 1) + i; #endif - if (!(childdevs[i] = ata_add_child(dev, devices[i], unit))) { - free(devices[i], M_ATA); - devices[i]=NULL; - } - else { - if (ata_getparam(devices[i], 1)) { - device_delete_child(dev, childdevs[i]); - free(devices[i], M_ATA); - childdevs[i] = NULL; - devices[i] = NULL; + 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); } - devices[i] = NULL; - childdevs[i] = NULL; } - bus_generic_probe(dev); bus_generic_attach(dev); return 0; @@ -895,6 +889,16 @@ ata_mode2str(int mode) } int +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)); +} + +int ata_pmode(struct ata_params *ap) { if (ap->atavalid & ATA_FLAG_64_70) { Modified: head/sys/dev/ata/ata-all.h ============================================================================== --- head/sys/dev/ata/ata-all.h Thu Oct 9 12:25:07 2008 (r183723) +++ head/sys/dev/ata/ata-all.h Thu Oct 9 12:56:57 2008 (r183724) @@ -563,6 +563,7 @@ void ata_modify_if_48bit(struct ata_requ void ata_udelay(int interval); char *ata_unit2str(struct ata_device *atadev); char *ata_mode2str(int mode); +int ata_atapi(device_t dev); int ata_pmode(struct ata_params *ap); int ata_wmode(struct ata_params *ap); int ata_umode(struct ata_params *ap); Modified: head/sys/dev/ata/ata-dma.c ============================================================================== --- head/sys/dev/ata/ata-dma.c Thu Oct 9 12:25:07 2008 (r183723) +++ head/sys/dev/ata/ata-dma.c Thu Oct 9 12:56:57 2008 (r183724) @@ -81,7 +81,7 @@ ata_dmainit(device_t dev) ch->dma.segsize = 63536; ch->dma.max_iosize = 128 * DEV_BSIZE; ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT; - ch->dma.dma_slots = 2; + ch->dma.dma_slots = 6; if (bus_dma_tag_create(bus_get_dma_tag(dev), ch->dma.alignment, 0, ch->dma.max_address, BUS_SPACE_MAXADDR, Modified: head/sys/dev/ata/ata-pci.c ============================================================================== --- head/sys/dev/ata/ata-pci.c Thu Oct 9 12:25:07 2008 (r183723) +++ head/sys/dev/ata/ata-pci.c Thu Oct 9 12:56:57 2008 (r183724) @@ -54,140 +54,34 @@ static MALLOC_DEFINE(M_ATAPCI, "ata_pci" /* misc defines */ #define IOMASK 0xfffffffc -#define ATA_PROBE_OK -10 - -int -ata_legacy(device_t dev) -{ - return (((pci_read_config(dev, PCIR_PROGIF, 1)&PCIP_STORAGE_IDE_MASTERDEV)&& - ((pci_read_config(dev, PCIR_PROGIF, 1) & - (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC)) != - (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC))) || - (!pci_read_config(dev, PCIR_BAR(0), 4) && - !pci_read_config(dev, PCIR_BAR(1), 4) && - !pci_read_config(dev, PCIR_BAR(2), 4) && - !pci_read_config(dev, PCIR_BAR(3), 4) && - !pci_read_config(dev, PCIR_BAR(5), 4))); -} +/* local prototypes */ +static int ata_generic_chipinit(device_t dev); +static void ata_generic_setmode(device_t dev, int mode); + +/* + * generic PCI ATA device probe + */ int ata_pci_probe(device_t dev) { + struct ata_pci_controller *ctlr = device_get_softc(dev); + char buffer[64]; + + /* is this a storage class device ? */ if (pci_get_class(dev) != PCIC_STORAGE) return ENXIO; - /* if this is an AHCI chipset grab it */ - if (pci_get_subclass(dev) == PCIS_STORAGE_SATA) { - if (!ata_ahci_ident(dev)) - return ATA_PROBE_OK; - } - - /* run through the vendor specific drivers */ - switch (pci_get_vendor(dev)) { - case ATA_ACARD_ID: - if (!ata_acard_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_ACER_LABS_ID: - if (!ata_ali_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_AMD_ID: - if (!ata_amd_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_ADAPTEC_ID: - if (!ata_adaptec_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_ATI_ID: - if (!ata_ati_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_CYRIX_ID: - if (!ata_cyrix_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_CYPRESS_ID: - if (!ata_cypress_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_HIGHPOINT_ID: - if (!ata_highpoint_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_INTEL_ID: - if (!ata_intel_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_ITE_ID: - if (!ata_ite_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_JMICRON_ID: - if (!ata_jmicron_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_MARVELL_ID: - if (!ata_marvell_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_NATIONAL_ID: - if (!ata_national_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_NETCELL_ID: - if (!ata_netcell_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_NVIDIA_ID: - if (!ata_nvidia_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_PROMISE_ID: - if (!ata_promise_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_SERVERWORKS_ID: - if (!ata_serverworks_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_SILICON_IMAGE_ID: - if (!ata_sii_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_SIS_ID: - if (!ata_sis_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_VIA_ID: - if (!ata_via_ident(dev)) - return ATA_PROBE_OK; - break; - case ATA_CENATEK_ID: - if (pci_get_devid(dev) == ATA_CENATEK_ROCKET) { - ata_generic_ident(dev); - device_set_desc(dev, "Cenatek Rocket Drive controller"); - return ATA_PROBE_OK; - } - break; - case ATA_MICRON_ID: - if (pci_get_devid(dev) == ATA_MICRON_RZ1000 || - pci_get_devid(dev) == ATA_MICRON_RZ1001) { - ata_generic_ident(dev); - device_set_desc(dev, - "RZ 100? ATA controller !WARNING! data loss/corruption risk"); - return ATA_PROBE_OK; - } - break; - } + /* is this an IDE/ATA type device ? */ + if (pci_get_subclass(dev) != PCIS_STORAGE_IDE) + return ENXIO; + + sprintf(buffer, "%s ATA controller", ata_pcivendor2str(dev)); + device_set_desc_copy(dev, buffer); + ctlr->chipinit = ata_generic_chipinit; - /* unknown chipset, try generic DMA if it seems possible */ - if (pci_get_subclass(dev) == PCIS_STORAGE_IDE) { - if (!ata_generic_ident(dev)) - return ATA_PROBE_OK; - } - return ENXIO; + /* we are a low priority handler */ + return -100; } int @@ -286,7 +180,6 @@ ata_pci_resume(device_t dev) return error; } - struct resource * ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) @@ -414,6 +307,28 @@ ata_pci_teardown_intr(device_t dev, devi } } +static void +ata_generic_setmode(device_t dev, int mode) +{ + struct ata_device *atadev = device_get_softc(dev); + + mode = ata_limit_mode(dev, mode, ATA_UDMA2); + mode = ata_check_80pin(dev, mode); + if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) + atadev->mode = mode; +} + +static int +ata_generic_chipinit(device_t dev) +{ + struct ata_pci_controller *ctlr = device_get_softc(dev); + + if (ata_setup_interrupt(dev, ata_generic_intr)) + return ENXIO; + ctlr->setmode = ata_generic_setmode; + return 0; +} + int ata_pci_allocate(device_t dev) { @@ -545,35 +460,6 @@ ata_pci_dmainit(device_t dev) ch->dma.reset = ata_pci_dmareset; } -char * -ata_pcivendor2str(device_t dev) -{ - switch (pci_get_vendor(dev)) { - case ATA_ACARD_ID: return "Acard"; - case ATA_ACER_LABS_ID: return "AcerLabs"; - case ATA_AMD_ID: return "AMD"; - case ATA_ADAPTEC_ID: return "Adaptec"; - case ATA_ATI_ID: return "ATI"; - case ATA_CYRIX_ID: return "Cyrix"; - case ATA_CYPRESS_ID: return "Cypress"; - case ATA_HIGHPOINT_ID: return "HighPoint"; - case ATA_INTEL_ID: return "Intel"; - case ATA_ITE_ID: return "ITE"; - case ATA_JMICRON_ID: return "JMicron"; - case ATA_MARVELL_ID: return "Marvell"; - case ATA_NATIONAL_ID: return "National"; - case ATA_NETCELL_ID: return "Netcell"; - case ATA_NVIDIA_ID: return "nVidia"; - case ATA_PROMISE_ID: return "Promise"; - case ATA_SERVERWORKS_ID: return "ServerWorks"; - case ATA_SILICON_IMAGE_ID: return "SiI"; - case ATA_SIS_ID: return "SiS"; - case ATA_VIA_ID: return "VIA"; - case ATA_CENATEK_ID: return "Cenatek"; - case ATA_MICRON_ID: return "Micron"; - default: return "Generic"; - } -} static device_method_t ata_pci_methods[] = { /* device interface */ @@ -595,7 +481,7 @@ static device_method_t ata_pci_methods[] { 0, 0 } }; -devclass_t atapci_devclass; +devclass_t ata_pci_devclass; static driver_t ata_pci_driver = { "atapci", @@ -603,7 +489,7 @@ static driver_t ata_pci_driver = { sizeof(struct ata_pci_controller), }; -DRIVER_MODULE(atapci, pci, ata_pci_driver, atapci_devclass, 0, 0); +DRIVER_MODULE(atapci, pci, ata_pci_driver, ata_pci_devclass, 0, 0); MODULE_VERSION(atapci, 1); MODULE_DEPEND(atapci, ata, 1, 1, 1); @@ -728,3 +614,171 @@ driver_t ata_pcichannel_driver = { }; DRIVER_MODULE(ata, atapci, ata_pcichannel_driver, ata_devclass, 0, 0); + + +/* + * misc support fucntions + */ +int +ata_legacy(device_t dev) +{ + return (((pci_read_config(dev, PCIR_PROGIF, 1)&PCIP_STORAGE_IDE_MASTERDEV)&& + ((pci_read_config(dev, PCIR_PROGIF, 1) & + (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC)) != + (PCIP_STORAGE_IDE_MODEPRIM | PCIP_STORAGE_IDE_MODESEC))) || + (!pci_read_config(dev, PCIR_BAR(0), 4) && + !pci_read_config(dev, PCIR_BAR(1), 4) && + !pci_read_config(dev, PCIR_BAR(2), 4) && + !pci_read_config(dev, PCIR_BAR(3), 4) && + !pci_read_config(dev, PCIR_BAR(5), 4))); +} + +void +ata_generic_intr(void *data) +{ + struct ata_pci_controller *ctlr = data; + struct ata_channel *ch; + int unit; + + for (unit = 0; unit < ctlr->channels; unit++) { + if ((ch = ctlr->interrupt[unit].argument)) + ctlr->interrupt[unit].function(ch); + } +} + +int +ata_setup_interrupt(device_t dev, void *intr_func) +{ + struct ata_pci_controller *ctlr = device_get_softc(dev); + int rid = ATA_IRQ_RID; + + if (!ata_legacy(dev)) { + if (!(ctlr->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE))) { + device_printf(dev, "unable to map interrupt\n"); + return ENXIO; + } + if ((bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS, NULL, + intr_func, ctlr, &ctlr->handle))) { + /* SOS XXX release r_irq */ + device_printf(dev, "unable to setup interrupt\n"); + return ENXIO; + } + } + return 0; +} + +void +ata_set_desc(device_t dev) +{ + struct ata_pci_controller *ctlr = device_get_softc(dev); + char buffer[128]; + + sprintf(buffer, "%s %s %s controller", + ata_pcivendor2str(dev), ctlr->chip->text, + ata_mode2str(ctlr->chip->max_dma)); + device_set_desc_copy(dev, buffer); +} + +struct ata_chip_id * +ata_match_chip(device_t dev, struct ata_chip_id *index) +{ + while (index->chipid != 0) { + if (pci_get_devid(dev) == index->chipid && + pci_get_revid(dev) >= index->chiprev) + return index; + index++; + } + return NULL; +} + +struct ata_chip_id * +ata_find_chip(device_t dev, struct ata_chip_id *index, int slot) +{ + device_t *children; + int nchildren, i; + + if (device_get_children(device_get_parent(dev), &children, &nchildren)) + return 0; + + while (index->chipid != 0) { + for (i = 0; i < nchildren; i++) { + if (((slot >= 0 && pci_get_slot(children[i]) == slot) || + (slot < 0 && pci_get_slot(children[i]) <= -slot)) && + pci_get_devid(children[i]) == index->chipid && + pci_get_revid(children[i]) >= index->chiprev) { + free(children, M_TEMP); + return index; + } + } + index++; + } + free(children, M_TEMP); + return NULL; +} + +void +ata_print_cable(device_t dev, u_int8_t *who) +{ + device_printf(dev, + "DMA limited to UDMA33, %s found non-ATA66 cable\n", who); +} + +int +ata_check_80pin(device_t dev, int mode) +{ + struct ata_device *atadev = device_get_softc(dev); + + if (!ata_dma_check_80pin) { + if (bootverbose) + device_printf(dev, "Skipping 80pin cable check\n"); + return mode; + } + + if (mode > ATA_UDMA2 && !(atadev->param.hwres & ATA_CABLE_ID)) { + ata_print_cable(dev, "device"); + mode = ATA_UDMA2; + } + return mode; +} + +char * +ata_pcivendor2str(device_t dev) +{ + switch (pci_get_vendor(dev)) { + case ATA_ACARD_ID: return "Acard"; + case ATA_ACER_LABS_ID: return "AcerLabs"; + case ATA_AMD_ID: return "AMD"; + case ATA_ADAPTEC_ID: return "Adaptec"; + case ATA_ATI_ID: return "ATI"; + case ATA_CYRIX_ID: return "Cyrix"; + case ATA_CYPRESS_ID: return "Cypress"; + case ATA_HIGHPOINT_ID: return "HighPoint"; + case ATA_INTEL_ID: return "Intel"; + case ATA_ITE_ID: return "ITE"; + case ATA_JMICRON_ID: return "JMicron"; + case ATA_MARVELL_ID: return "Marvell"; + case ATA_NATIONAL_ID: return "National"; + case ATA_NETCELL_ID: return "Netcell"; + case ATA_NVIDIA_ID: return "nVidia"; + case ATA_PROMISE_ID: return "Promise"; + case ATA_SERVERWORKS_ID: return "ServerWorks"; + case ATA_SILICON_IMAGE_ID: return "SiI"; + case ATA_SIS_ID: return "SiS"; + case ATA_VIA_ID: return "VIA"; + case ATA_CENATEK_ID: return "Cenatek"; + case ATA_MICRON_ID: return "Micron"; + default: return "Generic"; + } +} + +int +ata_mode2idx(int mode) +{ + if ((mode & ATA_DMA_MASK) == ATA_UDMA0) + return (mode & ATA_MODE_MASK) + 8; + if ((mode & ATA_DMA_MASK) == ATA_WDMA0) + return (mode & ATA_MODE_MASK) + 5; + return (mode & ATA_MODE_MASK) - ATA_PIO0; +} + Modified: head/sys/dev/ata/ata-pci.h ============================================================================== --- head/sys/dev/ata/ata-pci.h Thu Oct 9 12:25:07 2008 (r183723) +++ head/sys/dev/ata/ata-pci.h Thu Oct 9 12:56:57 2008 (r183724) @@ -395,79 +395,6 @@ struct ata_connect_task { #define ATA_VIA6420 0x31491106 #define ATA_VIA6421 0x32491106 -/* chipset setup related defines */ -#define AHCI 1 -#define ATPOLD 1 - -#define ALIOLD 0x01 -#define ALINEW 0x02 -#define ALISATA 0x04 - -#define ATIPATA 0x01 -#define ATISATA 0x02 -#define ATIAHCI 0x04 - -#define HPT366 0 -#define HPT370 1 -#define HPT372 2 -#define HPT374 3 -#define HPTOLD 0x01 - -#define MV50XX 50 -#define MV60XX 60 -#define MV61XX 61 - -#define PROLD 0 -#define PRNEW 1 -#define PRTX 2 -#define PRMIO 3 -#define PRTX4 0x01 -#define PRSX4X 0x02 -#define PRSX6K 0x04 -#define PRPATA 0x08 -#define PRCMBO 0x10 -#define PRCMBO2 0x20 -#define PRSATA 0x40 -#define PRSATA2 0x80 - -#define SWKS33 0 -#define SWKS66 1 -#define SWKS100 2 -#define SWKSMIO 3 - -#define SIIMEMIO 1 -#define SIIPRBIO 2 -#define SIIINTR 0x01 -#define SIISETCLK 0x02 -#define SIIBUG 0x04 -#define SII4CH 0x08 - -#define SIS_SOUTH 1 -#define SISSATA 2 -#define SIS133NEW 3 -#define SIS133OLD 4 -#define SIS100NEW 5 -#define SIS100OLD 6 -#define SIS66 7 -#define SIS33 8 - -#define VIA33 0 -#define VIA66 1 -#define VIA100 2 -#define VIA133 3 -#define AMDNVIDIA 4 - -#define AMDCABLE 0x0001 -#define AMDBUG 0x0002 -#define NVIDIA 0x0004 -#define NV4 0x0010 -#define NVQ 0x0020 -#define VIACLK 0x0100 -#define VIABUG 0x0200 -#define VIABAR 0x0400 -#define VIAAHCI 0x0800 - - /* global prototypes ata-pci.c */ int ata_pci_probe(device_t dev); int ata_pci_attach(device_t dev); @@ -483,32 +410,62 @@ int ata_pci_status(device_t dev); void ata_pci_hw(device_t dev); void ata_pci_dmainit(device_t dev); char *ata_pcivendor2str(device_t dev); - - -/* global prototypes ata-chipset.c */ -int ata_generic_ident(device_t); -int ata_ahci_ident(device_t); -int ata_acard_ident(device_t); -int ata_ali_ident(device_t); -int ata_amd_ident(device_t); -int ata_adaptec_ident(device_t); -int ata_ati_ident(device_t); -int ata_cyrix_ident(device_t); -int ata_cypress_ident(device_t); -int ata_highpoint_ident(device_t); -int ata_intel_ident(device_t); -int ata_ite_ident(device_t); -int ata_jmicron_ident(device_t); -int ata_marvell_ident(device_t); -int ata_national_ident(device_t); -int ata_nvidia_ident(device_t); -int ata_netcell_ident(device_t); -int ata_promise_ident(device_t); -int ata_serverworks_ident(device_t); -int ata_sii_ident(device_t); -int ata_sis_ident(device_t); -int ata_via_ident(device_t); int ata_legacy(device_t); +void ata_generic_intr(void *data); +int ata_setup_interrupt(device_t dev, void *intr_func); +void ata_set_desc(device_t dev); +struct ata_chip_id *ata_match_chip(device_t dev, struct ata_chip_id *index); +struct ata_chip_id *ata_find_chip(device_t dev, struct ata_chip_id *index, int slot); +void ata_print_cable(device_t dev, u_int8_t *who); +int ata_check_80pin(device_t dev, int mode); +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); +int ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis); +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); +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); /* global prototypes ata-dma.c */ void ata_dmainit(device_t); + +/* externs */ +extern devclass_t ata_pci_devclass; + +/* macro for easy definition of all driver module stuff */ +#define ATA_DECLARE_DRIVER(dname) \ +static device_method_t __CONCAT(dname,_methods)[] = { \ + DEVMETHOD(device_probe, __CONCAT(dname,_probe)), \ + DEVMETHOD(device_attach, ata_pci_attach), \ + DEVMETHOD(device_detach, ata_pci_detach), \ + DEVMETHOD(device_suspend, bus_generic_suspend), \ + DEVMETHOD(device_resume, bus_generic_resume), \ + DEVMETHOD(device_shutdown, bus_generic_shutdown), \ + DEVMETHOD(bus_alloc_resource, ata_pci_alloc_resource), \ + DEVMETHOD(bus_release_resource, ata_pci_release_resource), \ + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), \ + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), \ + DEVMETHOD(bus_setup_intr, ata_pci_setup_intr), \ + DEVMETHOD(bus_teardown_intr, ata_pci_teardown_intr), \ + { 0, 0 } \ +}; \ +static driver_t __CONCAT(dname,_driver) = { \ + "atapci", \ + __CONCAT(dname,_methods), \ + sizeof(struct ata_pci_controller) \ +}; \ +DRIVER_MODULE(dname, pci, __CONCAT(dname,_driver), ata_pci_devclass, 0, 0); \ +MODULE_VERSION(dname, 1); \ +MODULE_DEPEND(dname, ata, 1, 1, 1); \ +MODULE_DEPEND(dname, atapci, 1, 1, 1); + Added: head/sys/dev/ata/ata-sata.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/ata/ata-sata.c Thu Oct 9 12:56:57 2008 (r183724) @@ -0,0 +1,357 @@ +/*- + * Copyright (c) 1998 - 2008 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "opt_ata.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * SATA support functions + */ +void +ata_sata_phy_event(void *context, int dummy) +{ + struct ata_connect_task *tp = (struct ata_connect_task *)context; + struct ata_channel *ch = device_get_softc(tp->dev); + device_t *children; + int nchildren, i; + + mtx_lock(&Giant); /* newbus suckage it needs Giant */ + if (tp->action == ATA_C_ATTACH) { + if (bootverbose) + device_printf(tp->dev, "CONNECTED\n"); + ATA_RESET(tp->dev); + ata_identify(tp->dev); + } + if (tp->action == ATA_C_DETACH) { + if (!device_get_children(tp->dev, &children, &nchildren)) { + for (i = 0; i < nchildren; i++) + if (children[i]) + device_delete_child(tp->dev, children[i]); + free(children, M_TEMP); + } + mtx_lock(&ch->state_mtx); + ch->state = ATA_IDLE; + mtx_unlock(&ch->state_mtx); + if (bootverbose) + device_printf(tp->dev, "DISCONNECTED\n"); + } + mtx_unlock(&Giant); /* suckage code dealt with, release Giant */ + free(tp, M_ATA); +} + +void +ata_sata_phy_check_events(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR); + + /* clear error bits/interrupt */ + ATA_IDX_OUTL(ch, ATA_SERROR, error); + + /* do we have any events flagged ? */ + if (error) { + struct ata_connect_task *tp; + u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS); + + /* if we have a connection event deal with it */ + if ((error & ATA_SE_PHY_CHANGED) && + (tp = (struct ata_connect_task *) + malloc(sizeof(struct ata_connect_task), + M_ATA, M_NOWAIT | M_ZERO))) { + + if (((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1) || + ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)) { + if (bootverbose) + device_printf(dev, "CONNECT requested\n"); + tp->action = ATA_C_ATTACH; + } + else { + if (bootverbose) + device_printf(dev, "DISCONNECT requested\n"); + tp->action = ATA_C_DETACH; + } + tp->dev = dev; + TASK_INIT(&tp->task, 0, ata_sata_phy_event, tp); + taskqueue_enqueue(taskqueue_thread, &tp->task); + } + } +} + +static int +ata_sata_connect(struct ata_channel *ch) +{ + u_int32_t status; + int timeout; + + /* wait up to 1 second for "connect well" */ + for (timeout = 0; timeout < 100 ; timeout++) { + status = ATA_IDX_INL(ch, ATA_SSTATUS); + if ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1 || + (status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2) + break; + ata_udelay(10000); + } + if (timeout >= 100) { + if (bootverbose) + device_printf(ch->dev, "SATA connect status=%08x\n", status); + return 0; + } + if (bootverbose) + device_printf(ch->dev, "SATA connect time=%dms\n", timeout * 10); + + /* clear SATA error register */ + ATA_IDX_OUTL(ch, ATA_SERROR, ATA_IDX_INL(ch, ATA_SERROR)); + + return 1; +} + +int +ata_sata_phy_reset(device_t dev) +{ + struct ata_channel *ch = device_get_softc(dev); + int loop, retry; + + if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE) + return ata_sata_connect(ch); + + for (retry = 0; retry < 10; retry++) { + for (loop = 0; loop < 10; loop++) { + ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_RESET); + ata_udelay(100); + if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == + ATA_SC_DET_RESET) + break; + } + ata_udelay(5000); + for (loop = 0; loop < 10; loop++) { + ATA_IDX_OUTL(ch, ATA_SCONTROL, ATA_SC_DET_IDLE | + ATA_SC_IPM_DIS_PARTIAL | + ATA_SC_IPM_DIS_SLUMBER); + ata_udelay(100); + if ((ATA_IDX_INL(ch, ATA_SCONTROL) & ATA_SC_DET_MASK) == 0) + return ata_sata_connect(ch); + } + } + return 0; +} + +void +ata_sata_setmode(device_t dev, int mode) +{ + struct ata_device *atadev = device_get_softc(dev); + + /* + * if we detect that the device isn't a real SATA device we limit + * the transfer mode to UDMA5/ATA100. + * this works around the problems some devices has with the + * Marvell 88SX8030 SATA->PATA converters and UDMA6/ATA133. + */ + if (atadev->param.satacapabilities != 0x0000 && + atadev->param.satacapabilities != 0xffff) { + struct ata_channel *ch = device_get_softc(device_get_parent(dev)); + + /* on some drives we need to set the transfer mode */ + ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, + ata_limit_mode(dev, mode, ATA_UDMA6)); + + /* query SATA STATUS for the speed */ + if (ch->r_io[ATA_SSTATUS].res && + ((ATA_IDX_INL(ch, ATA_SSTATUS) & ATA_SS_CONWELL_MASK) == + ATA_SS_CONWELL_GEN2)) + atadev->mode = ATA_SA300; + else + atadev->mode = ATA_SA150; + } + else { + mode = ata_limit_mode(dev, mode, ATA_UDMA5); + if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode)) + atadev->mode = mode; + } +} + +int +ata_request2fis_h2d(struct ata_request *request, u_int8_t *fis) +{ + struct ata_device *atadev = device_get_softc(request->dev); + + if (request->flags & ATA_R_ATAPI) { + fis[0] = 0x27; /* host to device */ + fis[1] = 0x80 | (atadev->unit & 0x0f); + fis[2] = ATA_PACKET_CMD; + if (request->flags & (ATA_R_READ | ATA_R_WRITE)) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***