From owner-freebsd-hackers Wed Sep 11 01:37:07 1996 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.7.5/8.7.3) id BAA21218 for hackers-outgoing; Wed, 11 Sep 1996 01:37:07 -0700 (PDT) Received: from abel.pdmi.ras.ru ([194.88.2.5]) by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id BAA21208 for ; Wed, 11 Sep 1996 01:37:00 -0700 (PDT) Received: (from pialkin@localhost) by abel.pdmi.ras.ru (8.7.5/8.7.3) id MAA00354 for hackers@freebsd.org; Wed, 11 Sep 1996 12:36:53 +0400 (MSD) From: Alexey Pialkin Message-Id: <199609110836.MAA00354@abel.pdmi.ras.ru> Subject: ATAPI patch To: hackers@freebsd.org Date: Wed, 11 Sep 1996 12:36:52 +0400 (MSD) X-Mailer: ELM [version 2.4 PL23] Content-Type: text Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Hi ! I made some small ATAPI patch for FreeBSD 2.1.5 - it solves my problems with Panasonic 572B & GoldStar GCD-R542 CDROM's. I hope it will help somone to. This patch trying to solve IMHO to very common problems with ATAPI cdrom's - unknown phase problem & to slow report on commands. (it's rather hack then patch - but it will help somebody as help me.... :) Any comments ? *** ./atapi.c Sat Sep 30 03:11:15 1995 --- /usr/src/sys/i386/isa/atapi.c Wed Sep 11 12:19:25 1996 *************** *** 130,135 **** --- 130,137 ---- #define PHASE_DATAOUT ARS_DRQ #define PHASE_COMPLETED (ARI_IN | ARI_CMD) #define PHASE_ABORTED 0 /* nonstandard - for NEC 260 */ + #define PHASE_COMPL ARI_IN + #define PHASE_COMPL2 ARI_CMD struct atapicmd { /* ATAPI command block */ struct atapicmd *next; /* next command in queue */ *************** *** 247,252 **** --- 249,255 ---- free (ap, M_TEMP); return; } + switch (ap->devtype) { default: /* unknown ATAPI device */ *************** *** 327,333 **** --- 330,338 ---- /* Issue ATAPI IDENTIFY command. */ outb (port + AR_DRIVE, unit ? ARD_DRIVE1 : ARD_DRIVE0); + DELAY(10); outb (port + AR_COMMAND, ATAPIC_IDENTIFY); + DELAY(10); /* Check that device is present. */ if (inb (port + AR_STATUS) == 0xff) { *************** *** 335,340 **** --- 340,346 ---- if (unit == 1) /* Select unit 0. */ outb (port + AR_DRIVE, ARD_DRIVE0); + DELAY(10); return (0); } *************** *** 345,353 **** --- 351,361 ---- if (unit == 1) /* Select unit 0. */ outb (port + AR_DRIVE, ARD_DRIVE0); + DELAY(10); return (0); } + DELAY(40); /* Obtain parameters. */ insw (port + AR_DATA, tb, sizeof(tb) / sizeof(short)); *************** *** 510,515 **** --- 518,524 ---- ac->result.status = 0; outb (ata->port + AR_DRIVE, ac->unit ? ARD_DRIVE1 : ARD_DRIVE0); + DELAY(10); if (atapi_wait (ata->port, 0) < 0) { printf ("atapi%d.%d: controller not ready for cmd\n", ata->ctrlr, ac->unit); *************** *** 519,530 **** /* Set up the controller registers. */ outb (ata->port + AR_FEATURES, 0); outb (ata->port + AR_IREASON, 0); outb (ata->port + AR_TAG, 0); outb (ata->port + AR_CNTLO, ac->count & 0xff); outb (ata->port + AR_CNTHI, ac->count >> 8); outb (ata->port + AR_COMMAND, ATAPIC_PACKET); ! if (ata->debug) printf ("atapi%d.%d: start\n", ata->ctrlr, ac->unit); return (0); --- 528,544 ---- /* Set up the controller registers. */ outb (ata->port + AR_FEATURES, 0); + DELAY(10); outb (ata->port + AR_IREASON, 0); + DELAY(10); outb (ata->port + AR_TAG, 0); + DELAY(10); outb (ata->port + AR_CNTLO, ac->count & 0xff); + DELAY(10); outb (ata->port + AR_CNTHI, ac->count >> 8); + DELAY(10); outb (ata->port + AR_COMMAND, ATAPIC_PACKET); ! DELAY(30); if (ata->debug) printf ("atapi%d.%d: start\n", ata->ctrlr, ac->unit); return (0); *************** *** 550,558 **** --- 564,574 ---- ac->result.error = inb (ata->port + AR_ERROR); return (-1); } + DELAY(40); return (0); } + /* * Send packet cmd. */ *************** *** 613,622 **** } 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); if (ata->debug) { printf ("atapi%d.%d: intr ireason=0x%x, len=%d, status=%b, error=%b\n", --- 629,642 ---- } ac->result.status = inb (ata->port + AR_STATUS); + DELAY(10); ac->result.error = inb (ata->port + AR_ERROR); + DELAY(70); + ireason = inb (ata->port + AR_IREASON); + DELAY(10); len = inb (ata->port + AR_CNTLO); + DELAY(10); len |= inb (ata->port + AR_CNTHI) << 8; if (ata->debug) { printf ("atapi%d.%d: intr ireason=0x%x, len=%d, status=%b, error=%b\n", *************** *** 687,706 **** ac->count -= len; return (1); case PHASE_ABORTED: case PHASE_COMPLETED: if (ac->result.status & (ARS_CHECK | ARS_DF)) ac->result.code = RES_ERR; ! else if (ac->count < 0) { ! print (("atapi%d.%d: send data overrun, %d bytes left\n", ! ata->ctrlr, ac->unit, -ac->count)); ! ac->result.code = RES_OVERRUN; ! } else if (ac->count > 0) { ! print (("atapi%d.%d: recv data underrun, %d bytes left\n", ! ata->ctrlr, ac->unit, ac->count)); ! ac->result.code = RES_UNDERRUN; ! bzero (ac->addr, ac->count); ! } else ac->result.code = RES_OK; break; } --- 707,720 ---- ac->count -= len; return (1); + case PHASE_COMPL: + case PHASE_COMPL2: case PHASE_ABORTED: case PHASE_COMPLETED: + if (ac->result.status & (ARS_CHECK | ARS_DF)) ac->result.code = RES_ERR; ! else ac->result.code = RES_OK; break; } *************** *** 837,843 **** if (atapi_start_cmd (ata, ac) >= 0 && atapi_wait_cmd (ata, ac) >= 0) { /* Send packet command. */ atapi_send_cmd (ata, ac); ! /* Wait for data i/o phase. */ for (cnt=20000; cnt>0; --cnt) if (((inb (ata->port + AR_IREASON) & (ARI_CMD | ARI_IN)) | --- 851,857 ---- if (atapi_start_cmd (ata, ac) >= 0 && atapi_wait_cmd (ata, ac) >= 0) { /* Send packet command. */ atapi_send_cmd (ata, ac); ! DELAY(40); /* Wait for data i/o phase. */ for (cnt=20000; cnt>0; --cnt) if (((inb (ata->port + AR_IREASON) & (ARI_CMD | ARI_IN)) | Alexey Pialkin