- s = SPL_UP();
- /* If the attention flag in dr_flags is set, it probably means that
- an attention has arrived by the time a previous DMA end-of-range
- interrupt was serviced. If ATRX is set, we will return with out
- sleeping, since we have received an attention since the last call
- to wait on attention.
- This may not be appropriate for some applications.
- */
- if (!(dra->dr_flags & DR_ATRX)) {
- dra->dr_flags |= DR_ATWT; /* Set waiting flag */
- rsaddr->dr_pulse = IENB; /* Enable interrupt; use pulse
- reg. so function bits are
- not changed */
- sleep((caddr_t)&dra->dr_cmd,DRPRI);
- }
- splx(s);
- break;
-
- case DRPIOW:
- /* Write to p-i/o register */
- rsaddr->dr_data = data[0];
- break;
-
- case DRPACL:
- /* Send pulse to device */
- rsaddr->dr_pulse = FCN2;
- break;
-
- case DRDACL:
- /* Defer alco pulse until go */
- dra->dr_cmd |= DR_DACL;
- break;
-
- case DRPCYL:
- /* Set cycle with next go */
- dra->dr_cmd |= DR_PCYL;
- break;
-
- case DRDFCN:
- /* Do not update function bits until next go issued */
- dra->dr_cmd |= DR_DFCN;
- break;
-
- case DRRATN:
- /* Reset attention flag -- use with extreme caution */
- rsaddr->dr_pulse = RATN;
- break;
-
- case DRRDMA:
- /* Reset DMA e-o-r flag -- should never used */
- rsaddr->dr_pulse = RDMA;
- break;
-
- case DRSFCN:
- /* Set function bits */
- temp = data[0] & DR_FMSK;
- rsaddr->dr_cstat = temp; /* Write to control register */
- /* This has a very important side effect -- It clears the interrupt
- enable flag. That is fine for this driver, but if it is desired
- to leave interrupt enable at all times, it will be necessary to
- to read the status register first to get IENB, or carry a software
- flag that indicates whether interrupts are set, and or this into
- the controll register value being written.
- */
- break;
-
- case DRRPER:
- /* Clear parity flag */
- rsaddr->dr_pulse = RPER;
- break;
-
- case DRSETRSTALL:
- /* Set read stall mode. */
- dra->dr_flags &= (~DR_NORSTALL);
- break;
-
- case DRSETNORSTALL:
- /* Set no stall read mode. */
- dra->dr_flags |= DR_NORSTALL;
- break;
-
- case DRGETRSTALL:
- /* Returns true if in read stall mode. */
- data[0] = (dra->dr_flags & DR_NORSTALL)? 0 : 1;
- break;
-
- case DRSETRTIMEOUT:
- /* Set the number of ticks before a no stall read times out.
- The argument is given in tenths of a second. */
- if (data[0] < 1) {
- u.u_error = EINVAL;
- temp = 1;
- }
- dra->rtimoticks = (data[0] * hz )/10;
- break;
-
- case DRGETRTIMEOUT:
- /* Returns the number of tenths of seconds before
- a no stall read times out. */
- /* The argument is given in tenths of a second. */
- data[0] = ((dra->rtimoticks)*10)/hz;
- break;
-
- case DRSETWSTALL:
- /* Set write stall mode. */
- dra->dr_flags &= (~DR_NOWSTALL);
- break;
-
- case DRSETNOWSTALL:
- /* Set write stall mode. */
- dra->dr_flags |= DR_NOWSTALL;
- break;
-
- case DRGETWSTALL:
- /* Returns true if in write stall mode. */
- data[0] = (dra->dr_flags & DR_NOWSTALL)? 0 : 1;
- break;
-
- case DRSETWTIMEOUT:
- /* Set the number of ticks before a no stall write times out.
- The argument is given in tenths of a second. */
- if (data[0] < 1) {
- u.u_error = EINVAL;
- temp = 1;
+ break;
+
+ case DRRESET: /* Reset device */
+ /* Reset DMA ATN RPER flag */
+ rsaddr->dr_pulse = (MCLR|RDMA|RATN|RPER);
+ DELAY(0x1f000);
+ while ((rsaddr->dr_cstat & REDY) == 0)
+ sleep((caddr_t)dra, DRPRI); /* Wakeup by drtimo() */
+ dra->dr_istat = 0;
+ dra->dr_cmd = 0;
+ dra->currenttimo = 0;
+ break;
+
+ case DR11STAT: { /* Copy back dr11 status to user */
+ register struct dr11io *dr = (struct dr11io *)data;
+ dr->arg[0] = dra->dr_flags;
+ dr->arg[1] = rsaddr->dr_cstat;
+ dr->arg[2] = dra->dr_istat; /* Status at last interrupt */
+ dr->arg[3] = rsaddr->dr_data; /* P-i/o input data */
+ status = (u_short)((rsaddr->dr_addmod << 8) & 0xff00);
+ dr->arg[4] = status | (u_short)(rsaddr->dr_intvect & 0xff);
+ dr->arg[5] = rsaddr->dr_range;
+ dr->arg[6] = rsaddr->dr_rahi;
+ dr->arg[7] = rsaddr->dr_ralo;
+ break;