summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>1999-05-17 15:58:47 +0000
committersos <sos@FreeBSD.org>1999-05-17 15:58:47 +0000
commit7ba9cdf25988ac144f8f7a77e123dcef4d984d1e (patch)
treede7d4539b76752f8ce813a6bf835a8089ad67526
parentbe12e9cff9420f50283ce88e2d205ec57996c3ef (diff)
downloadFreeBSD-src-7ba9cdf25988ac144f8f7a77e123dcef4d984d1e.zip
FreeBSD-src-7ba9cdf25988ac144f8f7a77e123dcef4d984d1e.tar.gz
Seventh update to the new ATA/ATAPI driver:
Fixed problems: LS120 drives currupted data. The workaround for drives not supporting upto 64K transfers has been reworked. It works now both on LS120 & ZIP drives. ISA only configs wont compile. Fixed. The ATA driver wont share interrupts. Fixed. The "unwanted interrupt" warning gave wrong controller. Another lun<>unit messup from the newbus integration. 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! -Søren
-rw-r--r--sys/dev/ata/ata-all.c34
-rw-r--r--sys/dev/ata/ata-disk.c7
-rw-r--r--sys/dev/ata/ata-dma.c20
-rw-r--r--sys/dev/ata/atapi-all.c5
-rw-r--r--sys/dev/ata/atapi-all.h3
-rw-r--r--sys/dev/ata/atapi-cd.c6
-rw-r--r--sys/dev/ata/atapi-fd.c16
-rw-r--r--sys/dev/ata/atapi-tape.c4
8 files changed, 53 insertions, 42 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 69b0cc9..647db7b 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.11 1999/04/22 08:07:44 sos Exp $
+ * $Id: ata-all.c,v 1.12 1999/05/08 21:58:58 dfr Exp $
*/
#include "ata.h"
@@ -54,8 +54,10 @@
#include <machine/smp.h>
#include <i386/isa/intr_machdep.h>
#endif
+#if NPCI > 0
#include <pci/pcivar.h>
#include <pci/pcireg.h>
+#endif
#include <isa/isavar.h>
#include <isa/isareg.h>
#include <dev/ata/ata-all.h>
@@ -223,7 +225,7 @@ ata_pciattach(device_t dev)
u_int8_t class, subclass;
u_int32_t cmd;
int32_t iobase_1, iobase_2, altiobase_1, altiobase_2;
- int32_t bmaddr_1 = 0, bmaddr_2 = 0, sysctrl = 0, irq1, irq2;
+ int32_t bmaddr_1 = 0, bmaddr_2 = 0, irq1, irq2;
int32_t lun;
/* set up vendor-specific stuff */
@@ -246,7 +248,6 @@ ata_pciattach(device_t dev)
irq1 = irq2 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff;
bmaddr_1 = pci_read_config(dev, 0x20, 4) & 0xfffc;
bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1;
- sysctrl = (pci_read_config(dev, 0x20, 4) & 0xfffc) + 0x1c;
outb(bmaddr_1 + 0x1f, inb(bmaddr_1 + 0x1f) | 0x01);
printf("ata-pci%d: Busmastering DMA supported\n", unit);
}
@@ -311,13 +312,15 @@ ata_pciattach(device_t dev)
int rid = 0;
void *ih;
- irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0,1,RF_ACTIVE);
- if (sysctrl)
- bus_setup_intr(dev, irq, INTR_TYPE_BIO,
- promise_intr, scp, &ih);
+ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (!irq)
+ printf("ata_pciattach: Unable to alloc interrupt\n");
+
+ if (type == 0x4d33105a)
+ bus_setup_intr(dev, irq, INTR_TYPE_BIO, promise_intr, scp, &ih);
else
- bus_setup_intr(dev, irq, INTR_TYPE_BIO,
- ataintr, scp, &ih);
+ bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr, scp, &ih);
}
printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
lun, iobase_1, isa_apic_irq(irq1), unit);
@@ -338,9 +341,14 @@ ata_pciattach(device_t dev)
int rid = 0;
void *ih;
- irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0,1,RF_ACTIVE);
- if (!sysctrl)
+ if (type != 0x4d33105a) {
+ irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (!irq)
+ printf("ata_pciattach: Unable to alloc interrupt\n");
+
bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr, scp, &ih);
+ }
}
printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
lun, iobase_2, isa_apic_irq(irq2), unit);
@@ -544,10 +552,8 @@ ataintr(void *data)
struct buf *ata_request;
u_int8_t status;
static int32_t intr_count = 0;
- int unit;
scp = (struct ata_softc *)data;
- unit = scp->unit;
/* find & call the responsible driver to process this interrupt */
switch (scp->active) {
@@ -576,7 +582,7 @@ ataintr(void *data)
status = inb(scp->ioaddr + ATA_STATUS);
if (intr_count++ < 10)
printf("ata%d: unwanted interrupt %d status = %02x\n",
- unit, intr_count, status);
+ scp->lun, intr_count, status);
return;
}
scp->active = ATA_IDLE;
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 86b4ff4..0f00d1c 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.9 1999/05/07 16:37:06 peter Exp $
+ * $Id: ata-disk.c,v 1.10 1999/05/11 19:53:58 phk Exp $
*/
#include "ata.h"
@@ -51,9 +51,6 @@
#include <sys/devfsext.h>
#endif
#include <machine/clock.h>
-#include <pci/pcivar.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
#include <dev/ata/ata-all.h>
#include <dev/ata/ata-disk.h>
@@ -608,7 +605,7 @@ oops:
bufq_remove(&adp->controller->ata_queue, bp);
bp->b_resid = bp->b_bcount - adp->donecount;
biodone(bp);
- devstat_end_transaction(&adp->stats, bp->b_bcount - bp->b_resid,
+ devstat_end_transaction(&adp->stats, adp->donecount,
DEVSTAT_TAG_NONE,
(bp->b_flags & B_READ) ?
DEVSTAT_READ : DEVSTAT_WRITE);
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 0873033..0f5a539 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.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-dma.c,v 1.5 1999/04/16 21:21:53 peter Exp $
+ * $Id: ata-dma.c,v 1.6 1999/04/18 20:48:15 sos Exp $
*/
#include "ata.h"
@@ -39,8 +39,10 @@
#include <sys/bus.h>
#include <vm/vm.h>
#include <vm/pmap.h>
+#if NPCI > 0
#include <pci/pcivar.h>
#include <pci/pcireg.h>
+#endif
#include <dev/ata/ata-all.h>
#ifdef __alpha__
@@ -86,7 +88,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (udmamode >= 2) {
int32_t mask48, new48;
- printf("ata%d: %s: settting up UDMA2 mode on PIIX4 chip ",
+ printf("ata%d: %s: setting up UDMA2 mode on PIIX4 chip ",
scp->lun, (device) ? "slave" : "master");
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR);
@@ -125,7 +127,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
pci_write_config(scp->dev, 0x40, new40, 4);
pci_write_config(scp->dev, 0x44, new44, 4);
}
- printf("ata%d: %s: settting up WDMA2 mode on PIIX3/4 chip ",
+ printf("ata%d: %s: setting up WDMA2 mode on PIIX3/4 chip ",
scp->lun, (device) ? "slave" : "master");
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR);
@@ -168,7 +170,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
case 0x4d33105a: /* Promise Ultra/33 / FastTrack controllers */
devno = (scp->unit << 1) + (device ? 1 : 0);
if (udmamode >=2) {
- printf("ata%d: %s: settting up UDMA2 mode on Promise chip ",
+ printf("ata%d: %s: setting up UDMA2 mode on Promise chip ",
scp->lun, (device) ? "slave" : "master");
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR);
@@ -181,7 +183,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
return 0;
}
else if (wdmamode >= 2 && apiomode >= 4) {
- printf("ata%d: %s: settting up WDMA2 mode on Promise chip ",
+ printf("ata%d: %s: setting up WDMA2 mode on Promise chip ",
scp->lun, (device) ? "slave" : "master");
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR);
@@ -194,7 +196,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
return 0;
}
else {
- printf("ata%d: %s: settting up PIO mode on Promise chip OK\n",
+ printf("ata%d: %s: setting up PIO mode on Promise chip OK\n",
scp->lun, (device) ? "slave" : "master");
pci_write_config(scp->dev, 0x60 + (devno << 2), 0x004fe924, 4);
}
@@ -204,7 +206,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (udmamode >=2) {
int32_t word54 = pci_read_config(scp->dev, 0x54, 4);
- printf("ata%d: %s: settting up UDMA2 mode on Aladdin chip ",
+ printf("ata%d: %s: setting up UDMA2 mode on Aladdin chip ",
scp->lun, (device) ? "slave" : "master");
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR);
@@ -220,7 +222,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
}
else if (wdmamode >= 2 && apiomode >= 4) {
- printf("ata%d: %s: settting up WDMA2 mode on Aladdin chip ",
+ printf("ata%d: %s: setting up WDMA2 mode on Aladdin chip ",
scp->lun, (device) ? "slave" : "master");
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR);
@@ -235,7 +237,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
default: /* well, we have no support for this, but try anyways */
if ((wdmamode >= 2 && apiomode >= 4) || udmamode >= 2) {
- printf("ata%d: %s: settting up generic WDMA2 mode ",
+ printf("ata%d: %s: setting up generic WDMA2 mode ",
scp->lun, (device) ? "slave" : "master");
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_WDMA2, ATA_C_FEA_SETXFER, ATA_WAIT_INTR);
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index 3b48966..2189921 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.6 1999/04/10 18:53:35 sos Exp $
+ * $Id: atapi-all.c,v 1.7 1999/04/16 21:21:53 peter Exp $
*/
#include "ata.h"
@@ -176,6 +176,7 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data,
request->device = atp;
request->data = data;
request->bytecount = count;
+ request->donecount = 0;
request->flags = flags;
if (callback) {
request->callback = callback;
@@ -319,6 +320,7 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
(void *)((uintptr_t)request->data), length / sizeof(int16_t));
}
request->bytecount -= length;
+ request->donecount += length;
request->data += length;
return ATA_OP_CONTINUES;
@@ -340,6 +342,7 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
(void *)((uintptr_t)request->data), length / sizeof(int16_t));
}
request->bytecount -= length;
+ request->donecount += length;
request->data += length;
return ATA_OP_CONTINUES;
diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h
index f8337a7..917c2eb 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.3 1999/03/07 21:49:14 sos Exp $
+ * $Id: atapi-all.h,v 1.4 1999/03/28 18:57:19 sos Exp $
*/
/* ATAPI misc defines */
@@ -227,6 +227,7 @@ struct atapi_request {
#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 */
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index 4bdfc21..d779c5e 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.6 1999/04/27 11:13:54 phk Exp $
+ * $Id: atapi-cd.c,v 1.7 1999/05/07 07:03:13 phk Exp $
*/
#include "ata.h"
@@ -1008,7 +1008,7 @@ acd_start(struct acd_softc *cdp)
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);
+ (bp->b_flags&B_READ)?A_READ : 0, acd_done, cdp, bp);
}
static void
@@ -1017,7 +1017,7 @@ 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_end_transaction(cdp->stats, request->donecount,
DEVSTAT_TAG_NONE,
(bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE);
if (request->result) {
diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c
index 41f92cf..d84a033 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.5 1999/04/10 18:53:35 sos Exp $
+ * $Id: atapi-fd.c,v 1.6 1999/05/07 07:03:14 phk Exp $
*/
#include "ata.h"
@@ -306,7 +306,7 @@ afd_start(struct afd_softc *fdp)
if (!bp)
return;
- bzero(ccb, sizeof(ccb));
+
bufq_remove(&fdp->buf_queue, bp);
/* Should reject all queued entries if media have changed. */
@@ -320,9 +320,12 @@ 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;
- if (count > 64) /* only needed for ZIP drives SOS */
+ /* Should only be needed for ZIP drives, but better safe than sorry */
+ if (count > 64)
count = 64;
+ bzero(ccb, sizeof(ccb));
+
if (bp->b_flags & B_READ)
ccb[0] = ATAPI_READ_BIG;
else
@@ -338,7 +341,7 @@ afd_start(struct afd_softc *fdp)
devstat_start_transaction(&fdp->stats);
- atapi_queue_cmd(fdp->atp, ccb, bp->b_data, count*fdp->cap.sector_size,
+ 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);
}
@@ -348,18 +351,17 @@ 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_end_transaction(&fdp->stats, request->donecount,
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;
+ bp->b_resid = bp->b_bcount - request->donecount;
biodone(bp);
afd_start(fdp);
}
diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c
index a436224..43edafa 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.6 1999/04/10 18:53:35 sos Exp $
+ * $Id: atapi-tape.c,v 1.7 1999/05/07 07:03:15 phk Exp $
*/
#include "ata.h"
@@ -422,7 +422,7 @@ 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_end_transaction(&stp->stats, request->donecount,
DEVSTAT_TAG_NONE,
(bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE);
OpenPOWER on IntegriCloud