[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[MiNT] Fwd: [Mint-cvs] [FreeMiNT CVS] freemint/sys/usb/src.km/udd/storage



wow...what a nice surprise....thanks Roger!!


---------- Forwarded message ----------
From:  <cvs@sparemint.org>
Date: 2014-04-07 9:47 GMT+02:00
Subject: [Mint-cvs] [FreeMiNT CVS] freemint/sys/usb/src.km/udd/storage
To: cz-bobek-lists-mint-cvs@lists.bobek.cz


Update of /mint/freemint/sys/usb/src.km/udd/storage
In directory mail.sparemint.org:/tmp/cvs-serv27001/sys/usb/src.km/udd/storage

Modified Files:
      Tag: usbtos
        SRCFILES usb_storage.c xhdi.c xhdi.h
Added Files:
      Tag: usbtos
        install.c vectors.S
Removed Files:
      Tag: usbtos
        bios.S debug2.S
Log Message:
Move bios.S and debug2.S to C
Contributed by Roger Burrows.


--- NEW FILE: vectors.S ---
Index: freemint/sys/usb/src.km/udd/storage/vectors.S
diff -u /dev/null freemint/sys/usb/src.km/udd/storage/vectors.S:1.1.2.1
--- /dev/null   Mon Apr  7 03:47:30 2014
+++ freemint/sys/usb/src.km/udd/storage/vectors.S       Mon Apr  7 03:47:27 2014
@@ -0,0 +1,217 @@
+/*
+ *      vectors.S: bios vector intercepts for USB storage under TOS/FreeMiNT
+ *
+ *             Based on the assembler code by David Galvez (2010-2012), which
+ *             was itself extracted from the USB disk utility assembler code by
+ *             Didier Mequignon (2005-2009).
+ *
+ *      Copyright 2014 Roger Burrows <rfburrows@ymail.com>
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
+       .global _install_vectors
+       .extern _usb_getbpb,_usb_rwabs,_usb_mediach
+
+/*
+ *     miscellaneous definitions
+ */
+#define _hdv_bpb               0x472
+#define _hdv_rw                        0x476
+#define _hdv_mediach   0x47E
+#define pinfo_pun              2               /* offset to pun[]
within PUN_INFO */
+
+// FixME - defined in xhdi.h as well
+#ifdef TOSONLY
+#define MAX_LOGICAL_DRIVE      16
+#else
+#define MAX_LOGICAL_DRIVE      32
+#endif
+
+       .text
+/*
+ *     install vectors
+ */
+_install_vectors:
+       lea             -16(sp),sp
+       movem.l d0-d1/a0-a1,(sp)        //save registers
+       move.w  sr,d0                           //save old status register
+       move.w  d0,-(sp)
+       ori.l   #0x0700,d0
+       move.w  d0,sr                           //mask interrupts
+
+       move.l  #_hdv_bpb,a0            //bpb handler
+       lea             save_hdv_bpb,a1
+       move.l  (a0),(a1)                               //save old
+       lea             my_hdv_bpb,a1
+       move.l  a1,(a0)                                 //install new
+
+       move.l  #_hdv_rw,a0                     //rw handler
+       lea             save_hdv_rw,a1
+       move.l  (a0),(a1)                               //save old
+       lea             my_hdv_rw,a1
+       move.l  a1,(a0)                                 //install new
+
+       move.l  #_hdv_mediach,a0        //mediach handler
+       lea             save_hdv_mediach,a1
+       move.l  (a0),(a1)                               //save old
+       lea             my_hdv_mediach,a1
+       move.l  a1,(a0)                                 //install new
+
+       move.w  (sp)+,d0                        //exit:
+       move.w  d0,sr                                   //restore interrupts
+       movem.l (sp),d0-d1/a0-a1
+       lea             16(sp),sp
//restore registers
+       rts
+
+/*
+ *     hdv_bpb intercept
+ */
+       dc.l    0x58425241                      //XBRA
+       dc.l    0x5f555342                      //id _USB
+save_hdv_bpb:
+       dc.l    0
+my_hdv_bpb:
+       moveq   #0,d0                                   //ok to
clobber, since Getbpb() returns a value in d0
+       move.w  4(sp),d0                                //d0 = drive
+       move.l  a0,-(sp)                                //save work register
+       cmpi.l  #MAX_LOGICAL_DRIVE,d0   //valid drive?
+       bcc.s   .bpbnext                                //no, go to next handler
+       lea             _pun_usb,a0                             //a0 -> pun_usb
+       tst.b   pinfo_pun(a0,d0.l)              //is it one of ours?
+       bpl.s   .bpbget                                 //yes, go get bpb
+.bpbnext:                                              //go to next handler
+       move.l  (sp)+,a0                                //restore register
+       move.l  save_hdv_bpb,-(sp)              //& go
+       rts
+
+.bpbget:
+       subq.l  #8,sp
+       movem.l d1/a1,(sp)                              //save other
GCC scratch registers
+       move.l  d0,-(sp)                                //drive number
+       jsr             _usb_getbpb
+       addq.l  #4,sp
+       movem.l (sp),d1/a1                              //restore d1, a1
+       addq.l  #8,sp
+       move.l  (sp)+,a0                                //restore a0
+       rts
+
+/*
+ *     hdv_rw intercept
+ */
+       dc.l    0x58425241                      //XBRA
+       dc.l    0x5f555342                      //id _USB
+save_hdv_rw:
+       dc.l    0
+my_hdv_rw:
+                                                               //ok
to clobber d0, since Rwabs() returns a value in d0
+       move.w  4(sp),d0                                //d0.w = mode
+       swap    d0
+       move.w  14(sp),d0                               //d0.w = drive
+       move.l  a0,-(sp)                                //save work register
+       btst    #3+16,d0                                //physical mode?
+       beq.s   .rwlogical              //no, go handle
+
//handle physical mode requests
+
//note: we subtract 2 from the physical drive #
+       andi.l  #0x0000ffff,d0                  //d0.l = drive
+       subq.l  #2,d0                                   //allow for floppies
+       bmi.b   .rwnext                                 //not for us
+       btst    #5,d0                                   //is the
PUN_USB bit set?
+       beq.s   .rwnext                                 //no, can't be for us
+       btst    #6,d0                                   //is bit 6 set?
+       bne.s   .rwnext                                 //yes, not ours
+
//search pun[] for match
+       lea             _pun_usb+pinfo_pun,a0   //a0 -> pun[]
+.rwloop:
+       tst.b   (a0)                                    //entry valid?
+       bmi.s   .rwincr                                 //no
+       cmp.b   (a0),d0                                 //matching entry?
+       beq.b   .rwio                                   //yes, ok
+.rwincr:
+       addq.l  #1,a0
+       cmpa.l  #_pun_usb+pinfo_pun+MAX_LOGICAL_DRIVE,a0
+       bne.s   .rwloop
+       bra.s   .rwnext                                 //not found,
on to next handler
+
//handle normal requests
+.rwlogical:
+       andi.l  #0x0000ffff,d0                  //d0.l = drive
+       cmpi.l  #MAX_LOGICAL_DRIVE,d0   //valid drive?
+       bcc.s   .rwnext                                 //no, go to next handler
+       lea             _pun_usb,a0                             //a0 -> pun_usb
+       tst.b   pinfo_pun(a0,d0.l)              //is it one of ours?
+       bpl.s   .rwio                                   //yes, go do i/o
+.rwnext:                                               //go to next handler
+       move.l  (sp)+,a0                                //restore register
+       move.l  save_hdv_rw,-(sp)               //& go
+       rts
+
+.rwio:                                                 //do the i/o
+       lea             -12(sp),sp
+       movem.l d1-d2/a1,(sp)                   //save registers
+       movea.w 4+16(sp),a1                             //a1 = mode
+       movea.l 6+16(sp),a0                             //a0 = buffer ptr
+       moveq.l #0,d2
+       move.w  10+16(sp),d2                    //d2 == sector count
+       moveq.l #0,d1
+       move.w  12+16(sp),d1                    //d1 = sector number
+       cmpi.w  #0xffff,d1                              //special value?
+       bne.s   .rwcall                                 //no, branch
+       move.l  16+16(sp),d1                    //else use long value
+.rwcall:                                               //call the C routine
+       move.l  a1,-(sp)                                //mode
+       move.l  a0,-(sp)                                //buffer ptr
+       move.l  d2,-(sp)                                //logical sector count
+       move.l  d1,-(sp)                                //logical sector number
+       move.l  d0,-(sp)                                //drive number
+       jsr             _usb_rwabs
+       lea             20(sp),sp
+       movem.l (sp),d1-d2/a1                   //restore registers
+       lea             12(sp),sp
+       move.l  (sp)+,a0                                //restore a0
+       rts
+
+/*
+ *     hdv_mediach intercept
+ */
+       dc.l    0x58425241                      //XBRA
+       dc.l    0x5f555342                      //id _USB
+save_hdv_mediach:
+       dc.l    0
+my_hdv_mediach:
+                                                               //ok
to clobber d0, since Mediach() returns a value in d0
+       moveq   #0,d0
+       move.w  4(sp),d0                                //d0 = drive
+       move.l  a0,-(sp)                                //save work register
+       cmpi.l  #MAX_LOGICAL_DRIVE,d0   //valid drive?
+       bcc.s   .medianext                              //no, go to next handler
+       lea             _pun_usb,a0                             //a0 -> pun_usb
+       tst.b   pinfo_pun(a0,d0.l)              //is it one of ours?
+       bpl.s   .mediatst                               //yes, go test
mediachange
+.medianext:                                            //go to next handler
+       move.l  (sp)+,a0                                //restore register
+       move.l  save_hdv_mediach,-(sp)          //& go
+       rts
+
+.mediatst:
+       subq.l  #8,sp
+       movem.l d1/a1,(sp)                              //save other
GCC scratch registers
+       move.l  d0,-(sp)                                //drive number
+       jsr             _usb_mediach
+       addq.l  #4,sp
+       movem.l (sp),d1/a1                              //restore d1, a1
+       addq.l  #8,sp
+       move.l  (sp)+,a0                                //restore a0
+       rts

--- bios.S DELETED ---

Index: freemint/sys/usb/src.km/udd/storage/xhdi.c
diff -u freemint/sys/usb/src.km/udd/storage/xhdi.c:1.2.2.6
freemint/sys/usb/src.km/udd/storage/xhdi.c:1.2.2.7
--- freemint/sys/usb/src.km/udd/storage/xhdi.c:1.2.2.6  Wed Apr  2 12:45:53 2014
+++ freemint/sys/usb/src.km/udd/storage/xhdi.c  Mon Apr  7 03:47:27 2014
@@ -73,7 +73,6 @@
 /*--- External variables ---*/

 extern char *drv_version;
-extern long usb_1st_disk_drive;

 /* --- External functions ---*/

@@ -92,8 +91,8 @@

 /*--- Global variables ---*/

-long my_drvbits;
-long product_name[32];
+ulong my_drvbits;
+char *product_name[32];        /* indexed by device number */
 PUN_INFO pun_usb;

 /*---Functions ---*/
@@ -151,8 +150,7 @@
                        return ret;
        }

