[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