Subject: MCD Probing Fixes
To: None <current-users@sun-lamp.cs.berkeley.edu>
From: Holger Veit <Holger.Veit@gmd.de>
List: current-users
Date: 02/20/1994 20:15:14
The following code undoes the weird method of accessing the mcd drive
during probing, and replaces it by a less critical method (by using
functions that were already in the code for this purpose. Also corrects
code that cannot work (like 'if (check='M')'). This is a temporary fix,
I search for a better solution.

*** tmp/mcd.c	Fri Feb 18 09:37:32 1994
--- mcd.c	Fri Feb 18 09:52:10 1994
***************
*** 2,7 ****
--- 2,8 ----
   * Copyright 1993 by Holger Veit (data part)
   * Copyright 1993 by Brian Moore (audio part)
   * CHANGES Copyright 1993 Gary Clark II (gclarkii@freefall.cdrom.com)
+  * (in the meantime CHANGES undone, because all were bogus)
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
***************
*** 150,155 ****
--- 151,157 ----
  int	mcdioctl(dev_t dev, int cmd, caddr_t addr, int flags, struct proc *p);
  int	mcdsize(dev_t dev);
  static	void	mcd_done(struct mcd_mbx *mbx);
+ static	int	mcd_getreply(int unit,int dly);
  static	void	mcd_start(int unit);
  static	int	mcd_getdisklabel(int unit);
  static	void	mcd_configure(struct mcd_data *cd);
***************
*** 308,317 ****
  /*MCD_TRACE("strategy: buf=0x%lx, unit=%ld, block#=%ld bcount=%ld\n",
  	bp,unit,bp->b_blkno,bp->b_bcount);*/
  	if (unit >= NMCD || bp->b_blkno < 0) {
  		printf("mcdstrategy: unit = %d, blkno = %d, bcount = %d\n",
  			unit, bp->b_blkno, bp->b_bcount);
! 		pg("mcd: mcdstratregy failure");
  		bp->b_error = EINVAL;
  		bp->b_flags |= B_ERROR;
  		goto bad;
  	}
--- 310,321 ----
  /*MCD_TRACE("strategy: buf=0x%lx, unit=%ld, block#=%ld bcount=%ld\n",
  	bp,unit,bp->b_blkno,bp->b_bcount);*/
  	if (unit >= NMCD || bp->b_blkno < 0) {
+ #ifdef DEBUG
  		printf("mcdstrategy: unit = %d, blkno = %d, bcount = %d\n",
  			unit, bp->b_blkno, bp->b_bcount);
! 		printf("mcd: mcdstratregy failure");
  		bp->b_error = EINVAL;
+ #endif
  		bp->b_flags |= B_ERROR;
  		goto bad;
  	}
***************
*** 546,551 ****
--- 550,556 ----
  
  /* check if there is a cdrom */
  /* Heavly hacked by gclarkii@sugar.neosoft.com */
+ /*        ^^^^^^ infact, that was it */
  
  int mcd_probe(struct isa_device *dev)
  {
***************
*** 566,626 ****
  #endif
  
  	/* send a reset */
! 	outb(port+MCD_FLAGS,0);
  	DELAY(100000);
  	/* get any pending status and throw away...*/
  	for (i=10; i != 0; i--) {
! 		inb(port+MCD_DATA);
  	}
  	DELAY(1000);
  
! 	outb(port+MCD_DATA,MCD_CMDGETSTAT);	/* Send get status command */
  
! 	/* Loop looking for avail of status */
! 	/* XXX May have to increase for fast machinces */
! 	for (i = 1000; i != 0; i--) {
! 		if ((inb(port+MCD_FLAGS) & 0xF ) == STATUS_AVAIL) {
! 			break;
! 		}
! 		DELAY(10);
! 	}
! 	/* get status */
! 
! 	if (i == 0) {
  #ifdef DEBUG
  		printf ("Mitsumi drive NOT detected\n");
  #endif
! 	return 0;
  	}
  
  /*
   * The following code uses the 0xDC command, it returns a M from the
!  * second byte and a number in the third.  Does anyone know what the
!  * number is for? Better yet, how about someone thats REAL good in
!  * i80x86 asm looking at the Dos driver... Most of this info came
!  * from a friend of mine spending a whole weekend.....
!  */
  
  	DELAY (2000);
! 	outb(port+MCD_DATA,MCD_CMDCONTINFO);
! 	for (i = 0; i < 100000; i++) {
! 		if ((inb(port+MCD_FLAGS) & 0xF) == STATUS_AVAIL)
! 			break;
! 	}
! 	if (i > 100000) {
  #ifdef DEBUG
  		printf ("Mitsumi drive error\n");
  #endif
  		return 0;
  	}
! 	DELAY (40000);
! 	st = inb(port+MCD_DATA);
! 	DELAY (500);
! 	check = inb(port+MCD_DATA);
! 	DELAY (500);
! 	junk = inb(port+MCD_DATA);	/* What is byte used for?!?!? */
  
! 	if (check = 'M') {
  #ifdef DEBUG
  		printf("Mitsumi drive detected\n");
  #endif
--- 571,628 ----
  #endif
  
  	/* send a reset */
! 	outb(port+mcd_reset,0);
  	DELAY(100000);
  	/* get any pending status and throw away...*/
  	for (i=10; i != 0; i--) {
! 		inb(port+mcd_status);
  	}
  	DELAY(1000);
  
! 	outb(port+mcd_command,MCD_CMDGETSTAT);	/* Send get status command */
! 	i = mcd_getreply(unit,DELAY_GETREPLY);
  
! 	if (i < 0) {
  #ifdef DEBUG
  		printf ("Mitsumi drive NOT detected\n");
  #endif
! 		return 0;
  	}
  
  /*
   * The following code uses the 0xDC command, it returns a M from the
!  * second byte and a number in the third.
!  * (I hope you have the right drive for that, most drives don't do!) 
!  * Whole code entirely rewriten by veit@gmd.de, the changes accessed
!  * the drive in an illegal way. Proper way is to use the timeout
!  * driven routines mcd_getreply etc. rather than arbitrary delays. 
! */
  
  	DELAY (2000);
! 	outb(port+mcd_command,MCD_CMDCONTINFO);
! 	i = mcd_getreply(unit,DELAY_GETREPLY);
! 
! 	if (i < 0) {
  #ifdef DEBUG
  		printf ("Mitsumi drive error\n");
  #endif
  		return 0;
  	}
! 	st = mcd_getreply(unit,DELAY_GETREPLY);
! 	if (st<0) return 0;
! 	check = mcd_getreply(unit,DELAY_GETREPLY);
! 	if (st<0) return 0;
! 	/* flush junk */
! 	mcd_getreply(unit,DELAY_GETREPLY);
  
! 	/* the following is code which is not guaranteed to work
! 	 * for all drives, because the meaning of the expected 'M' is not
! 	 * clear (M_itsumi is an obvious assumption, but I don't
! 	 * trust that). Also, the original hack had a bogus condition
! 	 * that always returned true.
! 	 */
! #ifdef notdef
! 	if (check == 'M') {
  #ifdef DEBUG
  		printf("Mitsumi drive detected\n");
  #endif
***************
*** 630,635 ****
--- 632,639 ----
  		printf("Mitsumi drive error\n");
  		return 0;
  	}
+ #endif
+ 	return 4;
  }
  
  static int mcd_waitrdy(int port,int dly)
*** tmp/mcdreg.h	Fri Feb 18 09:37:34 1994
--- mcdreg.h	Fri Feb 18 09:36:12 1994
***************
*** 81,92 ****
  #define	STATUS_AVAIL	0xb
  #define	DATA_AVAIL	0xf
  
- /* ports */
- #define	MCD_DATA	0
- #define	MCD_FLAGS	1
- #define	MCD_DONT_KNOW	2	/* What are these two ports for??? */
- #define	CHANNEL		3
- 
  /* Status bits */
  #define	MCD_ST_DOOROPEN		0x80
  #define	MCD_ST_DSKIN		0x40
--- 81,86 ----

-- 
         Dr. Holger Veit                   | INTERNET: Holger.Veit@gmd.de
|  |   / GMD-SET German National Research  | Phone: (+49) 2241 14 2448
|__|  /  Center for Computer Science       | Fax:   (+49) 2241 14 2342
|  | /   Schloss Birlinghoven              | Had a nightmare yesterday:
|  |/    53754 St. Augustin, Germany       | My system started up with
                                           | ... Booting vmunix.el ...

------------------------------------------------------------------------------