From owner-freebsd-current Mon Feb 23 13:44:08 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id NAA19079 for freebsd-current-outgoing; Mon, 23 Feb 1998 13:44:08 -0800 (PST) (envelope-from owner-freebsd-current@FreeBSD.ORG) Received: from thelab.hub.org (dyna2-156.acadiau.ca [131.162.2.156]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id NAA18706 for ; Mon, 23 Feb 1998 13:41:22 -0800 (PST) (envelope-from scrappy@hub.org) Received: from localhost (scrappy@localhost) by thelab.hub.org (8.8.8/8.8.2) with SMTP id RAA01389 for ; Mon, 23 Feb 1998 17:40:25 -0400 (AST) X-Authentication-Warning: thelab.hub.org: scrappy owned process doing -bs Date: Mon, 23 Feb 1998 17:40:25 -0400 (AST) From: The Hermit Hacker To: freebsd-current@FreeBSD.ORG Subject: ATAPI related patch .. Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG Hi... I recently grabbed a patch that Luigi (freebsd-multimedia) has that is required in order to read audio tracks (using something like tosha) from a CD...with minor modifications, I've got it in my -current kernel and haven't noticed any problems. I would like to commit the patch to the -current source tree, so am asking here if there are any objections to doing this. If I hear nothing by Wednesday (long enough?), I'll assume that it is okay and commit it... Patch included below... Thanks... Marc G. Fournier Systems Administrator @ hub.org primary: scrappy@hub.org secondary: scrappy@{freebsd|postgresql}.org *** isa/wcd.c Mon Feb 9 02:08:43 1998 --- isa.n/wcd.c Sun Feb 22 23:33:18 1998 *************** *** 346,351 **** --- 346,352 ---- struct atapires result; struct changer *chp; int i; + int loops = 0; if (wcdnlun >= NUNIT) { printf ("wcd: too many units\n"); *************** *** 369,385 **** } /* Get drive capabilities. */ result = atapi_request_immediate (ata, unit, ATAPI_MODE_SENSE, 0, CAP_PAGE, 0, 0, 0, 0, sizeof (cdp->cap) >> 8, sizeof (cdp->cap), 0, 0, 0, 0, 0, 0, 0, (char*) &cdp->cap, sizeof (cdp->cap)); ! /* Do it twice to avoid the stale media changed state. */ ! if (result.code == RES_ERR && ! (result.error & AER_SKEY) == AER_SK_UNIT_ATTENTION) ! result = atapi_request_immediate (ata, unit, ATAPI_MODE_SENSE, ! 0, CAP_PAGE, 0, 0, 0, 0, sizeof (cdp->cap) >> 8, ! sizeof (cdp->cap), 0, 0, 0, 0, 0, 0, 0, ! (char*) &cdp->cap, sizeof (cdp->cap)); /* Some drives have shorter capabilities page. */ if (result.code == RES_UNDERRUN) --- 370,384 ---- } /* Get drive capabilities. */ + for (loops = 0 ; loops < 10 ; loops++) { + /* some drives are slow to respond at boot time... */ result = atapi_request_immediate (ata, unit, ATAPI_MODE_SENSE, 0, CAP_PAGE, 0, 0, 0, 0, sizeof (cdp->cap) >> 8, sizeof (cdp->cap), 0, 0, 0, 0, 0, 0, 0, (char*) &cdp->cap, sizeof (cdp->cap)); ! if (result.code == 0 || result.code == RES_UNDERRUN) ! break; ! } /* Some drives have shorter capabilities page. */ if (result.code == RES_UNDERRUN) *************** *** 511,516 **** --- 510,544 ---- if (t->cap.prevent) printf (", lock protected"); printf ("\n"); + + printf ("wcd%d: ", t->lun); + if (t->cap.composite) + printf(" comp. A/V,"); + if (t->cap.dport1 || t->cap.dport2) + printf(" dig.audio %s%s,", + t->cap.dport1 ? "1 ":"", t->cap.dport2 ? "2":""); + if (t->cap.mode2_form1 || t->cap.mode2_form2) + printf(" mode 2 form %s%s,", + t->cap.mode2_form1 ? "1(XA) ":"", + t->cap.mode2_form2 ? "2":""); + if (t->cap.multisession) + printf(" multisession,"); + if (t->cap.cd_da || t->cap.cd_da_stream) + printf(" CD-DA %s%s,", + t->cap.cd_da ? "read ":"", + t->cap.cd_da_stream ? "stream":""); + if (t->cap.rw) + printf(" combined rw,"); + if (t->cap.rw_corr) + printf(" rw correct.,"); + if (t->cap.c2) + printf(" C2,"); + if (t->cap.isrc) + printf(" ISRC,"); + if (t->cap.upc) + printf(" UPC"); + printf("\n"); + } static int *************** *** 738,743 **** --- 766,827 ---- *f = lba % 75; } + #if 1 + #define CDIOCATAPIREQ _IOWR('c',100,struct atapireq) + + struct atapireq { + u_char cmd[16]; + caddr_t databuf; + int datalen; + struct atapires result; + }; + + static void arstrategy(struct buf *); + static void ar_done(struct wcd *, struct buf *, int, struct atapires); + + static void + arstrategy(struct buf *bp) + { + struct wcd *t = bp->b_driver1; + struct atapireq *ar = bp->b_driver2; + + if (t == NULL || ar == NULL) { + bp->b_error = EINVAL; + bp->b_flags |= B_ERROR; + biodone(bp); + return; + } + + /* Can't ever write to a CD. */ + if (!(bp->b_flags & B_READ)) { + bp->b_error = EROFS; + bp->b_flags |= B_ERROR; + biodone(bp); + return; + } + + atapi_request_callback(t->ata, t->unit, + ar->cmd[0], ar->cmd[1], ar->cmd[2], ar->cmd[3], + ar->cmd[4], ar->cmd[5], ar->cmd[6], ar->cmd[7], + ar->cmd[8], ar->cmd[9], ar->cmd[10], ar->cmd[11], + ar->cmd[12], ar->cmd[13], ar->cmd[14], ar->cmd[15], + (u_char*) bp->b_data, bp->b_bcount, ar_done, t, bp); + } + + static void + ar_done(struct wcd *t, struct buf *bp, int resid, struct atapires result) + { + struct atapireq *ar = bp->b_driver2; + + if (result.code) + wcd_error(t, result); + bp->b_resid = 0; + ar->datalen -= resid; + ar->result = result; + biodone(bp); + } + #endif + /* * Perform special action on behalf of the user. * Knows about the internals of this device *************** *** 834,839 **** --- 918,973 ---- return (EIO); bcopy (&t->toc.hdr, addr, sizeof t->toc.hdr); break; + + #ifdef CDIOCATAPIREQ + case CDIOCATAPIREQ: { + struct atapireq *ar, *oar = (struct atapireq *)addr; + struct buf *bp; + + MALLOC(ar, struct atapireq *, sizeof *ar, M_TEMP, M_WAITOK); + MALLOC(bp, struct buf *, sizeof *bp, M_TEMP, M_WAITOK); + + bcopy(oar, ar, sizeof *ar); + bzero(bp, sizeof *bp); + + bp->b_proc = p; + bp->b_dev = dev; + bp->b_driver1 = t; + bp->b_driver2 = ar; + + if (ar->datalen) { + struct uio auio; + struct iovec aiov; + + if (ar->datalen < 0) + return (EINVAL); + + aiov.iov_base = ar->databuf; + aiov.iov_len = ar->datalen; + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + + auio.uio_offset = 0; + auio.uio_resid = ar->datalen; + + auio.uio_rw = UIO_READ; /* CD is readonly */ + auio.uio_segflg = UIO_USERSPACE; + auio.uio_procp = p; + + bp->b_bcount = ar->datalen; + error = physio(arstrategy, bp, dev, 1, minphys, &auio); + } else { + bp->b_flags = B_READ | B_BUSY; + arstrategy(bp); + error = bp->b_error; + } + + bcopy(ar, oar, sizeof *ar); + FREE(ar, M_TEMP); + FREE(bp, M_TEMP); + break; + } + #endif case CDIOREADTOCENTRYS: { struct ioc_read_toc_entry *te = *** isa/atapi.c Mon Feb 9 02:08:24 1998 --- isa.n/atapi.c Sun Feb 22 22:44:16 1998 *************** *** 214,220 **** /* DRQ type */ switch (ap->drqtype) { ! case AT_DRQT_MPROC: ata->slow = 1; break; case AT_DRQT_INTR: printf (", intr"); ata->intrcmd = 1; break; case AT_DRQT_ACCEL: printf (", accel"); break; default: printf (", drq%d", ap->drqtype); --- 214,220 ---- /* DRQ type */ switch (ap->drqtype) { ! case AT_DRQT_MPROC: printf (", slow"); ata->slow = 1; break; case AT_DRQT_INTR: printf (", intr"); ata->intrcmd = 1; break; case AT_DRQT_ACCEL: printf (", accel"); break; default: printf (", drq%d", ap->drqtype); *************** *** 338,343 **** --- 338,344 ---- case 0x4b: return ("PAUSE"); case 0x48: return ("PLAY_TRACK"); case 0xa5: return ("PLAY_BIG"); + case 0xbe: return ("READ_CD"); /* XXX */ } sprintf (buf, "[0x%x]", cmd); return (buf); *************** *** 778,796 **** --- 779,841 ---- print (("atapi%d.%d: recv data overrun, %d bytes left\n", ata->ctrlr, ac->unit, ac->count)); ac->result.code = RES_OVERRUN; + if(ac->count != 0) insw (ata->port + AR_DATA, ac->addr, ac->count / sizeof(short)); for (i=ac->count; iport + AR_DATA); + len = ac->count; } else insw (ata->port + AR_DATA, ac->addr, len / sizeof(short)); ac->addr += len; ac->count -= len; + #if 1 + /* + * some drives appear not to assert BSY after a + * CDDA transfer, and then do not generate the intrq + * to complete the transfer. Among these: + * Sony CDU331, Goldstar GCD580 + * Obviate by testing BSY and going on anyways. + */ + for (i = 0 ; i < 2 ; i++) { + int j = inb (ata->port + AR_STATUS); + if ( (j & (ARS_DRQ | ARS_BSY)) == ARS_BSY ) + break; + } + if (i == 2 ) { + if (atapi_wait (ata->port, 0) < 0) { + ac->result.status = inb (ata->port + AR_STATUS); + ac->result.error = inb (ata->port + AR_ERROR); + ac->result.code = RES_NOTRDY; + printf ("atapi%d.%d: controller not ready, status=%b, error= %b\n", + ata->ctrlr, ac->unit, ac->result.status, ARS_BITS, + ac->result.error, AER_BITS); + return (0); + } + + ac->result.status = inb (ata->port + AR_STATUS); + ac->result.error = inb (ata->port + AR_ERROR); + len = inb (ata->port + AR_CNTLO); + len |= inb (ata->port + AR_CNTHI) << 8; + ireason = inb (ata->port + AR_IREASON); + + goto complete; + /* + * unfortunately, my Sony CDU-55E does assert BSY + * but then forgets to generate the intrq at times... + * Maybe I should check that len is a multiple of + * the CDDA size (2352) and return anyways if + * count == 0 ? + */ + } + #endif + return (1); case PHASE_ABORTED: case PHASE_COMPLETED: + complete: if (ac->result.status & (ARS_CHECK | ARS_DF)) ac->result.code = RES_ERR; else if (ac->count < 0) { To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message