From owner-freebsd-mobile Sat Apr 10 14:39:42 1999 Delivered-To: freebsd-mobile@freebsd.org Received: from rover.village.org (rover.village.org [204.144.255.49]) by hub.freebsd.org (Postfix) with ESMTP id 1A3D614D22 for ; Sat, 10 Apr 1999 14:39:33 -0700 (PDT) (envelope-from imp@harmony.village.org) Received: from harmony.village.org (harmony.village.org [10.0.0.6]) by rover.village.org (8.9.3/8.9.3) with ESMTP id PAA30094 for ; Sat, 10 Apr 1999 15:37:15 -0600 (MDT) (envelope-from imp@harmony.village.org) Received: from harmony.village.org (localhost.village.org [127.0.0.1]) by harmony.village.org (8.9.3/8.8.3) with ESMTP id PAA00752 for ; Sat, 10 Apr 1999 15:36:59 -0600 (MDT) Message-Id: <199904102136.PAA00752@harmony.village.org> To: mobile@freebsd.org Subject: Testing/review wanted Date: Sat, 10 Apr 1999 15:36:59 -0600 From: Warner Losh Sender: owner-freebsd-mobile@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org I've modified Soren's new ata code to work with ata flash memory (and hopefully pcmcia based ata controllers). However, since I only have one ata flash card, I've been able to do limited testing. Please find enclosed diffs against today's -current that I'd like people to test and/or review. I've not done anything with card unloading yet. Also, I've not tried to implement Microsoft's Flash File System (mffs), but I did find it documented on a MS web page the other day with a disclaimer saying that they won't litigate against anybody using the informtaion in that document. Comments? Warner Index: dev/ata/ata-all.c =================================================================== RCS file: /home/imp/FreeBSD/CVS/src/sys/dev/ata/ata-all.c,v retrieving revision 1.6 diff -d -u -r1.6 ata-all.c --- ata-all.c 1999/04/10 18:53:35 1.6 +++ ata-all.c 1999/04/10 20:55:33 @@ -33,6 +33,7 @@ #include "isa.h" #include "pci.h" #include "atadisk.h" +#include "card.h" #include #include #include @@ -53,6 +54,12 @@ #include #include #include +#if NCARD > 0 +#include +#include +#include +#include +#endif /* misc defines */ #define UNIT(dev) (dev>>3 & 0x1f) /* assume 8 minor # per unit */ @@ -71,6 +78,11 @@ static void ata_pciattach(pcici_t, int32_t); static void promise_intr(int32_t); #endif +#if NCARD > 0 +static int ata_pccard_init(struct pccard_devinfo *); +static void ata_pccard_unload(struct pccard_devinfo *); +static int ata_pccard_intr(struct pccard_devinfo *); +#endif static int32_t ata_probe(int32_t, int32_t, int32_t, pcici_t, int32_t *); static void ataintr(int32_t); @@ -262,6 +274,41 @@ } #endif +#if NCARD > 0 +PCCARD_MODULE(ata, ata_pccard_init, ata_pccard_unload, ata_pccard_intr, + 0, bio_imask); + +static int +ata_pccard_init(struct pccard_devinfo *devi) +{ + if (ata_isaprobe(&devi->isahd) == 0) + return ENXIO; + if (ata_isaattach(&devi->isahd) == 0) + return ENXIO; + printf("ata-pcmcia%d at 0x%x irq %d on pcmcia\n", + devi->isahd.id_unit, devi->isahd.id_iobase, ffs(devi->isahd.id_irq)); + /* + * probe the ata bus for atapi disks and old ata disks/flash cards + */ + atapi_attach_ctlr(atadevices[devi->isahd.id_unit]); + ad_attach_ctlr(atadevices[devi->isahd.id_unit]); + return 0; +} + +static void +ata_pccard_unload(struct pccard_devinfo *devi) +{ + printf("ata%d: unload -- unsupproted nop\n", devi->isahd.id_unit); +} + +static int +ata_pccard_intr(struct pccard_devinfo *devi) +{ + ataintr(devi->isahd.id_unit); + return 1; +} +#endif + static int32_t ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr, pcici_t tag, int32_t *unit) @@ -382,7 +429,7 @@ scp->devices |= ATA_ATAPI_SLAVE; } if (status0 != 0x00 && !(scp->devices & ATA_ATAPI_MASTER)) { - outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER)); + outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER)); DELAY(1); outb(scp->ioaddr + ATA_ERROR, 0x58); outb(scp->ioaddr + ATA_CYL_LSB, 0xa5); @@ -430,7 +477,10 @@ u_int8_t status; static int32_t intr_count = 0; - if (unit < 0 || unit > atanlun) { +#ifdef ATA_DEBUG + printf("ataintr: entered unit=%d\n", unit); +#endif + if (unit < 0 || unit > atanlun || atadevices[unit] == NULL) { printf("ataintr: unit %d unusable\n", unit); return; } Index: dev/ata/ata-disk.c =================================================================== RCS file: /home/imp/FreeBSD/CVS/src/sys/dev/ata/ata-disk.c,v retrieving revision 1.6 diff -d -u -r1.6 ata-disk.c --- ata-disk.c 1999/04/10 18:53:35 1.6 +++ ata-disk.c 1999/04/10 20:56:40 @@ -97,6 +97,100 @@ static int32_t adnlun = 0; /* number of config'd drives */ static struct intr_config_hook *ad_attach_hook; +void +ad_attach_ctlr(struct ata_softc *sc) +{ + struct ad_softc *adp; + int32_t dev, secsperint; + int8_t model_buf[40+1]; + int8_t revision_buf[8+1]; + + for (dev=0; dev<2; dev++) { + if (sc->devices & (dev ? ATA_ATA_SLAVE : ATA_ATA_MASTER)) { +#ifdef ATA_STATIC_ID + adnlun = dev + sc->unit * 2; +#endif + adp = adtab[adnlun]; + if (adp) { + printf("ad%d: unit already attached\n", adnlun); + continue; + } + if (!(adp = malloc(sizeof(struct ad_softc), M_DEVBUF, M_NOWAIT))) { + printf("ad%d: failed to allocate driver storage\n", adnlun); + continue; + } + bzero(adp, sizeof(struct ad_softc)); + adp->controller = sc; + adp->unit = (dev == 0) ? ATA_MASTER : ATA_SLAVE; + adp->lun = adnlun; + if (ad_getparam(adp)) { +#if ATA_DEBUG + printf("ata%d: device at %d not a disk", sc->unit, dev); +#endif + free(adp, M_DEVBUF); + continue; + } + adp->cylinders = adp->ata_parm->cylinders; + adp->heads = adp->ata_parm->heads; + adp->sectors = adp->ata_parm->sectors; + adp->total_secs = adp->cylinders * adp->heads * adp->sectors; + if (adp->cylinders == 16383 && + adp->total_secs < adp->ata_parm->lbasize) { + adp->total_secs = adp->ata_parm->lbasize; + adp->cylinders = adp->total_secs/(adp->heads*adp->sectors); + } + + /* support multiple sectors / interrupt ? */ + adp->transfersize = DEV_BSIZE; + secsperint = min(adp->ata_parm->nsecperint, 16); + + if (!ata_command(adp->controller, adp->unit, ATA_C_SET_MULTI, + 0, 0, 0, 0, secsperint, ATA_WAIT_INTR) && + ata_wait(adp->controller, adp->unit, ATA_S_DRDY) >= 0) + adp->transfersize *= secsperint; + + bpack(adp->ata_parm->model, model_buf, sizeof(model_buf)); + bpack(adp->ata_parm->revision, revision_buf, sizeof(revision_buf)); + printf("ad%d: <%s/%s> ATA-%c disk at ata%d as %s\n", + adnlun, + model_buf, revision_buf, + ad_version(adp->ata_parm->versmajor), + sc->unit, + (adp->unit == ATA_MASTER) ? "master" : "slave "); + printf("ad%d: %luMB (%u sectors), " + "%u cyls, %u heads, %u S/T, %u B/S\n", + adnlun, + adp->total_secs / ((1024L * 1024L) / DEV_BSIZE), + adp->total_secs, + adp->cylinders, + adp->heads, + adp->sectors, + DEV_BSIZE); + printf("ad%d: %d secs/int, %d depth queue \n", + adnlun, adp->transfersize / DEV_BSIZE, + adp->ata_parm->queuelen & 0x1f); + devstat_add_entry(&adp->stats, "ad", adnlun, DEV_BSIZE, + DEVSTAT_NO_ORDERED_TAGS, + DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE, + 0x180); +#ifdef DEVFS + adp->cdevs_token = devfs_add_devswf(&ad_cdevsw, + dkmakeminor(adp->lun, 0, 0), + DV_CHR, + UID_ROOT, GID_OPERATOR, + 0640, "rad%d", adp->lun); + adp->bdevs_token = devfs_add_devswf(&ad_cdevsw, + dkmakeminor(adp->lun, 0, 0), + DV_BLK, + UID_ROOT, GID_OPERATOR, + 0640, "ad%d", adp->lun); +#endif + bufq_init(&adp->queue); + adtab[adnlun++] = adp; + } + } +} + static __inline int apiomode(struct ata_params *ap) { @@ -132,112 +226,11 @@ static void ad_attach(void *notused) { - struct ad_softc *adp; - int32_t ctlr, dev, secsperint; - int8_t model_buf[40+1]; - int8_t revision_buf[8+1]; + int32_t ctlr; /* now, run through atadevices and look for ATA disks */ - for (ctlr=0; ctlrdevices & - (dev ? ATA_ATA_SLAVE : ATA_ATA_MASTER)) { -#ifdef ATA_STATIC_ID - adnlun = dev + ctlr * 2; -#endif - adp = adtab[adnlun]; - if (adp) - printf("ad%d: unit already attached\n", adnlun); - if (!(adp = malloc(sizeof(struct ad_softc), - M_DEVBUF, M_NOWAIT))) { - printf("ad%d: failed to allocate driver storage\n", adnlun); - continue; - } - bzero(adp, sizeof(struct ad_softc)); - adp->controller = atadevices[ctlr]; - adp->unit = (dev == 0) ? ATA_MASTER : ATA_SLAVE; - adp->lun = adnlun; - if (ad_getparam(adp)) { - free(adp, M_DEVBUF); - continue; - } - adp->cylinders = adp->ata_parm->cylinders; - adp->heads = adp->ata_parm->heads; - adp->sectors = adp->ata_parm->sectors; - adp->total_secs = adp->cylinders * adp->heads * adp->sectors; - if (adp->cylinders == 16383 && - adp->total_secs < adp->ata_parm->lbasize) { - adp->total_secs = adp->ata_parm->lbasize; - adp->cylinders = adp->total_secs/(adp->heads*adp->sectors); - } - if (adp->ata_parm->atavalid & ATA_FLAG_54_58 && - adp->ata_parm->lbasize) - adp->flags |= AD_F_USE_LBA; - - /* use multiple sectors/interrupt if device supports it */ - adp->transfersize = DEV_BSIZE; - secsperint = min(adp->ata_parm->nsecperint, 16); - - if (!ata_command(adp->controller, adp->unit, ATA_C_SET_MULTI, - 0, 0, 0, secsperint, 0, ATA_WAIT_INTR) && - ata_wait(adp->controller, adp->unit, ATA_S_DRDY) >= 0) - adp->transfersize *= secsperint; - - /* use DMA if drive & controller supports it */ - if (!ata_dmainit(adp->controller, adp->unit, - apiomode(adp->ata_parm), - wdmamode(adp->ata_parm), - udmamode(adp->ata_parm))) - adp->flags |= AD_F_DMA_ENABLED; - - bpack(adp->ata_parm->model, model_buf, sizeof(model_buf)); - bpack(adp->ata_parm->revision, revision_buf, - sizeof(revision_buf)); - printf("ad%d: <%s/%s> ATA-%c disk at ata%d as %s\n", - adnlun, - model_buf, revision_buf, - ad_version(adp->ata_parm->versmajor), - ctlr, - (adp->unit == ATA_MASTER) ? "master" : "slave "); - printf("ad%d: %luMB (%u sectors), " - "%u cyls, %u heads, %u S/T, %u B/S\n", - adnlun, - adp->total_secs / ((1024L * 1024L) / DEV_BSIZE), - adp->total_secs, - adp->cylinders, - adp->heads, - adp->sectors, - DEV_BSIZE); - printf("ad%d: piomode=%d, dmamode=%d, udmamode=%d\n", - adnlun, - apiomode(adp->ata_parm), - wdmamode(adp->ata_parm), - udmamode(adp->ata_parm)); - printf("ad%d: %d secs/int, %d depth queue, %s mode\n", - adnlun, adp->transfersize / DEV_BSIZE, - adp->ata_parm->queuelen & 0x1f, - (adp->flags & AD_F_DMA_ENABLED) ? "DMA" :"PIO"); - devstat_add_entry(&adp->stats, "ad", adnlun, DEV_BSIZE, - DEVSTAT_NO_ORDERED_TAGS, - DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE, - 0x180); -#ifdef DEVFS - adp->cdevs_token = devfs_add_devswf(&ad_cdevsw, - dkmakeminor(adp->lun, 0, 0), - DV_CHR, - UID_ROOT, GID_OPERATOR, - 0640, "rad%d", adp->lun); - adp->bdevs_token = devfs_add_devswf(&ad_cdevsw, - dkmakeminor(adp->lun, 0, 0), - DV_BLK, - UID_ROOT, GID_OPERATOR, - 0640, "ad%d", adp->lun); -#endif - bufq_init(&adp->queue); - adtab[adnlun++] = adp; - } - } + for (ctlr=0; ctlrdevices & - (dev ? ATA_ATAPI_SLAVE : ATA_ATAPI_MASTER)) { - if (!(atp = malloc(sizeof(struct atapi_softc), - M_DEVBUF, M_NOWAIT))) { - printf("atapi: failed to allocate driver storage\n"); - continue; - } - bzero(atp, sizeof(struct atapi_softc)); - atp->controller = atadevices[ctlr]; - atp->unit = (dev == 0) ? ATA_MASTER : ATA_SLAVE; - if (atapi_getparam(atp)) { - free(atp, M_DEVBUF); - continue; - } + for (dev=0; dev<2; dev++) { + if (sc->devices & + (dev ? ATA_ATAPI_SLAVE : ATA_ATAPI_MASTER)) { + if (!(atp = malloc(sizeof(struct atapi_softc), + M_DEVBUF, M_NOWAIT))) { + printf("atapi: failed to allocate driver storage\n"); + continue; + } + bzero(atp, sizeof(struct atapi_softc)); + atp->controller = sc; + atp->unit = (dev == 0) ? ATA_MASTER : ATA_SLAVE; + if (atapi_getparam(atp)) { + free(atp, M_DEVBUF); + continue; + } - switch (atp->atapi_parm->device_type) { + switch (atp->atapi_parm->device_type) { #if NATAPICD > 0 - case ATAPI_TYPE_CDROM: - if (acdattach(atp)) - goto notfound; - break; + case ATAPI_TYPE_CDROM: + if (acdattach(atp)) + goto notfound; + break; #endif #if NATAPIFD > 0 - case ATAPI_TYPE_DIRECT: - if (afdattach(atp)) - goto notfound; - break; + case ATAPI_TYPE_DIRECT: + if (afdattach(atp)) + goto notfound; + break; #endif #if NATAPIST > 0 - case ATAPI_TYPE_TAPE: - if (astattach(atp)) - goto notfound; - break; + case ATAPI_TYPE_TAPE: + if (astattach(atp)) + goto notfound; + break; #endif notfound: - default: - bpack(atp->atapi_parm->model, model_buf, sizeof(model_buf)); - bpack(atp->atapi_parm->revision, revision_buf, - sizeof(revision_buf)); - printf("atapi: <%s/%s> %s device at ata%d as %s " - "- NO DRIVER!\n", - model_buf, revision_buf, - atapi_type(atp->atapi_parm->device_type), - ctlr, - (dev) ? "slave" : "master "); - free(atp, M_DEVBUF); - } - } - } + default: + bpack(atp->atapi_parm->model, model_buf, sizeof(model_buf)); + bpack(atp->atapi_parm->revision, revision_buf, + sizeof(revision_buf)); + printf("atapi: <%s/%s> %s device at ata%d as %s " + "- NO DRIVER!\n", + model_buf, revision_buf, + atapi_type(atp->atapi_parm->device_type), + sc->unit, + (dev) ? "slave" : "master "); + free(atp, M_DEVBUF); + } + } + } +} + +static void +atapi_attach(void *notused) +{ + int32_t ctlr; + + /* now, run through atadevices and look for ATAPI devices */ + for (ctlr=0; ctlr