56 #include <linux/module.h>
57 #include <linux/slab.h>
72 #include <asm/setup.h>
73 #include <asm/uaccess.h>
82 #define IOCTL_RAW_TRACK 0x5254524B
96 #define FD_NOTACTIVE 3
107 #define FD_NODRIVE 0x00000000
108 #define FD_DD_3 0xffffffff
109 #define FD_HD_3 0x55555555
110 #define FD_DD_5 0xaaaaaaaa
113 static unsigned long int fd_def_df0 =
FD_DD_3;
121 #define MOTOR_ON (ciab.prb &= ~DSKMOTOR)
122 #define MOTOR_OFF (ciab.prb |= DSKMOTOR)
123 #define SELECT(mask) (ciab.prb &= ~mask)
124 #define DESELECT(mask) (ciab.prb |= mask)
125 #define SELMASK(drive) (1 << (3 + (drive & 3)))
130 {
FD_DD_3,
"DD 3.5", 80, 2, 14716, 13630, 1, 80,161, 3, 18, 1},
131 {
FD_HD_3,
"HD 3.5", 80, 2, 28344, 27258, 2, 80,161, 3, 18, 1},
132 {
FD_DD_5,
"DD 5.25", 40, 2, 14716, 13630, 1, 40, 81, 6, 30, 2},
133 {
FD_NODRIVE,
"No Drive", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
135 static int num_dr_types =
ARRAY_SIZE(drive_types);
137 static int amiga_read(
int),
dos_read(
int);
138 static void amiga_write(
int),
dos_write(
int);
140 {
"Amiga", 11 , amiga_read, amiga_write},
151 static int on_attempts;
155 static volatile int fdc_busy = -1;
156 static volatile int fdc_nested;
161 static volatile int selected = -1;
163 static int writepending;
164 static int writefromint;
165 static char *raw_buf;
166 static int fdc_queue;
170 #define RAW_BUF_SIZE 30000
177 static volatile char block_flag;
181 static unsigned char mfmencode[16]={
182 0x2a, 0x29, 0x24, 0x25, 0x12, 0x11, 0x14, 0x15,
183 0x4a, 0x49, 0x44, 0x45, 0x52, 0x51, 0x54, 0x55
185 static unsigned char mfmdecode[128];
189 #define MS_TICKS ((amiga_eclock+50)/1000)
196 #define MAX_ERRORS 12
198 #define custom amiga_custom
201 static int fd_ref[4] = { 0,0,0,0 };
202 static int fd_device[4] = { 0, 0, 0, 0 };
220 static void ms_delay(
int ms)
239 static inline int try_fdc(
int drive)
242 return ((fdc_busy < 0) || (fdc_busy == drive));
245 static void get_fdc(
int drive)
251 printk(
"get_fdc: drive %d fdc_busy %d fdc_nested %d\n",drive,fdc_busy,fdc_nested);
260 static inline void rel_fdc(
void)
264 printk(
"fd: unmatched rel_fdc\n");
265 printk(
"rel_fdc: fdc_busy %d fdc_nested %d\n",fdc_busy,fdc_nested);
268 if (fdc_nested == 0) {
274 static void fd_select (
int drive)
276 unsigned char prb = ~0;
280 printk(
"selecting %d\n",drive);
282 if (drive == selected)
289 if (
unit[drive].motor == 1)
298 static void fd_deselect (
int drive)
305 printk(
"deselecting %d\n",drive);
307 if (drive != selected) {
326 static void motor_on_callback(
unsigned long nr)
328 if (!(
ciaa.pra &
DSKRDY) || --on_attempts == 0) {
331 motor_on_timer.expires =
jiffies +
HZ/10;
336 static int fd_motor_on(
int nr)
342 if (!
unit[nr].motor) {
347 motor_on_timer.data =
nr;
355 if (on_attempts == 0) {
362 printk (
KERN_WARNING "DSKRDY not set after 1.5 seconds - assuming drive is spinning notwithstanding\n");
369 static void fd_motor_off(
unsigned long drive)
375 decusecount = drive & 0x40000000;
377 calledfromint = drive & 0x80000000;
379 if (calledfromint && !try_fdc(drive)) {
381 motor_off_timer[drive].expires =
jiffies + 1;
385 unit[drive].motor = 0;
391 static void floppy_off (
unsigned int nr)
397 motor_off_timer[drive].data = nr | 0x80000000;
398 mod_timer(motor_off_timer + drive, jiffies + 3*
HZ);
401 static int fd_calibrate(
int drive)
408 if (!fd_motor_on (drive))
415 for (n =
unit[drive].
type->tracks/2; n != 0; --n) {
423 ms_delay(
unit[drive].
type->step_delay);
425 ms_delay (
unit[drive].
type->settle_time);
427 n =
unit[drive].type->tracks + 20;
434 ms_delay(
unit[drive].
type->step_delay + 1);
438 printk (
KERN_ERR "fd%d: calibrate failed, turning motor off\n", drive);
439 fd_motor_off (drive);
440 unit[drive].track = -1;
445 unit[drive].track = 0;
446 ms_delay(
unit[drive].
type->settle_time);
453 static int fd_seek(
int drive,
int track)
459 printk(
"seeking drive %d to track %d\n",drive,track);
463 if (
unit[drive].track == track) {
467 if (!fd_motor_on(drive)) {
471 if (
unit[drive].track < 0 && !fd_calibrate(drive)) {
477 cnt =
unit[drive].track/2 - track/2;
487 if (track % 2 !=
unit[drive].track % 2)
488 ms_delay (
unit[drive].
type->side_time);
501 ms_delay (
unit[drive].
type->step_delay);
502 }
while (--cnt != 0);
503 ms_delay (
unit[drive].
type->settle_time);
510 static unsigned long fd_get_drive_id(
int drive)
532 for (i=0; i<32; i++) {
565 if (block_flag == 2) {
567 post_write_timer.expires =
jiffies + 1;
568 post_write_timer.data = selected;
578 static void raw_read(
int drive)
604 static int raw_write(
int drive)
639 static void post_write (
unsigned long drive)
642 printk(
"post_write for drive %ld\n",drive);
649 unit[drive].dirty = 0;
662 static unsigned long scan_sync(
unsigned long raw,
unsigned long end)
666 while (ptr < endp && *ptr++ != 0x4489)
669 while (*ptr == 0x4489 && ptr < endp)
676 static inline unsigned long checksum(
unsigned long *
addr,
int len)
678 unsigned long csum = 0;
680 len /=
sizeof(*addr);
683 csum = ((csum>>1) & 0x55555555) ^ (csum & 0x55555555);
688 static unsigned long decode (
unsigned long *
data,
unsigned long *raw,
702 *data++ = ((*odd++ & 0x55555555) << 1) | (*even++ & 0x55555555);
703 }
while (--len != 0);
718 static int amiga_read(
int drive)
727 raw = (
long) raw_buf;
728 end = raw +
unit[drive].type->read_size;
730 for (scnt = 0;scnt <
unit[drive].dtype->sects *
unit[drive].type->sect_mult; scnt++) {
731 if (!(raw = scan_sync(raw, end))) {
741 (
char *)&hdr.
hdrchk-(
char *)&hdr);
744 printk (
"(%x,%d,%d,%d) (%lx,%lx,%lx,%lx) %lx %lx\n",
762 raw = decode ((
ulong *)(
unit[drive].trackbuf + hdr.
sect*512),
782 static void encode(
unsigned long data,
unsigned long *
dest)
787 data2 = data ^ 0x55555555;
788 data |= ((data2 >> 1) | 0x80000000) & (data2 << 1);
790 if (*(dest - 1) & 0x00000001)
796 static void encode_block(
unsigned long *dest,
unsigned long *
src,
int len)
802 for (cnt = 0; cnt < len / 4; cnt++) {
803 data = src[
cnt] >> 1;
804 encode(data, dest + to_cnt++);
808 for (cnt = 0; cnt < len / 4; cnt++) {
810 encode(data, dest + to_cnt++);
814 static unsigned long *putsec(
int disk,
unsigned long *raw,
int cnt)
820 *raw = (raw[-1]&1) ? 0x2AAAAAAA : 0xAAAAAAAA;
827 hdr.ord =
unit[disk].dtype->sects *
unit[disk].type->sect_mult -
cnt;
828 for (i = 0; i < 16; i++)
831 (
char *)&
hdr.hdrchk-(
char *)&
hdr);
834 encode_block(raw, (
ulong *)&
hdr.magic, 4);
836 encode_block(raw, (
ulong *)&
hdr.labels, 16);
838 encode_block(raw, (
ulong *)&
hdr.hdrchk, 4);
840 encode_block(raw, (
ulong *)&
hdr.datachk, 4);
842 encode_block(raw, (
ulong *)(
unit[disk].trackbuf+cnt*512), 512);
848 static void amiga_write(
int disk)
851 unsigned long *ptr = (
unsigned long *)raw_buf;
855 for (cnt = 0; cnt < 415 *
unit[disk].type->sect_mult; cnt++)
859 for (cnt = 0; cnt <
unit[disk].dtype->sects *
unit[disk].type->sect_mult; cnt++)
860 ptr = putsec (disk, ptr, cnt);
861 *(
ushort *)ptr = (ptr[-1]&1) ? 0x2AA8 : 0xAAA8;
932 static ushort dos_crc(
void * data_a3,
int data_d0,
int data_d1,
int data_d3)
934 static unsigned char CRCTable1[] = {
935 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x81,0x91,0xa1,0xb1,0xc1,0xd1,0xe1,0xf1,
936 0x12,0x02,0x32,0x22,0x52,0x42,0x72,0x62,0x93,0x83,0xb3,0xa3,0xd3,0xc3,0xf3,0xe3,
937 0x24,0x34,0x04,0x14,0x64,0x74,0x44,0x54,0xa5,0xb5,0x85,0x95,0xe5,0xf5,0xc5,0xd5,
938 0x36,0x26,0x16,0x06,0x76,0x66,0x56,0x46,0xb7,0xa7,0x97,0x87,0xf7,0xe7,0xd7,0xc7,
939 0x48,0x58,0x68,0x78,0x08,0x18,0x28,0x38,0xc9,0xd9,0xe9,0xf9,0x89,0x99,0xa9,0xb9,
940 0x5a,0x4a,0x7a,0x6a,0x1a,0x0a,0x3a,0x2a,0xdb,0xcb,0xfb,0xeb,0x9b,0x8b,0xbb,0xab,
941 0x6c,0x7c,0x4c,0x5c,0x2c,0x3c,0x0c,0x1c,0xed,0xfd,0xcd,0xdd,0xad,0xbd,0x8d,0x9d,
942 0x7e,0x6e,0x5e,0x4e,0x3e,0x2e,0x1e,0x0e,0xff,0xef,0xdf,0xcf,0xbf,0xaf,0x9f,0x8f,
943 0x91,0x81,0xb1,0xa1,0xd1,0xc1,0xf1,0xe1,0x10,0x00,0x30,0x20,0x50,0x40,0x70,0x60,
944 0x83,0x93,0xa3,0xb3,0xc3,0xd3,0xe3,0xf3,0x02,0x12,0x22,0x32,0x42,0x52,0x62,0x72,
945 0xb5,0xa5,0x95,0x85,0xf5,0xe5,0xd5,0xc5,0x34,0x24,0x14,0x04,0x74,0x64,0x54,0x44,
946 0xa7,0xb7,0x87,0x97,0xe7,0xf7,0xc7,0xd7,0x26,0x36,0x06,0x16,0x66,0x76,0x46,0x56,
947 0xd9,0xc9,0xf9,0xe9,0x99,0x89,0xb9,0xa9,0x58,0x48,0x78,0x68,0x18,0x08,0x38,0x28,
948 0xcb,0xdb,0xeb,0xfb,0x8b,0x9b,0xab,0xbb,0x4a,0x5a,0x6a,0x7a,0x0a,0x1a,0x2a,0x3a,
949 0xfd,0xed,0xdd,0xcd,0xbd,0xad,0x9d,0x8d,0x7c,0x6c,0x5c,0x4c,0x3c,0x2c,0x1c,0x0c,
950 0xef,0xff,0xcf,0xdf,0xaf,0xbf,0x8f,0x9f,0x6e,0x7e,0x4e,0x5e,0x2e,0x3e,0x0e,0x1e
953 static unsigned char CRCTable2[] = {
954 0x00,0x21,0x42,0x63,0x84,0xa5,0xc6,0xe7,0x08,0x29,0x4a,0x6b,0x8c,0xad,0xce,0xef,
955 0x31,0x10,0x73,0x52,0xb5,0x94,0xf7,0xd6,0x39,0x18,0x7b,0x5a,0xbd,0x9c,0xff,0xde,
956 0x62,0x43,0x20,0x01,0xe6,0xc7,0xa4,0x85,0x6a,0x4b,0x28,0x09,0xee,0xcf,0xac,0x8d,
957 0x53,0x72,0x11,0x30,0xd7,0xf6,0x95,0xb4,0x5b,0x7a,0x19,0x38,0xdf,0xfe,0x9d,0xbc,
958 0xc4,0xe5,0x86,0xa7,0x40,0x61,0x02,0x23,0xcc,0xed,0x8e,0xaf,0x48,0x69,0x0a,0x2b,
959 0xf5,0xd4,0xb7,0x96,0x71,0x50,0x33,0x12,0xfd,0xdc,0xbf,0x9e,0x79,0x58,0x3b,0x1a,
960 0xa6,0x87,0xe4,0xc5,0x22,0x03,0x60,0x41,0xae,0x8f,0xec,0xcd,0x2a,0x0b,0x68,0x49,
961 0x97,0xb6,0xd5,0xf4,0x13,0x32,0x51,0x70,0x9f,0xbe,0xdd,0xfc,0x1b,0x3a,0x59,0x78,
962 0x88,0xa9,0xca,0xeb,0x0c,0x2d,0x4e,0x6f,0x80,0xa1,0xc2,0xe3,0x04,0x25,0x46,0x67,
963 0xb9,0x98,0xfb,0xda,0x3d,0x1c,0x7f,0x5e,0xb1,0x90,0xf3,0xd2,0x35,0x14,0x77,0x56,
964 0xea,0xcb,0xa8,0x89,0x6e,0x4f,0x2c,0x0d,0xe2,0xc3,0xa0,0x81,0x66,0x47,0x24,0x05,
965 0xdb,0xfa,0x99,0xb8,0x5f,0x7e,0x1d,0x3c,0xd3,0xf2,0x91,0xb0,0x57,0x76,0x15,0x34,
966 0x4c,0x6d,0x0e,0x2f,0xc8,0xe9,0x8a,0xab,0x44,0x65,0x06,0x27,0xc0,0xe1,0x82,0xa3,
967 0x7d,0x5c,0x3f,0x1e,0xf9,0xd8,0xbb,0x9a,0x75,0x54,0x37,0x16,0xf1,0xd0,0xb3,0x92,
968 0x2e,0x0f,0x6c,0x4d,0xaa,0x8b,0xe8,0xc9,0x26,0x07,0x64,0x45,0xa2,0x83,0xe0,0xc1,
969 0x1f,0x3e,0x5d,0x7c,0x9b,0xba,0xd9,0xf8,0x17,0x36,0x55,0x74,0x93,0xb2,0xd1,0xf0
974 register unsigned char *CRCT1, *CRCT2, *
data,
c, crch, crcl;
981 for (i=data_d3; i>=0; i--) {
982 c = (*data++) ^ crch;
983 crch = CRCT1[
c] ^ crcl;
986 return (crch<<8)|crcl;
991 return dos_crc(&(hdr->
track), 0xb2, 0x30, 3);
994 static inline ushort dos_data_crc(
unsigned char *data)
996 return dos_crc(data, 0xe2, 0x95 ,511);
999 static inline unsigned char dos_decode_byte(
ushort word)
1002 register unsigned char byte;
1003 register unsigned char *dec = mfmdecode;
1015 static unsigned long dos_decode(
unsigned char *data,
unsigned short *raw,
int len)
1019 for (i = 0; i < len; i++)
1020 *data++=dos_decode_byte(*raw++);
1021 return ((
ulong)raw);
1025 static void dbg(
unsigned long ptr)
1027 printk(
"raw data @%08lx: %08lx, %08lx ,%08lx, %08lx\n", ptr,
1042 raw = (
long) raw_buf;
1043 end = raw +
unit[drive].type->read_size;
1045 for (scnt=0; scnt <
unit[drive].dtype->sects *
unit[drive].type->sect_mult; scnt++) {
1047 if (!(raw = scan_sync (raw, end))) {
1049 "track %d, unit %d for sector %d\n",
1050 unit[drive].track,drive,scnt);
1056 }
while (*((
ushort *)raw)!=0x5554);
1058 raw = dos_decode((
unsigned char *)&hdr,(
ushort *) raw,8);
1059 crc = dos_hdr_crc(&hdr);
1066 if (crc != hdr.
crc) {
1071 if (hdr.
track !=
unit[drive].track/
unit[drive].type->heads) {
1074 unit[drive].track/
unit[drive].type->heads);
1078 if (hdr.
side !=
unit[drive].track%
unit[drive].type->heads) {
1081 unit[drive].track%
unit[drive].type->heads);
1091 printk(
"hdr accepted\n");
1093 if (!(raw = scan_sync (raw, end))) {
1095 "%d, unit %d for sector%d, disk sector %d\n",
1096 unit[drive].track, drive, scnt, hdr.
sec);
1103 if (*((
ushort *)raw)!=0x5545) {
1105 "sync (%d,%d,%d,%d) sc=%d\n",
1111 raw = dos_decode((
unsigned char *)(
unit[drive].trackbuf + (hdr.
sec - 1) * 512), (
ushort *) raw, 512);
1112 raw = dos_decode((
unsigned char *)data_crc,(
ushort *) raw,4);
1113 crc = dos_data_crc(
unit[drive].trackbuf + (hdr.
sec - 1) * 512);
1115 if (crc != data_crc[0]) {
1130 static inline ushort dos_encode_byte(
unsigned char byte)
1132 register unsigned char *enc, b2, b1;
1139 word=enc[b2] <<8 | enc [b1];
1140 return (word|((word&(256|64)) ? 0: 128));
1143 static void dos_encode_block(
ushort *dest,
unsigned char *src,
int len)
1147 for (i = 0; i < len; i++) {
1148 *dest=dos_encode_byte(*src++);
1149 *dest|=((dest[-1]&1)||(*dest&0x4000))? 0: 0x8000;
1154 static unsigned long *ms_putsec(
int drive,
unsigned long *raw,
int cnt)
1157 {78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78}};
1174 hdr.
crc=dos_hdr_crc(&hdr);
1177 dos_encode_block((
ushort *)raw,(
unsigned char *) &hdr.
track,28);
1189 dos_encode_block((
ushort *)raw,
1190 (
unsigned char *)
unit[drive].trackbuf+cnt*512,512);
1194 crc[0]=dos_data_crc(
unit[drive].trackbuf+cnt*512);
1195 dos_encode_block((
ushort *) raw,(
unsigned char *)crc,4);
1208 unsigned long raw = (
unsigned long) raw_buf;
1209 unsigned long *ptr=(
unsigned long *)raw;
1213 for (cnt=0;cnt<425;cnt++)
1218 for(cnt=0;cnt<473;cnt++)
1222 for (cnt=0;cnt<20;cnt++)
1224 for (cnt=0;cnt<6;cnt++)
1228 for (cnt=0;cnt<20;cnt++)
1232 for(cnt = 0; cnt <
unit[disk].dtype->sects *
unit[disk].type->sect_mult; cnt++)
1233 ptr=ms_putsec(disk,ptr,cnt);
1248 static void flush_track_callback(
unsigned long nr)
1254 flush_track_timer[
nr].expires =
jiffies + 1;
1259 (*
unit[
nr].dtype->write_fkt)(nr);
1260 if (!raw_write(nr)) {
1268 static int non_int_flush_track (
unsigned long nr)
1270 unsigned long flags;
1276 if (!fd_motor_on(nr)) {
1282 if (writepending != 2) {
1284 (*
unit[
nr].dtype->write_fkt)(nr);
1285 if (!raw_write(nr)) {
1302 static int get_track(
int drive,
int track)
1307 if (
unit[drive].track == track)
1310 if (!fd_motor_on(drive)) {
1317 non_int_flush_track (drive);
1321 if (!fd_seek(drive, track))
1324 error = (*
unit[drive].dtype->read_fkt)(drive);
1330 unit[drive].track = -1;
1340 static struct request *set_next_request(
void)
1347 fdc_queue = fdc_queue + 1;
1359 q =
unit[fdc_queue].gendisk->queue;
1373 static void redo_fd_request(
void)
1380 unsigned long flags;
1384 rq = set_next_request();
1390 floppy = rq->rq_disk->private_data;
1391 drive = floppy -
unit;
1395 for (cnt = 0, err = 0; cnt < blk_rq_cur_sectors(rq); cnt++) {
1397 printk(
"fd: sector %ld + %d requested for %s\n",
1398 blk_rq_pos(rq), cnt,
1399 (rq_data_dir(rq) ==
READ) ?
"read" :
"write");
1401 block = blk_rq_pos(rq) +
cnt;
1402 if ((
int)block > floppy->
blocks) {
1407 track = block / (floppy->
dtype->sects * floppy->
type->sect_mult);
1408 sector = block % (floppy->
dtype->sects * floppy->
type->sect_mult);
1409 data = rq->buffer + 512 *
cnt;
1411 printk(
"access to track %d, sector %d, with buffer at "
1412 "0x%08lx\n", track, sector, data);
1415 if (get_track(drive, track) == -1) {
1420 if (rq_data_dir(rq) ==
READ) {
1426 if (!fd_motor_on(drive)) {
1438 mod_timer (flush_track_timer + drive, jiffies + 1);
1457 geo->
heads = unit[drive].type->heads;
1458 geo->
sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult;
1459 geo->
cylinders = unit[drive].type->tracks;
1464 unsigned int cmd,
unsigned long param)
1467 int drive = p -
unit;
1474 if (fd_ref[drive] > 1) {
1479 if (fd_motor_on(drive) == 0) {
1483 if (fd_calibrate(drive) == 0) {
1494 if (fd_seek(drive,param) != 0){
1496 p->
dtype->sects * p->
type->sect_mult * 512);
1497 non_int_flush_track(drive);
1510 memset((
void *)&getprm, 0,
sizeof (getprm));
1511 getprm.track=p->
type->tracks;
1512 getprm.head=p->
type->heads;
1513 getprm.sect=p->
dtype->sects * p->
type->sect_mult;
1523 non_int_flush_track(drive);
1530 return p->
type->read_size;
1541 unsigned int cmd,
unsigned long param)
1546 ret = fd_locked_ioctl(bdev, mode, cmd, param);
1552 static void fd_probe(
int dev)
1559 code = fd_get_drive_id(drive);
1562 for (type = 0; type < num_dr_types; type++)
1563 if (drive_types[type].code == code)
1566 if (type >= num_dr_types) {
1568 "%08lx found\n", code);
1569 unit[drive].type = &drive_types[num_dr_types-1];
1573 unit[drive].type = drive_types +
type;
1574 unit[drive].track = -1;
1576 unit[drive].disk = -1;
1577 unit[drive].motor = 0;
1578 unit[drive].busy = 0;
1579 unit[drive].status = -1;
1592 unsigned long flags;
1595 old_dev = fd_device[drive];
1597 if (fd_ref[drive] && old_dev != system) {
1610 fd_deselect (drive);
1622 fd_device[drive] =
system;
1625 unit[drive].dtype=&data_types[
system];
1626 unit[drive].blocks=unit[drive].type->heads*unit[drive].type->tracks*
1627 data_types[
system].
sects*unit[drive].type->sect_mult;
1628 set_capacity(unit[drive].gendisk, unit[drive].blocks);
1631 unit[drive].type->name, data_types[system].
name);
1637 static int floppy_release(
struct gendisk *disk,
fmode_t mode)
1640 int drive = p -
unit;
1643 if (unit[drive].
dirty == 1) {
1645 non_int_flush_track (drive);
1648 if (!fd_ref[drive]--) {
1654 floppy_off (drive | 0x40000000);
1666 static unsigned amiga_check_events(
struct gendisk *disk,
unsigned int clearing)
1669 int drive = p -
unit;
1671 static int first_time = 1;
1674 changed = first_time--;
1679 fd_deselect (drive);
1689 return DISK_EVENT_MEDIA_CHANGE;
1694 static const struct block_device_operations floppy_fops = {
1696 .open = floppy_open,
1697 .release = floppy_release,
1699 .getgeo = fd_getgeo,
1700 .check_events = amiga_check_events,
1703 static int __init fd_probe_drives(
void)
1705 int drive,drives,nomem;
1711 struct gendisk *disk;
1720 unit[drive].gendisk = disk;
1731 unit[drive].type = &drive_types[num_dr_types - 1];
1737 disk->first_minor = drive;
1738 disk->fops = &floppy_fops;
1739 sprintf(disk->disk_name,
"fd%d", drive);
1740 disk->private_data = &unit[drive];
1741 set_capacity(disk, 880*2);
1744 if ((drives > 0) || (nomem == 0)) {
1756 int drive = *part & 3;
1760 return get_disk(unit[drive].gendisk);
1773 printk(
"fd: cannot get chip mem buffer\n");
1779 printk(
"fd: cannot get irq for dma\n");
1784 printk(
"fd: cannot get irq for timer\n");
1789 if (fd_probe_drives() < 1)
1797 motor_on_timer.expires = 0;
1798 motor_on_timer.data = 0;
1799 motor_on_timer.function = motor_on_callback;
1802 motor_off_timer[
i].expires = 0;
1803 motor_off_timer[
i].data = i|0x80000000;
1804 motor_off_timer[
i].function = fd_motor_off;
1806 flush_track_timer[
i].expires = 0;
1807 flush_track_timer[
i].data =
i;
1808 flush_track_timer[
i].function = flush_track_callback;
1814 post_write_timer.expires = 0;
1815 post_write_timer.data = 0;
1816 post_write_timer.function = post_write;
1818 for (i = 0; i < 128; i++)
1820 for (i = 0; i < 16; i++)
1821 mfmdecode[mfmencode[i]]=i;
1851 kfree(unit[i].trackbuf);
1867 .name =
"amiga-floppy",
1872 static int __init amiga_floppy_init(
void)
1880 static int __init amiga_floppy_setup (
char *
str)
1892 __setup(
"floppy=", amiga_floppy_setup);