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
This commit is contained in:
Søren Schmidt 1999-05-17 15:58:47 +00:00
parent 6a0ce00218
commit b5bb732345
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=47272
8 changed files with 53 additions and 42 deletions

View File

@ -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;

View File

@ -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 @@ printf("extra SMP interrupt\n");
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);

View File

@ -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);

View File

@ -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;

View File

@ -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 */

View File

@ -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) {

View File

@ -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);
}

View File

@ -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);