Skip site navigation (1)Skip section navigation (2)
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>

next in thread | raw e-mail | index | archive | help
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199609110836.MAA00354>