-       if (drv < usb_1st_disk_drive ||
-           drv > usb_1st_disk_drive + MAX_LOGICAL_DRIVE)
+       if (pun_usb.pun[drv] & PUN_VALID)
                return ENODEV;

        if (major) {
@@ -221,8 +219,7 @@
                        return ret;
        }

-       if (drv < usb_1st_disk_drive ||
-           drv > usb_1st_disk_drive + MAX_LOGICAL_DRIVE)
+       if (pun_usb.pun[drv] & PUN_VALID)
                return ENODEV;

        return XHInqDev2(drv, major, minor, start, bpb, NULL, NULL);
@@ -238,7 +235,7 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        return ENOSYS;
@@ -253,7 +250,7 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        return ENOSYS;
@@ -268,7 +265,7 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        return ENOSYS;
@@ -283,11 +280,11 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        /* device number in the USB bus */
-       short dev = pun_usb.dev_num[major & PUN_DEV];
+       short dev = major & PUN_DEV;

        usb_stor_eject(dev);

@@ -305,17 +302,16 @@
                        return ret;
        }

-       if (dev < usb_1st_disk_drive ||
-           dev > usb_1st_disk_drive + MAX_LOGICAL_DRIVE)
+       if (pun_usb.pun[dev] & PUN_VALID)
                return ENODEV;

        name = DRIVER_NAME;
        version = drv_version;
        company = DRIVER_COMPANY;
