[comp.os.minix] News about PS/2 problem

ast@cs.vu.nl (Andy Tanenbaum) (01/11/89)

Several people are working on the PS-2 interrupt problem.  Unfortunately I
seem to be unable to communicate with a couple of them, including Gary Craig.
I received the following message from him today, along with a new floppy.c
I made a cdif listing against 1.3, which is enclosed below.  I suggest that
we have the PS/2 discussion in the newsgroup since there are no doubt other
people with PS/2s who haven't joined in so far but are potentially interested.

One note about the code below.  I think we should strive to have a single
floppy.c for the PC, AT, and PS/2.  Thus doing things like changing HC_SIZE
is probably not a good idea.  Better would be to add

#define PS2_HC_SIZE  ...

and use if (ps) ... PS2_HC_SIZE ...

or something like that.  Another potential problem is the Model 30.  1.3
has been tested on the Model 30 and it works.  In fact, the variable ps really
means Model 30 at the moment.  I am not sure if another variable ps50 is needed
for Microchannel architectures, but we should try to avoid breaking the Model
30 code while repairing it for the Model 50.


Andy Tanenbaum (ast@cs.vu.nl)

P.S. Will the following people please send me their exact paths from uunet
All mail to them seems to bounce.

Gary Craig
Steve Ackerman
johnr@systech.uucp
Patrick McCormick <unm-la!LANL.GOV!mcormick@uunet.UU.NET>
Jay Black <relay.ubc.ca!jpblack@nith.waterloo.cdn>
vrdxhq!jimv@nluug.nl
Alan Perry <zardoz!allan@dhw68k.cts.com>



------------------------ Message from Gary L. Craig ------------------------
What follows is what I have managed to blow the dust off of for a floppy.c
for PS/2 model 50 & 60.  Some notes, after each hardware interrupt we found
it necessary to "clear" the mask bit for DMA channel 2.  This code should
really be moved to interrupt in proc.c.  Also, the version of proc.c we ran
this with did not have the statement for port hex 3C - in fact in my 
50/60 hardware technical reference, I can't find any reference to such a
port.  (There is of course the general problem of reenabling interrupts before
EIO).  Andy, I also couldn't find any reference to a PCR on the 50/60 but my
technical reference does not have any information on the fixed drive.

I would test this code, but we are having problems getting 1.3c running -
most notably I have a bad 1.2 asld (I think), all our source must be read
via dosread, and all the PCs available (non-PS2) are only 2 floppy systems.
I have a student building 1.3.  Once we get a boot disk and file systems
build I will have several students trying to get things going on the PS/2s.
*** floppy.c	Wed Jan 11 11:16:03 1989
--- /local/ast/minix/tape3/kernel/floppy.c	Mon Sep 26 23:34:08 1988
***************
*** 79,96 ****
  /* DMA channel commands. */
  #define DMA_READ        0x46	/* DMA read opcode */
  #define DMA_WRITE       0x4A	/* DMA write opcode */
- /* PS/2 50&60 DMA channel commands */
- #define PS_DMA_READ        0x06	/* DMA read opcode */
- #define PS_DMA_WRITE       0x0A	/* DMA write opcode */
  
- 
  /* Parameters for the disk drive. */
  #define SECTOR_SIZE      512	/* physical sector size in bytes */
! #define HC_SIZE         2880	/* # sectors on a high-capacity (1.2M) disk */
  #define NR_HEADS        0x02	/* two heads (i.e., two tracks/cylinder) */
  #define DTL             0xFF	/* determines data length (sector size) */
  #define SPEC1           0xDF	/* first parameter to SPECIFY */
- #define PS_SPEC1        0xA1    /* first parameter to Specify on PS/2 */
  #define SPEC2           0x02	/* second parameter to SPECIFY */
  
  #define MOTOR_OFF       3*HZ	/* how long to wait before stopping motor */
--- 79,91 ----
  /* DMA channel commands. */
  #define DMA_READ        0x46	/* DMA read opcode */
  #define DMA_WRITE       0x4A	/* DMA write opcode */
  
  /* Parameters for the disk drive. */
  #define SECTOR_SIZE      512	/* physical sector size in bytes */
