summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2000-01-18 21:02:59 +0000
committersos <sos@FreeBSD.org>2000-01-18 21:02:59 +0000
commit841c5b6aa808db8ac648f9af237cc856d50058c6 (patch)
treebbd15141d47f1d11ebb77e77689734b311ee93b4 /sys/dev/ata
parent9fe69108f21206d84ce6ad53222e6403b12bd80b (diff)
downloadFreeBSD-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.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-all.c155
-rw-r--r--sys/dev/ata/ata-all.h130
-rw-r--r--sys/dev/ata/ata-disk.c321
-rw-r--r--sys/dev/ata/ata-disk.h102
-rw-r--r--sys/dev/ata/atapi-all.c230
-rw-r--r--sys/dev/ata/atapi-all.h100
-rw-r--r--sys/dev/ata/atapi-cd.c31
-rw-r--r--sys/dev/ata/atapi-cd.h11
-rw-r--r--sys/dev/ata/atapi-fd.c15
-rw-r--r--sys/dev/ata/atapi-tape.c17
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
OpenPOWER on IntegriCloud