summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>1999-05-20 09:12:06 +0000
committersos <sos@FreeBSD.org>1999-05-20 09:12:06 +0000
commit6997b3715ff83b7e8157c9771617c5dfefdcd4fb (patch)
treee4e3a29756b79128903b03b3396a7c102fa4c1b4 /sys/dev/ata
parent7f4b070df424fc1ca8cea977dddb9b23742246c2 (diff)
downloadFreeBSD-src-6997b3715ff83b7e8157c9771617c5dfefdcd4fb.zip
FreeBSD-src-6997b3715ff83b7e8157c9771617c5dfefdcd4fb.tar.gz
Eigth update to the new ATA/ATAPI driver:
Fixed problems: LS120/ZIP drives still currupted data. Reworked once again, buffered I/O is just ignoring any sizehints it is given :( Now the atapifd driver splits up requests for devices that has limitted transfer size. ISA only configs fails on boot with interrupt timeouts. The new-bus integration introduced a bug where the softc ptr was lost during the probe. Some minor cleanups and rearrangements as well. As usual USE AT YOUR OWN RISK!!, this is still pre alpha level code. Especially the DMA support can hose your disk real bad if anything goes wrong, again you have been warned :) Notebook owners should be carefull that their machines dont suspend as this might cause trouble... But please tell me how it works for you! Enjoy!
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-all.c15
-rw-r--r--sys/dev/ata/ata-disk.h4
-rw-r--r--sys/dev/ata/atapi-all.c15
-rw-r--r--sys/dev/ata/atapi-all.h8
-rw-r--r--sys/dev/ata/atapi-fd.c84
-rw-r--r--sys/dev/ata/atapi-fd.h14
6 files changed, 99 insertions, 41 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 647db7b..05f2812 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.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-all.c,v 1.12 1999/05/08 21:58:58 dfr Exp $
+ * $Id: ata-all.c,v 1.13 1999/05/17 15:58:44 sos Exp $
*/
#include "ata.h"
@@ -92,12 +92,13 @@ ata_isaprobe(device_t dev)
int32_t ctlr, res;
int32_t lun;
- /* Allocate the port range */
+ /* allocate the port range */
rid = 0;
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
if (!port)
return (ENOMEM);
+ /* check if allready in use by a PCI device */
for (ctlr = 0; ctlr < atanlun; ctlr++) {
if (atadevices[ctlr]->ioaddr == rman_get_start(port)) {
printf("ata-isa%d: already registered as ata%d\n",
@@ -115,6 +116,7 @@ ata_isaprobe(device_t dev)
if (res) {
isa_set_portsize(dev, res);
+ *(int *)device_get_softc(dev) = lun;
return 0;
}
@@ -124,7 +126,6 @@ ata_isaprobe(device_t dev)
static int
ata_isaattach(device_t dev)
{
- struct ata_softc *scp;
struct resource *port;
struct resource *irq;
void *ih;
@@ -142,8 +143,8 @@ ata_isaattach(device_t dev)
bus_release_resource(dev, SYS_RES_IOPORT, 0, port);
return (ENOMEM);
}
- scp = device_get_softc(dev);
- return bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr, scp, &ih);
+ return bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr,
+ atadevices[*(int *)device_get_softc(dev)], &ih);
}
static device_method_t ata_isa_methods[] = {
@@ -154,7 +155,7 @@ static device_method_t ata_isa_methods[] = {
};
static driver_t ata_isa_driver = {
- "ata-isa",
+ "ata",
ata_isa_methods,
sizeof(int),
};
@@ -666,7 +667,7 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
u_int32_t count, u_int32_t feature, int32_t flags)
{
#ifdef ATA_DEBUG
-printf("ata_command: addr=%04x, device=%02x, cmd=%02x, c=%d, h=%d, s=%d, count=%d, flags=%02x\n", scp->ioaddr, device, command, cylinder, head, sector, count, flags);
+printf("ata%d: ata_command: addr=%04x, device=%02x, cmd=%02x, c=%d, h=%d, s=%d, count=%d, flags=%02x\n", scp->lun, scp->ioaddr, device, command, cylinder, head, sector, count, flags);
#endif
/* ready to issue command ? */
diff --git a/sys/dev/ata/ata-disk.h b/sys/dev/ata/ata-disk.h
index 5056c78..bf5ba1f 100644
--- a/sys/dev/ata/ata-disk.h
+++ b/sys/dev/ata/ata-disk.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: ata-disk.h,v 1.4 1999/03/07 21:49:14 sos Exp $
+ * $Id: ata-disk.h,v 1.5 1999/03/28 18:57:18 sos Exp $
*/
/* ATA device parameter information */
@@ -131,7 +131,6 @@ struct ad_softc {
u_int32_t total_secs; /* total # of sectors (LBA) */
u_int32_t transfersize; /* size of each transfer */
u_int32_t currentsize; /* size of current transfer */
- struct buf_queue_head queue; /* head of request queue */
u_int32_t bytecount; /* bytes to transfer */
u_int32_t donecount; /* bytes transferred */
u_int32_t active; /* active processing request */
@@ -142,6 +141,7 @@ struct ad_softc {
#define AD_F_DMA_ENABLED 0x0008
#define AD_F_DMA_USED 0x0010
+ struct buf_queue_head queue; /* head of request queue */
struct devstat stats; /* devstat entry */
#ifdef DEVFS
void *cdevs_token;
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index 2189921..c0aa1b2 100644
--- a/sys/dev/ata/atapi-all.c
+++ b/sys/dev/ata/atapi-all.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-all.c,v 1.7 1999/04/16 21:21:53 peter Exp $
+ * $Id: atapi-all.c,v 1.8 1999/05/17 15:58:45 sos Exp $
*/
#include "ata.h"
@@ -220,7 +220,7 @@ atapi_transfer(struct atapi_request *request)
{
struct atapi_softc *atp;
int32_t timeout;
- int8_t reason; /* not needed really */
+ int8_t reason;
/* get device params */
atp = request->device;
@@ -310,8 +310,13 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
if (request->bytecount < length) {
printf("atapi_interrupt: write data underrun %d/%d\n",
length, request->bytecount);
+#if 0
outsw(atp->controller->ioaddr + ATA_DATA,
(void *)((uintptr_t)request->data), length / sizeof(int16_t));
+#else
+ outsl(atp->controller->ioaddr + ATA_DATA,
+ (void *)((uintptr_t)request->data), length / sizeof(int32_t));
+#endif
for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
outw(atp->controller->ioaddr + ATA_DATA, 0);
}
@@ -332,8 +337,13 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
if (request->bytecount < length) {
printf("atapi_interrupt: read data overrun %d/%d\n",
length, request->bytecount);
+#if 0
insw(atp->controller->ioaddr + ATA_DATA,
(void *)((uintptr_t)request->data), length / sizeof(int16_t));
+#else
+ insl(atp->controller->ioaddr + ATA_DATA,
+ (void *)((uintptr_t)request->data), length / sizeof(int32_t));
+#endif
for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
inw(atp->controller->ioaddr + ATA_DATA);
}
@@ -352,6 +362,7 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
if (atp->controller->status & (ATA_S_ERROR | ATA_S_DWF)) {
/* check sense !! SOS */
request->result = atp->controller->error;
+ break;
}
#ifdef ATAPI_DEBUG
if (request->bytecount > 0) {
diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h
index 917c2eb..6600eaf 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.4 1999/03/28 18:57:19 sos Exp $
+ * $Id: atapi-all.h,v 1.5 1999/05/17 15:58:45 sos Exp $
*/
/* ATAPI misc defines */
@@ -221,14 +221,14 @@ struct atapi_request {
void *driver; /* ptr to calling driver */
u_int8_t ccb[16]; /* command control block */
int32_t ccbsize; /* size of ccb (12 | 16) */
+ u_int32_t bytecount; /* bytes to transfer */
+ u_int32_t donecount; /* bytes transferred */
+ u_int32_t result; /* result code */
int32_t flags;
#define A_READ 0x0001
#define ATAPI_F_DMA_ENABLED 0x0002
#define ATAPI_F_DMA_USED 0x0004
- u_int32_t bytecount; /* bytes to transfer */
- u_int32_t donecount; /* bytes transferred */
- u_int32_t result; /* result code */
int8_t *data; /* pointer to data buf */
struct buf *bp; /* associated buf ptr */
atapi_callback_t *callback; /* ptr to callback func */
diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c
index d84a033..e6bad60 100644
--- a/sys/dev/ata/atapi-fd.c
+++ b/sys/dev/ata/atapi-fd.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-fd.c,v 1.6 1999/05/07 07:03:14 phk Exp $
+ * $Id: atapi-fd.c,v 1.7 1999/05/17 15:58:46 sos Exp $
*/
#include "ata.h"
@@ -86,6 +86,7 @@ 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_partial_done(struct atapi_request *);
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);
@@ -117,6 +118,9 @@ afdattach(struct atapi_softc *atp)
return -1;
}
+ if (!strncmp(atp->atapi_parm->model, "IOMEGA ZIP", 11))
+ fdp->transfersize = 64;
+
afd_describe(fdp);
afdtab[afdnlun++] = fdp;
devstat_add_entry(&fdp->stats, "afd", fdp->lun, DEV_BSIZE,
@@ -180,12 +184,24 @@ afd_describe(struct afd_softc *fdp)
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),
+ ((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);
+ printf("afd%d: Medium: ", fdp->lun);
switch (fdp->header.medium_type) {
+ case MFD_2DD:
+ printf("720KB DD disk"); break;
+
+ case MFD_HD_12:
+ printf("1.2MB HD disk"); break;
+
+ case MFD_HD_144:
+ printf("1.44MB HD disk"); break;
+
+ case MFD_UHD:
+ printf("120MB UHD disk"); break;
+
default: printf("Unknown media (0x%x)", fdp->header.medium_type);
}
if (fdp->header.wp) printf(", writeprotected");
@@ -303,6 +319,7 @@ afd_start(struct afd_softc *fdp)
struct buf *bp = bufq_first(&fdp->buf_queue);
u_int32_t lba, count;
int8_t ccb[16];
+ int8_t *data_ptr;
if (!bp)
return;
@@ -319,10 +336,8 @@ afd_start(struct afd_softc *fdp)
lba = bp->b_blkno / (fdp->cap.sector_size / DEV_BSIZE);
count = (bp->b_bcount + (fdp->cap.sector_size - 1)) / fdp->cap.sector_size;
-
- /* Should only be needed for ZIP drives, but better safe than sorry */
- if (count > 64)
- count = 64;
+ data_ptr = bp->b_data;
+ bp->b_resid = 0;
bzero(ccb, sizeof(ccb));
@@ -331,18 +346,48 @@ afd_start(struct afd_softc *fdp)
else
ccb[0] = ATAPI_WRITE_BIG;
- ccb[1] = 0;
- ccb[2] = lba>>24;
+ devstat_start_transaction(&fdp->stats);
+
+ while (fdp->transfersize && (count > fdp->transfersize)) {
+
+ ccb[2] = lba>>24;
+ ccb[3] = lba>>16;
+ ccb[4] = lba>>8;
+ ccb[5] = lba;
+ ccb[7] = fdp->transfersize>>8;
+ ccb[8] = fdp->transfersize;
+
+ atapi_queue_cmd(fdp->atp, ccb, data_ptr,
+ fdp->transfersize * fdp->cap.sector_size,
+ (bp->b_flags & B_READ) ? A_READ : 0,
+ afd_partial_done, fdp, bp);
+
+ count -= fdp->transfersize;
+ lba += fdp->transfersize;
+ data_ptr += fdp->transfersize * fdp->cap.sector_size;
+ }
+
+ ccb[2] = lba>>24;
ccb[3] = lba>>16;
ccb[4] = lba>>8;
- ccb[5] = lba;
+ ccb[5] = lba;
ccb[7] = count>>8;
ccb[8] = count;
- devstat_start_transaction(&fdp->stats);
+ atapi_queue_cmd(fdp->atp, ccb, data_ptr, count * fdp->cap.sector_size,
+ (bp->b_flags & B_READ) ? A_READ : 0, afd_done, fdp, bp);
+}
- atapi_queue_cmd(fdp->atp, ccb, bp->b_data, count * fdp->cap.sector_size,
- (bp->b_flags & B_READ) ? A_READ : 0, afd_done, fdp, bp);
+static void
+afd_partial_done(struct atapi_request *request)
+{
+ struct buf *bp = request->bp;
+
+ if (request->result) {
+ bp->b_error = EIO;
+ bp->b_flags |= B_ERROR;
+ }
+ bp->b_resid += request->bytecount;
}
static void
@@ -351,17 +396,18 @@ afd_done(struct atapi_request *request)
struct buf *bp = request->bp;
struct afd_softc *fdp = request->driver;
- devstat_end_transaction(&fdp->stats, request->donecount,
- DEVSTAT_TAG_NONE,
- (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE);
-
- if (request->result) {
+ if (request->result || (bp->b_flags & B_ERROR)) {
atapi_error(request->device, request->result);
bp->b_error = EIO;
bp->b_flags |= B_ERROR;
}
else
- bp->b_resid = bp->b_bcount - request->donecount;
+ bp->b_resid += request->bytecount;
+
+ devstat_end_transaction(&fdp->stats, bp->b_bcount - bp->b_resid,
+ DEVSTAT_TAG_NONE,
+ (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE);
+
biodone(bp);
afd_start(fdp);
}
diff --git a/sys/dev/ata/atapi-fd.h b/sys/dev/ata/atapi-fd.h
index 9904992..4d6a6d2 100644
--- a/sys/dev/ata/atapi-fd.h
+++ b/sys/dev/ata/atapi-fd.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$
+ * $Id: atapi-fd.h,v 1.1 1999/03/03 21:10:29 sos Exp $
*/
/* MODE SENSE parameter header */
@@ -34,11 +34,11 @@ struct afd_header {
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_HD_UN 0x20
+#define MFD_HD_12_98 0x22
+#define MFD_HD_12 0x23
+#define MFD_HD_144 0x24
+#define MFD_UHD 0x31
#define MFD_UNKNOWN 0x00
#define MFD_NO_DISC 0x70
@@ -76,7 +76,7 @@ struct afd_softc {
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 */
+ int32_t transfersize; /* max size of each transfer */
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 */
OpenPOWER on IntegriCloud