! #define HC_SIZE         2400	/* # sectors on a high-capacity (1.2M) disk */
  #define NR_HEADS        0x02	/* two heads (i.e., two tracks/cylinder) */
  #define DTL             0xFF	/* determines data length (sector size) */
  #define SPEC1           0xDF	/* first parameter to SPECIFY */
  #define SPEC2           0x02	/* second parameter to SPECIFY */
  
  #define MOTOR_OFF       3*HZ	/* how long to wait before stopping motor */
***************
*** 110,116 ****
  #define NR_DRIVES          2	/* maximum number of drives */
  #define DIVISOR          128	/* used for sector size encoding */
  #define MAX_FDC_RETRY    100	/* max # times to try to output to FDC */
! #define NT                 7	/* number of diskette/drive combinations */
  
  /* Variables. */
  PRIVATE struct floppy {		/* main drive struct, one entry per drive */
--- 105,111 ----
  #define NR_DRIVES          2	/* maximum number of drives */
  #define DIVISOR          128	/* used for sector size encoding */
  #define MAX_FDC_RETRY    100	/* max # times to try to output to FDC */
! #define NT                 6	/* number of diskette/drive combinations */
  
  /* Variables. */
  PRIVATE struct floppy {		/* main drive struct, one entry per drive */
***************
*** 141,149 ****
  PRIVATE message mess;		/* message buffer for in and out */
  
  PRIVATE char len[] = {-1,0,1,-1,2,-1,-1,3,-1,-1,-1,-1,-1,-1,-1,4};
! PRIVATE char interleave[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18};
  
! /* Seven combinations of diskette/drive are supported:
   * # Drive  diskette  Sectors  Tracks  Rotation Data-rate  Comment
   * 0  360K    360K      9       40     300 RPM  250 kbps   Standard PC DSDD
   * 1  1.2M    1.2M     15       80     360 RPM  500 kbps   AT disk in AT drive
--- 136,144 ----
  PRIVATE message mess;		/* message buffer for in and out */
  
  PRIVATE char len[] = {-1,0,1,-1,2,-1,-1,3,-1,-1,-1,-1,-1,-1,-1,4};
! PRIVATE char interleave[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
  
! /* Six combinations of diskette/drive are supported:
   * # Drive  diskette  Sectors  Tracks  Rotation Data-rate  Comment
   * 0  360K    360K      9       40     300 RPM  250 kbps   Standard PC DSDD
   * 1  1.2M    1.2M     15       80     360 RPM  500 kbps   AT disk in AT drive
***************
*** 151,171 ****
   * 3  720K    720K      9       80     300 RPM  250 kbps   Toshiba, et al.
   * 4  1.2M    360K      9       40     360 RPM  300 kbps   PC disk in AT drive
   * 5  1.2M    720K      9       80     360 RPM  300 kbps   Toshiba in AT drive
-  * 6  1.44M   1.44M    18       80     360 RPM  500 kbps   IBM PS/2
   */
  PRIVATE int gap[NT] =
! 	{0x2A, 0x1B, 0x2A, 0x2A, 0x23, 0x23, 0x1b}; /* gap size */
  PRIVATE int rate[NT] = 
! 	{0x02, 0x00, 0x02, 0x02, 0x01, 0x01, 0x00}; /* 250,300,500 kbps*/
  PRIVATE int nr_sectors[NT] = 
! 	{9,    15,   9,    9,    9,    9,    18};   /* sectors/track */
  PRIVATE int nr_blocks[NT] = 
! 	{720,  2400, 720,  1440, 720,  1440, 2880}; /* sectors/diskette*/
  PRIVATE int steps_per_cyl[NT] = 
! 	{1,    1,    2,    1,    2,    1,    1};   /* 2 = dbl step */
  PRIVATE int mtr_setup[NT] = 
! 	{HZ/4,3*HZ/4,HZ/4,2*HZ/4,3*HZ/4,3*HZ/4,3*HZ/4};/* in ticks */
! char    valu;   
  
  /*===========================================================================*
   *				floppy_task				     * 
--- 146,164 ----
   * 3  720K    720K      9       80     300 RPM  250 kbps   Toshiba, et al.
   * 4  1.2M    360K      9       40     360 RPM  300 kbps   PC disk in AT drive
   * 5  1.2M    720K      9       80     360 RPM  300 kbps   Toshiba in AT drive
   */
  PRIVATE int gap[NT] =
! 	{0x2A, 0x1B, 0x2A, 0x2A, 0x23, 0x23}; /* gap size */
  PRIVATE int rate[NT] = 
! 	{0x02, 0x00, 0x02, 0x02, 0x01, 0x01}; /* 250,300,500 kbps*/
  PRIVATE int nr_sectors[NT] = 
! 	{9,    15,   9,    9,    9,    9};   /* sectors/track */
  PRIVATE int nr_blocks[NT] = 
! 	{720,  2400, 720,  1440, 720,  1440}; /* sectors/diskette*/
  PRIVATE int steps_per_cyl[NT] = 
! 	{1,    1,    2,    1,    2,    1};   /* 2 = dbl step */
  PRIVATE int mtr_setup[NT] = 
! 	{HZ/4,3*HZ/4,HZ/4,2*HZ/4,3*HZ/4,3*HZ/4};/* in ticks */
  
  /*===========================================================================*
   *				floppy_task				     * 
***************
*** 298,307 ****
    phys_bytes user_phys;
    extern phys_bytes umap();
  
!   if (ps)
!     mode = (fp->fl_opcode == DISK_READ ? PS_DMA_READ : PS_DMA_WRITE);
!   else
!     mode = (fp->fl_opcode == DISK_READ ? DMA_READ : DMA_WRITE);
    vir = (vir_bytes) fp->fl_address;
    ct = (vir_bytes) fp->fl_count;
    user_phys = umap(proc_addr(fp->fl_procnr), D, vir, ct);
--- 291,297 ----
    phys_bytes user_phys;
    extern phys_bytes umap();
  
!   mode = (fp->fl_opcode == DISK_READ ? DMA_READ : DMA_WRITE);
    vir = (vir_bytes) fp->fl_address;
    ct = (vir_bytes) fp->fl_count;
    user_phys = umap(proc_addr(fp->fl_procnr), D, vir, ct);
***************
*** 322,335 ****
  
    /* Now set up the DMA registers. */
    s = lock();
-   if (ps) {
-    port_out(DMA_INIT, 6);	/* set channel 2 mask bit */
-    port_out(DMA_M2, 6);		/* clear byte pointer */
-    port_out(0x31a8, 2);	        /* setup the arbitration level for DMA channel
-    port_in(0x31a6, &valu);	    2     */ 
-    port_out(0x31a9, valu);	
-   }
- 
    port_out(DMA_M2, mode);	/* set the DMA mode */
    port_out(DMA_M1, mode);	/* set it again */
    port_out(DMA_ADDR, low_addr);	/* output low-order 8 bits */
--- 312,317 ----
***************
*** 419,432 ****
    fdc_out(fp->fl_cylinder * steps_per_cyl[d]);
    if (need_reset) return(ERR_SEEK);	/* if controller is sick, abort seek */
    receive(HARDWARE, &mess);
-   if (ps) {  /* reenable interrupts  - Note this could be moved to routine
- 		interrupt (I think) */
-     s = lock();
-     port_in(INT_CTLMASK, &valu);	    
-     valu &= 0xbf
-     port_out(INT_CTLMASK, valu);	
-     restore(s);
-   }
  
    /* Interrupt has been received.  Check drive status. */
    fdc_out(FDC_SENSE);		/* probe FDC to make it return status */
--- 401,406 ----
***************
*** 477,489 ****
    /* Block, waiting for disk interrupt. */
    if (need_reset) return(ERR_TRANSFER);	/* if controller is sick, abort op */
    receive(HARDWARE, &mess);
-   if (ps) {
-     s = lock();
-     port_in(INT_CTLMASK, &valu);	    
-     valu &= 0xbf
-     port_out(INT_CTLMASK, valu);	
-     restore(s);
-   }
  
    /* Get controller status and check for errors. */
    r = fdc_results(fp);
--- 451,456 ----
***************
*** 593,605 ****
    fdc_out(fp->fl_drive);	/* specify drive */
    if (need_reset) return(ERR_SEEK);	/* don't wait if controller is sick */
    receive(HARDWARE, &mess);	/* wait for interrupt message */
-   if (ps) {
-     s = lock();
-     port_in(INT_CTLMASK, &valu);	    
-     valu &= 0xbf
-     port_out(INT_CTLMASK, valu);	
-     restore(s);
-   }
  
    /* Determine if the recalibration succeeded. */
    fdc_out(FDC_SENSE);		/* issue SENSE command to see where we are */
--- 560,565 ----
***************
*** 644,656 ****
    port_out(DOR, ENABLE_INT);	/* strobe it high again */
    restore(old_state);		/* interrupts allowed again */
    receive(HARDWARE, &mess);	/* collect the RESET interrupt */
-   if (ps) {
-     s = lock();
-     port_in(INT_CTLMASK, &valu);	    
-     valu &= 0xbf
-     port_out(INT_CTLMASK, valu);	
-     restore(s);
-   }
  
    /* Interrupt from the reset has been received.  Continue resetting. */
    fp = &floppy[0];		/* use floppy[0] for scratch */
--- 604,609 ----
***************
*** 661,670 ****
  
    /* Tell FDC drive parameters. */
    fdc_out(FDC_SPECIFY);		/* specify some timing parameters */
!   if (ps)
!     fdc_out(PS_SPEC1);		/* step-rate and head-unload-time */
!   else
!     fdc_out(SPEC1);		/* step-rate and head-unload-time */
    fdc_out(SPEC2);		/* head-load-time and non-dma */
  
    for (i = 0; i < NR_DRIVES; i++) floppy[i].fl_calibration = UNCALIBRATED;
--- 614,620 ----
  
    /* Tell FDC drive parameters. */
    fdc_out(FDC_SPECIFY);		/* specify some timing parameters */
!   fdc_out(SPEC1);		/* step-rate and head-unload-time */
    fdc_out(SPEC2);		/* head-load-time and non-dma */
  
    for (i = 0; i < NR_DRIVES; i++) floppy[i].fl_calibration = UNCALIBRATED;

DEDOUREK%UNB.CA@CORNELLC.CIT.CORNELL.EDU (01/13/89)

> or something like that.  Another potential problem is the Model 30.
> 1.3 has been tested on the Model 30 and it works.  In fact, the
> variable ps really means Model 30 at the moment.  I am not sure if
> another variable ps50 is needed for Microchannel architectures, but we
> should try to avoid breaking the Model 30 code while repairing it for
> the Model 50.
On a related question, does Model 30 mean just PS/2 Model 30, or
also Model 30-286.  The latter is a new machine with (as I understand
it) a more or less AT compatible bus (not microchannel) with an
80286 processor (not 8086) and a 1.44 M 3 1/2" floppy drive
(instead of the Model 30's 720K floppy). Also has an optional
20 M disk and VGA graphics.  I am interested because my
true blue PC was just replaced by this new thing.
John DeDourek
dedourek@unb.ca if you know about domain ca (canada)
dedourek@unbmvs1 on some old bitnet mailers

ast@cs.vu.nl (Andy Tanenbaum) (01/13/89)

In article <6604@louie.udel.EDU> DEDOUREK%UNB.CA@CORNELLC.CIT.CORNELL.EDU writes:
>> or something like that.  Another potential problem is the Model 30.
>> 1.3 has been tested on the Model 30 and it works.  In fact, the
>> variable ps really means Model 30 at the moment.  I am not sure if
>> another variable ps50 is needed for Microchannel architectures, but we
>> should try to avoid breaking the Model 30 code while repairing it for
>> the Model 50.
>On a related question, does Model 30 mean just PS/2 Model 30, or
>also Model 30-286.

I don't know.  If and when we get the PS/2 stuff debugged and find out
what the problems are, we can see how many variables we need.  If it turns
out that as far as MINIX is concerned all microchannel machines have to
programmed in one way and all non-microchannel PS/2 in a different way,
then we will need two variables, ps and mca.  If it turns out that there
are four or five categories, we will need more variables.  But first we
have to figure out why PS/2's are different.

Andy Tanenbaum (ast@cs.vu.nl)