-       memcpy(ahdi_version, &(pun_usb.version_num), sizeof(short));
+       *ahdi_version = pun_usb.version_num;
        *max_IPL = MAX_IPL;

-       return ENOSYS;
+       return E_OK;
 }

 static long
@@ -340,7 +336,7 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        return ENOSYS;
@@ -382,7 +378,7 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        return ENOSYS;
@@ -397,7 +393,7 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        return ENOSYS;
@@ -416,7 +412,7 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        if (blocksize) {
@@ -433,14 +429,13 @@
        }

        if (productname) {
-               short drv = major & PUN_DEV;
+               short dev = major & PUN_DEV;

-               DEBUG(("XHInqTarget2(%d.%d) %d", major, minor, drv));
+               DEBUG(("XHInqTarget2(%d.%d) %d", major, minor, dev));

-               strncpy(productname, (const char *)product_name[drv],
-                       stringlen - 1);
+               strncpy(productname, product_name[dev], stringlen - 1);
                DEBUG(("XHInqTarget2. %d product_name %s %s stringlen %d",
-                       drv, product_name[drv], productname, stringlen));
+                       dev, product_name[dev], productname, stringlen));
        }

        return E_OK;
@@ -457,7 +452,7 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        return XHInqTarget2(major, minor, blocksize, deviceflags,
@@ -477,7 +472,7 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        return ENOSYS;
@@ -499,7 +494,7 @@
                        return ret;
        }

