The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/chips/fdc_82077_hdw.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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: 05712d86253b55e6ee7cac76845c2b81


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.