summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>1999-03-03 21:10:29 +0000
committersos <sos@FreeBSD.org>1999-03-03 21:10:29 +0000
commitfb974f8ed94734f43dfc82e27445b482593a491d (patch)
treed5601f3a4d38e27cf2213659e87de8c365373d5a /sys/dev
parentee38b913245110a5902f02f489c58c5b31c1cb92 (diff)
downloadFreeBSD-src-fb974f8ed94734f43dfc82e27445b482593a491d.zip
FreeBSD-src-fb974f8ed94734f43dfc82e27445b482593a491d.tar.gz
Added driver to support ATAPI floppies ie LS-120 & ZIP drives.
Added "options ATA_STATIC_ID" that wires ATA disks like the old wd driver. Fixed problems: Dont use more sectors/intr than the drive supports. Fix announce of > 8.4G disks. Dont call ad_interrupt/ad_transfer when no disks config'd. Use the right page# for CDR write mode params. Fix breakage when no PCI support in kernel. Implement DEVFS stuff. General code clenaup.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ata/ata-all.c99
-rw-r--r--sys/dev/ata/ata-all.h11
-rw-r--r--sys/dev/ata/ata-disk.c68
-rw-r--r--sys/dev/ata/ata-disk.h14
-rw-r--r--sys/dev/ata/atapi-all.c10
-rw-r--r--sys/dev/ata/atapi-all.h16
-rw-r--r--sys/dev/ata/atapi-cd.c366
-rw-r--r--sys/dev/ata/atapi-cd.h266
-rw-r--r--sys/dev/ata/atapi-fd.c434
-rw-r--r--sys/dev/ata/atapi-fd.h90
-rw-r--r--sys/dev/ata/atapi-tape.c250
-rw-r--r--sys/dev/ata/atapi-tape.h147
12 files changed, 1159 insertions, 612 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 50a82b2..d493ab6 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -25,12 +25,14 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: ata-all.c,v 1.4 1999/03/01 21:03:15 sos Exp sos $
+ * $Id: ata-all.c,v 1.1 1999/03/01 21:19:18 sos Exp $
*/
#include "ata.h"
#if NATA > 0
+#include "isa.h"
#include "pci.h"
+#include "atadisk.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -53,24 +55,28 @@
#define UNIT(dev) (dev>>3 & 0x1f) /* assume 8 minor # per unit */
/* prototypes */
-void ataintr(int32_t);
+#if NISA > 0
static int32_t ata_isaprobe(struct isa_device *);
static int32_t ata_isaattach(struct isa_device *);
+#endif
+#if NPCI > 0
static const char *ata_pciprobe(pcici_t, pcidi_t);
static void ata_pciattach(pcici_t, int32_t);
+static void promise_intr(int32_t);
+#endif
static int32_t ata_probe(int32_t, int32_t, int32_t *);
static int32_t ata_attach(int32_t);
-static void promise_intr(int32_t);
-static int32_t ata_reset(struct ata_softc *);
+static void ataintr(int32_t);
static int32_t ata_device_attach(struct ata_softc *, int32_t);
static int32_t atapi_device_attach(struct ata_softc *, int32_t);
static void bswap(int8_t *, int32_t);
static void btrim(int8_t *, int32_t);
-static int32_t atanlun, sysctrl = 0;
+static int32_t atanlun = 0, sysctrl = 0;
struct ata_softc *atadevices[MAXATA];
struct isa_driver atadriver = { ata_isaprobe, ata_isaattach, "ata" };
+#if NISA > 0
static int32_t
ata_isaprobe(struct isa_device *devp)
{
@@ -85,7 +91,7 @@ ata_isaprobe(struct isa_device *devp)
}
res=ata_probe(devp->id_iobase, devp->id_iobase+ATA_ALTPORT, &devp->id_unit);
if (res)
- devp->id_intr = ataintr;
+ devp->id_intr = (inthand2_t *)ataintr;
return res;
}
@@ -94,7 +100,9 @@ ata_isaattach(struct isa_device *devp)
{
return ata_attach(devp->id_unit);
}
+#endif
+#if NPCI > 0
static u_long ata_pcicount;
static struct pci_device ata_pcidevice = {
"ata-pci", ata_pciprobe, ata_pciattach, &ata_pcicount, 0
@@ -127,7 +135,7 @@ ata_pciprobe(pcici_t tag, pcidi_t type)
case 0x522910b9:
return "Acer Aladdin IV/V IDE controller";
default:
- return ("Unknown PCI IDE controller");
+ return "Unknown PCI IDE controller";
}
}
return NULL;
@@ -208,9 +216,10 @@ ata_pciattach(pcici_t tag, int32_t unit)
register_intr(irq1, 0, 0, (inthand2_t *)ataintr, &bio_imask, lun);
else {
if (sysctrl)
- pci_map_int(tag, promise_intr, (void *)lun, &bio_imask);
+ pci_map_int(tag, (inthand2_t *)promise_intr,
+ (void *)lun, &bio_imask);
else
- pci_map_int(tag, ataintr, (void *)lun, &bio_imask);
+ pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask);
}
printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
lun, iobase_1, irq1, unit);
@@ -221,7 +230,7 @@ ata_pciattach(pcici_t tag, int32_t unit)
register_intr(irq2, 0, 0, (inthand2_t *)ataintr, &bio_imask, lun);
else {
if (!sysctrl)
- pci_map_int(tag, ataintr, (void *) lun, &bio_imask);
+ pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask);
}
printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
lun, iobase_2, irq2, unit);
@@ -237,37 +246,42 @@ promise_intr(int32_t unit)
if (inl(sysctrl) & 0x00004000)
ataintr(unit+1);
}
+#endif
static int32_t
ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit)
{
struct ata_softc *scp = atadevices[atanlun];
- u_int8_t status0, status1;
int32_t mask = 0;
int32_t timeout;
+ int32_t lun = atanlun;
+ u_int8_t status0, status1;
- if (atanlun > MAXATA) {
- printf("ata: unit of of range(%d)\n", atanlun);
- return(0);
+#ifdef ATA_STATIC_ID
+ atanlun++;
+#endif
+ if (lun > MAXATA) {
+ printf("ata: unit of of range(%d)\n", lun);
+ return 0;
}
if (scp) {
- printf("ata%d: unit already attached\n", atanlun);
- return(0);
+ printf("ata%d: unit already attached\n", lun);
+ return 0;
}
scp = malloc(sizeof(struct ata_softc), M_DEVBUF, M_NOWAIT);
if (scp == NULL) {
- printf("ata%d: failed to allocate driver storage\n", atanlun);
- return(0);
+ printf("ata%d: failed to allocate driver storage\n", lun);
+ return 0;
}
bzero(scp, sizeof(struct ata_softc));
- scp->unit = atanlun;
+ scp->unit = lun;
scp->ioaddr = ioaddr;
scp->altioaddr = altioaddr;
#ifdef ATA_DEBUG
printf("ata%d: iobase=0x%04x altiobase=0x%04x\n",
- atanlun, scp->ioaddr, scp->altioaddr);
+ scp->unit, scp->ioaddr, scp->altioaddr);
#endif
/* do we have any signs of ATA/ATAPI HW being present ? */
@@ -283,7 +297,7 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit)
mask |= 0x02;
#ifdef ATA_DEBUG
printf("ata%d: mask=%02x status0=%02x status1=%02x\n",
- atanlun, mask, status0, status1);
+ scp->unit, mask, status0, status1);
#endif
if (!mask) {
free(scp, M_DEVBUF);
@@ -325,7 +339,7 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit)
mask &= ~0x02;
#ifdef ATA_DEBUG
printf("ata%d: mask=%02x status0=%02x status1=%02x\n",
- atanlun, mask, status0, status1);
+ scp->unit, mask, status0, status1);
#endif
if (!mask) {
free(scp, M_DEVBUF);
@@ -370,7 +384,7 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit)
}
}
#ifdef ATA_DEBUG
- printf("ata%d: devices = 0x%x\n", atanlun, scp->devices);
+ printf("ata%d: devices = 0x%x\n", scp->unit, scp->devices);
#endif
if (!(scp->devices & (ATA_ATA_MASTER|ATA_ATAPI_MASTER)))
scp->flags |= ATA_F_SLAVE_ONLY;
@@ -380,8 +394,11 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit)
}
bufq_init(&scp->ata_queue);
TAILQ_INIT(&scp->atapi_queue);
- *unit = atanlun;
- atadevices[atanlun++] = scp;
+ *unit = scp->unit;
+ atadevices[scp->unit] = scp;
+#ifndef ATA_STATIC_ID
+ atanlun++;
+#endif
return ATA_IOSIZE;
}
@@ -410,7 +427,7 @@ ata_attach(int32_t unit)
return scp->devices;
}
-void
+static void
ataintr(int32_t unit)
{
struct ata_softc *scp;
@@ -431,16 +448,12 @@ ataintr(int32_t unit)
/* find & call the responsible driver to process this interrupt */
switch (scp->active) {
- case ATA_IDLE:
- if (intcount++ < 5)
- printf("ata%d: unwanted interrupt\n", unit);
- break;
-
+#if NATADISK > 0
case ATA_ACTIVE_ATA:
if ((ata_request = bufq_first(&scp->ata_queue)))
ad_interrupt(ata_request);
break;
-
+#endif
case ATA_ACTIVE_ATAPI:
if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue)))
atapi_interrupt(atapi_request);
@@ -449,6 +462,12 @@ ataintr(int32_t unit)
case ATA_IGNORE_INTR:
scp->active = ATA_IDLE;
break;
+
+ default:
+ case ATA_IDLE:
+ if (intcount++ < 5)
+ printf("ata%d: unwanted interrupt\n", unit);
+ break;
}
}
@@ -509,22 +528,6 @@ ata_wait(struct ata_softc *scp, u_int8_t mask)
}
static int32_t
-ata_reset(struct ata_softc *scp)
-{
- outb(scp->altioaddr, ATA_A_RESET | ATA_A_IDS);
- DELAY(10000);
- outb(scp->altioaddr, ATA_A_IDS);
- DELAY(10000);
- inb(scp->ioaddr + ATA_ERROR);
- outb(scp->altioaddr, ATA_A_4BIT);
- if (ata_wait(scp, 0) < 0) {
- printf("ata%d: RESET failed\n", scp->unit);
- return 1;
- }
- return 0;
-}
-
-static int32_t
ata_device_attach(struct ata_softc *scp, int32_t device)
{
struct ata_params *ata_parm;
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index df6791d..a63b4b32 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -25,11 +25,10 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: ata-all.h,v 1.3 1999/03/01 21:03:15 sos Exp sos $
+ * $Id: ata-all.h,v 1.1 1999/03/01 21:19:18 sos Exp $
*/
/* ATA register defines */
-
#define ATA_DATA 0x00 /* data register */
#define ATA_ERROR 0x01 /* (R) error register */
#define ATA_PRECOMP 0x01 /* (W) precompensation */
@@ -153,9 +152,7 @@ struct ata_params {
int16_t securelevel;
};
-/*
- * Structure describing an ATA device
- */
+/* Structure describing an ATA device */
struct ata_softc {
u_int32_t unit; /* this instance's number */
u_int32_t ioaddr; /* port addr */
@@ -178,10 +175,6 @@ struct ata_softc {
struct ata_params *ata_parm[2]; /* ata device params */
TAILQ_HEAD(, atapi_request) atapi_queue; /* head of ATAPI queue */
struct atapi_params *atapi_parm[2]; /* atapi device params */
-
-#ifdef DEVFS
- static void *devfs_token;
-#endif
};
struct ata_request {
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index bfbf877..cf1551e 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: ata-disk.c,v 1.14 1999/03/01 21:03:15 sos Exp sos $
+ * $Id: ata-disk.c,v 1.1 1999/03/01 21:19:18 sos Exp $
*/
#include "ata.h"
@@ -58,8 +58,8 @@
static d_open_t adopen;
static d_close_t adclose;
-static d_write_t adwrite;
static d_read_t adread;
+static d_write_t adwrite;
static d_ioctl_t adioctl;
static d_strategy_t adstrategy;
static d_psize_t adpsize;
@@ -95,7 +95,7 @@ static void
ad_attach(void *notused)
{
struct ad_softc *adp;
- int32_t ctlr, dev;
+ int32_t ctlr, dev, secsperint;
int8_t model_buf[40+1];
int8_t revision_buf[8+1];
@@ -103,6 +103,9 @@ ad_attach(void *notused)
for (ctlr=0; ctlr<MAXATA && atadevices[ctlr]; ctlr++) {
for (dev=0; dev<2; dev++) {
if (atadevices[ctlr]->ata_parm[dev]) {
+#ifdef ATA_STATIC_ID
+ adnlun = dev + ctlr * 2;
+#endif
adp = adtab[adnlun];
if (adp)
printf("ad%d: unit already attached\n", adnlun);
@@ -113,20 +116,23 @@ ad_attach(void *notused)
adp->controller = atadevices[ctlr];
adp->ata_parm = atadevices[ctlr]->ata_parm[dev];
adp->unit = (dev == 0) ? ATA_MASTER : ATA_SLAVE;
+ adp->lun = adnlun;
adp->cylinders = adp->ata_parm->cylinders;
adp->heads = adp->ata_parm->heads;
adp->sectors = adp->ata_parm->sectors;
adp->total_secs = adp->ata_parm->lbasize;
+ if (!adp->total_secs)
+ adp->total_secs = adp->cylinders*adp->heads*adp->sectors;
+ if (adp->cylinders == 16383)
+ adp->cylinders = adp->total_secs/(adp->heads*adp->sectors);
/* support multiple sectors / interrupt ? */
- if (ad_command(adp, ATA_C_SET_MULTI, 0, 0, 0, 16))
- adp->transfersize = DEV_BSIZE;
- else {
- if (ata_wait(adp->controller, ATA_S_DRDY) < 0)
- adp->transfersize = DEV_BSIZE;
- else
- adp->transfersize = 16*DEV_BSIZE;
- }
+ adp->transfersize = DEV_BSIZE;
+ secsperint = min(adp->ata_parm->nsecperint, 16);
+ if (!ad_command(adp, ATA_C_SET_MULTI, 0, 0, 0, secsperint) &&
+ ata_wait(adp->controller, ATA_S_DRDY) >= 0)
+ adp->transfersize *= secsperint;
+
bpack(adp->ata_parm->model, model_buf, sizeof(model_buf));
bpack(adp->ata_parm->revision, revision_buf,
sizeof(revision_buf));
@@ -152,6 +158,18 @@ ad_attach(void *notused)
DEVSTAT_NO_ORDERED_TAGS,
DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE,
0x180);
+#ifdef DEVFS
+ adp->cdevs_token = devfs_add_devswf(&ad_cdevsw,
+ dkmakeminor(adp->lun, 0, 0),
+ DV_CHR,
+ UID_ROOT, GID_OPERATOR,
+ 0640, "rad%d", adp->lun);
+ adp->bdevs_token = devfs_add_devswf(&ad_cdevsw,
+ dkmakeminor(adp->lun, 0, 0),
+ DV_BLK,
+ UID_ROOT, GID_OPERATOR,
+ 0640, "ad%d", adp->lun);
+#endif
bufq_init(&adp->queue);
adtab[adnlun++] = adp;
}
@@ -245,17 +263,6 @@ adioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
return ENOTTY;
}
-static int32_t
-adpsize(dev_t dev)
-{
- struct ad_softc *adp;
- int32_t lun = UNIT(dev);
-
- if (lun >= adnlun || !(adp = adtab[lun]))
- return -1;
- return (dssize(dev, &adp->slices, adopen, adclose));
-}
-
static void
adstrategy(struct buf *bp)
{
@@ -301,6 +308,17 @@ done:
splx(s);
}
+static int32_t
+adpsize(dev_t dev)
+{
+ struct ad_softc *adp;
+ int32_t lun = UNIT(dev);
+
+ if (lun >= adnlun || !(adp = adtab[lun]))
+ return -1;
+ return dssize(dev, &adp->slices, adopen, adclose);
+}
+
static void
ad_strategy(struct buf *bp)
{
@@ -434,14 +452,14 @@ ad_interrupt(struct buf *bp)
if (adp->controller->status & (ATA_S_ERROR | ATA_S_CORR)) {
oops:
printf("ad%d: status=%02x error=%02x\n",
- adp->unit, adp->controller->status, adp->controller->error);
+ adp->lun, adp->controller->status, adp->controller->error);
if (adp->controller->status & ATA_S_ERROR) {
- printf("ad_interrupt: hard error");
+ printf("ad_interrupt: hard error\n");
bp->b_error = EIO;
bp->b_flags |= B_ERROR;
}
if (adp->controller->status & ATA_S_CORR)
- printf("ad_interrupt: soft ECC");
+ printf("ad_interrupt: soft ECC\n");
}
/* if this was a read operation, get the data */
if (((bp->b_flags & (B_READ | B_ERROR)) == B_READ) && adp->active) {
diff --git a/sys/dev/ata/ata-disk.h b/sys/dev/ata/ata-disk.h
index 618b8e2..3da1752 100644
--- a/sys/dev/ata/ata-disk.h
+++ b/sys/dev/ata/ata-disk.h
@@ -25,17 +25,16 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: ata-disk.h,v 1.5 1999/03/01 12:11:01 sos Exp $
+ * $Id: ata-disk.h,v 1.1 1999/03/01 21:19:18 sos Exp $
*/
-/*
- * Structure describing an ATA disk
- */
+/* Structure describing an ATA disk */
struct ad_softc {
struct ata_softc *controller; /* ptr to parent ctrl */
struct ata_params *ata_parm; /* ata device params */
struct diskslices *slices;
int32_t unit; /* ATA_MASTER or ATA_SLAVE */
+ int32_t lun; /* logical unit number */
u_int16_t cylinders; /* disk geometry (probed) */
u_int8_t heads;
u_int8_t sectors;
@@ -47,9 +46,12 @@ struct ad_softc {
u_int32_t donecount; /* bytes transferred */
u_int32_t active; /* active processing request */
u_int32_t flags; /* drive flags */
-#define AD_F_LABELLING 0x0001
-
struct devstat stats; /* devstat entry */
+#define AD_F_LABELLING 0x0001
+#ifdef DEVFS
+ void *cdevs_token;
+ void *bdevs_token;
+#endif
};
void ad_transfer(struct buf *);
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index a5c9fdd..b1a333a 100644
--- a/sys/dev/ata/atapi-all.c
+++ b/sys/dev/ata/atapi-all.c
@@ -25,13 +25,13 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: atapi-all.c,v 1.5 1999/03/01 21:03:15 sos Exp sos $
+ * $Id: atapi-all.c,v 1.1 1999/03/01 21:19:18 sos Exp $
*/
#include "ata.h"
#include "atapicd.h"
#include "atapist.h"
-/*#include "atapifd.h"*/
+#include "atapifd.h"
#include "opt_devfs.h"
#if NATA > 0
@@ -326,7 +326,7 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
TAILQ_REMOVE(&atp->controller->atapi_queue, request, chain);
#ifdef ATAPI_DEBUG
-printf("atapi_interrupt: error=%02x\n", request->result);
+printf("atapi_interrupt: error=0x%02x\n", request->result);
#endif
if (request->callback) {
(request->callback)(request);
@@ -341,7 +341,7 @@ printf("atapi_interrupt: error=%02x\n", request->result);
void
atapi_error(struct atapi_softc *atp, int32_t error)
{
- printf("atapi: error = %02x\n", error);
+ printf("atapi: error = 0x%02x\n", error);
}
void
@@ -350,7 +350,7 @@ atapi_dump(int8_t *label, void *data, int32_t len)
u_int8_t *p = data;
printf ("atapi: %s %x", label, *p++);
- while (--len > 0) printf ("-%x", *p++);
+ while (--len > 0) printf ("-%02x", *p++);
printf ("\n");
}
diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h
index ba0e42e..9a12f64 100644
--- a/sys/dev/ata/atapi-all.h
+++ b/sys/dev/ata/atapi-all.h
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: atapi-all.h,v 1.2 1999/03/01 12:11:01 sos Exp $
+ * $Id: atapi-all.h,v 1.1 1999/03/01 21:19:18 sos Exp $
*/
/* ATAPI misc defines */
@@ -88,25 +88,25 @@
/* ATAPI device parameter information */
struct atapi_params {
- u_int cmdsize :2; /* packet command size */
+ u_int8_t cmdsize :2; /* packet command size */
#define ATAPI_PSIZE_12 0 /* 12 bytes */
#define ATAPI_PSIZE_16 1 /* 16 bytes */
- u_int :3;
- u_int drqtype :2; /* DRQ type */
+ 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_int removable :1; /* device is removable */
- u_int device_type :5; /* device type */
+ 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_int :1;
- u_int proto :2; /* command protocol */
+ u_int8_t :1;
+ u_int8_t proto :2; /* command protocol */
#define ATAPI_PROTO_ATAPI 2
int16_t reserved1[9];
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index 6c16dd8..c9fb72d 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: atapi-cd.c,v 1.5 1999/03/01 21:03:15 sos Exp sos $
+ * $Id: atapi-cd.c,v 1.1 1999/03/01 21:19:18 sos Exp $
*/
#include "ata.h"
@@ -56,8 +56,8 @@
static d_open_t acdopen;
static d_close_t acdclose;
-static d_write_t acdwrite;
static d_read_t acdread;
+static d_write_t acdwrite;
static d_ioctl_t acdioctl;
static d_strategy_t acdstrategy;
@@ -106,6 +106,9 @@ static int32_t acd_close_track(struct acd_softc *);
static int32_t acd_close_disk(struct acd_softc *);
static int32_t acd_read_track_info(struct acd_softc *, int, struct acd_track_info*);
static int32_t acd_blank_disk(struct acd_softc *);
+static void lba2msf(int32_t, u_int8_t *, u_int8_t *, u_int8_t *);
+static int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t);
+static void acd_drvinit(void *);
int
acdattach(struct atapi_softc *atp)
@@ -201,7 +204,7 @@ acdattach(struct atapi_softc *atp)
return 0;
}
-struct acd_softc *
+static struct acd_softc *
acd_init_lun(struct atapi_softc *atp, int32_t lun, struct devstat *stats)
{
struct acd_softc *acd;
@@ -227,27 +230,25 @@ acd_init_lun(struct atapi_softc *atp, int32_t lun, struct devstat *stats)
else
acd->stats = stats;
#ifdef DEVFS
- acd->ra_devfs_token =
- devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, 0),
- DV_CHR, UID_ROOT, GID_OPERATOR, 0640,
- "racd%da", lun);
- acd->rc_devfs_token =
- devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, RAW_PART),
- DV_CHR, UID_ROOT, GID_OPERATOR, 0640,
- "racd%dc", lun);
- acd->a_devfs_token =
- devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, 0),
- DV_BLK, UID_ROOT, GID_OPERATOR, 0640,
- "acd%da", lun);
- acd->c_devfs_token =
- devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, RAW_PART),
- DV_BLK, UID_ROOT, GID_OPERATOR, 0640,
- "acd%dc", lun);
+ acd->a_cdevfs_token = devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, 0),
+ DV_CHR, UID_ROOT, GID_OPERATOR, 0644,
+ "racd%da", lun);
+ acd->c_cdevfs_token = devfs_add_devswf(&acd_cdevsw,
+ dkmakeminor(lun, 0, RAW_PART),
+ DV_CHR, UID_ROOT, GID_OPERATOR, 0644,
+ "racd%dc", lun);
+ acd->a_bdevfs_token = devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, 0),
+ DV_BLK, UID_ROOT, GID_OPERATOR, 0644,
+ "acd%da", lun);
+ acd->c_bdevfs_token = devfs_add_devswf(&acd_cdevsw,
+ dkmakeminor(lun, 0, RAW_PART),
+ DV_BLK, UID_ROOT, GID_OPERATOR, 0644,
+ "acd%dc", lun);
#endif
return acd;
}
-void
+static void
acd_describe(struct acd_softc *cdp)
{
int32_t comma;
@@ -377,7 +378,24 @@ acd_describe(struct acd_softc *cdp)
printf("\n");
}
-static int
+static __inline void
+lba2msf(int32_t lba, u_int8_t *m, u_int8_t *s, u_int8_t *f)
+{
+ lba += 150;
+ lba &= 0xffffff;
+ *m = lba / (60 * 75);
+ lba %= (60 * 75);
+ *s = lba / 75;
+ *f = lba % 75;
+}
+
+static __inline int32_t
+msf2lba(u_int8_t m, u_int8_t s, u_int8_t f)
+{
+ return (m * 60 + s) * 75 + f - 150;
+}
+
+static int32_t
acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
{
int32_t lun = dkunit(dev);
@@ -393,7 +411,7 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
if (fmt == S_IFBLK)
cdp->flags |= F_BOPEN;
else
- ++cdp->refcnt;
+ cdp->refcnt++;
if ((flags & O_NONBLOCK) == 0) {
if ((flags & FWRITE) != 0) {
@@ -413,7 +431,7 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
return 0;
}
-int32_t
+static int32_t
acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
{
int32_t lun = dkunit(dev);
@@ -425,7 +443,7 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
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) {
@@ -442,155 +460,19 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
return 0;
}
-static int
+static int32_t
acdread(dev_t dev, struct uio *uio, int32_t ioflag)
{
return physio(acdstrategy, NULL, dev, 1, minphys, uio);
}
-static int
+static int32_t
acdwrite(dev_t dev, struct uio *uio, int32_t ioflag)
{
return physio(acdstrategy, NULL, dev, 0, minphys, uio);
}
-void
-acdstrategy(struct buf *bp)
-{
- int32_t lun = dkunit(bp->b_dev);
- struct acd_softc *cdp = acdtab[lun];
- int32_t x;
-
-#ifdef NOTYET
- /* allow write only on CD-R/RW media */ /* all for now SOS */
- if (!(bp->b_flags & B_READ) && !(writeable_media)) {
- bp->b_error = EROFS;
- bp->b_flags |= B_ERROR;
- biodone(bp);
- return;
- }
-#endif
-
- if (bp->b_bcount == 0) {
- bp->b_resid = 0;
- biodone(bp);
- return;
- }
-
- /* check for valid blocksize SOS */
-
- bp->b_pblkno = bp->b_blkno;
- bp->b_resid = bp->b_bcount;
-
- x = splbio();
- bufqdisksort(&cdp->buf_queue, bp);
- acd_start(cdp);
- splx(x);
-}
-
-static void
-acd_start(struct acd_softc *cdp)
-{
- struct buf *bp = bufq_first(&cdp->buf_queue);
- u_long lba, count;
- int8_t ccb[16];
-
- if (!bp)
- return;
- bzero(ccb, sizeof(ccb));
- bufq_remove(&cdp->buf_queue, bp);
-
- /* Should reject all queued entries if media have changed. */
- if (cdp->flags & F_MEDIA_CHANGED) {
- bp->b_error = EIO;
- bp->b_flags |= B_ERROR;
- biodone(bp);
- return;
- }
- acd_select_slot(cdp);
- if ((bp->b_flags & B_READ) == B_WRITE) {
- if ((cdp->flags & F_TRACK_PREPED) == 0) {
- if ((cdp->flags & F_TRACK_PREP) == 0) {
- printf("acd%d: sequence error\n", cdp->lun);
- bp->b_error = EIO;
- bp->b_flags |= B_ERROR;
- biodone(bp);
- return;
- } else {
- if (acd_open_track(cdp, &cdp->preptrack) != 0) {
- biodone(bp);
- return;
- }
- cdp->flags |= F_TRACK_PREPED;
- }
- }
- }
- if (bp->b_flags & B_READ) {
- lba = bp->b_blkno / (cdp->block_size / DEV_BSIZE);
- ccb[0] = ATAPI_READ_BIG;
- }
- else {
- lba = cdp->next_writeable_lba + (bp->b_offset / cdp->block_size);
- ccb[0] = ATAPI_WRITE_BIG;
- }
- count = (bp->b_bcount + (cdp->block_size - 1)) / cdp->block_size;
-
- ccb[1] = 0;
- ccb[2] = lba>>24;
- ccb[3] = lba>>16;
- ccb[4] = lba>>8;
- ccb[5] = lba;
- ccb[7] = count>>8;
- ccb[8] = count;
-
- devstat_start_transaction(cdp->stats);
-
- atapi_queue_cmd(cdp->atp, ccb, bp->b_data, bp->b_bcount,
- (bp->b_flags&B_READ)?A_READ : 0, acd_done, cdp, (void *)bp);
-}
-
-static void
-acd_done(struct atapi_request *request)
-{
- struct buf *bp = request->bp;
- struct acd_softc *cdp = request->driver;
-
- devstat_end_transaction(cdp->stats, bp->b_bcount-request->bytecount,
- DEVSTAT_TAG_NONE,
- (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE);
- if (request->result) {
- printf("acd_done: ");
- atapi_error(request->device, request->result);
- bp->b_error = EIO;
- bp->b_flags |= B_ERROR;
- }
- else {
- bp->b_resid = request->bytecount;
- if ((bp->b_flags & B_READ) == B_WRITE)
- cdp->flags |= F_WRITTEN;
- }
- biodone(bp);
- acd_start(cdp);
-}
-
-static __inline void
-lba2msf(int32_t lba, u_int8_t *m, u_int8_t *s, u_int8_t *f)
-{
- lba += 150;
- lba &= 0xffffff;
- *m = lba / (60 * 75);
- lba %= (60 * 75);
- *s = lba / 75;
- *f = lba % 75;
-}
-
-static __inline int32_t
-msf2lba(u_int8_t m, u_int8_t s, u_int8_t f)
-{
- return (m * 60 + s) * 75 + f - 150;
-}
-
-int32_t
+static int32_t
acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
{
int32_t lun = dkunit(dev);
@@ -634,7 +516,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
case CDIOCRESET:
error = suser(p->p_ucred, &p->p_acflag);
if (error)
- return (error);
+ return error;
return acd_test_unit_ready(cdp);
case CDIOCEJECT:
@@ -658,7 +540,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
struct ioc_read_toc_entry *te = (struct ioc_read_toc_entry *)addr;
struct toc *toc = &cdp->toc;
struct toc buf;
- u_long len;
+ u_int32_t len;
u_int8_t starting_track = te->starting_track;
if (!cdp->toc.hdr.ending_track)
@@ -741,7 +623,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
struct ioc_read_subchannel *args =
(struct ioc_read_subchannel *)addr;
struct cd_sub_channel_info data;
- u_long len = args->data_len;
+ u_int32_t len = args->data_len;
int32_t abslba, rellba;
int8_t ccb[16] = { ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, 0, 0,
sizeof(cdp->subchan)>>8, sizeof(cdp->subchan),
@@ -755,7 +637,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
sizeof(cdp->subchan), A_READ, NULL, NULL, NULL))
return EIO;
#ifdef ACD_DEBUG
- atapi_dump("acd: subchan", &cdp->subchan, sizeof(cdp->subchan));
+ atapi_dump("acd: subchan", &cdp->subchan, sizeof(cdp->subchan));
#endif
abslba = cdp->subchan.abslba;
@@ -807,7 +689,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
case CDIOCPLAYTRACKS:
{
struct ioc_play_track *args = (struct ioc_play_track *)addr;
- u_long start, len;
+ u_int32_t start, len;
int32_t t1, t2;
int8_t ccb[16];
@@ -1049,6 +931,128 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
return error;
}
+static void
+acdstrategy(struct buf *bp)
+{
+ int32_t lun = dkunit(bp->b_dev);
+ struct acd_softc *cdp = acdtab[lun];
+ int32_t x;
+
+#ifdef NOTYET
+ /* allow write only on CD-R/RW media */ /* all for now SOS */
+ if (!(bp->b_flags & B_READ) && !(writeable_media)) {
+ bp->b_error = EROFS;
+ bp->b_flags |= B_ERROR;
+ biodone(bp);
+ return;
+ }
+#endif
+
+ if (bp->b_bcount == 0) {
+ bp->b_resid = 0;
+ biodone(bp);
+ return;
+ }
+
+ /* check for valid blocksize SOS */
+
+ bp->b_pblkno = bp->b_blkno;
+ bp->b_resid = bp->b_bcount;
+
+ x = splbio();
+ bufqdisksort(&cdp->buf_queue, bp);
+ acd_start(cdp);
+ splx(x);
+}
+
+static void
+acd_start(struct acd_softc *cdp)
+{
+ struct buf *bp = bufq_first(&cdp->buf_queue);
+ u_int32_t lba, count;
+ int8_t ccb[16];
+
+ if (!bp)
+ return;
+
+ bufq_remove(&cdp->buf_queue, bp);
+
+ /* Should reject all queued entries if media have changed. */
+ if (cdp->flags & F_MEDIA_CHANGED) {
+ bp->b_error = EIO;
+ bp->b_flags |= B_ERROR;
+ biodone(bp);
+ return;
+ }
+ acd_select_slot(cdp);
+ if ((bp->b_flags & B_READ) == B_WRITE) {
+ if ((cdp->flags & F_TRACK_PREPED) == 0) {
+ if ((cdp->flags & F_TRACK_PREP) == 0) {
+ printf("acd%d: sequence error\n", cdp->lun);
+ bp->b_error = EIO;
+ bp->b_flags |= B_ERROR;
+ biodone(bp);
+ return;
+ } else {
+ if (acd_open_track(cdp, &cdp->preptrack) != 0) {
+ biodone(bp);
+ return;
+ }
+ cdp->flags |= F_TRACK_PREPED;
+ }
+ }
+ }
+ bzero(ccb, sizeof(ccb));
+ if (bp->b_flags & B_READ) {
+ lba = bp->b_blkno / (cdp->block_size / DEV_BSIZE);
+ ccb[0] = ATAPI_READ_BIG;
+ }
+ else {
+ lba = cdp->next_writeable_lba + (bp->b_offset / cdp->block_size);
+ ccb[0] = ATAPI_WRITE_BIG;
+ }
+ count = (bp->b_bcount + (cdp->block_size - 1)) / cdp->block_size;
+
+#ifdef ACD_DEBUG
+ printf("acd%d: lba=%d, count=%d\n", cdp->lun, lba, count);
+#endif
+ ccb[1] = 0;
+ ccb[2] = lba>>24;
+ ccb[3] = lba>>16;
+ ccb[4] = lba>>8;
+ ccb[5] = lba;
+ ccb[7] = count>>8;
+ ccb[8] = count;
+
+ devstat_start_transaction(cdp->stats);
+
+ atapi_queue_cmd(cdp->atp, ccb, bp->b_data, bp->b_bcount,
+ (bp->b_flags&B_READ)?A_READ : 0, acd_done, cdp, (void *)bp);
+}
+
+static void
+acd_done(struct atapi_request *request)
+{
+ struct buf *bp = request->bp;
+ struct acd_softc *cdp = request->driver;
+
+ devstat_end_transaction(cdp->stats, bp->b_bcount-request->bytecount,
+ DEVSTAT_TAG_NONE,
+ (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE);
+ if (request->result) {
+ atapi_error(request->device, request->result);
+ bp->b_error = EIO;
+ bp->b_flags |= B_ERROR;
+ }
+ else {
+ bp->b_resid = request->bytecount;
+ if ((bp->b_flags & B_READ) == B_WRITE)
+ cdp->flags |= F_WRITTEN;
+ }
+ biodone(bp);
+ acd_start(cdp);
+}
+
static int32_t
acd_test_unit_ready(struct acd_softc *cdp)
{
@@ -1095,8 +1099,8 @@ acd_mode_sense(struct acd_softc *cdp, u_int8_t page,
error = atapi_queue_cmd(cdp->atp, ccb, pagebuf, pagesize, A_READ,
NULL, NULL, NULL);
-#ifdef AST_DEBUG
- atapi_dump("acd: mode sense ", &cdp->au, sizeof(cdp->au));
+#ifdef ACD_DEBUG
+ atapi_dump("acd: mode sense ", pagebuf, pagesize);
#endif
return error;
}
@@ -1107,8 +1111,9 @@ acd_mode_select(struct acd_softc *cdp, void *pagebuf, int32_t pagesize)
int8_t ccb[16] = { ATAPI_MODE_SELECT, 0x10, 0, 0, 0, 0, 0,
pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 };
-#ifdef AST_DEBUG
- atapi_dump("acd: mode select ", &cdp->au, sizeof(cdp->au));
+#ifdef ACD_DEBUG
+ printf("acd: modeselect pagesize=%d\n", pagesize);
+ atapi_dump("acd: mode select ", pagebuf, pagesize);
#endif
return atapi_queue_cmd(cdp->atp, ccb, pagebuf, pagesize, 0,
NULL, NULL, NULL);
@@ -1196,9 +1201,6 @@ acd_read_toc(struct acd_softc *cdp)
return 0;
}
-/*
- * Set up the audio channel masks.
- */
static int32_t
acd_setchan(struct acd_softc *cdp,
u_int8_t c0, u_int8_t c1, u_int8_t c2, u_int8_t c3)
@@ -1287,7 +1289,7 @@ acd_select_slot(struct acd_softc *cdp)
acd_lock_device(cdp, 1);
}
-static int
+static int32_t
acd_rezero_unit(struct acd_softc *cdp)
{
int8_t ccb[16];
@@ -1297,14 +1299,14 @@ acd_rezero_unit(struct acd_softc *cdp)
return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL);
}
-static int
+static int32_t
acd_open_disk(struct acd_softc *cdp, int32_t test)
{
cdp->next_writeable_lba = 0;
return 0;
}
-static int
+static int32_t
acd_close_disk(struct acd_softc *cdp)
{
int8_t ccb[16];
@@ -1316,7 +1318,7 @@ acd_close_disk(struct acd_softc *cdp)
return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL);
}
-static int
+static int32_t
acd_open_track(struct acd_softc *cdp, struct wormio_prepare_track *ptp)
{
struct write_param param;
@@ -1386,7 +1388,7 @@ acd_open_track(struct acd_softc *cdp, struct wormio_prepare_track *ptp)
return acd_mode_select(cdp, &param, sizeof(param));
}
-static int
+static int32_t
acd_close_track(struct acd_softc *cdp)
{
int8_t ccb[16];
@@ -1396,7 +1398,7 @@ acd_close_track(struct acd_softc *cdp)
return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL);
}
-static int
+static int32_t
acd_read_track_info(struct acd_softc *cdp,
int32_t lba, struct acd_track_info *info)
{
@@ -1418,7 +1420,7 @@ acd_read_track_info(struct acd_softc *cdp,
return 0;
}
-static int
+static int32_t
acd_blank_disk(struct acd_softc *cdp)
{
int32_t error;
diff --git a/sys/dev/ata/atapi-cd.h b/sys/dev/ata/atapi-cd.h
index f602e37..2531989 100644
--- a/sys/dev/ata/atapi-cd.h
+++ b/sys/dev/ata/atapi-cd.h
@@ -25,21 +25,17 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: atapi-cd.h,v 1.3 1999/03/01 21:03:15 sos Exp sos $
+ * $Id: atapi-cd.h,v 1.1 1999/03/01 21:19:18 sos Exp $
*/
-/*
- * CDROM Table Of Contents
- */
+/* CDROM Table Of Contents */
#define MAXTRK 99
struct toc {
- struct ioc_toc_header hdr;
- struct cd_toc_entry tab[MAXTRK + 1];
+ struct ioc_toc_header hdr;
+ struct cd_toc_entry tab[MAXTRK + 1];
};
-/*
- * CDROM Audio Control Parameters Page
- */
+/* CDROM Audio Control Parameters Page */
struct audiopage {
/* Mode Page data header */
u_int16_t data_length;
@@ -63,22 +59,21 @@ struct audiopage {
u_int8_t reserved5;
u_int16_t lb_per_sec;
struct port_control {
- u_int8_t channels:4;
+ u_int8_t channels:4;
#define CHANNEL_0 1
#define CHANNEL_1 2
#define CHANNEL_2 4
#define CHANNEL_3 8
- u_int8_t volume;
+
+ u_int8_t volume;
} port[4];
};
-/*
- * CDROM Capabilities and Mechanical Status Page
- */
+/* CDROM Capabilities and Mechanical Status Page */
struct cappage {
/* Mode data header */
u_int16_t data_length;
- u_int8_t medium_type; /* Present media type */
+ u_int8_t medium_type;
#define MST_TYPE_MASK_LOW 0x0f
#define MST_FMT_NONE 0x00
#define MST_DATA_120 0x01
@@ -108,55 +103,55 @@ struct cappage {
#define ATAPI_CDROM_CAP_PAGE 0x2a
u_int8_t param_len;
- u_int8_t read_cdr :1; /* Supports CD-R read */
- u_int8_t read_cdrw :1; /* Supports CD-RW read */
- u_int8_t method2 :1; /* Supports reading packet tracks */
- u_int8_t byte2_37 :5;
- u_int8_t write_cdr :1; /* Supports CD-R write */
- u_int8_t write_cdrw :1; /* Supports CD-RW write */
- u_int8_t test_write :1; /* Supports test writing */
- u_int8_t byte3_37 :5;
- u_int8_t audio_play :1; /* Audio play supported */
- u_int8_t composite :1; /* Composite audio/video supported */
- u_int8_t dport1 :1; /* Digital audio on port 1 */
- u_int8_t dport2 :1; /* Digital audio on port 2 */
- u_int8_t mode2_form1 :1; /* Mode 2 form 1 (XA) read */
- u_int8_t mode2_form2 :1; /* Mode 2 form 2 format */
- u_int8_t multisession :1; /* Multi-session photo-CD */
+ u_int8_t read_cdr :1; /* supports CD-R read */
+ u_int8_t read_cdrw :1; /* supports CD-RW read */
+ u_int8_t method2 :1; /* supports reading packet tracks */
+ u_int8_t reserved2_37 :5;
+ u_int8_t write_cdr :1; /* supports CD-R write */
+ u_int8_t write_cdrw :1; /* supports CD-RW write */
+ u_int8_t test_write :1; /* supports test writing */
+ u_int8_t reserved3_37 :5;
+ u_int8_t audio_play :1; /* audio play supported */
+ u_int8_t composite :1; /* composite audio/video supported */
+ u_int8_t dport1 :1; /* digital audio on port 1 */
+ u_int8_t dport2 :1; /* digital audio on port 2 */
+ u_int8_t mode2_form1 :1; /* mode 2 form 1 (XA) read */
+ u_int8_t mode2_form2 :1; /* mode 2 form 2 format */
+ u_int8_t multisession :1; /* multi-session photo-CD */
u_int8_t :1;
- u_int8_t cd_da :1; /* Audio-CD read supported */
+ u_int8_t cd_da :1; /* audio-CD read supported */
u_int8_t cd_da_stream :1; /* CD-DA streaming */
- u_int8_t rw :1; /* Combined R-W subchannels */
+ u_int8_t rw :1; /* combined R-W subchannels */
u_int8_t rw_corr :1; /* R-W subchannel data corrected */
u_int8_t c2 :1; /* C2 error pointers supported */
- u_int8_t isrc :1; /* Can return the ISRC info */
- u_int8_t upc :1; /* Can return the catalog number UPC */
+ u_int8_t isrc :1; /* can return the ISRC info */
+ u_int8_t upc :1; /* can return the catalog number UPC */
u_int8_t :1;
- u_int8_t lock :1; /* Can be locked */
- u_int8_t locked :1; /* Current lock state */
- u_int8_t prevent :1; /* Prevent jumper installed */
- u_int8_t eject :1; /* Can eject */
+ u_int8_t lock :1; /* can be locked */
+ u_int8_t locked :1; /* current lock state */
+ u_int8_t prevent :1; /* prevent jumper installed */
+ u_int8_t eject :1; /* can eject */
u_int8_t :1;
- u_int8_t mech :3; /* Loading mechanism type */
+ u_int8_t mech :3; /* loading mechanism type */
#define MST_MECH_CADDY 0
#define MST_MECH_TRAY 1
#define MST_MECH_POPUP 2
#define MST_MECH_CHANGER 4
#define MST_MECH_CARTRIDGE 5
- u_int8_t sep_vol :1; /* Independent volume of channels */
- u_int8_t sep_mute :1; /* Independent mute of channels */
+ u_int8_t sep_vol :1; /* independent volume of channels */
+ u_int8_t sep_mute :1; /* independent mute of channels */
u_int8_t:6;
- u_int16_t max_speed; /* Max raw data rate in bytes/1000 */
- u_int16_t max_vol_levels; /* Number of discrete volume levels */
- u_int16_t buf_size; /* Internal buffer size in bytes/1024 */
- u_int16_t cur_speed; /* Current data rate in bytes/1000 */
+ u_int16_t max_speed; /* max raw data rate in bytes/1000 */
+ u_int16_t max_vol_levels; /* number of discrete volume levels */
+ u_int16_t buf_size; /* internal buffer size in bytes/1024 */
+ u_int16_t cur_speed; /* current data rate in bytes/1000 */
u_int8_t reserved3;
- u_int8_t bckf :1; /* Data valid on failing edge of BCK */
- u_int8_t rch :1; /* High LRCK indicates left channel */
- u_int8_t lsbf :1; /* Set if LSB first */
+ u_int8_t bckf :1; /* data valid on failing edge of BCK */
+ u_int8_t rch :1; /* high LRCK indicates left channel */
+ u_int8_t lsbf :1; /* set if LSB first */
u_int8_t dlen :2;
#define MST_DLEN_32 0
#define MST_DLEN_16 1
@@ -167,42 +162,38 @@ struct cappage {
u_int8_t reserved4[2];
};
-/*
- * CDROM Changer mechanism status structure
- */
+/* CDROM Changer mechanism status structure */
struct changer {
- u_int8_t current_slot :5; /* Active changer slot */
- u_int8_t mech_state :2; /* Current changer state */
+ u_int8_t current_slot :5; /* active changer slot */
+ u_int8_t mech_state :2; /* current changer state */
#define CH_READY 0
#define CH_LOADING 1
#define CH_UNLOADING 2
#define CH_INITIALIZING 3
- u_int8_t fault :1; /* Fault in last operation */
+ u_int8_t fault :1; /* fault in last operation */
u_int8_t reserved0 :5;
- u_int8_t cd_state :3; /* Current mechanism state */
+ u_int8_t cd_state :3; /* current mechanism state */
#define CD_IDLE 0
#define CD_AUDIO_ACTIVE 1
#define CD_AUDIO_SCAN 2
#define CD_HOST_ACTIVE 3
#define CD_NO_STATE 7
- u_int8_t current_lba[3]; /* Current LBA */
- u_int8_t slots; /* Number of available slots */
- u_int16_t table_length; /* Slot table length */
+ u_int8_t current_lba[3]; /* current LBA */
+ u_int8_t slots; /* number of available slots */
+ u_int16_t table_length; /* slot table length */
struct {
- u_int8_t changed :1; /* Media has changed in this slot */
- u_int8_t unused :6;
- u_int8_t present :1; /* Slot has a CD present */
- u_int8_t reserved0;
- u_int8_t reserved1;
- u_int8_t reserved2;
+ u_int8_t changed :1; /* media has changed in this slot */
+ u_int8_t unused :6;
+ u_int8_t present :1; /* slot has a CD present */
+ u_int8_t reserved0;
+ u_int8_t reserved1;
+ u_int8_t reserved2;
} slot[32];
};
-/*
- * CDROM Write Parameters Mode Page (Burners ONLY)
- */
+/* CDROM Write Parameters Mode Page (Burners ONLY) */
struct write_param {
/* Mode Page data header */
u_int16_t data_length;
@@ -213,63 +204,63 @@ struct write_param {
/* Write Parameters mode page */
u_int8_t page_code;
-#define ATAPI_CDROM_WRITE_PARAMETERS_PAGE 0x0e
+#define ATAPI_CDROM_WRITE_PARAMETERS_PAGE 0x05
u_int8_t page_length; /* 0x32 */
- u_int8_t write_type :4; /* Write stream type */
+ u_int8_t write_type :4; /* write stream type */
#define CDR_WTYPE_PACKET 0x00
#define CDR_WTYPE_TRACK 0x01
#define CDR_WTYPE_SESSION 0x02
#define CDR_WTYPE_RAW 0x03
- u_int8_t test_write :1; /* Test write enable */
+ u_int8_t test_write :1; /* test write enable */
u_int8_t reserved2_567 :3;
- u_int8_t track_mode :4; /* Track mode */
+ u_int8_t track_mode :4; /* track mode */
#define CDR_TMODE_AUDIO 0x01
#define CDR_TMODE_INCR_DATA 0x01
#define CDR_TMODE_ALLOW_COPY 0x02
#define CDR_TMODE_DATA 0x04
#define CDR_TMODE_QUAD_AUDIO 0x08
- u_int8_t copy :1; /* Generation stamp */
- u_int8_t fp :1; /* Fixed packet type */
- u_int8_t multi_session :2; /* Multi-session type */
+ u_int8_t copy :1; /* generation stamp */
+ u_int8_t fp :1; /* fixed packet type */
+ u_int8_t multi_session :2; /* multi-session type */
#define CDR_MSES_NONE 0x00
#define CDR_MSES_FINAL 0x01
#define CDR_MSES_RESERVED 0x02
#define CDR_MSES_NULTI 0x03
- u_int8_t data_block_type :4; /* Data block type code */
+ u_int8_t data_block_type :4; /* data block type code */
#define CDR_DB_RAW 0x0 /* 2352 bytes of raw data */
#define CDR_DB_RAW_PQ 0x1 /* 2368 bytes raw data + P/Q subchan */
#define CDR_DB_RAW_PW 0x2 /* 2448 bytes raw data + P-W subchan */
#define CDR_DB_RAW_PW_R 0x3 /* 2448 bytes raw data + P-W raw sub */
-#define CDR_DB_RES_4 0x4 /* Reserved */
-#define CDR_DB_RES_5 0x5 /* Reserved */
-#define CDR_DB_RES_6 0x6 /* Reserved */
-#define CDR_DB_VS_7 0x7 /* Vendor specific */
+#define CDR_DB_RES_4 0x4 /* reserved */
+#define CDR_DB_RES_5 0x5 /* reserved */
+#define CDR_DB_RES_6 0x6 /* reserved */
+#define CDR_DB_VS_7 0x7 /* vendor specific */
#define CDR_DB_ROM_MODE1 0x8 /* 2048 bytes Mode 1 (ISO/IEC 10149) */
#define CDR_DB_ROM_MODE2 0x9 /* 2336 bytes Mode 2 (ISO/IEC 10149) */
#define CDR_DB_XA_MODE1 0x10 /* 2048 bytes Mode 1 (CD-ROM XA 1) */
#define CDR_DB_XA_MODE2_F1 0x11 /* 2056 bytes Mode 2 (CD-ROM XA 1) */
#define CDR_DB_XA_MODE2_F2 0x12 /* 2324 bytes Mode 2 (CD-ROM XA 2) */
#define CDR_DB_XA_MODE2_MIX 0x13 /* 2332 bytes Mode 2 (CD-ROM XA 1/2) */
-#define CDR_DB_RES_14 0x14 /* Reserved */
-#define CDR_DB_VS_15 0x15 /* Vendor specific */
+#define CDR_DB_RES_14 0x14 /* reserved */
+#define CDR_DB_VS_15 0x15 /* vendor specific */
u_int8_t reserved4_4567 :4;
u_int8_t reserved5;
u_int8_t reserved6;
- u_int8_t host_app_code :6; /* Host application code */
+ u_int8_t host_app_code :6; /* host application code */
u_int8_t reserved7_67 :2;
- u_int8_t session_format; /* Session format */
+ u_int8_t session_format; /* session format */
#define CDR_SESS_CDROM 0x00
#define CDR_SESS_CDI 0x10
#define CDR_SESS_CDROM_XA 0x20
u_int8_t reserved9;
- u_int32_t packet_size; /* Packet size in bytes */
- u_int16_t audio_pause_length; /* Audio pause length in secs */
+ u_int32_t packet_size; /* packet size in bytes */
+ u_int16_t audio_pause_length; /* audio pause length in secs */
u_int8_t media_catalog_number[16];
u_int8_t isr_code[16];
u_int8_t sub_hdr_byte0;
@@ -284,75 +275,72 @@ struct write_param {
*/
} __attribute__((packed));
-/*
- * CDROM Read Track Information structure
- */
+
+/* CDROM Read Track Information structure */
struct acd_track_info {
u_int16_t data_length;
- u_int8_t track_number; /* Current track number */
- u_int8_t session_number; /* Current session number */
+ u_int8_t track_number; /* current track number */
+ u_int8_t session_number; /* current session number */
u_int8_t reserved4;
- u_int8_t track_mode :4; /* Mode of this track */
- u_int8_t copy :1; /* Generation stamp */
- u_int8_t damage :1; /* Damaged track */
+ u_int8_t track_mode :4; /* mode of this track */
+ u_int8_t copy :1; /* generation stamp */
+ u_int8_t damage :1; /* damaged track */
u_int8_t reserved5_67 :2;
- u_int8_t data_mode :4; /* Data mode of this disc */
- u_int8_t fp :1; /* Fixed packet */
- u_int8_t packet :1; /* Packet track */
- u_int8_t blank :1; /* Blank (empty) track */
- u_int8_t rt :1; /* Reserved track */
+ u_int8_t data_mode :4; /* data mode of this disc */
+ u_int8_t fp :1; /* fixed packet */
+ u_int8_t packet :1; /* packet track */
+ u_int8_t blank :1; /* blank (empty) track */
+ u_int8_t rt :1; /* reserved track */
u_int8_t nwa_valid :1; /* next_writeable_addr field valid */
u_int8_t reserved7_17 :7;
- u_int track_start_addr; /* Start of this track */
- u_int next_writeable_addr; /* Next writeable addr on this disc */
- u_int free_blocks; /* Free block on this disc */
- u_int fixed_packet_size; /* Size of packets on this track */
- u_int track_length; /* Length of this track */
+ u_int track_start_addr; /* start of this track */
+ u_int next_writeable_addr; /* next writeable addr on this disc */
+ u_int free_blocks; /* free block on this disc */
+ u_int fixed_packet_size; /* size of packets on this track */
+ u_int track_length; /* length of this track */
};
-/*
- * Structure describing an ATAPI CDROM device
- */
+/* Structure describing an ATAPI CDROM device */
struct acd_softc {
- struct atapi_softc *atp; /* Controller structure */
- int32_t lun; /* Logical device unit */
- int32_t flags; /* Device state flags */
- int32_t refcnt; /* The number of raw opens */
+ struct atapi_softc *atp; /* controller structure */
+ int32_t lun; /* logical device unit */
+ int32_t flags; /* device state flags */
+ int32_t refcnt; /* the number of raw opens */
struct buf_queue_head buf_queue; /* Queue of i/o requests */
- struct toc toc; /* Table of disc contents */
+ struct toc toc; /* table of disc contents */
struct {
- u_int32_t volsize; /* Volume size in blocks */
- u_int32_t blksize; /* Block size in bytes */
- } info;
- struct audiopage au; /* Audio page info */
- struct cappage cap; /* Capabilities page info */
- struct audiopage aumask; /* Audio page mask */
- struct { /* Subchannel info */
- u_int8_t void0;
- u_int8_t audio_status;
- u_int16_t data_length;
- u_int8_t data_format;
- u_int8_t control;
- u_int8_t track;
- u_int8_t indx;
- u_int32_t abslba;
- u_int32_t rellba;
+ u_int32_t volsize; /* volume size in blocks */
+ u_int32_t blksize; /* block size in bytes */
+ } info;
+ struct audiopage au; /* audio page info */
+ struct cappage cap; /* capabilities page info */
+ struct audiopage aumask; /* audio page mask */
+ struct { /* subchannel info */
+ u_int8_t void0;
+ u_int8_t audio_status;
+ u_int16_t data_length;
+ u_int8_t data_format;
+ u_int8_t control;
+ u_int8_t track;
+ u_int8_t indx;
+ u_int32_t abslba;
+ u_int32_t rellba;
} subchan;
- struct changer *changer_info; /* Changer info */
- int32_t slot; /* This lun's slot number */
- u_int32_t block_size; /* Blocksize currently used */
- u_int8_t dummy; /* Use dummy writes */
- u_int8_t speed; /* Select drive speed */
- u_int32_t next_writeable_lba; /* Next writable position */
- struct wormio_prepare_track preptrack; /* Scratch region */
+ struct changer *changer_info; /* changer info */
+ int32_t slot; /* this lun's slot number */
+ u_int32_t block_size; /* blocksize currently used */
+ u_int8_t dummy; /* use dummy writes */
+ u_int8_t speed; /* select drive speed */
+ u_int32_t next_writeable_lba; /* next writable position */
+ struct wormio_prepare_track preptrack; /* scratch region */
struct devstat *stats; /* devstat entry */
#ifdef DEVFS
- void *ra_devfs_token;
- void *rc_devfs_token;
- void *a_devfs_token;
- void *c_devfs_token;
+ void *a_cdevfs_token;
+ void *c_cdevfs_token;
+ void *a_bdevfs_token;
+ void *c_bdevfs_token;
#endif
};
-#define CDRIOCBLANK _IO('c',100) /* Blank a CDRW disc */
+#define CDRIOCBLANK _IO('c',100) /* blank a CDRW disc */
#define CDRIOCNEXTWRITEABLEADDR _IOR('c',101,int)
diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c
new file mode 100644
index 0000000..6aa18db
--- /dev/null
+++ b/sys/dev/ata/atapi-fd.c
@@ -0,0 +1,434 @@
+/*-
+ * Copyright (c) 1998,1999 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "ata.h"
+#include "atapifd.h"
+#include "opt_devfs.h"
+
+#if NATA > 0 && NATAPIFD > 0
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/buf.h>
+#include <sys/disklabel.h>
+#include <sys/diskslice.h>
+#include <sys/devicestat.h>
+#include <sys/cdio.h>
+#include <sys/fcntl.h>
+#include <sys/conf.h>
+#include <sys/stat.h>
+#ifdef DEVFS
+#include <sys/devfsext.h>
+#endif
+#include <dev/ata/ata-all.h>
+#include <dev/ata/atapi-all.h>
+#include <dev/ata/atapi-fd.h>
+
+static d_open_t afdopen;
+static d_close_t afdclose;
+static d_read_t afdread;
+static d_write_t afdwrite;
+static d_ioctl_t afdioctl;
+static d_strategy_t afdstrategy;
+
+#define CDEV_MAJOR 87
+#define BDEV_MAJOR 1
+
+static struct cdevsw afd_cdevsw = {
+ afdopen, afdclose, afdread, afdwrite,
+ afdioctl, nostop, nullreset, nodevtotty,
+ seltrue, nommap, afdstrategy, "afd",
+ NULL, -1 };
+
+#define NUNIT 8
+#define UNIT(d) ((minor(d) >> 3) & 3)
+
+#define F_OPEN 0x0001 /* The device is opened */
+#define F_MEDIA_CHANGED 0x0002 /* The media have changed */
+
+static struct afd_softc *afdtab[NUNIT]; /* Drive info by unit number */
+static int32_t afdnlun = 0; /* Number of config'd drives */
+
+int32_t afdattach(struct atapi_softc *);
+static int32_t afd_sense(struct afd_softc *);
+static void afd_describe(struct afd_softc *);
+static void afd_strategy(struct buf *);
+static void afd_start(struct afd_softc *);
+static void afd_done(struct atapi_request *);
+static int32_t afd_start_device(struct afd_softc *, int32_t);
+static int32_t afd_lock_device(struct afd_softc *, int32_t);
+static int32_t afd_eject(struct afd_softc *, int32_t);
+static void afd_drvinit(void *);
+
+int32_t
+afdattach(struct atapi_softc *atp)
+{
+ struct afd_softc *fdp;
+
+ if (afdnlun >= NUNIT) {
+ printf("afd: too many units\n");
+ return -1;
+ }
+ fdp = malloc(sizeof(struct afd_softc), M_TEMP, M_NOWAIT);
+ if (!fdp) {
+ printf("afd: out of memory\n");
+ return -1;
+ }
+ bzero(fdp, sizeof(struct afd_softc));
+ bufq_init(&fdp->buf_queue);
+ fdp->atp = atp;
+ fdp->lun = afdnlun;
+ fdp->flags = F_MEDIA_CHANGED;
+
+ if (afd_sense(fdp)) {
+ free(fdp, M_TEMP);
+ return -1;
+ }
+
+ afd_describe(fdp);
+ afdtab[afdnlun++] = fdp;
+ devstat_add_entry(&fdp->stats, "afd", fdp->lun, DEV_BSIZE,
+ DEVSTAT_NO_ORDERED_TAGS,
+ DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE,
+ 0x178);
+#ifdef DEVFS
+ fdp->cdevs_token = devfs_add_devswf(&afd_cdevsw, dkmakeminor(fdp->lun, 0,0),
+ DV_CHR, UID_ROOT, GID_OPERATOR,
+ 0640, "rafd%d", fdp->lun);
+ fdp->bdevs_token = devfs_add_devswf(&afd_cdevsw, dkmakeminor(fdp->lun, 0,0),
+ DV_BLK, UID_ROOT, GID_OPERATOR,
+ 0640, "afd%d", fdp->lun);
+#endif
+ return 0;
+}
+
+static int32_t
+afd_sense(struct afd_softc *fdp)
+{
+ int32_t error, count;
+ int8_t buffer[256];
+ int8_t ccb[16] = { ATAPI_MODE_SENSE, 0, ATAPI_REWRITEABLE_CAP_PAGE,
+ 0, 0, 0, 0, sizeof(buffer)>>8, sizeof(buffer) & 0xff,
+ 0, 0, 0, 0, 0, 0, 0 };
+
+ bzero(buffer, sizeof(buffer));
+ /* Get drive capabilities, some drives needs this repeated */
+ for (count = 0 ; count < 5 ; count++) {
+ if (!(error = atapi_queue_cmd(fdp->atp, ccb, buffer, sizeof(buffer),
+ A_READ, NULL, NULL, NULL)))
+ break;
+ }
+#ifdef AFD_DEBUG
+ atapi_dump("afd: sense", buffer, sizeof(buffer));
+#endif
+ if (error)
+ return error;
+ bcopy(buffer, &fdp->header, sizeof(struct afd_header));
+ bcopy(buffer+sizeof(struct afd_header), &fdp->cap,
+ sizeof(struct afd_cappage));
+ if (fdp->cap.page_code != ATAPI_REWRITEABLE_CAP_PAGE)
+ return 1;
+ fdp->cap.cylinders = ntohs(fdp->cap.cylinders);
+ fdp->cap.sector_size = ntohs(fdp->cap.sector_size);
+ return 0;
+}
+
+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,
+ fdp->atp->controller->unit,
+ (fdp->atp->unit == ATA_MASTER) ? "master" : "slave ");
+ printf("afd%d: %luMB (%u sectors), %u cyls, %u heads, %u S/T, %u B/S\n",
+ afdnlun,
+ (fdp->cap.cylinders * fdp->cap.heads * fdp->cap.sectors) /
+ ((1024L * 1024L) / fdp->cap.sector_size),
+ fdp->cap.cylinders * fdp->cap.heads * fdp->cap.sectors,
+ fdp->cap.cylinders, fdp->cap.heads, fdp->cap.sectors,
+ fdp->cap.sector_size);
+ printf("afd%d: ", fdp->lun);
+ switch (fdp->header.medium_type) {
+ default: printf("Unknown media (0x%x)", fdp->header.medium_type);
+ }
+ if (fdp->header.wp) printf(", writeprotected");
+ printf("\n");
+}
+
+static int32_t
+afdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
+{
+ struct afd_softc *fdp;
+ struct disklabel label;
+ int32_t lun = UNIT(dev);
+
+ if (lun >= afdnlun || !(fdp = afdtab[lun]))
+ return ENXIO;
+
+ fdp->flags &= ~F_MEDIA_CHANGED;
+ afd_lock_device(fdp, 1);
+ if (afd_sense(fdp))
+ printf("afd%d: sense media type failed\n", fdp->lun);
+
+ /* build disklabel and initilize slice tables */
+ bzero(&label, sizeof label);
+ label.d_secsize = fdp->cap.sector_size;
+ label.d_nsectors = fdp->cap.sectors;
+ label.d_ntracks = fdp->cap.heads;
+ label.d_ncylinders = fdp->cap.cylinders;
+ label.d_secpercyl = fdp->cap.heads * fdp->cap.sectors;
+ label.d_secperunit = fdp->cap.heads * fdp->cap.sectors * fdp->cap.cylinders;
+
+ /* Initialize slice tables. */
+ return dsopen("afd", dev, fmt, 0, &fdp->slices, &label, afd_strategy,
+ (ds_setgeom_t *)NULL, &afd_cdevsw);
+}
+
+static int32_t
+afdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
+{
+ int32_t lun = UNIT(dev);
+ struct afd_softc *fdp;
+
+ if (lun >= afdnlun || !(fdp = afdtab[lun]))
+ return ENXIO;
+
+ dsclose(dev, fmt, fdp->slices);
+ if(!dsisopen(fdp->slices))
+ afd_lock_device(fdp, 0);
+ return 0;
+}
+
+static int32_t
+afdread(dev_t dev, struct uio *uio, int32_t ioflag)
+{
+ return physio(afdstrategy, NULL, dev, 1, minphys, uio);
+}
+
+static int32_t
+afdwrite(dev_t dev, struct uio *uio, int32_t ioflag)
+{
+ return physio(afdstrategy, NULL, dev, 0, minphys, uio);
+}
+
+static int32_t
+afdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
+{
+ int32_t lun = UNIT(dev);
+ int32_t error = 0;
+ struct afd_softc *fdp;
+
+ if (lun >= afdnlun || !(fdp = afdtab[lun]))
+ return ENXIO;
+
+ switch (cmd) {
+
+ case CDIOCEJECT:
+ if ((fdp->flags & F_OPEN) && fdp->refcnt)
+ return EBUSY;
+ return afd_eject(fdp, 0);
+
+ case CDIOCCLOSE:
+ if ((fdp->flags & F_OPEN) && fdp->refcnt)
+ return 0;
+ return afd_eject(fdp, 1);
+
+ default:
+ return ENOTTY;
+ }
+ return error;
+}
+
+static void
+afdstrategy(struct buf *bp)
+{
+ int32_t lun = UNIT(bp->b_dev);
+ struct afd_softc *fdp = afdtab[lun];
+ int32_t x;
+
+ if (bp->b_bcount == 0) {
+ bp->b_resid = 0;
+ biodone(bp);
+ return;
+ }
+ if (dscheck(bp, fdp->slices) <= 0) {
+ x = splbio();
+ biodone(bp);
+ splx(x);
+ return;
+ }
+ x = splbio();
+ bufq_insert_tail(&fdp->buf_queue, bp);
+ afd_start(fdp);
+ splx(x);
+}
+
+static void
+afd_strategy(struct buf *bp)
+{
+ afdstrategy(bp);
+}
+
+static void
+afd_start(struct afd_softc *fdp)
+{
+ struct buf *bp = bufq_first(&fdp->buf_queue);
+ u_int32_t lba, count;
+ int8_t ccb[16];
+
+ if (!bp)
+ return;
+ bzero(ccb, sizeof(ccb));
+ bufq_remove(&fdp->buf_queue, bp);
+
+ /* Should reject all queued entries if media have changed. */
+ if (fdp->flags & F_MEDIA_CHANGED) {
+ bp->b_error = EIO;
+ bp->b_flags |= B_ERROR;
+ biodone(bp);
+ return;
+ }
+
+ lba = bp->b_blkno / (fdp->cap.sector_size / DEV_BSIZE);
+ count = (bp->b_bcount + (fdp->cap.sector_size - 1)) / fdp->cap.sector_size;
+
+ if (bp->b_flags & B_READ)
+ ccb[0] = ATAPI_READ_BIG;
+ else
+ ccb[0] = ATAPI_WRITE_BIG;
+
+ ccb[1] = 0;
+ ccb[2] = lba>>24;
+ ccb[3] = lba>>16;
+ ccb[4] = lba>>8;
+ ccb[5] = lba;
+ ccb[7] = count>>8;
+ ccb[8] = count;
+
+ devstat_start_transaction(&fdp->stats);
+
+ atapi_queue_cmd(fdp->atp, ccb, bp->b_data, bp->b_bcount,
+ (bp->b_flags & B_READ) ? A_READ : 0, afd_done, fdp, bp);
+}
+
+static void
+afd_done(struct atapi_request *request)
+{
+ struct buf *bp = request->bp;
+ struct afd_softc *fdp = request->driver;
+
+ devstat_end_transaction(&fdp->stats, bp->b_bcount-request->bytecount,
+ DEVSTAT_TAG_NONE,
+ (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE);
+
+ if (request->result) {
+ printf("afd_done: ");
+ atapi_error(request->device, request->result);
+ bp->b_error = EIO;
+ bp->b_flags |= B_ERROR;
+ }
+ else
+ bp->b_resid = request->bytecount;
+ biodone(bp);
+ afd_start(fdp);
+}
+
+static int32_t
+afd_start_device(struct afd_softc *fdp, int32_t start)
+{
+ int8_t ccb[16] = { ATAPI_START_STOP, 0, 0, 0, start,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ return atapi_queue_cmd(fdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL);
+}
+
+static int32_t
+afd_lock_device(struct afd_softc *fdp, int32_t lock)
+{
+ int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ return atapi_queue_cmd(fdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL);
+}
+
+static int32_t
+afd_eject(struct afd_softc *fdp, int32_t close)
+{
+ int32_t error;
+
+ error = afd_start_device(fdp, 0);
+ if ((error & ATAPI_SK_MASK) &&
+ ((error & ATAPI_SK_MASK) == ATAPI_SK_NOT_READY ||
+ (error & ATAPI_SK_MASK) == ATAPI_SK_UNIT_ATTENTION)) {
+
+ if (!close)
+ return 0;
+ if ((error = afd_start_device(fdp, 3)))
+ return error;
+ afd_lock_device(fdp, 1);
+ return 0;
+ }
+ if (error) {
+ atapi_error(fdp->atp, error);
+ return EIO;
+ }
+ if (close)
+ return 0;
+
+ tsleep((caddr_t) &lbolt, PRIBIO, "afdej1", 0);
+ tsleep((caddr_t) &lbolt, PRIBIO, "afdej2", 0);
+ afd_lock_device(fdp, 0);
+ fdp->flags |= F_MEDIA_CHANGED;
+ return afd_start_device(fdp, 2);
+}
+
+
+static void
+afd_drvinit(void *unused)
+{
+ static afd_devsw_installed = 0;
+
+ if (!afd_devsw_installed) {
+ cdevsw_add_generic(BDEV_MAJOR, CDEV_MAJOR, &afd_cdevsw);
+ afd_devsw_installed = 1;
+ }
+}
+
+SYSINIT(afddev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, afd_drvinit, NULL)
+#endif /* NATA & NATAPIFD */
diff --git a/sys/dev/ata/atapi-fd.h b/sys/dev/ata/atapi-fd.h
new file mode 100644
index 0000000..9904992
--- /dev/null
+++ b/sys/dev/ata/atapi-fd.h
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 1998,1999 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/* MODE SENSE parameter header */
+struct afd_header {
+ u_int16_t data_length;
+ u_int8_t medium_type;
+#define MFD_2DD_UN 0x10
+#define MFD_2DD 0x11
+#define MFD_2HD_UN 0x20
+#define MFD_2HD_12_98 0x22
+#define MFD_2HD_12 0x23
+#define MFD_2HD_144 0x24
+#define MFD_LS120 0x31
+
+#define MFD_UNKNOWN 0x00
+#define MFD_NO_DISC 0x70
+#define MFD_DOOR_OPEN 0x71
+#define MFD_FMT_ERROR 0x72
+
+ u_int8_t reserved0 :7;
+ u_int8_t wp :1; /* write protect */
+ u_int8_t unused[4];
+};
+
+/* ATAPI Rewriteable drive Capabilities and Mechanical Status Page */
+#define ATAPI_REWRITEABLE_CAP_PAGE 0x05
+
+struct afd_cappage {
+ u_int8_t page_code :6;
+ u_int8_t reserved1_6 :1;
+ u_int8_t ps :1; /* page save supported */
+ u_int8_t page_length; /* page length */
+ u_int16_t transfer_rate; /* in kilobits per second */
+ u_int8_t heads; /* number of heads */
+ u_int8_t sectors; /* number of sectors per track */
+ u_int16_t sector_size; /* number of bytes per sector */
+ u_int16_t cylinders; /* number of cylinders */
+ u_int8_t reserved10[10];
+ u_int8_t motor_delay; /* motor off delay */
+ u_int8_t reserved21[7];
+ u_int16_t rpm; /* rotations per minute */
+ u_int8_t reserved30[2];
+};
+
+
+struct afd_softc {
+ struct atapi_softc *atp; /* controller structure */
+ int32_t lun; /* logical device unit */
+ int32_t flags; /* device state flags */
+ int32_t refcnt; /* the number of raw opens */
+ int32_t maxblks; /* transfer size limit */
+ struct buf_queue_head buf_queue; /* queue of i/o requests */
+ struct afd_header header; /* capabilities page info */
+ struct afd_cappage cap; /* capabilities page info */
+ struct diskslices *slices; /* virtual drives */
+ struct devstat stats;
+#ifdef DEVFS
+ void *cdevs_token;
+ void *bdevs_token;
+#endif
+};
+
diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c
index ea21e99..c51521d 100644
--- a/sys/dev/ata/atapi-tape.c
+++ b/sys/dev/ata/atapi-tape.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: atapi-tape.c,v 1.5 1999/03/01 21:03:15 sos Exp sos $
+ * $Id: atapi-tape.c,v 1.1 1999/03/01 21:19:18 sos Exp $
*/
#include "ata.h"
@@ -41,6 +41,7 @@
#include <sys/malloc.h>
#include <sys/buf.h>
#include <sys/mtio.h>
+#include <sys/disklabel.h>
#include <sys/devicestat.h>
#ifdef DEVFS
#include <sys/devfsext.h>
@@ -50,21 +51,21 @@
#include <dev/ata/atapi-all.h>
#include <dev/ata/atapi-tape.h>
-static d_open_t astopen;
-static d_read_t astread;
-static d_write_t astwrite;
-static d_close_t astclose;
-static d_ioctl_t astioctl;
-static d_strategy_t aststrategy;
+static d_open_t astopen;
+static d_close_t astclose;
+static d_read_t astread;
+static d_write_t astwrite;
+static d_ioctl_t astioctl;
+static d_strategy_t aststrategy;
#define CDEV_MAJOR 90
#define BDEV_MAJOR 24
static struct cdevsw ast_cdevsw = {
- astopen, astclose, astread, astwrite,
- astioctl, nostop, nullreset, nodevtotty,
- seltrue, nommap, aststrategy, "ast",
- NULL, -1 };
+ astopen, astclose, astread, astwrite,
+ astioctl, nostop, nullreset, nodevtotty,
+ seltrue, nommap, aststrategy, "ast",
+ NULL, -1 };
static u_int32_t ast_total = 0;
@@ -123,12 +124,11 @@ astattach(struct atapi_softc *atp)
DEVSTAT_NO_ORDERED_TAGS,
DEVSTAT_TYPE_SEQUENTIAL | DEVSTAT_TYPE_IF_IDE,
0x178);
-
-
#ifdef DEVFS
- t->cdevs = devfs_add_devswf(&ast_cdevsw, 0, DV_CHR, UID_ROOT, GID_OPERATOR,
- 0640, "rast%d", t->lun);
-#endif /* DEVFS */
+ stp->cdevs_token = devfs_add_devswf(&ast_cdevsw, dkmakeminor(stp->lun, 0,0),
+ DV_CHR, UID_ROOT, GID_OPERATOR, 0640,
+ "rast%d", stp->lun);
+#endif
return 0;
}
@@ -209,14 +209,14 @@ ast_describe(struct ast_softc *stp)
printf("\n");
}
-int
+static int32_t
astopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
{
int32_t lun = UNIT(dev);
struct ast_softc *stp;
if (lun >= astnlun || !(stp = asttab[lun]))
- return(ENXIO);
+ return ENXIO;
if (stp->flags == F_OPEN)
return EBUSY;
if (ast_sense(stp))
@@ -225,17 +225,17 @@ astopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
stp->flags &= ~(F_DATA_WRITTEN | F_FM_WRITTEN);
stp->flags |= F_OPEN;
ast_total = 0;
- return(0);
+ return 0;
}
-int32_t
+static int32_t
astclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
{
int32_t lun = UNIT(dev);
struct ast_softc *stp;
if (lun >= astnlun || !(stp = asttab[lun]))
- return(ENXIO);
+ return ENXIO;
/* Flush buffers, some drives fail here, but they should report ctl = 0 */
if (stp->cap.ctl && (stp->flags & F_DATA_WRITTEN))
@@ -254,111 +254,22 @@ astclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
printf("ast%d: %ud total bytes transferred\n", stp->lun, ast_total);
#endif
stp->flags &= ~F_CTL_WARN;
- return(0);
+ return 0;
}
-static int
+static int32_t
astread(dev_t dev, struct uio *uio, int32_t ioflag)
{
- return (physio(aststrategy, NULL, dev, 1, minphys, uio));
+ return physio(aststrategy, NULL, dev, 1, minphys, uio);
}
-static int
+static int32_t
astwrite(dev_t dev, struct uio *uio, int32_t ioflag)
{
- return (physio(aststrategy, NULL, dev, 0, minphys, uio));
-}
-
-void
-aststrategy(struct buf *bp)
-{
- int32_t lun = UNIT(bp->b_dev);
- struct ast_softc *stp = asttab[lun];
- int32_t x;
-
- /* If it's a null transfer, return immediatly. */
- if (bp->b_bcount == 0) {
- bp->b_resid = 0;
- biodone(bp);
- return;
- }
-
- /* Check for != blocksize requests */
- if (bp->b_bcount % stp->blksize) {
- printf("ast%d: bad request, must be multiple of %d\n",
- lun, stp->blksize);
- bp->b_error = EIO;
- bp->b_flags |= B_ERROR;
- biodone(bp);
- return;
- }
- if (bp->b_bcount > stp->blksize * stp->cap.ctl) {
- if ((stp->flags & F_CTL_WARN) == 0) {
- printf("ast%d: WARNING: CTL exceeded %ld>%d\n",
- lun, bp->b_bcount, stp->blksize * stp->cap.ctl);
- stp->flags |= F_CTL_WARN;
- }
- }
-
- x = splbio();
- ast_total += bp->b_bcount;
- bufq_insert_tail(&stp->buf_queue, bp);
- ast_start(stp);
- splx(x);
-}
-
-static void
-ast_start(struct ast_softc *stp)
-{
- struct buf *bp = bufq_first(&stp->buf_queue);
- u_long blkcount;
- int8_t ccb[16];
-
- if (!bp)
- return;
- bzero(ccb, sizeof(ccb));
- bufq_remove(&stp->buf_queue, bp);
- blkcount = bp->b_bcount / stp->blksize;
- if (bp->b_flags & B_READ) {
- ccb[0] = ATAPI_TAPE_READ_CMD;
- } else {
- ccb[0] = ATAPI_TAPE_WRITE_CMD;
- stp->flags |= F_DATA_WRITTEN;
- }
- ccb[1] = 1;
- ccb[2] = blkcount>>16;
- ccb[3] = blkcount>>8;
- ccb[4] = blkcount;
-
- devstat_start_transaction(&stp->stats);
-
- atapi_queue_cmd(stp->atp, ccb, bp->b_data, bp->b_bcount,
- (bp->b_flags & B_READ) ? A_READ : 0, ast_done, stp, bp);
-}
-
-static void
-ast_done(struct atapi_request *request)
-{
- struct buf *bp = request->bp;
- struct ast_softc *stp = request->driver;
-
- devstat_end_transaction(&stp->stats, bp->b_bcount-request->bytecount,
- DEVSTAT_TAG_NONE,
- (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE);
-
- if (request->result) {
- printf("ast_done: ");
- atapi_error(request->device, request->result);
- bp->b_error = EIO;
- bp->b_flags |= B_ERROR;
- }
- else
- bp->b_resid = request->bytecount;
- biodone(bp);
- ast_start(stp);
+ return physio(aststrategy, NULL, dev, 0, minphys, uio);
}
-int32_t
+static int32_t
astioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
{
int32_t lun = UNIT(dev);
@@ -444,12 +355,100 @@ astioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
return error;
}
default:
- return(ENOTTY);
+ return ENOTTY;
+ }
+ return error;
+}
+
+static void
+aststrategy(struct buf *bp)
+{
+ int32_t lun = UNIT(bp->b_dev);
+ struct ast_softc *stp = asttab[lun];
+ int32_t x;
+
+ /* If it's a null transfer, return immediatly. */
+ if (bp->b_bcount == 0) {
+ bp->b_resid = 0;
+ biodone(bp);
+ return;
+ }
+
+ /* Check for != blocksize requests */
+ if (bp->b_bcount % stp->blksize) {
+ printf("ast%d: bad request, must be multiple of %d\n",
+ lun, stp->blksize);
+ bp->b_error = EIO;
+ bp->b_flags |= B_ERROR;
+ biodone(bp);
+ return;
+ }
+ if (bp->b_bcount > stp->blksize * stp->cap.ctl) {
+ if ((stp->flags & F_CTL_WARN) == 0) {
+ printf("ast%d: WARNING: CTL exceeded %ld>%d\n",
+ lun, bp->b_bcount, stp->blksize * stp->cap.ctl);
+ stp->flags |= F_CTL_WARN;
+ }
+ }
+
+ x = splbio();
+ ast_total += bp->b_bcount;
+ bufq_insert_tail(&stp->buf_queue, bp);
+ ast_start(stp);
+ splx(x);
+}
+
+static void
+ast_start(struct ast_softc *stp)
+{
+ struct buf *bp = bufq_first(&stp->buf_queue);
+ u_int32_t blkcount;
+ int8_t ccb[16];
+
+ if (!bp)
+ return;
+ bzero(ccb, sizeof(ccb));
+ bufq_remove(&stp->buf_queue, bp);
+ blkcount = bp->b_bcount / stp->blksize;
+ if (bp->b_flags & B_READ) {
+ ccb[0] = ATAPI_TAPE_READ_CMD;
+ } else {
+ ccb[0] = ATAPI_TAPE_WRITE_CMD;
+ stp->flags |= F_DATA_WRITTEN;
+ }
+ ccb[1] = 1;
+ ccb[2] = blkcount>>16;
+ ccb[3] = blkcount>>8;
+ ccb[4] = blkcount;
+
+ devstat_start_transaction(&stp->stats);
+
+ atapi_queue_cmd(stp->atp, ccb, bp->b_data, bp->b_bcount,
+ (bp->b_flags & B_READ) ? A_READ : 0, ast_done, stp, bp);
+}
+
+static void
+ast_done(struct atapi_request *request)
+{
+ struct buf *bp = request->bp;
+ struct ast_softc *stp = request->driver;
+
+ devstat_end_transaction(&stp->stats, bp->b_bcount-request->bytecount,
+ DEVSTAT_TAG_NONE,
+ (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE);
+
+ if (request->result) {
+ atapi_error(request->device, request->result);
+ bp->b_error = EIO;
+ bp->b_flags |= B_ERROR;
}
- return(error);
+ else
+ bp->b_resid = request->bytecount;
+ biodone(bp);
+ ast_start(stp);
}
-static int
+static int32_t
ast_space_cmd(struct ast_softc *stp, u_int8_t function, u_int32_t count)
{
int32_t error;
@@ -463,14 +462,13 @@ ast_space_cmd(struct ast_softc *stp, u_int8_t function, u_int32_t count)
ccb[4] = count;
if ((error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL))){
- printf("ast_space_cmd: ");
atapi_error(stp->atp, error);
return EIO;
}
return 0;
}
-static int
+static int32_t
ast_write_filemark(struct ast_softc *stp, u_int8_t function)
{
int32_t error;
@@ -487,14 +485,13 @@ ast_write_filemark(struct ast_softc *stp, u_int8_t function)
ccb[4] = function;
if ((error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL))){
- printf("ast_write_filemark: ");
atapi_error(stp->atp, error);
return EIO;
}
return 0;
}
-static int
+static int32_t
ast_load_unload(struct ast_softc *stp, u_int8_t function)
{
int32_t error;
@@ -505,14 +502,13 @@ ast_load_unload(struct ast_softc *stp, u_int8_t function)
ccb[4] = function;
if ((error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL))){
- printf("ast_load_unload: ");
atapi_error(stp->atp, error);
return EIO;
}
return 0;
}
-static int
+static int32_t
ast_erase(struct ast_softc *stp)
{
int32_t error;
@@ -526,14 +522,13 @@ ast_erase(struct ast_softc *stp)
ccb[1] = 3;
if ((error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL))){
- printf("ast_erase: ");
atapi_error(stp->atp, error);
return EIO;
}
return 0;
}
-static int
+static int32_t
ast_rewind(struct ast_softc *stp)
{
int32_t error;
@@ -543,7 +538,6 @@ ast_rewind(struct ast_softc *stp)
ccb[0] = ATAPI_TAPE_REWIND;
if ((error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL))){
- printf("ast_rewind: ");
atapi_error(stp->atp, error);
return EIO;
}
diff --git a/sys/dev/ata/atapi-tape.h b/sys/dev/ata/atapi-tape.h
index fe0ecfa..cbc7461 100644
--- a/sys/dev/ata/atapi-tape.h
+++ b/sys/dev/ata/atapi-tape.h
@@ -1,3 +1,32 @@
+/*-
+ * Copyright (c) 1998,1999 Søren Schmidt
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $Id: atapi-tape.h,v 1.1 1999/03/01 21:19:18 sos Exp $
+ */
/* ATAPI tape commands not in std ATAPI command set */
#define ATAPI_TAPE_REWIND 0x01
@@ -18,95 +47,89 @@
#define DSC_POLL_INTERVAL 10
-/*
- * MODE SENSE parameter header
- */
+/* MODE SENSE parameter header */
struct ast_header {
- u_int8_t data_length; /* Total length of data */
- u_int8_t medium_type; /* Medium type (if any) */
- u_int8_t dsp; /* Device specific parameter */
- u_int8_t bdl; /* Block Descriptor Length */
+ u_int8_t data_length; /* total length of data */
+ u_int8_t medium_type; /* medium type (if any) */
+ u_int8_t dsp; /* device specific parameter */
+ u_int8_t bdl; /* block Descriptor Length */
};
-/*
- * ATAPI tape drive Capabilities and Mechanical Status Page
- */
+/* ATAPI tape drive Capabilities and Mechanical Status Page */
#define ATAPI_TAPE_CAP_PAGE 0x2a
struct ast_cappage {
- u_int8_t page_code :6; /* Page code == 0x2a */
+ u_int8_t page_code :6; /* page code == 0x2a */
u_int8_t reserved1_67 :2;
- u_int8_t page_length; /* Page Length == 0x12 */
+ u_int8_t page_length; /* page Length == 0x12 */
u_int8_t reserved2;
u_int8_t reserved3;
- u_int8_t readonly :1; /* Read Only Mode */
+ u_int8_t readonly :1; /* read Only Mode */
u_int8_t reserved4_1234 :4;
- u_int8_t reverse :1; /* Supports reverse direction */
+ u_int8_t reverse :1; /* supports reverse direction */
u_int8_t reserved4_67 :2;
u_int8_t reserved5_012 :3;
- u_int8_t eformat :1; /* Supports ERASE formatting */
+ u_int8_t eformat :1; /* supports ERASE formatting */
u_int8_t reserved5_4 :1;
- u_int8_t qfa :1; /* Supports QFA formats */
+ u_int8_t qfa :1; /* supports QFA formats */
u_int8_t reserved5_67 :2;
- u_int8_t lock :1; /* Supports locking media */
- u_int8_t locked :1; /* The media is locked */
- u_int8_t prevent :1; /* Defaults to prevent state */
- u_int8_t eject :1; /* Supports eject */
- u_int8_t disconnect :1; /* Can break request > ctl */
+ u_int8_t lock :1; /* supports locking media */
+ u_int8_t locked :1; /* the media is locked */
+ u_int8_t prevent :1; /* defaults to prevent state */
+ u_int8_t eject :1; /* supports eject */
+ u_int8_t disconnect :1; /* can break request > ctl */
u_int8_t reserved6_5 :1;
- u_int8_t ecc :1; /* Supports error correction */
- u_int8_t compress :1; /* Supports data compression */
+ u_int8_t ecc :1; /* supports error correction */
+ u_int8_t compress :1; /* supports data compression */
u_int8_t reserved7_0 :1;
- u_int8_t blk512 :1; /* Supports 512b block size */
- u_int8_t blk1024 :1; /* Supports 1024b block size */
+ u_int8_t blk512 :1; /* supports 512b block size */
+ u_int8_t blk1024 :1; /* supports 1024b block size */
u_int8_t reserved7_3456 :4;
- u_int8_t slowb :1; /* Restricts byte count */
- u_int16_t max_speed; /* Supported speed in KBps */
- u_int16_t max_defects; /* Max stored defect entries */
- u_int16_t ctl; /* Continuous Transfer Limit */
- u_int16_t speed; /* Current Speed, in KBps */
- u_int16_t buffer_size; /* Buffer Size, in 512 bytes */
+ u_int8_t slowb :1; /* restricts byte count */
+ u_int16_t max_speed; /* supported speed in KBps */
+ u_int16_t max_defects; /* max stored defect entries */
+ u_int16_t ctl; /* continuous transfer limit */
+ u_int16_t speed; /* current Speed, in KBps */
+ u_int16_t buffer_size; /* buffer Size, in 512 bytes */
u_int8_t reserved18;
u_int8_t reserved19;
};
-/*
- * REQUEST SENSE structure
- */
+/* REQUEST SENSE structure */
struct ast_reqsense {
- u_int8_t error_code :7; /* Current or deferred errors */
- u_int8_t valid :1; /* Follows QIC-157C */
- u_int8_t reserved1; /* Segment Number - Reserved */
- u_int8_t sense_key :4; /* Sense Key */
- u_int8_t reserved2_4 :1; /* Reserved */
- u_int8_t ili :1; /* Incorrect Length Indicator */
- u_int8_t eom :1; /* End Of Medium */
- u_int8_t filemark :1; /* Filemark */
- u_int8_t info __attribute__((packed)); /* Cmd specific info */
- u_int8_t asl; /* Additional sense length (n-7) */
- u_int8_t command_specific; /* Additional cmd specific info */
- u_int8_t asc; /* Additional Sense Code */
- u_int8_t ascq; /* Additional Sense Code Qualifier */
- u_int8_t replaceable_unit_code; /* Field Replaceable Unit Code */
- u_int8_t sk_specific1 :7; /* Sense Key Specific */
- u_int8_t sksv :1; /* Sense Key Specific info valid */
- u_int8_t sk_specific2; /* Sense Key Specific */
- u_int8_t sk_specific3; /* Sense Key Specific */
- u_int8_t pad[2]; /* Padding */
+ u_int8_t error_code :7; /* current or deferred errors */
+ u_int8_t valid :1; /* follows QIC-157C */
+ u_int8_t reserved1; /* Segment number - reserved */
+ u_int8_t sense_key :4; /* sense key */
+ u_int8_t reserved2_4 :1; /* reserved */
+ u_int8_t ili :1; /* incorrect length indicator */
+ u_int8_t eom :1; /* end of medium */
+ u_int8_t filemark :1; /* filemark */
+ u_int8_t info __attribute__((packed)); /* cmd specific info */
+ u_int8_t asl; /* additional sense length (n-7) */
+ u_int8_t command_specific; /* additional cmd specific info */
+ u_int8_t asc; /* additional sense code */
+ u_int8_t ascq; /* additional sense code qualifier */
+ u_int8_t replaceable_unit_code; /* field replaceable unit code */
+ u_int8_t sk_specific1 :7; /* sense key specific */
+ u_int8_t sksv :1; /* sense key specific info valid */
+ u_int8_t sk_specific2; /* sense key specific */
+ u_int8_t sk_specific3; /* sense key Specific */
+ u_int8_t pad[2]; /* padding */
};
struct ast_softc {
- struct atapi_softc *atp; /* Controller structure */
- int32_t lun; /* Logical device unit */
- int32_t flags; /* Device state flags */
- int32_t blksize; /* Block size (512 | 1024) */
- struct buf_queue_head buf_queue; /* Queue of i/o requests */
- struct atapi_params *param; /* Drive parameters table */
+ struct atapi_softc *atp; /* controller structure */
+ int32_t lun; /* logical device unit */
+ int32_t flags; /* device state flags */
+ int32_t blksize; /* block size (512 | 1024) */
+ struct buf_queue_head buf_queue; /* queue of i/o requests */
+ struct atapi_params *param; /* drive parameters table */
struct ast_header header; /* MODE SENSE param header */
- struct ast_cappage cap; /* Capabilities page info */
+ struct ast_cappage cap; /* capabilities page info */
struct devstat stats; /* devstat entry */
#ifdef DEVFS
- void *cdevs;
- void *bdevs;
+ void *cdevs_token;
+ void *bdevs_token;
#endif
};
OpenPOWER on IntegriCloud