leo@marco.UUCP (Matthias Pfaller) (03/07/90)
Now (after twice trashing my minix-partition) I know, how to have minix run with my ST (with hypercache) and my ICD-harddisk. I compared the original AHDI program with the minix-ST harddisk driver. I found no difference, and this almost drived me crazy, because TOS worked wonderfully with my harddrive. It absolutely didn't care about the fact that TOS doesn't use IRQs and minix does. The problem *IS* that the TOS driver writes data and control register with *ONE* longword access, whereas minix does this with *TWO* 16bit transfers. I now (after finding this out by myself) found a paragraph in 'Das Atari ST Profibuch', where it states that atari had stated (somewhere you'll never find it) that *THIS* is the correct way to access the DMA-controller: use one long-word transfer to write data and control (if you send command bytes to the ACSI-device)! The following patch to the 1.5.0 stwini.c and stdma.c cured the problem. From time to time I read that other people had similar problems with their STs even without an hypercache installed. Perhaps this patch can help in such a case too. leo@marco.UUCP (Matthias Pfaller) PS: If you use the diskclocks, you possible have to do some changes in this code too. I haven't touched this because I do not use it. ----------------------------------- cut -------------------------------------- *** stwini.c Wed Mar 7 09:39:31 1990 --- new/stwini.c Wed Mar 7 09:27:36 1990 *************** *** 73,79 **** #endif /* CLOCKS */ /* Parameters for the disk drive. */ #define SECTOR_SIZE 512 /* physical sector size in bytes */ ! #define NR_DRIVES 1 /* maximum number of drives */ #define MAX_MINOR (NR_DRIVES<<3) #define MAX_ERRORS 10 /* how often to try rd/wt before quitting */ /* dis/enable interrupts */ --- 73,79 ---- #endif /* CLOCKS */ /* Parameters for the disk drive. */ #define SECTOR_SIZE 512 /* physical sector size in bytes */ ! #define NR_DRIVES 4 /* maximum number of drives */ #define MAX_MINOR (NR_DRIVES<<3) #define MAX_ERRORS 10 /* how often to try rd/wt before quitting */ /* dis/enable interrupts */ *************** *** 263,270 **** IENABLE(); #endif dmacomm(wrbit | FDC | SCREG, count, HDC_DELAY); ! dmawdat(wrbit | FDC | HDC | A0, 0, HDC_DELAY); ! DMA->dma_mode = wrbit; /* needed? */ receive(HARDWARE, &mess); /* Wait for interrupt. */ #ifdef SUPRA IDISABLE(); --- 263,270 ---- IENABLE(); #endif dmacomm(wrbit | FDC | SCREG, count, HDC_DELAY); ! DMA->dma_mode = wrbit | FDC | HDC | A0; ! dmawcmd(0, wrbit); receive(HARDWARE, &mess); /* Wait for interrupt. */ #ifdef SUPRA IDISABLE(); *************** *** 297,304 **** int cmd; { DMA->dma_mode = FDC | HDC; ! DMA->dma_data = (short)(((drive>>1)<<5) | (cmd&0x1F)); ! DMA->dma_mode = FDC | HDC | A0; } PRIVATE int cmdtail(drive, sector, count) --- 297,303 ---- int cmd; { DMA->dma_mode = FDC | HDC; ! dmawcmd((short)(((drive>>1)<<5) | (cmd&0x1F)), FDC | HDC | A0); } PRIVATE int cmdtail(drive, sector, count) *************** *** 310,329 **** DMA->dma_mode = FDC | HDC | A0; if (poll() != OK) return(ERROR); ! DMA->dma_data = (short) (((drive&1)<<5) | (((int)(sector>>16))&0x1F)); ! DMA->dma_mode = FDC | HDC | A0; if (poll() != OK) return(ERROR); ! DMA->dma_data = (short) ((int)sector >> 8); ! DMA->dma_mode = FDC | HDC | A0; if (poll() != OK) return(ERROR); ! DMA->dma_data = (short) sector; ! DMA->dma_mode = FDC | HDC | A0; if (poll() != OK) return(ERROR); ! DMA->dma_data = (short) count; ! DMA->dma_mode = FDC | HDC | A0; if (poll() != OK) return(ERROR); return(OK); --- 309,324 ---- DMA->dma_mode = FDC | HDC | A0; if (poll() != OK) return(ERROR); ! dmawcmd((short) (((drive&1)<<5) | (((int)(sector>>16))&0x1F)), FDC | HDC | A0); if (poll() != OK) return(ERROR); ! dmawcmd((short) ((int)sector >> 8), FDC | HDC | A0); if (poll() != OK) return(ERROR); ! dmawcmd((short) sector, FDC | HDC | A0); if (poll() != OK) return(ERROR); ! dmawcmd((short) count, FDC | HDC | A0); if (poll() != OK) return(ERROR); return(OK); *************** *** 353,359 **** } #ifdef CLOCKS ! #include <minix/sgtty.h> #define XFERSIZE 13 /*===========================================================================* * do_ioctl * --- 348,354 ---- } #ifdef CLOCKS ! #include <sgtty.h> #define XFERSIZE 13 /*===========================================================================* * do_ioctl * *** stdma.c Wed Mar 7 09:39:45 1990 --- new/stdma.c Wed Mar 7 09:27:15 1990 *************** *** 68,74 **** { message m; ! xxxint = 0; /* no more DMA interrupts */ ASSERT(qhead == p); qhead = QNEXT(p); QNEXT(p) = 0; --- 68,74 ---- { message m; ! xxxint = (int(*)())0; /* no more DMA interrupts */ ASSERT(qhead == p); qhead = QNEXT(p); QNEXT(p) = 0; *************** *** 120,132 **** DMA->dma_data = data; } PUBLIC void dmacomm(mode, data, delay) int mode; int data; int delay; { - DMA->dma_mode = mode; DMA->dma_mode = mode ^ WRBIT; DMA->dma_mode = mode; while (--delay >= 0); DMA->dma_data = data; --- 120,140 ---- DMA->dma_data = data; } + PUBLIC void dmawcmd(dm) + union { long l; struct { short data; short mode; } dm; } dm; + { + register long l; + l = dm.l; + *((long*)&DMA->dma_data) = l; + } + PUBLIC void dmacomm(mode, data, delay) int mode; int data; int delay; { DMA->dma_mode = mode ^ WRBIT; + while (--delay >= 0); DMA->dma_mode = mode; while (--delay >= 0); DMA->dma_data = data; ----------------------------------- cut --------------------------------------