-       if (major < PUN_USB || major > PUN_USB + PUN_DEV)
+       if ((major & PUN_USB) == 0)
                return ENODEV;

        if (minor != 0)
@@ -509,7 +504,7 @@
                return EERROR;

        /* device number in the USB bus */
-       short dev = pun_usb.dev_num[major & PUN_DEV];
+       short dev = major & PUN_DEV;

        if (rw & 0x0001) {
                ret = usb_stor_write(dev, sector, (long)count, buf);
@@ -517,7 +512,6 @@
                DEBUG(("usb_stor_write() returned %ld", ret));
        }
        else {
-               c_conws("XHDI READ\r\n");
                ret = usb_stor_read(dev, sector, (long)count, buf);

                DEBUG(("usb_stor_read() returned %ld", ret));
@@ -535,7 +529,6 @@
        ushort opcode = stack;

        DEBUG(("XHDI handler, opcode: %d", opcode));
-       c_conws("XHDI CALLED\r\n");

        switch (opcode)
        {

Index: freemint/sys/usb/src.km/udd/storage/usb_storage.c
diff -u freemint/sys/usb/src.km/udd/storage/usb_storage.c:1.11.2.7
freemint/sys/usb/src.km/udd/storage/usb_storage.c:1.11.2.8
--- freemint/sys/usb/src.km/udd/storage/usb_storage.c:1.11.2.7  Mon
Mar 24 19:26:42 2014
+++ freemint/sys/usb/src.km/udd/storage/usb_storage.c   Mon Apr  7 03:47:26 2014
@@ -160,8 +160,6 @@
                                 char *vendor, char *revision, char *product);
 extern long uninstall_usb_stor (long dev_num);

-/* Used by bios.S */
-unsigned long usb_1st_disk_drive = 0;

 /* direction table -- this indicates the direction of the data
  * transfer for each command code -- a 1 indicates input

Index: freemint/sys/usb/src.km/udd/storage/xhdi.h
diff -u freemint/sys/usb/src.km/udd/storage/xhdi.h:1.1.6.1
freemint/sys/usb/src.km/udd/storage/xhdi.h:1.1.6.2
--- freemint/sys/usb/src.km/udd/storage/xhdi.h:1.1.6.1  Mon Mar 24 19:26:43 2014
+++ freemint/sys/usb/src.km/udd/storage/xhdi.h  Mon Apr  7 03:47:27 2014
@@ -26,7 +26,7 @@
 #define PUN_SCSI          0x08 /* 1=SCSI 0=ACSI */
 #define PUN_IDE           0x10 /* Falcon IDE */
 #define PUN_USB           0x20 /* USB */
-#define PUN_REMOVABLE     0x40 /* Removable media */
+//#define PUN_REMOVABLE     0x40 /* Removable media */
 #define PUN_VALID         0x80 /* zero if valid */

 /* BIOS parameter block */
@@ -66,11 +66,12 @@
        long    psize[MAX_LOGICAL_DRIVE];
        short   flags[MAX_LOGICAL_DRIVE];               /* B15:swap,
B7:change, B0:bootable */
        BPB     bpb[MAX_LOGICAL_DRIVE];
-       uchar   dev_num[MAX_LOGICAL_DRIVE];
-
 } __attribute__((packed));
 typedef struct pun_info PUN_INFO;

+/* flags in PUN_INFO */
+#define CHANGE_FLAG            (1<<7)
+
 /* XHDI opcodes */
 #define XHGETVERSION    0
 #define XHINQTARGET     1

--- debug2.S DELETED ---

Index: freemint/sys/usb/src.km/udd/storage/SRCFILES
diff -u freemint/sys/usb/src.km/udd/storage/SRCFILES:1.3.6.2
freemint/sys/usb/src.km/udd/storage/SRCFILES:1.3.6.3
--- freemint/sys/usb/src.km/udd/storage/SRCFILES:1.3.6.2        Sun
Mar 23 16:51:55 2014
+++ freemint/sys/usb/src.km/udd/storage/SRCFILES        Mon Apr  7 03:47:25 2014
@@ -8,12 +8,12 @@
        xhdi.h

 COBJS = \
+       install.c \
        usb_storage.c \
        xhdi.c

 SSOBJS = \
-       bios.S \
-       debug2.S
+       vectors.S

 TOSCOBJS = \
         crtinit.c

