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)