From 775986fc096566bfec0d39772bfa80e397fc500a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Schmidt?= Date: Sat, 10 Apr 1999 18:53:35 +0000 Subject: [PATCH] Sixth update to the new ATA/ATAPI driver: Fixed problems: Promise controllers was not always set up correctly. Parantheses are a good thing, fixed. Some older CDROM's could hang the probe. Proberly wait for the drive to catch its breath after IDENTIFY. Some CD writers fails because they dont support rezero. Rearranged the code to not use rezero. Warnings now that we use EGCS. Fixed. --- sys/dev/ata/ata-all.c | 29 ++++++++++++++++++----------- sys/dev/ata/ata-disk.c | 19 ++++++++----------- sys/dev/ata/ata-dma.c | 9 +++------ sys/dev/ata/atapi-all.c | 20 +++++++++++++------- sys/dev/ata/atapi-cd.c | 34 ++++++++-------------------------- sys/dev/ata/atapi-fd.c | 4 ++-- sys/dev/ata/atapi-tape.c | 5 +++-- 7 files changed, 55 insertions(+), 65 deletions(-) diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 5257487598e..680c3349538 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.4 1999/03/07 21:49:14 sos Exp $ + * $Id: ata-all.c,v 1.5 1999/03/28 18:57:18 sos Exp $ */ #include "ata.h" @@ -74,7 +74,7 @@ static void promise_intr(int32_t); static int32_t ata_probe(int32_t, int32_t, int32_t, pcici_t, int32_t *); static void ataintr(int32_t); -static int32_t atanlun = 0, sysctrl = 0; +static int32_t atanlun = 0; struct ata_softc *atadevices[MAXATA]; struct isa_driver atadriver = { ata_isaprobe, ata_isaattach, "ata" }; @@ -151,7 +151,7 @@ ata_pciattach(pcici_t tag, int32_t unit) { pcidi_t type, class, cmd; int32_t iobase_1, iobase_2, altiobase_1, altiobase_2; - int32_t bmaddr_1 = 0, bmaddr_2 = 0, irq1, irq2; + int32_t bmaddr_1 = 0, bmaddr_2 = 0, sysctrl = 0, irq1, irq2; int32_t lun; /* set up vendor-specific stuff */ @@ -163,7 +163,7 @@ ata_pciattach(pcici_t tag, int32_t unit) printf("ata%d: type=%08x class=%08x cmd=%08x\n", unit, type, class, cmd); #endif - /* if this is at Promise controller handle it specially */ + /* if this is a Promise controller handle it specially */ if (type == 0x4d33105a) { iobase_1 = pci_conf_read(tag, 0x10) & 0xfffc; altiobase_1 = pci_conf_read(tag, 0x14) & 0xfffc; @@ -173,6 +173,7 @@ ata_pciattach(pcici_t tag, int32_t unit) bmaddr_1 = pci_conf_read(tag, 0x20) & 0xfffc; bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1; sysctrl = (pci_conf_read(tag, 0x20) & 0xfffc) + 0x1c; + outb(bmaddr_1 + 0x1f, inb(bmaddr_1 + 0x1f) | 0x01); printf("ata-pci%d: Busmastering DMA supported\n", unit); } /* everybody else seems to do it this way */ @@ -250,15 +251,19 @@ ata_pciattach(pcici_t tag, int32_t unit) static void promise_intr(int32_t unit) { - if (inl(sysctrl) & 0x00000400) + struct ata_softc *scp = atadevices[unit]; + int32_t channel = inl((pci_conf_read(scp->tag, 0x20) & 0xfffc) + 0x1c); + + if (channel & 0x00000400) ataintr(unit); - if (inl(sysctrl) & 0x00004000) + + if (channel & 0x00004000) ataintr(unit+1); } #endif static int32_t -ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr, +ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr, pcici_t tag, int32_t *unit) { struct ata_softc *scp = atadevices[atanlun]; @@ -422,7 +427,8 @@ ataintr(int32_t unit) struct ata_softc *scp; struct atapi_request *atapi_request; struct buf *ata_request; - static int32_t intcount = 0; + u_int8_t status; + static int32_t intr_count = 0; if (unit < 0 || unit > atanlun) { printf("ataintr: unit %d unusable\n", unit); @@ -455,9 +461,10 @@ ataintr(int32_t unit) default: case ATA_IDLE: - if (intcount++ < 10) - printf("ata%d: unwanted interrupt %d\n", unit, intcount); - inb(scp->ioaddr + ATA_STATUS); + status = inb(scp->ioaddr + ATA_STATUS); + if (intr_count++ < 10) + printf("ata%d: unwanted interrupt %d status = %02x\n", + unit, 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 893b8b96631..c5f7a418041 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.4 1999/03/07 21:49:14 sos Exp $ + * $Id: ata-disk.c,v 1.5 1999/03/28 18:57:18 sos Exp $ */ #include "ata.h" @@ -370,12 +370,14 @@ printf("adstrategy: entered\n"); || bp->b_bcount % DEV_BSIZE != 0) { bp->b_error = EINVAL; bp->b_flags |= B_ERROR; - goto done; + biodone(bp); + return; } - if (dscheck(bp, adp->slices) <= 0) - goto done; - + if (dscheck(bp, adp->slices) <= 0) { + biodone(bp); + return; + } /* hang around if somebody else is labelling */ if (adp->flags & AD_F_LABELLING) @@ -392,11 +394,6 @@ printf("adstrategy: entered\n"); splx(s); return; - -done: - s = splbio(); - biodone(bp); - splx(s); } static int @@ -665,7 +662,7 @@ ad_version(u_int16_t version) static void ad_drvinit(void) { - static ad_devsw_installed = 0; + static int32_t ad_devsw_installed = 0; if (!ad_devsw_installed) { cdevsw_add_generic(BDEV_MAJOR, CDEV_MAJOR, &ad_cdevsw); diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c index 2bf6c99c074..fe0a08c5644 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.2 1999/03/29 14:24:42 sos Exp $ + * $Id: ata-dma.c,v 1.3 1999/03/30 13:09:47 sos Exp $ */ #include "ata.h" @@ -88,7 +88,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, break; } printf("OK\n"); - devno = (scp->unit << 1) + (device) ? 1 : 0; + devno = (scp->unit << 1) + (device ? 1 : 0); mask48 = (1 << devno) + (3 << (16 + (devno << 2))); new48 = (1 << devno) + (2 << (16 + (devno << 2))); pci_conf_write(scp->tag, 0x48, @@ -156,7 +156,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device, break; case 0x4d33105a: /* Promise Ultra/33 / FastTrack controllers */ - devno = (scp->unit << 1) + (device) ? 1 : 0; + devno = (scp->unit << 1) + (device ? 1 : 0); if (udmamode >=2) { printf("ata%d: %s: settting up UDMA2 mode on Promise chip ", scp->lun, (device) ? "slave" : "master"); @@ -167,7 +167,6 @@ ata_dmainit(struct ata_softc *scp, int32_t device, break; } printf("OK\n"); - outb(scp->bmaddr + 0x1f, inb(scp->bmaddr + 0x1f) | 0x01); pci_conf_write(scp->tag, 0x60 + (devno << 2), 0x004127f3); return 0; } @@ -181,7 +180,6 @@ ata_dmainit(struct ata_softc *scp, int32_t device, break; } printf("OK\n"); - outb(scp->bmaddr + 0x1f, inb(scp->bmaddr + 0x1f) | 0x01); pci_conf_write(scp->tag, 0x60 + (devno << 2), 0x004367f3); return 0; } @@ -365,4 +363,3 @@ ata_dmastatus(struct ata_softc *scp, int32_t device) #endif /* NPCI > 0 */ #endif /* NATA > 0 */ - diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index d230b691e1b..63224756ab0 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.4 1999/03/07 21:49:14 sos Exp $ + * $Id: atapi-all.c,v 1.5 1999/03/28 18:57:19 sos Exp $ */ #include "ata.h" @@ -145,6 +145,8 @@ atapi_getparam(struct atapi_softc *atp) return -1; insw(atp->controller->ioaddr + ATA_DATA, buffer, sizeof(buffer)/sizeof(int16_t)); + if (atapi_wait(atp, 0)) + return -1; if (!(atapi_parm = malloc(sizeof(struct atapi_params), M_DEVBUF, M_NOWAIT))) return -1; bcopy(buffer, atapi_parm, sizeof(struct atapi_params)); @@ -183,17 +185,21 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data, request->ccbsize = (atp->atapi_parm->cmdsize) ? 16 : 12; bcopy(ccb, request->ccb, request->ccbsize); - /* link onto controller queue */ s = splbio(); + + /* link onto controller queue */ TAILQ_INSERT_TAIL(&atp->controller->atapi_queue, request, chain); - splx(s); -#ifdef ATAPI_DEBUG - printf("atapi: queued %s cmd\n", atapi_cmd2str(ccb[0])); -#endif /* try to start controller */ if (atp->controller->active == ATA_IDLE) ata_start(atp->controller); + + splx(s); + +#ifdef ATAPI_DEBUG + printf("atapi: queued %s cmd\n", atapi_cmd2str(ccb[0])); +#endif + if (!callback) { /* wait for command to complete */ if (tsleep((caddr_t)request, PRIBIO, "atprq", 0/*timeout*/)) @@ -464,7 +470,7 @@ atapi_wait(struct atapi_softc *atp, u_int8_t mask) DELAY(1); status = inb(atp->controller->ioaddr + ATA_STATUS); } - if (!(status & ATA_S_BSY)) + if (!(status & ATA_S_BSY) && (status & ATA_S_DRDY)) break; DELAY (10); } diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 11c9c368f5a..ad712e7b5c3 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.3 1999/03/05 09:43:30 sos Exp $ + * $Id: atapi-cd.c,v 1.4 1999/03/28 18:57:19 sos Exp $ */ #include "ata.h" @@ -100,7 +100,6 @@ static void acd_describe(struct acd_softc *); static int32_t acd_setchan(struct acd_softc *, u_int8_t, u_int8_t, u_int8_t, u_int8_t); static int32_t acd_eject(struct acd_softc *, int); static void acd_select_slot(struct acd_softc *); -static int32_t acd_rezero_unit(struct acd_softc *); static int32_t acd_open_disk(struct acd_softc *, int); static int32_t acd_open_track(struct acd_softc *, struct wormio_prepare_track *); static int32_t acd_close_track(struct acd_softc *); @@ -417,19 +416,12 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) else cdp->refcnt++; - if ((flags & O_NONBLOCK) == 0) { - if ((flags & FWRITE) != 0) { - /* read/write */ - if (acd_rezero_unit(cdp)) { - printf("acd%d: rezero failed\n", lun); - return EIO; - } - } else { - /* read only */ - if (acd_read_toc(cdp) != 0) { + if (!(flags & O_NONBLOCK)) { + if (acd_read_toc(cdp)) { + if (!(flags & FWRITE)) { printf("acd%d: read_toc failed\n", lun); - /* return EIO; */ - } + return EIO; + } } } return 0; @@ -747,7 +739,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) else return EINVAL; #ifndef CD_BUFFER_BLOCKS -#define CD_BUFFER_BLOCKS 8 +#define CD_BUFFER_BLOCKS 13 #endif if (!(buffer = malloc(CD_BUFFER_BLOCKS * 2352, M_TEMP,M_NOWAIT))) @@ -1292,16 +1284,6 @@ acd_select_slot(struct acd_softc *cdp) acd_lock_device(cdp, 1); } -static int32_t -acd_rezero_unit(struct acd_softc *cdp) -{ - int8_t ccb[16]; - - bzero(ccb, sizeof(ccb)); - ccb[0] = ATAPI_REZERO_UNIT; - return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL); -} - static int32_t acd_open_disk(struct acd_softc *cdp, int32_t test) { @@ -1441,7 +1423,7 @@ acd_blank_disk(struct acd_softc *cdp) static void acd_drvinit(void *unused) { - static acd_devsw_installed = 0; + static int32_t acd_devsw_installed = 0; if (!acd_devsw_installed) { cdevsw_add_generic(BDEV_MAJOR, CDEV_MAJOR, &acd_cdevsw); diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c index 1aa3f0fb3e4..8d5469b866e 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.3 1999/03/07 21:49:14 sos Exp $ + * $Id: atapi-fd.c,v 1.4 1999/03/28 18:57:19 sos Exp $ */ #include "ata.h" @@ -431,7 +431,7 @@ afd_eject(struct afd_softc *fdp, int32_t close) static void afd_drvinit(void *unused) { - static afd_devsw_installed = 0; + static int32_t afd_devsw_installed = 0; if (!afd_devsw_installed) { cdevsw_add_generic(BDEV_MAJOR, CDEV_MAJOR, &afd_cdevsw); diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index c4e6d1d9157..e2ecce1afb7 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.4 1999/03/07 21:49:14 sos Exp $ + * $Id: atapi-tape.c,v 1.5 1999/03/28 18:57:19 sos Exp $ */ #include "ata.h" @@ -441,6 +441,7 @@ ast_done(struct atapi_request *request) (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE); if (request->result) { + /* check for EOM and return ENOSPC */ atapi_error(request->device, request->result); bp->b_error = EIO; bp->b_flags |= B_ERROR; @@ -550,7 +551,7 @@ ast_rewind(struct ast_softc *stp) static void ast_drvinit(void *unused) { - static ast_devsw_installed = 0; + static int32_t ast_devsw_installed = 0; if (!ast_devsw_installed) { dev_t dev = makedev(CDEV_MAJOR, 0);