--- NEW FILE: install.c ---
Index: freemint/sys/usb/src.km/udd/storage/install.c
diff -u /dev/null freemint/sys/usb/src.km/udd/storage/install.c:1.1.2.1
--- /dev/null   Mon Apr  7 03:47:30 2014
+++ freemint/sys/usb/src.km/udd/storage/install.c       Mon Apr  7 03:47:26 2014
@@ -0,0 +1,518 @@
+/*
+ *      install.c: install functions for USB storage under TOS/FreeMiNT
+ *
+ *             Based on the assembler code by David Galvez (2010-2012), which
+ *             was itself extracted from the USB disk utility assembler code by
+ *             Didier Mequignon (2005-2009).
+ *
+ *      Copyright 2014 Roger Burrows <rfburrows@ymail.com>
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+#include "../../config.h"
+#include "../../global.h"
+#include "xhdi.h"                                      /* for PUN_XXX */
+
+/*
+ * the following should be in headers for other modules
+ */
+#define MAX_LOGSEC_SIZE                16384
+#define MAX_FAT12_CLUSTERS  4078    /* architectural constants */
+#define MAX_FAT16_CLUSTERS  65518
+
+#define RWFLAG                 0x0001          /* for Rwabs() 'mode' */
+#define NOTRANSLATE            0x0008
+
+#define bootdev                        *(short *)0x446
+#define drvbits                        *(unsigned long *)0x4C2
+
+void install_vectors(void);
                 //vectors.S
+
+#define DEFAULT_SECTOR_SIZE    2048
         //usb_storage.c
+unsigned long usb_stor_read(long device,unsigned long blknr,
+               unsigned long blkcnt,void *buffer);
         //usb_storage.c
+unsigned long usb_stor_write(long device,unsigned long blknr,
+               unsigned long blkcnt,const void *buffer);
 //usb_storage.c
+
+long install_xhdi_driver(void);
                 //xhdi.c
+extern PUN_INFO pun_usb;
                 //xhdi.c
+extern unsigned long my_drvbits;
         //xhdi.c
