diff options
author | sos <sos@FreeBSD.org> | 2000-01-18 21:02:59 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2000-01-18 21:02:59 +0000 |
commit | 841c5b6aa808db8ac648f9af237cc856d50058c6 (patch) | |
tree | bbd15141d47f1d11ebb77e77689734b311ee93b4 | |
parent | 9fe69108f21206d84ce6ad53222e6403b12bd80b (diff) | |
download | FreeBSD-src-841c5b6aa808db8ac648f9af237cc856d50058c6.zip FreeBSD-src-841c5b6aa808db8ac648f9af237cc856d50058c6.tar.gz |
Rearrange the probecode, so that 80pin cables can be identified
correctly on both master and slave.
Smash together the ata_params & atapi_params structures as they
are more or less equal anyways.
Get rid of the last SYSINIT's in here.
-rw-r--r-- | sys/dev/ata/ata-all.c | 155 | ||||
-rw-r--r-- | sys/dev/ata/ata-all.h | 130 | ||||
-rw-r--r-- | sys/dev/ata/ata-disk.c | 321 | ||||
-rw-r--r-- | sys/dev/ata/ata-disk.h | 102 | ||||
-rw-r--r-- | sys/dev/ata/atapi-all.c | 230 | ||||
-rw-r--r-- | sys/dev/ata/atapi-all.h | 100 | ||||
-rw-r--r-- | sys/dev/ata/atapi-cd.c | 31 | ||||
-rw-r--r-- | sys/dev/ata/atapi-cd.h | 11 | ||||
-rw-r--r-- | sys/dev/ata/atapi-fd.c | 15 | ||||
-rw-r--r-- | sys/dev/ata/atapi-tape.c | 17 |
10 files changed, 473 insertions, 639 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 327ee04..1ce5daf 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -78,13 +78,19 @@ /* prototypes */ static int32_t ata_probe(int32_t, int32_t, int32_t, device_t, int32_t *); +static void ata_attach(void *); +static int32_t ata_getparam(struct ata_softc *, int32_t, u_int8_t); static void ataintr(void *); static int8_t *active2str(int32_t); +static void bswap(int8_t *, int32_t); +static void btrim(int8_t *, int32_t); +static void bpack(int8_t *, int8_t *, int32_t); /* local vars */ static int32_t atanlun = 2; -struct ata_softc *atadevices[MAXATA]; +static struct intr_config_hook *ata_attach_hook = NULL; static devclass_t ata_devclass; +struct ata_softc *atadevices[MAXATA]; MALLOC_DEFINE(M_ATA, "ATA generic", "ATA driver generic layer"); #if NISA > 0 @@ -592,6 +598,23 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr, *unit = scp->lun; scp->dev = dev; atadevices[scp->lun] = scp; + + /* register callback for when interrupts are enabled */ + if (!ata_attach_hook) { + if (!(ata_attach_hook = (struct intr_config_hook *) + malloc(sizeof(struct intr_config_hook), + M_TEMP, M_NOWAIT))) { + printf("ata: ERROR malloc attach_hook failed\n"); + return 0; + } + bzero(ata_attach_hook, sizeof(struct intr_config_hook)); + + ata_attach_hook->ich_func = ata_attach; + if (config_intrhook_establish(ata_attach_hook) != 0) { + printf("ata: config_intrhook_establish failed\n"); + free(ata_attach_hook, M_TEMP); + } + } #if NAPM > 0 scp->resume_hook.ah_fun = (void *)ata_reinit; scp->resume_hook.ah_arg = scp; @@ -602,6 +625,96 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr, return ATA_IOSIZE; } +void +ata_attach(void *dummy) +{ + int32_t ctlr; + + /* + * run through atadevices[] and look for real ATA & ATAPI devices + * using the hints we found in the early probe to avoid probing + * of non-exsistent devices and thereby long delays + */ + for (ctlr=0; ctlr<MAXATA; ctlr++) { + if (!atadevices[ctlr]) continue; + + if (atadevices[ctlr]->devices & ATA_ATA_SLAVE) + if (ata_getparam(atadevices[ctlr], ATA_SLAVE, ATA_C_ATA_IDENTIFY)) + atadevices[ctlr]->devices &= ~ATA_ATA_SLAVE; + if (atadevices[ctlr]->devices & ATA_ATAPI_SLAVE) + if (ata_getparam(atadevices[ctlr], ATA_SLAVE, ATA_C_ATAPI_IDENTIFY)) + atadevices[ctlr]->devices &= ~ATA_ATAPI_SLAVE; + if (atadevices[ctlr]->devices & ATA_ATA_MASTER) + if (ata_getparam(atadevices[ctlr], ATA_MASTER, ATA_C_ATA_IDENTIFY)) + atadevices[ctlr]->devices &= ~ATA_ATA_MASTER; + if (atadevices[ctlr]->devices & ATA_ATAPI_MASTER) + if (ata_getparam(atadevices[ctlr], ATA_MASTER,ATA_C_ATAPI_IDENTIFY)) + atadevices[ctlr]->devices &= ~ATA_ATAPI_MASTER; + } + + /* now we know whats there, do the real attach, first the ATA disks */ + for (ctlr=0; ctlr<MAXATA; ctlr++) { + if (!atadevices[ctlr]) continue; + if (atadevices[ctlr]->devices & ATA_ATA_MASTER) + ad_attach(atadevices[ctlr], ATA_MASTER); + if (atadevices[ctlr]->devices & ATA_ATA_SLAVE) + ad_attach(atadevices[ctlr], ATA_SLAVE); + } + /* then the atapi devices */ + for (ctlr=0; ctlr<MAXATA; ctlr++) { + if (!atadevices[ctlr]) continue; + if (atadevices[ctlr]->devices & ATA_ATAPI_MASTER) + atapi_attach(atadevices[ctlr], ATA_MASTER); + if (atadevices[ctlr]->devices & ATA_ATAPI_SLAVE) + atapi_attach(atadevices[ctlr], ATA_SLAVE); + } + if (ata_attach_hook) { + config_intrhook_disestablish(ata_attach_hook); + free(ata_attach_hook, M_ATA); + ata_attach_hook = NULL; + } +} + +static int32_t +ata_getparam(struct ata_softc *scp, int32_t device, u_int8_t command) +{ + struct ata_params *ata_parm; + int8_t buffer[DEV_BSIZE]; + + /* select drive */ + outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device); + DELAY(1); + if (ata_command(scp, device, command, 0, 0, 0, 0, 0, ATA_WAIT_INTR)) { + printf("ata%d-%s: identify failed\n", + scp->lun, (device == ATA_MASTER) ? "master" : "slave "); + return -1; + } + if (ata_wait(scp, device, ATA_S_READY|ATA_S_DSC|ATA_S_DRQ)) { + printf("ata%d-%s: drive wont come ready after identify\n", + scp->lun, (device == ATA_MASTER) ? "master" : "slave "); + return -1; + } + insw(scp->ioaddr + ATA_DATA, buffer, sizeof(buffer)/sizeof(int16_t)); + ata_parm = malloc(sizeof(struct ata_params), M_ATA, M_NOWAIT); + if (!ata_parm) { + printf("ata%d-%s: malloc for ata_param failed\n", + scp->lun, (device == ATA_MASTER) ? "master" : "slave "); + return -1; + } + bcopy(buffer, ata_parm, sizeof(struct ata_params)); + if (command == ATA_C_ATA_IDENTIFY || + !((ata_parm->model[0] == 'N' && ata_parm->model[1] == 'E') || + (ata_parm->model[0] == 'F' && ata_parm->model[1] == 'X'))) + bswap(ata_parm->model, sizeof(ata_parm->model)); + btrim(ata_parm->model, sizeof(ata_parm->model)); + bpack(ata_parm->model, ata_parm->model, sizeof(ata_parm->model)); + bswap(ata_parm->revision, sizeof(ata_parm->revision)); + btrim(ata_parm->revision, sizeof(ata_parm->revision)); + bpack(ata_parm->revision, ata_parm->revision, sizeof(ata_parm->revision)); + scp->dev_param[(device == ATA_MASTER) ? 0 : 1] = ata_parm; + return 0; +} + static void ataintr(void *data) { @@ -992,7 +1105,41 @@ active2str(int32_t active) } } -void +int32_t +ata_pmode(struct ata_params *ap) +{ + if (ap->atavalid & ATA_FLAG_64_70) { + if (ap->apiomodes & 2) return 4; + if (ap->apiomodes & 1) return 3; + } + return -1; +} + +int32_t +ata_wmode(struct ata_params *ap) +{ + if (ap->atavalid & ATA_FLAG_64_70) { + if (ap->wdmamodes & 4) return 2; + if (ap->wdmamodes & 2) return 1; + if (ap->wdmamodes & 1) return 0; + } + return -1; +} + +int32_t +ata_umode(struct ata_params *ap) +{ + if (ap->atavalid & ATA_FLAG_88) { + if (ap->udmamodes & 0x10) return (ap->cblid ? 4 : 2); + if (ap->udmamodes & 0x08) return (ap->cblid ? 3 : 2); + if (ap->udmamodes & 0x04) return 2; + if (ap->udmamodes & 0x02) return 1; + if (ap->udmamodes & 0x01) return 0; + } + return -1; +} + +static void bswap(int8_t *buf, int32_t len) { u_int16_t *p = (u_int16_t*)(buf + len); @@ -1001,7 +1148,7 @@ bswap(int8_t *buf, int32_t len) *p = ntohs(*p); } -void +static void btrim(int8_t *buf, int32_t len) { int8_t *p; @@ -1013,7 +1160,7 @@ btrim(int8_t *buf, int32_t len) *p = 0; } -void +static void bpack(int8_t *src, int8_t *dst, int32_t len) { int32_t i, j, blank; diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index b9f739b..3a0e870 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -97,6 +97,9 @@ #define ATA_IOSIZE 0x08 #define ATA_OP_FINISHED 0x00 #define ATA_OP_CONTINUES 0x01 +#define ATA_DEV(unit) ((unit == ATA_MASTER) ? 0 : 1) +#define ATA_PARAM(scp, unit) scp->dev_param[ATA_DEV(unit)] + /* busmaster DMA related defines */ #define ATA_BM_OFFSET1 0x08 @@ -124,6 +127,126 @@ struct ata_dmaentry { u_int32_t count; }; +/* ATA/ATAPI device parameter information */ +struct ata_params { + u_int8_t cmdsize :2; /* packet command size */ +#define ATAPI_PSIZE_12 0 /* 12 bytes */ +#define ATAPI_PSIZE_16 1 /* 16 bytes */ + + u_int8_t :3; + u_int8_t drqtype :2; /* DRQ type */ +#define ATAPI_DRQT_MPROC 0 /* cpu 3 ms delay */ +#define ATAPI_DRQT_INTR 1 /* intr 10 ms delay */ +#define ATAPI_DRQT_ACCEL 2 /* accel 50 us delay */ + + u_int8_t removable :1; /* device is removable */ + u_int8_t device_type :5; /* device type */ +#define ATAPI_TYPE_DIRECT 0 /* disk/floppy */ +#define ATAPI_TYPE_TAPE 1 /* streaming tape */ +#define ATAPI_TYPE_CDROM 5 /* CD-ROM device */ +#define ATAPI_TYPE_OPTICAL 7 /* optical disk */ + + u_int8_t :1; + u_int8_t proto :2; /* command protocol */ +#define ATAPI_PROTO_ATAPI 2 + + u_int16_t cylinders; /* number of cylinders */ + int16_t reserved2; + u_int16_t heads; /* # heads */ + int16_t unfbytespertrk; /* # unformatted bytes/track */ + int16_t unfbytes; /* # unformatted bytes/sector */ + u_int16_t sectors; /* # sectors/track */ + int16_t vendorunique0[3]; + int8_t serial[20]; /* serial number */ + int16_t buffertype; /* buffer type */ +#define ATA_BT_SINGLEPORTSECTOR 1 /* 1 port, 1 sector buffer */ +#define ATA_BT_DUALPORTMULTI 2 /* 2 port, mult sector buffer */ +#define ATA_BT_DUALPORTMULTICACHE 3 /* above plus track cache */ + + int16_t buffersize; /* buf size, 512-byte units */ + int16_t necc; /* ecc bytes appended */ + int8_t revision[8]; /* firmware revision */ + int8_t model[40]; /* model name */ + int8_t nsecperint; /* sectors per interrupt */ + int8_t vendorunique1; + int16_t usedmovsd; /* double word read/write? */ + + u_int8_t vendorcap; /* vendor capabilities */ + u_int8_t dmaflag :1; /* DMA supported - always 1 */ + u_int8_t lbaflag :1; /* LBA supported - always 1 */ + u_int8_t iordydis :1; /* IORDY may be disabled */ + u_int8_t iordyflag :1; /* IORDY supported */ + u_int8_t :1; + u_int8_t stdby_ovlap :1; /* standby/overlap supported */ + u_int8_t :1; + u_int8_t idmaflag :1; /* interleaved DMA supported */ + int16_t capvalidate; /* validation for above */ + + int8_t vendorunique3; + int8_t opiomode; /* PIO modes 0-2 */ + int8_t vendorunique4; + int8_t odmamode; /* old DMA modes, not ATA-3 */ + + int16_t atavalid; /* fields valid */ +#define ATA_FLAG_54_58 1 /* words 54-58 valid */ +#define ATA_FLAG_64_70 2 /* words 64-70 valid */ +#define ATA_FLAG_88 4 /* word 88 valid */ + + int16_t currcyls; + int16_t currheads; + int16_t currsectors; + int16_t currsize0; + int16_t currsize1; + int8_t currmultsect; + int8_t multsectvalid; + int32_t lbasize; + + int16_t sdmamodes; /* singleword DMA modes */ + int16_t wdmamodes; /* multiword DMA modes */ + int16_t apiomodes; /* advanced PIO modes */ + + u_int16_t mwdmamin; /* min. M/W DMA time/word ns */ + u_int16_t mwdmarec; /* rec. M/W DMA time ns */ + u_int16_t pioblind; /* min. PIO cycle w/o flow */ + u_int16_t pioiordy; /* min. PIO cycle IORDY flow */ + + int16_t reserved69; + int16_t reserved70; + u_int16_t rlsovlap; /* rel time (us) for overlap */ + u_int16_t rlsservice; /* rel time (us) for service */ + int16_t reserved73; + int16_t reserved74; + int16_t queuelen; + int16_t reserved76; + int16_t reserved77; + int16_t reserved78; + int16_t reserved79; + int16_t versmajor; + int16_t versminor; + int16_t featsupp1; + int16_t featsupp2; + int16_t featsupp3; + int16_t featenab1; + int16_t featenab2; + int16_t featenab3; + int16_t udmamodes; /* UltraDMA modes */ + int16_t erasetime; + int16_t enherasetime; + int16_t apmlevel; + int16_t masterpasswdrev; + u_int16_t masterhwres :8; + u_int16_t slavehwres :5; + u_int16_t cblid :1; + u_int16_t reserved93_1415 :2; + int16_t reserved94[32]; + int16_t rmvstat; + int16_t securstat; + int16_t reserved129[30]; + int16_t cfapwrmode; + int16_t reserved161[84]; + int16_t integrity; +}; + /* structure describing an ATA device */ struct ata_softc { int32_t unit; /* unit on this controller */ @@ -133,6 +256,7 @@ struct ata_softc { int32_t altioaddr; /* alternate port addr */ int32_t bmaddr; /* bus master DMA port */ int32_t chiptype; /* pciid of controller chip */ + struct ata_params *dev_param[2]; /* ptr to devices params */ void *dev_softc[2]; /* ptr to devices softc's */ struct ata_dmaentry *dmatab[2]; /* DMA transfer tables */ int32_t mode[2]; /* transfer mode for devices */ @@ -191,9 +315,9 @@ int32_t ata_dmasetup(struct ata_softc *, int32_t, int8_t *, int32_t, int32_t); void ata_dmastart(struct ata_softc *); int32_t ata_dmastatus(struct ata_softc *); int32_t ata_dmadone(struct ata_softc *); +int32_t ata_pmode(struct ata_params *); +int32_t ata_wmode(struct ata_params *); +int32_t ata_umode(struct ata_params *); int8_t *ata_mode2str(int32_t); int8_t ata_pio2mode(int32_t); -void bswap(int8_t *, int32_t); -void btrim(int8_t *, int32_t); -void bpack(int8_t *, int8_t *, int32_t); int32_t ata_find_dev(device_t, int32_t); diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index c288987..b52fcaf 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -72,210 +72,130 @@ static struct cdevsw ad_cdevsw = { /* dump */ addump, /* psize */ nopsize, /* flags */ D_DISK, - /* bmaj */ 30, + /* bmaj */ 30 }; static struct cdevsw addisk_cdevsw; -static struct cdevsw fakewd_cdevsw; +static struct cdevsw fakewd_cdevsw = { + /* open */ adopen, + /* close */ nullclose, + /* read */ physread, + /* write */ physwrite, + /* ioctl */ noioctl, + /* poll */ nopoll, + /* mmap */ nommap, + /* strategy */ adstrategy, + /* name */ "wd", + /* maj */ 3, + /* dump */ addump, + /* psize */ nopsize, + /* flags */ D_DISK, + /* bmaj */ 0 +}; static struct cdevsw fakewddisk_cdevsw; /* prototypes */ -static void ad_attach(void *); -static int32_t ad_getparam(struct ad_softc *); static void ad_start(struct ad_softc *); static void ad_timeout(struct ad_request *); static int32_t ad_version(u_int16_t); -static void ad_drvinit(void); /* internal vars */ -static struct intr_config_hook *ad_attach_hook; MALLOC_DEFINE(M_AD, "AD driver", "ATA disk driver"); /* defines */ #define AD_MAX_RETRIES 3 +#define AD_PARAM ATA_PARAM(adp->controller, adp->unit) -static __inline int -apiomode(struct ata_params *ap) -{ - if (ap->atavalid & ATA_FLAG_64_70) { - if (ap->apiomodes & 2) return 4; - if (ap->apiomodes & 1) return 3; - } - return -1; -} - -static __inline int -wdmamode(struct ata_params *ap) -{ - if (ap->atavalid & ATA_FLAG_64_70) { - if (ap->wdmamodes & 4) return 2; - if (ap->wdmamodes & 2) return 1; - if (ap->wdmamodes & 1) return 0; - } - return -1; -} - -static __inline int -udmamode(struct ata_params *ap) -{ - if (ap->atavalid & ATA_FLAG_88) { - if (ap->udmamodes & 0x10) return (ap->cblid ? 4 : 2); - if (ap->udmamodes & 0x08) return (ap->cblid ? 3 : 2); - if (ap->udmamodes & 0x04) return 2; - if (ap->udmamodes & 0x02) return 1; - if (ap->udmamodes & 0x01) return 0; - } - return -1; -} - -static void -ad_attach(void *notused) +void +ad_attach(struct ata_softc *scp, int32_t device) { struct ad_softc *adp; - int32_t ctlr, dev, secsperint; - int8_t model_buf[40+1]; - int8_t revision_buf[8+1]; - dev_t dev1; static int32_t adnlun = 0; + dev_t dev1; + int32_t secsperint; - /* now, run through atadevices and look for ATA disks */ - for (ctlr=0; ctlr<MAXATA; ctlr++) { - if (!atadevices[ctlr]) continue; - for (dev=0; dev<2; dev++) { - if (atadevices[ctlr]->devices & - (dev ? ATA_ATA_SLAVE : ATA_ATA_MASTER)) { #ifdef ATA_STATIC_ID - adnlun = dev + ctlr * 2; + adnlun = (scp->lun << 1) + ATA_DEV(device); #endif - if (!(adp = malloc(sizeof(struct ad_softc), - M_AD, 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_AD); - continue; - } - adp->controller->dev_softc[(adp->unit==ATA_MASTER)?0:1] = adp; - adp->heads = adp->ata_parm->heads; - adp->sectors = adp->ata_parm->sectors; - adp->total_secs = - adp->ata_parm->cylinders * adp->heads * adp->sectors; - if (adp->ata_parm->cylinders == 16383 && - adp->total_secs < adp->ata_parm->lbasize) { - adp->total_secs = adp->ata_parm->lbasize; - } - if (adp->ata_parm->atavalid & ATA_FLAG_54_58 && - adp->ata_parm->lbasize) - adp->flags |= AD_F_LBA_ENABLED; - - /* use multiple sectors/interrupt if device supports it */ - adp->transfersize = DEV_BSIZE; - secsperint = max(1, 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_READY) >= 0) - adp->transfersize *= secsperint; - - /* enable read/write cacheing if not default on device */ - if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, - 0, 0, 0, 0, ATA_C_F_ENAB_RCACHE, ATA_WAIT_INTR)) - printf("ad%d: enabling readahead cache failed\n", adp->lun); - - if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, - 0, 0, 0, 0, ATA_C_F_ENAB_WCACHE, ATA_WAIT_INTR)) - printf("ad%d: enabling write cache failed\n", adp->lun); - - /* 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; - - /* use tagged queueing if supported (not yet) */ - if ((adp->num_tags = (adp->ata_parm->queuelen & 0x1f) + 1)) - adp->flags |= AD_F_TAG_ENABLED; - - bpack(adp->ata_parm->model, model_buf, sizeof(model_buf)); - bpack(adp->ata_parm->revision, revision_buf, - sizeof(revision_buf)); - - if (bootverbose) - printf("ad%d: piomode=%d dmamode=%d udmamode=%d cblid=%d\n", - adp->lun, apiomode(adp->ata_parm), - wdmamode(adp->ata_parm), udmamode(adp->ata_parm), - adp->ata_parm->cblid); - - printf("ad%d: <%s/%s> ATA-%d disk at ata%d as %s\n", - adp->lun, 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", - adp->lun, adp->total_secs / ((1024L * 1024L)/DEV_BSIZE), - adp->total_secs, - adp->total_secs / (adp->heads * adp->sectors), - adp->heads, adp->sectors, DEV_BSIZE); - - printf("ad%d: %d secs/int, %d depth queue, %s\n", - adp->lun, adp->transfersize / DEV_BSIZE, adp->num_tags, - ata_mode2str(adp->controller->mode[ - (adp->unit == ATA_MASTER) ? 0 : 1])); - - devstat_add_entry(&adp->stats, "ad", adp->lun, DEV_BSIZE, - DEVSTAT_NO_ORDERED_TAGS, - DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE, - DEVSTAT_PRIORITY_DISK); - - dev1 = disk_create(adp->lun, &adp->disk, 0, &ad_cdevsw, - &addisk_cdevsw); - dev1->si_drv1 = adp; - dev1->si_iosize_max = 256 * DEV_BSIZE; - - dev1 = disk_create(adp->lun, &adp->disk, 0, &fakewd_cdevsw, - &fakewddisk_cdevsw); - dev1->si_drv1 = adp; - dev1->si_iosize_max = 256 * DEV_BSIZE; - - bufq_init(&adp->queue); - } - } + if (!(adp = malloc(sizeof(struct ad_softc), M_AD, M_NOWAIT))) { + printf("ad%d: failed to allocate driver storage\n", adnlun); + return; } - config_intrhook_disestablish(ad_attach_hook); -} - -static int32_t -ad_getparam(struct ad_softc *adp) -{ - struct ata_params *ata_parm; - int8_t buffer[DEV_BSIZE]; - - /* select drive */ - outb(adp->controller->ioaddr + ATA_DRIVE, ATA_D_IBM | adp->unit); - DELAY(1); - if (ata_command(adp->controller, adp->unit, ATA_C_ATA_IDENTIFY, - 0, 0, 0, 0, 0, ATA_WAIT_INTR)) - return -1; - if (ata_wait(adp->controller, adp->unit, - ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) - return -1; - insw(adp->controller->ioaddr + ATA_DATA, buffer, - sizeof(buffer)/sizeof(int16_t)); - ata_parm = malloc(sizeof(struct ata_params), M_AD, M_NOWAIT); - if (!ata_parm) - return -1; - bcopy(buffer, ata_parm, sizeof(struct ata_params)); - bswap(ata_parm->model, sizeof(ata_parm->model)); - btrim(ata_parm->model, sizeof(ata_parm->model)); - bswap(ata_parm->revision, sizeof(ata_parm->revision)); - btrim(ata_parm->revision, sizeof(ata_parm->revision)); - adp->ata_parm = ata_parm; - return 0; + bzero(adp, sizeof(struct ad_softc)); + scp->dev_softc[ATA_DEV(device)] = adp; + adp->controller = scp; + adp->unit = device; + adp->lun = adnlun++; + adp->heads = AD_PARAM->heads; + adp->sectors = AD_PARAM->sectors; + adp->total_secs = AD_PARAM->cylinders * adp->heads * adp->sectors; + if (AD_PARAM->cylinders == 16383 && adp->total_secs < AD_PARAM->lbasize) + adp->total_secs = AD_PARAM->lbasize; + + if (AD_PARAM->atavalid & ATA_FLAG_54_58 && AD_PARAM->lbasize) + adp->flags |= AD_F_LBA_ENABLED; + + /* use multiple sectors/interrupt if device supports it */ + adp->transfersize = DEV_BSIZE; + secsperint = max(1, min(AD_PARAM->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_READY) >= 0) + adp->transfersize *= secsperint; + + /* enable read/write cacheing if not default on device */ + if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, + 0, 0, 0, 0, ATA_C_F_ENAB_RCACHE, ATA_WAIT_INTR)) + printf("ad%d: enabling readahead cache failed\n", adp->lun); + + if (ata_command(adp->controller, adp->unit, ATA_C_SETFEATURES, + 0, 0, 0, 0, ATA_C_F_ENAB_WCACHE, ATA_WAIT_INTR)) + printf("ad%d: enabling write cache failed\n", adp->lun); + + /* use DMA if drive & controller supports it */ + if (!ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), + ata_wmode(AD_PARAM), ata_umode(AD_PARAM))) + adp->flags |= AD_F_DMA_ENABLED; + + /* use tagged queueing if supported (not yet) */ + if ((adp->num_tags = (AD_PARAM->queuelen & 0x1f) + 1)) + adp->flags |= AD_F_TAG_ENABLED; + + + if (bootverbose) + printf("ad%d: piomode=%d dmamode=%d udmamode=%d cblid=%d\n", + adp->lun, ata_pmode(AD_PARAM), ata_wmode(AD_PARAM), + ata_umode(AD_PARAM), AD_PARAM->cblid); + + printf("ad%d: <%s/%s> ATA-%d disk at ata%d as %s\n", + adp->lun, AD_PARAM->model, AD_PARAM->revision, + ad_version(AD_PARAM->versmajor), scp->lun, + (adp->unit == ATA_MASTER) ? "master" : "slave "); + + printf("ad%d: %luMB (%u sectors), %u cyls, %u heads, %u S/T, %u B/S\n", + adp->lun, adp->total_secs / ((1024L * 1024L)/DEV_BSIZE), + adp->total_secs, + adp->total_secs / (adp->heads * adp->sectors), + adp->heads, adp->sectors, DEV_BSIZE); + + printf("ad%d: %d secs/int, %d depth queue, %s\n", + adp->lun, adp->transfersize / DEV_BSIZE, adp->num_tags, + ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)])); + + devstat_add_entry(&adp->stats, "ad", adp->lun, DEV_BSIZE, + DEVSTAT_NO_ORDERED_TAGS, + DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE, + DEVSTAT_PRIORITY_DISK); + + dev1 = disk_create(adp->lun, &adp->disk, 0, &ad_cdevsw, &addisk_cdevsw); + dev1->si_drv1 = adp; + dev1->si_iosize_max = 256 * DEV_BSIZE; + + dev1 = disk_create(adp->lun, &adp->disk, 0, &fakewd_cdevsw, + &fakewddisk_cdevsw); + dev1->si_drv1 = adp; + dev1->si_iosize_max = 256 * DEV_BSIZE; + + bufq_init(&adp->queue); } static int @@ -543,7 +463,7 @@ oops: printf(" retrying\n"); else { ata_dmainit(adp->controller, adp->unit, - apiomode(adp->ata_parm), -1, -1); + ata_pmode(AD_PARAM), -1, -1); adp->flags &= ~AD_F_DMA_ENABLED; printf(" falling back to PIO mode\n"); } @@ -555,7 +475,7 @@ oops: if (request->flags & AR_F_DMA_USED) { untimeout((timeout_t *)ad_timeout, request,request->timeout_handle); ata_dmainit(adp->controller, adp->unit, - apiomode(adp->ata_parm), -1, -1); + ata_pmode(AD_PARAM), -1, -1); request->flags |= AR_F_FORCE_PIO; adp->flags &= ~AD_F_DMA_ENABLED; TAILQ_INSERT_HEAD(&adp->controller->ata_queue, request, chain); @@ -638,8 +558,8 @@ ad_reinit(struct ad_softc *adp) ata_command(adp->controller, adp->unit, ATA_C_SET_MULTI, 0, 0, 0, adp->transfersize / DEV_BSIZE, 0, ATA_IMMEDIATE); ata_wait(adp->controller, adp->unit, ATA_S_READY); - ata_dmainit(adp->controller, adp->unit, apiomode(adp->ata_parm), - wdmamode(adp->ata_parm), udmamode(adp->ata_parm)); + ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), + ata_wmode(AD_PARAM), ata_umode(AD_PARAM)); } static void @@ -653,8 +573,7 @@ ad_timeout(struct ad_request *request) if (request->flags & AR_F_DMA_USED) { ata_dmadone(adp->controller); if (request->retries == AD_MAX_RETRIES) { - ata_dmainit(adp->controller, adp->unit, - apiomode(adp->ata_parm), -1, -1); + ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), -1,-1); adp->flags &= ~AD_F_DMA_ENABLED; printf("ad%d: ad_timeout: trying fallback to PIO mode\n", adp->lun); request->retries = 0; @@ -687,29 +606,3 @@ ad_version(u_int16_t version) return bit; return 0; } - -static void -ad_drvinit(void) -{ - fakewd_cdevsw = ad_cdevsw; - fakewd_cdevsw.d_maj = 3; - fakewd_cdevsw.d_bmaj = 0; - fakewd_cdevsw.d_name = "wd"; - - /* register callback for when interrupts are enabled */ - if (!(ad_attach_hook = - (struct intr_config_hook *)malloc(sizeof(struct intr_config_hook), - M_TEMP, M_NOWAIT))) { - printf("ad: malloc attach_hook failed\n"); - return; - } - bzero(ad_attach_hook, sizeof(struct intr_config_hook)); - - ad_attach_hook->ich_func = ad_attach; - if (config_intrhook_establish(ad_attach_hook) != 0) { - printf("ad: config_intrhook_establish failed\n"); - free(ad_attach_hook, M_TEMP); - } -} - -SYSINIT(addev, SI_SUB_DRIVERS, SI_ORDER_SECOND, ad_drvinit, NULL) diff --git a/sys/dev/ata/ata-disk.h b/sys/dev/ata/ata-disk.h index 709b1fb..63fb4c7 100644 --- a/sys/dev/ata/ata-disk.h +++ b/sys/dev/ata/ata-disk.h @@ -28,110 +28,9 @@ * $FreeBSD$ */ -/* ATA device parameter information */ -struct ata_params { - int16_t config; /* general configuration bits */ - u_int16_t cylinders; /* number of cylinders */ - int16_t reserved2; - u_int16_t heads; /* # heads */ - int16_t unfbytespertrk; /* # unformatted bytes/track */ - int16_t unfbytes; /* # unformatted bytes/sector */ - u_int16_t sectors; /* # sectors/track */ - int16_t vendorunique0[3]; - int8_t serial[20]; /* serial number */ - int16_t buffertype; /* buffer type */ -#define ATA_BT_SINGLEPORTSECTOR 1 /* 1 port, 1 sector buffer */ -#define ATA_BT_DUALPORTMULTI 2 /* 2 port, mult sector buffer */ -#define ATA_BT_DUALPORTMULTICACHE 3 /* above plus track cache */ - - int16_t buffersize; /* buf size, 512-byte units */ - int16_t necc; /* ecc bytes appended */ - int8_t revision[8]; /* firmware revision */ - int8_t model[40]; /* model name */ - int8_t nsecperint; /* sectors per interrupt */ - int8_t vendorunique1; - int16_t usedmovsd; /* double word read/write? */ - - u_int8_t vendorcap; /* vendor capabilities */ - u_int8_t dmaflag :1; /* DMA supported - always 1 */ - u_int8_t lbaflag :1; /* LBA supported - always 1 */ - u_int8_t iordydis :1; /* IORDY may be disabled */ - u_int8_t iordyflag :1; /* IORDY supported */ - u_int8_t :1; - u_int8_t standby :1; /* standby timer supported */ - u_int8_t :1; - u_int8_t :1; - int16_t capvalidate; /* validation for above */ - - int8_t vendorunique3; - int8_t opiomode; /* PIO modes 0-2 */ - int8_t vendorunique4; - int8_t odmamode; /* old DMA modes, not ATA-3 */ - - int16_t atavalid; /* fields valid */ -#define ATA_FLAG_54_58 1 /* words 54-58 valid */ -#define ATA_FLAG_64_70 2 /* words 64-70 valid */ -#define ATA_FLAG_88 4 /* word 88 valid */ - - int16_t currcyls; - int16_t currheads; - int16_t currsectors; - int16_t currsize0; - int16_t currsize1; - int8_t currmultsect; - int8_t multsectvalid; - int32_t lbasize; - - int16_t sdmamodes; /* singleword DMA modes */ - int16_t wdmamodes; /* multiword DMA modes */ - int16_t apiomodes; /* advanced PIO modes */ - - u_int16_t mwdmamin; /* min. M/W DMA time/word ns */ - u_int16_t mwdmarec; /* rec. M/W DMA time ns */ - u_int16_t pioblind; /* min. PIO cycle w/o flow */ - u_int16_t pioiordy; /* min. PIO cycle IORDY flow */ - - int16_t reserved69; - int16_t reserved70; - u_int16_t rlsovlap; /* rel time (us) for overlap */ - u_int16_t rlsservice; /* rel time (us) for service */ - int16_t reserved73; - int16_t reserved74; - int16_t queuelen; - int16_t reserved76; - int16_t reserved77; - int16_t reserved78; - int16_t reserved79; - int16_t versmajor; - int16_t versminor; - int16_t featsupp1; - int16_t featsupp2; - int16_t featsupp3; - int16_t featenab1; - int16_t featenab2; - int16_t featenab3; - int16_t udmamodes; /* UltraDMA modes */ - int16_t erasetime; - int16_t enherasetime; - int16_t apmlevel; - int16_t masterpasswdrev; - u_int16_t masterhwres :8; - u_int16_t slavehwres :5; - u_int16_t cblid :1; - u_int16_t reserved93_1415 :2; - int16_t reserved94[32]; - int16_t rmvstat; - int16_t securstat; - int16_t reserved129[30]; - int16_t cfapwrmode; - int16_t reserved161[84]; - int16_t integrity; -}; - /* structure describing an ATA disk */ struct ad_softc { struct ata_softc *controller; /* ptr to parent ctrl */ - struct ata_params *ata_parm; /* ata device params */ int32_t unit; /* ATA_MASTER or ATA_SLAVE */ int32_t lun; /* logical unit number */ u_int32_t total_secs; /* total # of sectors (LBA) */ @@ -171,6 +70,7 @@ struct ad_request { TAILQ_ENTRY(ad_request) chain; /* list management */ }; +void ad_attach(struct ata_softc *, int32_t); void ad_transfer(struct ad_request *); int32_t ad_interrupt(struct ad_request *); void ad_reinit(struct ad_softc *); diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index 07984bca..d15c61a 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -48,15 +48,12 @@ #include <dev/ata/atapi-all.h> /* prototypes */ -static void atapi_attach(void *); -static int32_t atapi_getparam(struct atapi_softc *); static void atapi_read(struct atapi_request *, int32_t); static void atapi_write(struct atapi_request *, int32_t); static void atapi_timeout(struct atapi_request *request); static int8_t *atapi_type(int32_t); static int8_t *atapi_cmd2str(u_int8_t); static int8_t *atapi_skey2str(u_int8_t); -static void atapi_init(void); /* extern references */ int32_t acdattach(struct atapi_softc *); @@ -64,166 +61,75 @@ int32_t afdattach(struct atapi_softc *); int32_t astattach(struct atapi_softc *); /* internal vars */ -static struct intr_config_hook *atapi_attach_hook; MALLOC_DEFINE(M_ATAPI, "ATAPI generic", "ATAPI driver generic layer"); /* defines */ -#define ATAPI_MAX_RETRIES 5 +#define ATAPI_MAX_RETRIES 5 +#define ATP_PARAM ATA_PARAM(atp->controller, atp->unit) -static __inline int -apiomode(struct atapi_params *ap) -{ - if (ap->atavalid & 2) { - if (ap->apiomodes & 2) return 4; - if (ap->apiomodes & 1) return 3; - } - return -1; -} - -static __inline int -wdmamode(struct atapi_params *ap) +void +atapi_attach(struct ata_softc *scp, int32_t device) { - if (ap->atavalid & 2) { - if (ap->wdmamodes & 4) return 2; - if (ap->wdmamodes & 2) return 1; - if (ap->wdmamodes & 1) return 0; - } - return -1; -} + struct atapi_softc *atp; -static __inline int -udmamode(struct atapi_params *ap) -{ - if (ap->atavalid & 4) { - if (ap->udmamodes & 4) return 2; - if (ap->udmamodes & 2) return 1; - if (ap->udmamodes & 1) return 0; + if (!(atp = malloc(sizeof(struct atapi_softc), M_ATAPI, M_NOWAIT))) { + printf("atapi: failed to allocate driver storage\n"); + return; } - return -1; -} - -static void -atapi_attach(void *notused) -{ - struct atapi_softc *atp; - int32_t ctlr, dev; - int8_t model_buf[40+1]; - int8_t revision_buf[8+1]; - - /* now, run through atadevices and look for ATAPI devices */ - for (ctlr=0; ctlr<MAXATA; ctlr++) { - if (!atadevices[ctlr]) continue; - for (dev=0; dev<2; dev++) { - if (atadevices[ctlr]->devices & - (dev ? ATA_ATAPI_SLAVE : ATA_ATAPI_MASTER)) { - if (!(atp = malloc(sizeof(struct atapi_softc), - M_ATAPI, 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_ATAPI); - continue; - } - if (bootverbose) - printf("ata%d-%s: piomode=%d dmamode=%d " - "udmamode=%d dmaflag=%d\n", - ctlr, (dev == ATA_MASTER) ? "master" : "slave", - apiomode(atp->atapi_parm), - wdmamode(atp->atapi_parm), - udmamode(atp->atapi_parm), - atp->atapi_parm->dmaflag); + bzero(atp, sizeof(struct atapi_softc)); + atp->controller = scp; + atp->unit = device; + if (bootverbose) + printf("ata%d-%s: piomode=%d dmamode=%d udmamode=%d dmaflag=%d\n", + scp->lun, (device == ATA_MASTER) ? "master" : "slave", + ata_pmode(ATP_PARAM), ata_wmode(ATP_PARAM), + ata_umode(ATP_PARAM), ATP_PARAM->dmaflag); #ifdef ATA_ENABLE_ATAPI_DMA - if (!(atp->atapi_parm->drqtype == ATAPI_DRQT_INTR)) { - if (!ata_dmainit(atp->controller, atp->unit, - (apiomode(atp->atapi_parm) < 0) ? - (atp->atapi_parm->dmaflag ? 4 : 0) : - apiomode(atp->atapi_parm), - (wdmamode(atp->atapi_parm) < 0) ? - (atp->atapi_parm->dmaflag ? 2 : 0) : - wdmamode(atp->atapi_parm), - udmamode(atp->atapi_parm))) - atp->flags |= ATAPI_F_DMA_ENABLED; - } - else + if (!(ATP_PARAM->drqtype == ATAPI_DRQT_INTR)) { + if (!ata_dmainit(atp->controller, atp->unit, + (ata_pmode(ATP_PARAM) < 0) ? + (ATP_PARAM->dmaflag ? 4 : 0) : ata_pmode(ATP_PARAM), + (ata_wmode(ATP_PARAM) < 0) ? + (ATP_PARAM->dmaflag ? 2 : 0) : ata_wmode(ATP_PARAM), + ata_umode(ATP_PARAM))) + atp->flags |= ATAPI_F_DMA_ENABLED; + } + else #endif - /* set PIO mode */ - ata_dmainit(atp->controller, atp->unit, - (apiomode(atp->atapi_parm) < 0) ? - 0 : apiomode(atp->atapi_parm), -1, -1); + /* set PIO mode */ + ata_dmainit(atp->controller, atp->unit, + (ata_pmode(ATP_PARAM)<0) ? 0 : ata_pmode(ATP_PARAM), -1,-1); - switch (atp->atapi_parm->device_type) { + switch (ATP_PARAM->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("ata%d-%s: <%s/%s> %s device - NO DRIVER!\n", - ctlr, (dev == ATA_MASTER) ? "master" : "slave", - model_buf, revision_buf, - atapi_type(atp->atapi_parm->device_type)); - free(atp, M_ATAPI); - atp = NULL; - } - /* store our softc */ - atp->controller->dev_softc[(atp->unit==ATA_MASTER)?0:1] = atp; - } - } + default: + printf("ata%d-%s: <%.40s/%.8s> %s device - NO DRIVER!\n", scp->lun, + (device == ATA_MASTER) ? "master" : "slave", ATP_PARAM->model, + ATP_PARAM->revision, atapi_type(ATP_PARAM->device_type)); + free(atp, M_ATAPI); + atp = NULL; } - config_intrhook_disestablish(atapi_attach_hook); -} - -static int32_t -atapi_getparam(struct atapi_softc *atp) -{ - struct atapi_params *atapi_parm; - int8_t buffer[DEV_BSIZE]; - - /* select drive */ - outb(atp->controller->ioaddr + ATA_DRIVE, ATA_D_IBM | atp->unit); - DELAY(1); - if (ata_command(atp->controller, atp->unit, ATA_C_ATAPI_IDENTIFY, - 0, 0, 0, 0, 0, ATA_WAIT_INTR)) - return -1; - if (ata_wait(atp->controller, atp->unit, ATA_S_DRQ)) - return -1; - insw(atp->controller->ioaddr + ATA_DATA, buffer, - sizeof(buffer)/sizeof(int16_t)); - if (ata_wait(atp->controller, atp->unit, 0)) - return -1; - if (!(atapi_parm = malloc(sizeof(struct atapi_params), M_ATAPI, M_NOWAIT))) - return -1; - bcopy(buffer, atapi_parm, sizeof(struct atapi_params)); - if (!((atapi_parm->model[0] == 'N' && atapi_parm->model[1] == 'E') || - (atapi_parm->model[0] == 'F' && atapi_parm->model[1] == 'X'))) - bswap(atapi_parm->model, sizeof(atapi_parm->model)); - btrim(atapi_parm->model, sizeof(atapi_parm->model)); - bswap(atapi_parm->revision, sizeof(atapi_parm->revision)); - btrim(atapi_parm->revision, sizeof(atapi_parm->revision)); - atp->atapi_parm = atapi_parm; - return 0; + /* store our softc */ + atp->controller->dev_softc[(atp->unit==ATA_MASTER)?0:1] = atp; } int32_t @@ -243,7 +149,7 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data, request->bytecount = count; request->flags = flags; request->timeout = timeout * hz; - request->ccbsize = (atp->atapi_parm->cmdsize) ? 16 : 12; + request->ccbsize = (ATP_PARAM->cmdsize) ? 16 : 12; bcopy(ccb, request->ccb, request->ccbsize); if (callback) { request->callback = callback; @@ -324,7 +230,7 @@ atapi_transfer(struct atapi_request *request) ata_dmastart(atp->controller); /* command interrupt device ? just return */ - if (atp->atapi_parm->drqtype == ATAPI_DRQT_INTR) + if (ATP_PARAM->drqtype == ATAPI_DRQT_INTR) return; /* ready to write ATAPI command */ @@ -513,11 +419,11 @@ atapi_reinit(struct atapi_softc *atp) { /* reinit device parameters */ ata_dmainit(atp->controller, atp->unit, - (apiomode(atp->atapi_parm) < 0) ? - (atp->atapi_parm->dmaflag ? 4 : 0) : apiomode(atp->atapi_parm), - (wdmamode(atp->atapi_parm) < 0) ? - (atp->atapi_parm->dmaflag ? 2 : 0) : wdmamode(atp->atapi_parm), - udmamode(atp->atapi_parm)); + (ata_pmode(ATP_PARAM) < 0) ? + (ATP_PARAM->dmaflag ? 4 : 0) : ata_pmode(ATP_PARAM), + (ata_wmode(ATP_PARAM) < 0) ? + (ATP_PARAM->dmaflag ? 2 : 0) : ata_wmode(ATP_PARAM), + ata_umode(ATP_PARAM)); } int32_t @@ -730,25 +636,3 @@ atapi_skey2str(u_int8_t skey) default: return("UNKNOWN"); } } - -static void -atapi_init(void) -{ - /* register callback for when interrupts are enabled */ - if (!(atapi_attach_hook = - (struct intr_config_hook *)malloc(sizeof(struct intr_config_hook), - M_TEMP, M_NOWAIT))) { - printf("atapi: malloc attach_hook failed\n"); - return; - } - bzero(atapi_attach_hook, sizeof(struct intr_config_hook)); - - atapi_attach_hook->ich_func = atapi_attach; - if (config_intrhook_establish(atapi_attach_hook) != 0) { - printf("atapi: config_intrhook_establish failed\n"); - free(atapi_attach_hook, M_TEMP); - } - -} - -SYSINIT(atconf, SI_SUB_CONFIGURE, SI_ORDER_SECOND, atapi_init, NULL) diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h index 289d1bf..36e84b6 100644 --- a/sys/dev/ata/atapi-all.h +++ b/sys/dev/ata/atapi-all.h @@ -109,104 +109,6 @@ #define ATAPI_MECH_STATUS 0xbd /* get changer status */ #define ATAPI_READ_CD 0xbe /* read data */ -/* ATAPI device parameter information */ -struct atapi_params { - u_int8_t cmdsize :2; /* packet command size */ -#define ATAPI_PSIZE_12 0 /* 12 bytes */ -#define ATAPI_PSIZE_16 1 /* 16 bytes */ - - u_int8_t :3; - u_int8_t drqtype :2; /* DRQ type */ -#define ATAPI_DRQT_MPROC 0 /* cpu 3 ms delay */ -#define ATAPI_DRQT_INTR 1 /* intr 10 ms delay */ -#define ATAPI_DRQT_ACCEL 2 /* accel 50 us delay */ - - u_int8_t removable :1; /* device is removable */ - u_int8_t device_type :5; /* device type */ -#define ATAPI_TYPE_DIRECT 0 /* disk/floppy */ -#define ATAPI_TYPE_TAPE 1 /* streaming tape */ -#define ATAPI_TYPE_CDROM 5 /* CD-ROM device */ -#define ATAPI_TYPE_OPTICAL 7 /* optical disk */ - - u_int8_t :1; - u_int8_t proto :2; /* command protocol */ -#define ATAPI_PROTO_ATAPI 2 - - int16_t reserved1; - int16_t reserved2; - int16_t reserved3; - int16_t reserved4; - int16_t reserved5; - int16_t reserved6; - int16_t reserved7; - int16_t reserved8; - int16_t reserved9; - int8_t serial[20]; /* serial number */ - int16_t reserved20; - int16_t reserved21; - int16_t reserved22; - int8_t revision[8]; /* firmware revision */ - int8_t model[40]; /* model name */ - int16_t reserved47; - int16_t reserved48; - - u_int8_t vendorcap; /* vendor capabilities */ - u_int8_t dmaflag :1; /* DMA supported */ - u_int8_t lbaflag :1; /* LBA supported - always 1 */ - u_int8_t iordydis :1; /* IORDY can be disabled */ - u_int8_t iordyflag :1; /* IORDY supported */ - u_int8_t :1; - u_int8_t ovlapflag :1; /* overlap supported */ - u_int8_t :1; - u_int8_t idmaflag :1; /* interleaved DMA supported */ - int16_t capvalidate; /* validation for above */ - - u_int16_t piotiming; /* PIO cycle timing */ - u_int16_t dmatiming; /* DMA cycle timing */ - - u_int16_t atavalid; /* fields valid */ -#define ATAPI_FLAG_54_58 1 /* words 54-58 valid */ -#define ATAPI_FLAG_64_70 2 /* words 64-70 valid */ - - int16_t reserved54[8]; - - int16_t sdmamodes; /* singleword DMA modes */ - int16_t wdmamodes; /* multiword DMA modes */ - int16_t apiomodes; /* advanced PIO modes */ - - u_int16_t mwdmamin; /* min. M/W DMA time/word ns */ - u_int16_t mwdmarec; /* rec. M/W DMA time ns */ - u_int16_t pioblind; /* min. PIO cycle w/o flow */ - u_int16_t pioiordy; /* min. PIO cycle IORDY flow */ - - int16_t reserved69; - int16_t reserved70; - u_int16_t rlsovlap; /* rel time (us) for overlap */ - u_int16_t rlsservice; /* rel time (us) for service */ - int16_t reserved73; - int16_t reserved74; - int16_t queuelen; - int16_t reserved76; - int16_t reserved77; - int16_t reserved78; - int16_t reserved79; - int16_t versmajor; - int16_t versminor; - int16_t featsupp1; - int16_t featsupp2; - int16_t featsupp3; - int16_t featenab1; - int16_t featenab2; - int16_t featenab3; - int16_t udmamodes; /* UltraDMA modes */ - int16_t erasetime; - int16_t enherasetime; - int16_t apmlevel; - int16_t reserved92[34]; - int16_t rmvcap; - int16_t securelevel; -}; - /* ATAPI request sense structure */ struct atapi_reqsense { u_int8_t error_code :7; /* current or deferred errors */ @@ -233,7 +135,6 @@ struct atapi_reqsense { struct atapi_softc { struct ata_softc *controller; /* ptr to parent ctrl */ - struct atapi_params *atapi_parm; /* ata device params */ int32_t unit; /* ATA_MASTER or ATA_SLAVE */ int8_t *devname; /* this devices name */ int8_t cmd; /* last cmd executed */ @@ -268,6 +169,7 @@ struct atapi_request { TAILQ_ENTRY(atapi_request) chain; /* list management */ }; +void atapi_attach(struct ata_softc *, int32_t); void atapi_transfer(struct atapi_request *); int32_t atapi_interrupt(struct atapi_request *); int32_t atapi_queue_cmd(struct atapi_softc *, int8_t [], void *, int32_t, int32_t, int32_t, atapi_callback_t, void *, struct buf *); diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 458f5a9..e799b5f 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -245,13 +245,10 @@ acd_describe(struct acd_softc *cdp) { int32_t comma = 0; int8_t *mechanism; - int8_t model_buf[40+1]; - int8_t revision_buf[8+1]; - bpack(cdp->atp->atapi_parm->model, model_buf, sizeof(model_buf)); - bpack(cdp->atp->atapi_parm->revision, revision_buf, sizeof(revision_buf)); - printf("acd%d: <%s/%s> %s drive at ata%d as %s\n", - cdp->lun, model_buf, revision_buf, + printf("acd%d: <%.40s/%.8s> %s drive at ata%d as %s\n", + cdp->lun, ATA_PARAM(cdp->atp->controller, cdp->atp->unit)->model, + ATA_PARAM(cdp->atp->controller, cdp->atp->unit)->revision, (cdp->cap.write_dvdr) ? "DVD-R" : (cdp->cap.write_dvdram) ? "DVD-RAM" : (cdp->cap.write_cdrw) ? "CD-RW" : @@ -280,7 +277,7 @@ acd_describe(struct acd_softc *cdp) } printf("%s %s\n", comma ? "," : "", ata_mode2str(cdp->atp->controller->mode[ - (cdp->atp->unit == ATA_MASTER) ? 0 : 1])); + ATA_DEV(cdp->atp->unit)])); printf("acd%d: Reads:", cdp->lun); comma = 0; @@ -439,23 +436,20 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) return EBUSY; if (flags & FWRITE) { - if ((cdp->flags & F_BOPEN) || cdp->refcnt) + if (cdp->refcnt) return EBUSY; else cdp->flags |= F_WRITING; } dev->si_bsize_phys = 2048; /* XXX SOS */ - if (!(cdp->flags & F_BOPEN) && !cdp->refcnt) { + if (!cdp->refcnt) { acd_prevent_allow(cdp, 1); cdp->flags |= F_LOCKED; if (!(flags & O_NONBLOCK) && !(flags & FWRITE)) acd_read_toc(cdp); } - if (fmt == S_IFBLK) - cdp->flags |= F_BOPEN; - else - cdp->refcnt++; + cdp->refcnt++; return 0; } @@ -464,13 +458,10 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) { struct acd_softc *cdp = dev->si_drv1; - if (fmt == S_IFBLK) - cdp->flags &= ~F_BOPEN; - else - cdp->refcnt--; + cdp->refcnt--; /* are we the last open ?? */ - if (!(cdp->flags & F_BOPEN) && !cdp->refcnt) + if (!cdp->refcnt) acd_prevent_allow(cdp, 0); cdp->flags &= ~(F_LOCKED | F_WRITING); @@ -533,7 +524,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) break; case CDIOCEJECT: - if ((cdp->flags & F_BOPEN) && cdp->refcnt) { + if (cdp->refcnt > 1) { error = EBUSY; break; } @@ -541,7 +532,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) break; case CDIOCCLOSE: - if ((cdp->flags & F_BOPEN) && cdp->refcnt) + if (cdp->refcnt > 1) break; error = acd_eject(cdp, 1); break; diff --git a/sys/dev/ata/atapi-cd.h b/sys/dev/ata/atapi-cd.h index eb92662..56e2c99 100644 --- a/sys/dev/ata/atapi-cd.h +++ b/sys/dev/ata/atapi-cd.h @@ -311,12 +311,11 @@ struct acd_softc { struct atapi_softc *atp; /* controller structure */ int32_t lun; /* logical device unit */ int32_t flags; /* device state flags */ -#define F_BOPEN 0x0001 /* the block device is opened */ -#define F_LOCKED 0x0002 /* this unit is locked */ -#define F_WRITING 0x0004 /* this unit is writing */ -#define F_WRITTEN 0x0008 /* medium has been written to */ -#define F_DISK_OPEN 0x0010 /* disk open for writing */ -#define F_TRACK_OPEN 0x0020 /* track open for writing */ +#define F_LOCKED 0x0001 /* this unit is locked */ +#define F_WRITING 0x0002 /* this unit is writing */ +#define F_WRITTEN 0x0004 /* medium has been written to */ +#define F_DISK_OPEN 0x0008 /* disk open for writing */ +#define F_TRACK_OPEN 0x0010 /* track open for writing */ int32_t refcnt; /* the number of raw opens */ struct buf_queue_head buf_queue; /* Queue of i/o requests */ diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c index f8e3291..c2b2d52 100644 --- a/sys/dev/ata/atapi-fd.c +++ b/sys/dev/ata/atapi-fd.c @@ -107,7 +107,8 @@ afdattach(struct atapi_softc *atp) return -1; } - if (!strncmp(atp->atapi_parm->model, "IOMEGA ZIP", 11)) + if (!strncmp(ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model, + "IOMEGA ZIP", 11)) fdp->transfersize = 64; afd_describe(fdp); @@ -155,13 +156,9 @@ afd_sense(struct afd_softc *fdp) static void afd_describe(struct afd_softc *fdp) { - int8_t model_buf[40+1]; - int8_t revision_buf[8+1]; - - bpack(fdp->atp->atapi_parm->model, model_buf, sizeof(model_buf)); - bpack(fdp->atp->atapi_parm->revision, revision_buf, sizeof(revision_buf)); - printf("afd%d: <%s/%s> rewriteable drive at ata%d as %s\n", - fdp->lun, model_buf, revision_buf, + printf("afd%d: <%.40s/%.8s> rewriteable drive at ata%d as %s\n", + fdp->lun, ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model, + ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->revision, fdp->atp->controller->lun, (fdp->atp->unit == ATA_MASTER) ? "master" : "slave "); printf("afd%d: %luMB (%u sectors), %u cyls, %u heads, %u S/T, %u B/S\n", @@ -175,7 +172,7 @@ afd_describe(struct afd_softc *fdp) if (fdp->transfersize) printf(" transfer limit %d blks,", fdp->transfersize); printf(" %s\n", ata_mode2str(fdp->atp->controller->mode[ - (fdp->atp->unit == ATA_MASTER) ? 0 : 1])); + ATA_DEV(fdp->atp->unit)])); printf("afd%d: Medium: ", fdp->lun); switch (fdp->header.medium_type) { case MFD_2DD: diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index 6b60f9c..f8c5b9f 100644 --- a/sys/dev/ata/atapi-tape.c +++ b/sys/dev/ata/atapi-tape.c @@ -116,7 +116,8 @@ astattach(struct atapi_softc *atp) return -1; } ast_describe(stp); - if (!strcmp(stp->atp->atapi_parm->model, " OnStream DI-30")) { + if (!strcmp(ATA_PARAM(stp->atp->controller, stp->atp->unit)->model, + "OnStream DI-30")) { struct ast_transferpage transfer; struct ast_identifypage identify; @@ -179,13 +180,9 @@ ast_sense(struct ast_softc *stp) static void ast_describe(struct ast_softc *stp) { - int8_t model_buf[40+1]; - int8_t revision_buf[8+1]; - - bpack(stp->atp->atapi_parm->model, model_buf, sizeof(model_buf)); - bpack(stp->atp->atapi_parm->revision, revision_buf, sizeof(revision_buf)); - printf("ast%d: <%s/%s> tape drive at ata%d as %s\n", - stp->lun, model_buf, revision_buf, + printf("ast%d: <%.40s/%.8s> tape drive at ata%d as %s\n", + stp->lun, ATA_PARAM(stp->atp->controller, stp->atp->unit)->model, + ATA_PARAM(stp->atp->controller, stp->atp->unit)->revision, stp->atp->controller->lun, (stp->atp->unit == ATA_MASTER) ? "master" : "slave "); printf("ast%d: ", stp->lun); @@ -193,7 +190,7 @@ ast_describe(struct ast_softc *stp) printf("transfer limit %d blk%s, ", stp->cap.ctl, (stp->cap.ctl>1)?"s":""); printf("%dKB buffer, ", (stp->cap.buffer_size * DEV_BSIZE) / 1024); printf("%s\n", ata_mode2str(stp->atp->controller->mode[ - (stp->atp->unit == ATA_MASTER) ? 0 : 1])); + ATA_DEV(stp->atp->unit)])); printf("ast%d: ", stp->lun); switch (stp->cap.medium_type) { case 0x00: printf("Drive empty"); break; @@ -536,7 +533,7 @@ ast_write_filemark(struct ast_softc *stp, u_int8_t function) error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, 10, NULL, NULL, NULL); if (error) return error; - return atapi_wait_ready(stp->atp, 5*60); + return atapi_wait_ready(stp->atp, 10*60); } static int32_t |