Date: Wed, 11 Sep 1996 12:36:52 +0400 (MSD) From: Alexey Pialkin <pialkin@abel.pdmi.ras.ru> To: hackers@freebsd.org Subject: ATAPI patch Message-ID: <199609110836.MAA00354@abel.pdmi.ras.ru>
index | next in thread | raw e-mail
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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199609110836.MAA00354>