+extern char *product_name[MAX_LOGICAL_DRIVE];                  //xhdi.c
+/*
+ * end of stuff for other headers
+ */
+
+
+/*
+ * these should be in e.g. install.h
+ */
+long install_usb_stor(long dev_num,unsigned long part_type,unsigned
long part_offset,
+                                       unsigned long part_size,char
*vendor,char *revision,char *product);
+long uninstall_usb_stor(long logdrv);
+BPB *usb_getbpb(long logdrv);
+long usb_mediach(long logdrv);
+long usb_rwabs(long logdrv,long start,long count,void *buffer,long mode);
+
+
+/*
+ * extended FAT12/FAT16 bootsector
+ */
+typedef struct {
+  /*   0 */    uchar bra[2];
+  /*   2 */    uchar loader[6];
+  /*   8 */    uchar serial[3];
+  /*   b */    uchar bps[2];                   /* bytes per sector */
+  /*   d */    uchar spc;                              /* sectors per
cluster */
+  /*   e */    uchar res[2];                   /* number of reserved sectors */
+  /*  10 */    uchar fat;                              /* number of FATs */
+  /*  11 */    uchar dir[2];                   /* number of DIR root entries */
+  /*  13 */    uchar sec[2];                   /* total number of sectors */
+  /*  15 */    uchar media;                    /* media descriptor */
+  /*  16 */    uchar spf[2];                   /* sectors per FAT */
+  /*  18 */    uchar spt[2];                   /* sectors per track */
+  /*  1a */    uchar sides[2];                 /* number of sides */
+  /*  1c */    uchar hid[4];                   /* number of hidden
sectors (earlier: 2 bytes) */
+  /*  20 */    uchar sec2[4];                  /* total number of
sectors (if not in sec) */
+  /*  24 */    uchar ldn;                              /* logical
drive number */
+  /*  25 */    uchar dirty;                    /* dirty filesystem flags */
+  /*  26 */    uchar ext;                              /* extended signature */
+  /*  27 */    uchar serial2[4];               /* extended serial number */
+  /*  2b */    uchar label[11];                /* volume label */
+  /*  36 */    uchar fstype[8];                /* file system type */
+  /*  3e */    uchar data[0x1c0];
+  /* 1fe */    uchar cksum[2];
+} FAT16_BS;
+
+/*
+ * various text values access as longs
+ */
+#define AHDI           0x41484449L             /* 'AHDI' */
+#define GEM                    0x0047454dL             /* '\0GEM' */
+#define BGM                    0x0042474dL             /* '\0BGM' */
+#define RAW                    0x00524157L             /* '\0RAW' */
+#define MINIX          0x00004481L
+#define LNX                    0x00004483L
+
+/*
+ * DOS partition ids that we support
+ */
+static const unsigned long valid_dos[] = { 0x04, 0x06, 0x0e, 0x0b,
0x0c, 0x81, 0x83, 0 };
+
+unsigned short vectors_installed = 0;
+char boot_sector[DEFAULT_SECTOR_SIZE];
+
+/*
+ *     local function prototypes
+ */
+static void build_bpb(BPB *bpbptr,FAT16_BS *bs);
+static void display_error(long dev_num,char *vendor,char
*revision,char *product,char *msg);
+static void display_installed(long dev_num,char *vendor,char
*revision,char *product,int logdrv);
+static void display_usb(long dev_num,char *vendor,char *revision,char
*product);
+static unsigned long getilong(uchar *byte);
+static unsigned short getiword(uchar *byte);
+static long valid_drive(long logdrv);
+
+#ifdef DEBUGGING_ROUTINES
+void hex_nybble(int n);
+void hex_byte(uchar n);
+void hex_word(ushort n);
+void hex_long(ulong n);
+
+void hex_nybble(int n)
+{
+       char c;
+
+       c = (n > 9) ? 'A'+n-10 : '0'+n;
+       c_conout(c);
+}
+
+void hex_byte(uchar n)
+{
+       hex_nybble(n>>4);
+       hex_nybble(n&0x0f);
+}
+
+void hex_word(ushort n)
+{
+       hex_byte(n>>8);
+       hex_byte(n&0xff);
+}
+
+void hex_long(ulong n)
+{
+       hex_word(n>>16);
+       hex_word(n&0xffff);
+};
+#endif
+
+/*
+ *     convert Intel (little-endian) values to big-endian
+ */
+static unsigned short getiword(uchar *byte)
+{
+       union {
+               char c[2];
+               unsigned short w;
+       } u;
+
+       u.c[1] = *byte++;
+       u.c[0] = *byte;
+
+       return u.w;
+}
+
+static unsigned long getilong(uchar *byte)
+{
+       union {
+               char c[4];
+               unsigned long l;
+       } u;
+
+       u.c[3] = *byte++;
+       u.c[2] = *byte++;
+       u.c[1] = *byte++;
+       u.c[0] = *byte;
+
+       return u.l;
+}
+
+/*
+ *     build the BPB from the boot sector
+ *
+ *     if it is neither FAT12 nor FAT16, we set 'recsiz' to zero
+ */
+static void build_bpb(BPB *bpbptr,FAT16_BS *bs)
+{
+       unsigned short bps, spf;
+       unsigned long res, sectors, clusters;
+
+       bpbptr->recsiz = 0;
 /* default to invalid size */
+
+       /*
+        * check for valid FAT16
+        */
+       if (bs->spc == 0)
+               return;
+       bps = getiword(bs->bps);                                /*
bytes per sector */
+       if (bps == 0)
+               return;
+
+       bpbptr->recsiz = bps;
+       bpbptr->clsiz = bs->spc;                                /*
sectors per cluster */
+       bpbptr->clsizb = bs->spc * bps;
+       bpbptr->rdlen = (32L*getiword(bs->dir)+bps-1) / bps;/* root
dir len, rounded up */
+
+       res = getiword(bs->res);                                /*
reserved sectors */
+       if (res == 0)
 /* shouldn't happen:          */
+               res = 1;
         /*  we use the TOS assumption */
+       spf = getiword(bs->spf);                                /*
sectors per fat */
+       bpbptr->fsiz = spf;
+       bpbptr->fatrec = res + spf;                             /*
start of fat #2 */
+       bpbptr->datrec = res + bs->fat*spf + bpbptr->rdlen;     /*
start of data */
+
+       sectors = getiword(bs->sec);                    /* old sector count */
+       if (!sectors)
 /* zero => more than 65535, */
+               sectors = getilong(bs->sec2);           /*  so use new
sector count */
+       clusters = (sectors - bpbptr->datrec) / bs->spc;        /*
number of clusters */
+       if (clusters > MAX_FAT16_CLUSTERS) {
+               bpbptr->recsiz = 0;
+               return;
+       }
+       bpbptr->numcl = clusters;
+       if (clusters > MAX_FAT12_CLUSTERS)
+               bpbptr->bflags = 1;
 /* FAT16 */
+}
+
+static void display_usb(long dev_num,char *vendor,char *revision,char *product)
+{
+       c_conws("USB ");
+       c_conout('0'+dev_num);          /* we assume dev_num <= 9 */
+       c_conws(".0 ");
+       c_conws(vendor);
+       c_conout(' ');
+       c_conws(revision);
+       c_conout(' ');
+       c_conws(product);
+}
+
+static void display_error(long dev_num,char *vendor,char
*revision,char *product,char *msg)
+{
+       display_usb(dev_num,vendor,revision,product);
+       c_conws(": ");
+       c_conws(msg);
+       c_conws("\r\n");
+}
+
+static void display_installed(long dev_num,char *vendor,char
*revision,char *product,int logdrv)
+{
+       display_usb(dev_num,vendor,revision,product);
+       c_conws(": installed as drive ");
+       c_conout('A'+logdrv);
+       c_conws("\r\n");
+}
+
+/*
+ *     test for valid DOS or GEMDOS partition
+ *     returns 1 iff valid
+ */
+static int valid_partition(unsigned long type)
+{
+       const unsigned long *valid;
+
+       for (valid = valid_dos; *valid; valid++)
+               if (type == *valid)
+                       return 1;
+
+       type &= 0x00ffffffL;
+
+       if ((type == GEM) || (type == BGM) || (type == RAW))
+               return 1;
+
+       return 0;
+}
+
+/*
+ *  install the new device
+ *
+ *     returns -1 for error, otherwise the drive number assigned
+ */
+long install_usb_stor(long dev_num,unsigned long part_type,unsigned
long part_offset,
+                                       unsigned long part_size,char
*vendor,char *revision,char *product)
+{
+       int logdrv;
+       long mask;
+
+       /*
+        * check input parameters
+        */
+       if (dev_num > PUN_DEV) {
+               display_error(dev_num,vendor,revision,product,"invalid
device number");
+               return -1L;
+       }
+       if (!valid_partition(part_type)) {
+               display_error(dev_num,vendor,revision,product,"invalid
partition type");
+               return -1L;
+       }
+
+       /*
+        * install PUN_INFO if necessary
+        */
+       if (pun_usb.cookie != AHDI) {
+               pun_usb.cookie = AHDI;
+               pun_usb.cookie_ptr = &pun_usb.cookie;
+               pun_usb.puns = 0;
+               pun_usb.version_num = 0x0300;
+               pun_usb.max_sect_siz = MAX_LOGSEC_SIZE;
+               memset(pun_usb.pun,0xff,MAX_LOGICAL_DRIVE);     /*
mark all puns invalid */
+       }
+
+       /*
+        * find first free non-floppy drive
+        */
+       for (logdrv = 'C'-'A', mask = (1L<<logdrv); logdrv <
MAX_LOGICAL_DRIVE; logdrv++, mask<<=1)
+               if (!(drvbits&mask))
+                       break;
+       if (logdrv >= MAX_LOGICAL_DRIVE) {
+               display_error(dev_num,vendor,revision,product,"no
drives available");
+               return -1L;
+       }
+
+       /*
+        * read in the first sector, which we'll get BPB info from
+        */
+       if (usb_stor_read(dev_num,part_offset,1,boot_sector) != 1) {
+               display_error(dev_num,vendor,revision,product,"boot
sector not readable");
+               return -1L;
+       }
+
+       /*
+        * fill in the pun_info structure
+        */
+       pun_usb.puns++;
+
+       pun_usb.pun[logdrv] = dev_num | PUN_USB;
+       pun_usb.partition_start[logdrv] = part_offset;
+
+       part_type <<= 8;                                        /* for
XHDI, make it a 3-character string */
+       if (part_type&0xff000000L)
         /* i.e. GEM/BGM/RAW */
+               pun_usb.ptype[logdrv] = part_type;
         /* e.g. 0x47454d00 */
+       else pun_usb.ptype[logdrv] = 0x00440000L | part_type;/* e.g.
0x00440600 */
+
+       pun_usb.psize[logdrv] = part_size;
+       pun_usb.flags[logdrv] = CHANGE_FLAG;
+       build_bpb(&pun_usb.bpb[logdrv],(FAT16_BS *)boot_sector);
+
+       /*
+        * update drive bits etc
+        */
+       drvbits |= 1L << logdrv;
+       my_drvbits |= 1L << logdrv;                     /* used for XHDI */
+       if (logdrv == 'C'-'A') {                        /* if drive C,
make it the boot drive */
+               bootdev = logdrv;                               /* (is
this correct?)                 */
+               d_setdrv(logdrv);
+       }
+
+       /*
+        * if necessary, install hdv_xxx vectors & xhdi driver
+        */
+       if (!vectors_installed) {
+               install_vectors();
+               install_xhdi_driver();
+               vectors_installed = 1;
+       }
+
+       /*
+        * save product name ptr for XHDI
+        *
+        * FIXME: assumes ptr points to a static area - is this valid?
+        */
+       product_name[dev_num] = product;
+
+       display_installed(dev_num,vendor,revision,product,logdrv);
+
+       return logdrv;
+}
+
+long uninstall_usb_stor(long logdrv)
+{
+       if ((logdrv < 0) || (logdrv >= MAX_LOGICAL_DRIVE))
+               return -1L;
+
+       pun_usb.puns--;
+       pun_usb.pun[logdrv] = 0xff;
+       pun_usb.partition_start[logdrv] = 0L;   /* probably unnecessary */
+
+       drvbits &= ~(1L<<logdrv);
+       my_drvbits &= ~(1L<<logdrv);
+
+       return 0L;
+}
+
+/*
+ *     the following functions are called from the various intercepts
+ */
+
+/*
+ *     validity check (paranoia, should already have been done by the caller)
+ */
+static long valid_drive(long logdrv)
+{
+       if ((logdrv < 0) || (logdrv >= MAX_LOGICAL_DRIVE))
+               return 0;
+       if (pun_usb.pun[logdrv]&PUN_VALID)      /* means invalid ... */
+               return 0;
+
+       if (!(pun_usb.pun[logdrv]&PUN_USB))
+               return 0;
+
+       return 1;
+}
+
+/*
+ *     return BPB pointer for specified drive
+ */
+BPB *usb_getbpb(long logdrv)
+{
+       unsigned long type;
+       BPB *bpbptr;
+
+       if (!valid_drive(logdrv))
+               return NULL;
+
+       type = pun_usb.ptype[logdrv] >> 8;
+       if ((type == LNX) || (type == MINIX) || (type == RAW))
+               return NULL;
+
+       bpbptr = &pun_usb.bpb[logdrv];
+#ifdef TOSONLY
+       /*
+        * note: we don't check for a proper Atari partition type, although we
+        * theoretically should.  this is to allow us to create TOS-readable
+        * memory sticks, by using Linux to create an Atari-format filesystem
+        * within a partition that's identified as DOS FAT16.
+        */
+       if (bpbptr->recsiz == 0)        /* not FAT16 when building the BPB */
+               return NULL;
+       if (bpbptr->clsiz != 2)         /* TOS only likes 2-sector clusters */
+               return NULL;
+#endif
+
+       return bpbptr;
+}
+
+/*
+ *     perform Rwabs()
+ */
+long usb_rwabs(long logdrv,long start,long count,void *buffer,long mode)
+{
+       long rc;
+       long physdev;                                   /* physical device */
+
+       if ((start < 0L) || (count < 0L) || !buffer)
+               return EBADR;                           /* same as EBADRQ */
+
+       if (mode & NOTRANSLATE) {               /* if physical mode,
the rwabs intercept */
+               physdev = logdrv;                       /*  has
already allowed for floppies     */
+       } else {
+               BPB *bpbptr;
+               unsigned short phys_per_log;/* physical sectors per
logical sector */
+
+               if (!valid_drive(logdrv))
+                       return ENXIO;                   /* same as EDRIVE */
+
+               bpbptr = &pun_usb.bpb[logdrv];
+               if (!bpbptr->recsiz)
+                       return ENXIO;
+               phys_per_log = bpbptr->recsiz / 512;
+
+               start = start * phys_per_log;
+               count = count * phys_per_log;
+               if ((start+count) > pun_usb.psize[logdrv])
+                       return EBADR;
+
+               start += pun_usb.partition_start[logdrv];
+               physdev = pun_usb.pun[logdrv] & PUN_DEV;
+       }
+
+       if (count == 0L)
+               return 0;
+
+       /*
+        * set up for read or write
+        */
+
+       if (mode&RWFLAG)
+               rc = usb_stor_write(physdev,start,count,buffer);
+       else rc = usb_stor_read(physdev,start,count,buffer);
+
+       return (rc==count) ? 0 : EIO;
+}
+
+/*
+ *     perform Mediach()
+ */
+long usb_mediach(long logdrv)
+{
+       long rc;
+
+       if (!valid_drive(logdrv))
+               return 0;
+
+       rc = (pun_usb.flags[logdrv]&CHANGE_FLAG) ? 2 : 0;
+       pun_usb.flags[logdrv] &= ~CHANGE_FLAG;
+
+       return rc;
+}

_______________________________________________
cz-bobek-lists-mint-cvs mailing list
mint-cvs@lists.bobek.cz
https://lists.bobek.cz/mailman/listinfo/cz-bobek-lists-mint-cvs