1 /*
2 * Mach Operating System
3 * Copyright (c) 1992 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: fdc_82077_hdw.c,v $
29 * Revision 2.5 93/05/15 19:38:23 mrt
30 * machparam.h -> machspl.h
31 *
32 * Revision 2.4 93/05/10 20:07:49 rvb
33 * Fixed types.
34 * [93/05/06 09:58:59 af]
35 *
36 * Revision 2.3 93/01/14 17:16:20 danner
37 * Store for future reference attempt at getting it working.
38 * Something wrong with DMA stopped me.
39 * [92/12/10 af]
40 *
41 * Revision 2.2 92/03/02 18:32:45 rpd
42 * Created, initial rough cut at init and probe only.
43 * [92/01/19 af]
44 *
45 */
46 /*
47 * File: fdi_82077_hdw.c
48 * Author: Alessandro Forin, Carnegie Mellon University
49 * Date: 1/92
50 *
51 * Driver for the Intel 82077 Floppy Disk Controller.
52 */
53
54 #include <fd.h>
55 #if NFD > 0
56
57 #include <mach/std_types.h>
58 #include <machine/machspl.h>
59 #include <chips/busses.h>
60
61 #include <chips/fdc_82077.h>
62 #include <platforms.h>
63
64 /* ---- */
65 #include <device/param.h>
66 #include <device/io_req.h>
67 #include <device/device_types.h>
68 #include <device/disk_status.h>
69 #define UNITNO(d) ((d)>>5)
70 #define SLAVENO(d) (((d)>>3)&0x3)
71 #define PARAMNO(d) ((d)&0x7)
72 /* ---- */
73
74 #ifdef MAXINE
75
76 /* we can only take one */
77 #define MAX_DRIVES 1
78
79 #define my_fdc_type fdc_82077aa
80 #define the_fdc_type fd->fdc_type
81 /* later: #define the_fdc_type my_fdc_type */
82
83 /* Registers are read/written as words, byte 0 */
84 /* padding is to x40 boundaries */
85 typedef struct {
86 volatile unsigned int fd_sra; /* r: status register A */
87 int pad0[15];
88 volatile unsigned int fd_srb; /* r: status register B */
89 int pad1[15];
90 volatile unsigned int fd_dor; /* rw: digital output reg */
91 int pad2[15];
92 volatile unsigned int fd_tdr; /* rw: tape drive register */
93 int pad3[15];
94 volatile unsigned int fd_msr; /* r: main status register */
95 /*#define fd_dsr fd_msr; /* w: data rate select reg */
96 int pad4[15];
97 volatile unsigned int fd_data; /* rw: fifo */
98 int pad5[15];
99 volatile unsigned int fd_xxx; /* --reserved-- */
100 int pad6[15];
101 volatile unsigned int fd_dir; /* r: digital input reg */
102 /*#define fd_ccr fd_dir; /* w: config control reg */
103 } fd_padded_regmap_t;
104
105 #define machdep_reset_8272a(f,r)
106
107 #else /* MAXINE */
108
109 /* Pick your chip and padding */
110 #define my_fdc_type fdc_8272a
111 #define the_fdc_type my_fdc_type
112
113 #define fd_padded_regmap_t fd_8272a_regmap_t
114
115 #define machdep_reset_8272a(f,r) 1
116
117 #endif /* MAXINE */
118
119
120 #ifndef MAX_DRIVES
121 #define MAX_DRIVES DRIVES_PER_FDC
122 #endif
123
124 /*
125 * Autoconf info
126 */
127
128 static vm_offset_t fd_std[NFD] = { 0 };
129 static struct bus_device *fd_info[NFD];
130 static struct bus_ctlr *fd_minfo[NFD];
131 static int fd_probe(), fd_slave(), fd_go();
132 static void fd_attach();
133
134 struct bus_driver fd_driver =
135 { fd_probe, fd_slave, fd_attach, fd_go, fd_std, "fd", fd_info,
136 "fdc", fd_minfo, /*BUS_INTR_B4_PROBE*/};
137
138 /*
139 * Externally visible functions
140 */
141 int fd_intr(); /* kernel */
142
143 /*
144 * Media table
145 *
146 * Cyls,Sec,spc,part,Mtype,RWFpl,FGpl
147 */
148 typedef struct {
149 unsigned char d_cylperunit;
150 unsigned char d_secpercyl;
151 unsigned short d_secperunit;
152 unsigned char d_secpertrk;
153 unsigned char d_gpl;
154 unsigned char d_fgpl;
155 unsigned char d_xfer_rate;
156 } fd_params_t;
157
158 fd_params_t fd_params[8] = {
159 {80, 18, 1440, 9, 0x2a, 0x50, FD_DSR_DD_250}, /* [0] 3.50" 720 Kb */
160 {80, 36, 2880, 18, 0x1b, 0x6c, FD_DSR_DD_500}, /* [1] 3.50" 1.44 Meg */
161 {40, 18, 720, 9, 0x2a, 0x50, FD_DSR_DD_250}, /* [2] 5.25" 360 Kb */
162 {80, 30, 2400, 15, 0x1b, 0x54, FD_DSR_DD_500}, /* [3] 5.25" 1.20 Meg */
163 };
164
165 /*
166 * Software status of chip
167 */
168 struct fd_softc {
169 fd_padded_regmap_t *regs;
170 char fdc_type;
171 char fdc_mode;
172 char messed_up;
173 char slave_active;
174 struct slave_t {
175 io_req_t ior;
176 decl_simple_lock_data(,slave_lock)
177
178 /* status at end of last command */
179 unsigned char st0;
180 unsigned char st1;
181 unsigned char st2;
182 unsigned char c;
183 unsigned char h;
184 unsigned char r;
185 unsigned char n;
186 unsigned char st3;
187 /* ... */
188 unsigned char medium_status;
189 # define ST_MEDIUM_PRESENT 1
190 # define ST_MEDIUM_KNOWN 2
191 char last_command;
192 char bytes_expected;
193 fd_params_t *params;
194
195 } slave_status[DRIVES_PER_FDC];
196 } fd_softc_data[NFD];
197
198 typedef struct fd_softc *fd_softc_t;
199
200 fd_softc_t fd_softc[NFD];
201
202 static char *chip_names[4] = { "8272-A", "82072", "82077-AA", 0 };
203 static char *mode_names[4] = { "PC AT", "PS/2", "Model 30", 0 };
204
205 /*
206 * Probe chip to see if it is there
207 */
208 static fd_probe (reg, ctlr)
209 vm_offset_t reg;
210 struct bus_ctlr *ctlr;
211 {
212 int unit = ctlr->unit;
213 fd_softc_t fd;
214 fd_padded_regmap_t *regs;
215
216 /*
217 * See if we are here
218 */
219 if (check_memory(reg, 0)) {
220 /* no rides today */
221 return 0;
222 }
223
224 fd = &fd_softc_data[unit];
225 fd_softc[unit] = fd;
226
227 regs = (fd_padded_regmap_t *)reg;
228 fd->regs = regs;
229 fd->fdc_type = my_fdc_type;
230
231 fd_reset(fd);
232
233 if (the_fdc_type == fdc_82077aa) {
234 /* See if properly functioning */
235 unsigned char temp = FD_CMD_VERSION;
236 if (!fd_go(fd, 0, &temp, 1, 1))
237 return 0; /* total brxage */
238 if (!fd_get_result(fd, &temp, 1, FALSE))
239 return 0; /* partial brxage */
240 if (temp != FD_VERSION_82077AA)
241 printf( "{ %s x%x } ",
242 "Accepting non-82077aa version id",
243 temp);
244 }
245
246 printf("%s%d: %s chip controller",
247 ctlr->name, ctlr->unit, chip_names[fd->fdc_type]);
248 if (the_fdc_type == fdc_82077aa)
249 printf(" in %s mode", mode_names[fd->fdc_mode]);
250 printf(".\n");
251
252 return 1;
253 }
254
255 /* See if we like this slave */
256 static fd_slave(ui, reg)
257 struct bus_device *ui;
258 vm_offset_t reg;
259 {
260 int slave = ui->slave;
261 fd_softc_t fd;
262 unsigned char sns[2];
263
264 if (slave >= MAX_DRIVES) return 0;
265
266 fd = fd_softc[ui->ctlr];
267
268 sns[0] = FD_CMD_SENSE_DRIVE_STATUS;
269 sns[1] = slave & 0x3;
270 if (the_fdc_type == fdc_82072)
271 sns[1] |= FD_CMD_SDS_NO_MOT;
272 if (!fd_go(fd, slave, sns, 2, 1)) return 0;
273 if (!fd_get_result(fd, sns, 1, FALSE)) return 0;
274
275 fd->slave_status[slave].st3 = sns[0];
276
277 return 1;
278 }
279
280 static void
281 fd_attach (ui)
282 struct bus_device *ui;
283 {
284 /* Attach a slave */
285 }
286
287 static boolean_t
288 fd_go(fd, slave, cmd, cmdlen, reply_count)
289 fd_softc_t fd;
290 unsigned char cmd[];
291 {
292
293 /* XXX check who active, enque ifnot */
294
295 fd->slave_active = slave;
296 fd->slave_status[slave].bytes_expected = reply_count;
297 fd->slave_status[slave].last_command = *cmd;
298 return fd_command(fd, cmd, cmdlen);
299 }
300
301 fd_intr (unit, spllevel)
302 {
303 fd_softc_t fd;
304 fd_padded_regmap_t *regs;
305 unsigned char msr;
306 register struct slave_t *slv;
307
308
309 splx(spllevel);
310
311 fd = fd_softc[unit];
312 regs = fd->regs;
313
314 /* did polling see a media change */
315 /* busy bit in msr sez ifasync or not */
316
317 msr = regs->fd_msr;
318 if ((msr & (FD_MSR_RQM|FD_MSR_DIO)) == (FD_MSR_RQM|FD_MSR_DIO)) {
319
320 /* result phase */
321 *(unsigned int *)0xbc040100 &= ~0x00600000;
322
323 slv = &fd->slave_status[fd->slave_active];
324 fd_get_result(fd, &slv->st0, slv->bytes_expected, FALSE);
325 fd_start(fd, fd->slave_active, TRUE);
326 return;
327 }
328 /* async interrupt, either seek complete or media change */
329 while (1) {
330 unsigned char st[2];
331 register int slave, m;
332
333 *st = FD_CMD_SENSE_INT_STATUS;
334 fd_command(fd, st, 1);
335
336 fd_get_result(fd, st, 2, FALSE);
337
338 slave = *st & FD_ST0_DS;
339 slv = &fd->slave_status[slave];
340 slv->c = st[1];
341
342 switch (*st & FD_ST0_IC_MASK) {
343
344 case FD_ST0_IC_OK:
345 /* we get an FD_ST0_SE for RECALIBRATE. Wait for it or discard ? */
346
347 case FD_ST0_IC_AT:
348
349 case FD_ST0_IC_BAD_CMD:
350 return;
351
352 case FD_ST0_IC_AT_POLL:
353 m = slv->medium_status;
354 if (m & ST_MEDIUM_PRESENT)
355 m &= ~ST_MEDIUM_PRESENT;
356 else
357 m |= ST_MEDIUM_PRESENT;
358 slv->medium_status = m;
359 }
360 }
361 }
362
363 /*
364 * Non-interface functions and utilities
365 */
366
367 fd_reset(fd)
368 fd_softc_t fd;
369 {
370 register fd_padded_regmap_t *regs;
371
372 regs = fd->regs;
373
374 /*
375 * Reset the chip
376 */
377 if (the_fdc_type == fdc_82072)
378 /* Fix if your box uses an external PLL */
379 regs->fd_dsr = FD_DSR_RESET | FD_DSR_EPLL;
380 else if (the_fdc_type == fdc_82077aa)
381 regs->fd_dor = 0;
382 else
383 machdep_reset_8272a(fd, regs);
384
385 delay(5); /* 4usecs in specs */
386
387 /*
388 * Be smart with the smart ones
389 */
390 if (the_fdc_type == fdc_82077aa) {
391
392 /*
393 * See in which mood we are (it cannot be changed)
394 */
395 int temp;
396
397 /* Take chip out of hw reset */
398 regs->fd_dor = FD_DOR_ENABLE | FD_DOR_DMA_GATE;
399 delay(10);
400
401 /* what do we readback from the DIR register as datarate ? */
402 regs->fd_ccr = FD_DSR_SD_125;
403 delay(10);
404
405 temp = regs->fd_dir;
406 if ((temp & 0x7) == FD_DSR_SD_125)
407 fd->fdc_mode = mod30_mode;
408 else if ((temp & (FD_DIR_ones | FD_DIR_DR_MASK_PS2)) ==
409 ((FD_DSR_SD_125 << FD_DIR_DR_SHIFT_PS2) | FD_DIR_ones))
410 fd->fdc_mode = ps2_mode;
411 else
412 /* this assumes tri-stated bits 1&2 read the same */
413 fd->fdc_mode = at_mode;
414
415 }
416
417 /*
418 * Send at least 4 sense interrupt cmds, one per slave
419 */
420 {
421
422 unsigned char sns, st[2];
423 int i, nloops;
424
425 sns = FD_CMD_SENSE_INT_STATUS;
426 i = nloops = 0;
427
428 do {
429 nloops++;
430
431 (void) fd_command(fd, &sns, 1);
432
433 st[0] = 0; /* in case bad status */
434 (void) fd_get_result(fd, st, 2, TRUE);
435
436 if ((st[0] & FD_ST0_IC_MASK) == FD_ST0_IC_AT_POLL) {
437 register int slave;
438
439 slave = st[0] & FD_ST0_DS;
440 fd->slave_status[slave].st0 = st[0];
441 fd->slave_status[slave].c = st[1];
442 i++;
443 }
444 } while ( (nloops < 30) &&
445 ((i < 4) || (st[0] != FD_ST0_IC_BAD_CMD)) );
446
447 /* sanity check */
448 if (nloops == 30) {
449 (void) fd_messed_up(fd);
450 return;
451 }
452 }
453
454 /*
455 * Install current parameters
456 */
457 if (the_fdc_type != fdc_8272a) {
458
459 unsigned char cnf[4];
460
461 /* send configure command to turn polling off */
462 cnf[0] = FD_CMD_CONFIGURE;
463 cnf[1] = 0x60; /* moff 110 */
464 cnf[2] = 0x48; /* eis, poll, thr=8 */
465 cnf[3] = 0;
466 if (!fd_command(fd, cnf, 4))
467 return;
468 /* no status */
469 }
470
471 /*
472 * Send specify to select defaults
473 */
474 {
475 unsigned char sfy[3];
476
477 sfy[0] = FD_CMD_SPECIFY;
478 #if 0
479 sfy[1] = (12 << 4) | 7; /* step 4, hut 112us @500 */
480 sfy[2] = 2 << 1; /* hlt 29us @500 */
481 #else
482 sfy[1] = (13 << 4) | 15;
483 sfy[2] = 1 << 1;
484 #endif
485 (void) fd_command(fd, sfy, 3);
486 /* no status */
487 }
488 }
489
490 #define FD_MAX_WAIT 1000
491
492 boolean_t
493 fd_command(fd, cmd, cmd_len)
494 fd_softc_t fd;
495 char *cmd;
496 {
497 register fd_padded_regmap_t *regs;
498
499 regs = fd->regs;
500
501 while (cmd_len > 0) {
502 register int i, s;
503
504 /* there might be long delays, so we pay this price */
505 s = splhigh();
506 for (i = 0; i < FD_MAX_WAIT; i++)
507 if ((regs->fd_msr & (FD_MSR_RQM|FD_MSR_DIO)) ==
508 FD_MSR_RQM)
509 break;
510 else
511 delay(10);
512 if (i == FD_MAX_WAIT) {
513 splx(s);
514 return fd_messed_up(fd);
515 }
516 regs->fd_data = *cmd++;
517 splx(s);
518 if (--cmd_len) delay(12);
519 }
520
521 return TRUE;
522 }
523
524 boolean_t
525 fd_get_result(fd, st, st_len, ignore_errors)
526 fd_softc_t fd;
527 char *st;
528 {
529 register fd_padded_regmap_t *regs;
530
531 regs = fd->regs;
532
533 while (st_len > 0) {
534 register int i, s;
535
536 /* there might be long delays, so we pay this price */
537 s = splhigh();
538 for (i = 0; i < FD_MAX_WAIT; i++)
539 if ((regs->fd_msr & (FD_MSR_RQM|FD_MSR_DIO)) ==
540 (FD_MSR_RQM|FD_MSR_DIO))
541 break;
542 else
543 delay(10);
544 if (i == FD_MAX_WAIT) {
545 splx(s);
546 return (ignore_errors) ? FALSE : fd_messed_up(fd);
547 }
548 *st++ = regs->fd_data;
549 splx(s);
550 st_len--;
551 }
552
553 return TRUE;
554 }
555
556
557 boolean_t
558 fd_messed_up(fd)
559 fd_softc_t fd;
560 {
561 fd->messed_up++;
562 printf("fd%d: messed up, disabling.\n", fd - fd_softc_data);
563 /* here code to
564 ior->error = ..;
565 restart
566 */
567 return FALSE;
568 }
569
570 /*
571 * Debugging aids
572 */
573
574 fd_state(unit)
575 {
576 fd_softc_t fd = fd_softc[unit];
577 fd_padded_regmap_t *regs;
578
579 if (!fd || !fd->regs) return 0;
580 regs = fd->regs;
581 if (the_fdc_type == fdc_8272a)
582 printf("msr %x\n", regs->fd_msr);
583 else
584 printf("sra %x srb %x dor %x tdr %x msr %x dir %x\n",
585 regs->fd_sra, regs->fd_srb, regs->fd_dor,
586 regs->fd_tdr, regs->fd_msr, regs->fd_dir);
587 }
588
589 #endif
590
591 /* to be moved in separate file, or the above modified to live with scsi */
592
593 fd_open(dev, mode, ior)
594 int dev;
595 dev_mode_t mode;
596 io_req_t ior;
597 {
598 unsigned char cmd[2];
599 fd_softc_t fd;
600 int slave;
601
602 fd = fd_softc[UNITNO(dev)];
603 slave = SLAVENO(dev);
604
605 /* XXX find out what medium we have, automagically XXX */
606 /* fornow, set params depending on minor */
607 fd->slave_status[slave].params = &fd_params[PARAMNO(dev)];
608
609 /* XXXYYYXXXYYY SEND CONFIGURE if params changed */
610
611 /* Turn motor on */
612 if (the_fdc_type == fdc_82072) {
613
614 cmd[0] = FD_CMD_MOTOR_ON_OFF | FD_CMD_MOT_ON |
615 ((slave << FD_CMD_MOT_DS_SHIFT) & FD_CMD_MOT_DS);
616 (void) fd_go(fd, slave, cmd, 1, 0);
617 /* no status */
618
619 } else if (the_fdc_type == fdc_82077aa) {
620
621 fd->regs->fd_dor |= ((1<<slave)<<4);
622 }
623
624 /* recalibrate to track 0 */
625 cmd[0] = FD_CMD_RECALIBRATE;
626 cmd[1] = slave;
627 if (!fd_go(fd, slave, cmd, 2, 0))
628 return D_DEVICE_DOWN;
629 /* will generate a completion interrupt */
630
631 /* if not writeable return D_READ_ONLY ? */
632
633 return D_SUCCESS;
634 }
635
636 fd_close(dev)
637 int dev;
638 {
639 fd_softc_t fd;
640 register int slave;
641 unsigned char cmd[2];
642
643 slave = SLAVENO(dev);
644 fd = fd_softc[UNITNO(dev)];
645
646 /* do not delete media info, do that iff interrupt sez changed */
647
648 /* Turn motor off */
649 if (the_fdc_type == fdc_82072) {
650
651 cmd[0] = FD_CMD_MOTOR_ON_OFF |
652 ((slave << FD_CMD_MOT_DS_SHIFT) & FD_CMD_MOT_DS);
653 (void) fd_go(fd, 0, cmd, 1, 0);
654 /* no status */
655
656 } else if (the_fdc_type == fdc_82077aa) {
657
658 fd->regs->fd_dor &= ~((1<<slave)<<4);
659 }
660 return D_SUCCESS;
661 }
662
663 fd_strategy(ior)
664 io_req_t ior;
665 {
666 #if 0
667 if (ior->io_op & IO_READ)
668 bzero(ior->io_data, ior->io_count);
669 iodone(ior);
670 #else
671 struct slave_t *slv;
672 fd_softc_t fd;
673 unsigned int i, rec, max, dev;
674 fd_params_t *params;
675
676 /* readonly */
677
678 dev = ior->io_unit;
679
680 /* only one partition */
681 fd = fd_softc[UNITNO(dev)];
682 slv = &fd->slave_status[SLAVENO(dev)];
683 params = slv->params;
684 max = params->d_secperunit;
685 rec = ior->io_recnum;
686 i = btodb(ior->io_count + DEV_BSIZE - 1);
687 if (((rec + i) > max) || (ior->io_count < 0)) {
688 ior->io_error = D_INVALID_SIZE;
689 ior->io_op |= IO_ERROR;
690 ior->io_residual = ior->io_count;
691 iodone(ior);
692 return;
693 }
694
695 ior->io_residual = rec / params->d_secpercyl;
696
697 /*
698 * Enqueue operation
699 */
700 i = splbio();
701 simple_lock(&slv->slave_lock);
702 if (slv->ior) {
703 disksort(slv->ior, ior);
704 simple_unlock(&slv->slave_lock);
705 } else {
706 ior->io_next = 0;
707 slv->ior = ior;
708 simple_unlock(&slv->slave_lock);
709 fd_start(fd, SLAVENO(dev), FALSE);
710 }
711 splx(i);
712 #endif
713 }
714
715 fd_start(fd, slave, done)
716 boolean_t done;
717 fd_softc_t fd;
718 {
719 register io_req_t ior;
720 struct slave_t *slv;
721
722 slv = &fd->slave_status[slave];
723 if ((ior = slv->ior) == 0)
724 return;
725
726 if (done) {
727 /* .. errors .. */
728 /* .. partial xfers .. */
729
730 /* dequeue next one */
731 {
732 io_req_t next;
733
734 simple_lock(&slv->target_lock);
735 next = ior->io_next;
736 slv->ior = next;
737 simple_unlock(&slv->target_lock);
738
739 iodone(ior);
740 if (next == 0)
741 return;
742
743 ior = next;
744 }
745 }
746
747 #ifdef no_eis
748 if (slv->c != ior->io_residual) SEEK_it;
749 #endif
750
751 /* setup dma */
752 #if 1
753 if (ior->io_op & IO_READ) /* like SCSI */
754 #else
755 if ((ior->io_op & IO_READ) == 0)
756 #endif
757 {
758 *(unsigned int *)0xbc040100 |= 0x00200000 | 0x00400000;
759 } else {
760 *(unsigned int *)0xbc040100 &= ~0x00400000;
761 *(unsigned int *)0xbc040100 |= 0x00200000;
762 }
763 *(unsigned int *)0xbc040070 = (((unsigned int)kvtophys(ior->io_data))>>2)<<5;
764 *(unsigned int *)0xbc0401a0 = 13;
765
766 #ifdef no_eis
767 if (slv->c == ior->io_residual) {
768 #else
769 {
770 #endif
771 unsigned char cmd[9];
772 unsigned char head, sec;
773 fd_params_t *params;
774
775 params = slv->params;
776
777 fd->regs->fd_dsr = params->d_xfer_rate;
778
779 sec = ior->io_recnum % params->d_secpercyl;
780 head = sec / params->d_secpertrk;
781 sec = (sec % params->d_secpertrk);
782
783 cmd[0] = (ior->io_op & IO_READ) ?
784 FD_CMD_MT | FD_CMD_MFM | FD_CMD_READ_DATA :
785 FD_CMD_MT | FD_CMD_MFM | FD_CMD_WRITE_DATA;
786 cmd[1] = (head << 2) | slave;
787 cmd[2] = ior->io_residual;
788 cmd[3] = head;
789 cmd[4] = sec + 1; /* 0 starts at 1 :-) */
790 cmd[5] = 0x2; /* 512 byte sectors */
791 cmd[6] = params->d_secpertrk;
792 cmd[7] = params->d_gpl;
793 cmd[8] = 0xff;
794
795 fd_go( fd, slave, cmd, 9, 7);
796
797 }
798 }
799
800 extern minphys();
801
802 fd_read(dev, ior)
803 int dev;
804 io_req_t ior;
805 {
806 return block_io(fd_strategy, minphys, ior);
807 }
808
809 int fdc_write_enable = 1;
810
811 fd_write(dev, ior)
812 int dev;
813 io_req_t ior;
814 {
815 /* check if writeable */
816
817 if (fdc_write_enable)
818 return block_io(fd_strategy, minphys, ior);
819 else return D_SUCCESS;
820 }
821
822 fd_set_status(dev, flavor, status, status_count)
823 int dev;
824 int flavor;
825 dev_status_t status;
826 unsigned int *status_count;
827 {
828 printf("fdc_set_status(%x, %x, %x, %x)", dev, flavor, status, status_count);
829 return D_SUCCESS;
830 }
831
832 fd_get_status(dev, flavor, status, status_count)
833 int dev;
834 int flavor;
835 dev_status_t status;
836 unsigned int status_count;
837 {
838 printf("fdc_get_status(%x, %x, %x, %x)", dev, flavor, status, status_count);
839 return D_SUCCESS;
840 }
841
Cache object: efc8bc9a28c700299c36ff9c8e77dd7f
|