fdc.c (bfbb029d8745290a139bf3b15d942717e986fd9f) fdc.c (bb6382fae2da7a1d5ba046f628a6cee698255f17)
1/*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Don Ahn.
7 *
8 * Copyright (c) 1993, 1994 by

--- 29 unchanged lines hidden (view full) ---

38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 *
45 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
1/*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Don Ahn.
7 *
8 * Copyright (c) 1993, 1994 by

--- 29 unchanged lines hidden (view full) ---

38 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 *
45 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91
46 * $Id: fd.c,v 1.91 1996/07/23 21:51:33 phk Exp $
46 * $Id: fd.c,v 1.92 1996/09/06 23:07:18 phk Exp $
47 *
48 */
49
50#include "ft.h"
51#if NFT < 1
52#undef NFDC
53#endif
54#include "fd.h"

--- 24 unchanged lines hidden (view full) ---

79#if NFT > 0
80#include <sys/ftape.h>
81#include <i386/isa/ftreg.h>
82#endif
83#ifdef DEVFS
84#include <sys/devfsext.h>
85#endif
86
47 *
48 */
49
50#include "ft.h"
51#if NFT < 1
52#undef NFDC
53#endif
54#include "fd.h"

--- 24 unchanged lines hidden (view full) ---

79#if NFT > 0
80#include <sys/ftape.h>
81#include <i386/isa/ftreg.h>
82#endif
83#ifdef DEVFS
84#include <sys/devfsext.h>
85#endif
86
87#define b_cylin b_resid /* XXX now spelled b_cylinder elsewhere */
88
89/* misuse a flag to identify format operation */
90#define B_FORMAT B_XXX
91
92/*
93 * this biotab field doubles as a field for the physical unit number
94 * on the controller
95 */
96#define id_physid id_scsiid

--- 911 unchanged lines hidden (view full) ---

1008
1009
1010/****************************************************************************/
1011/* fdstrategy */
1012/****************************************************************************/
1013void
1014fdstrategy(struct buf *bp)
1015{
87/* misuse a flag to identify format operation */
88#define B_FORMAT B_XXX
89
90/*
91 * this biotab field doubles as a field for the physical unit number
92 * on the controller
93 */
94#define id_physid id_scsiid

--- 911 unchanged lines hidden (view full) ---

1006
1007
1008/****************************************************************************/
1009/* fdstrategy */
1010/****************************************************************************/
1011void
1012fdstrategy(struct buf *bp)
1013{
1016 long nblocks, blknum;
1014 unsigned nblocks, blknum, cando;
1017 int s;
1018 fdcu_t fdcu;
1019 fdu_t fdu;
1020 fdc_p fdc;
1021 fd_p fd;
1022 size_t fdblk;
1023
1024 fdu = FDUNIT(minor(bp->b_dev));

--- 30 unchanged lines hidden (view full) ---

1055 bp->b_flags |= B_ERROR;
1056 goto bad;
1057 }
1058 }
1059
1060 /*
1061 * Set up block calculations.
1062 */
1015 int s;
1016 fdcu_t fdcu;
1017 fdu_t fdu;
1018 fdc_p fdc;
1019 fd_p fd;
1020 size_t fdblk;
1021
1022 fdu = FDUNIT(minor(bp->b_dev));

--- 30 unchanged lines hidden (view full) ---

1053 bp->b_flags |= B_ERROR;
1054 goto bad;
1055 }
1056 }
1057
1058 /*
1059 * Set up block calculations.
1060 */
1063 blknum = (unsigned long) bp->b_blkno * DEV_BSIZE/fdblk;
1061 if (bp->b_blkno > 20000000) {
1062 /*
1063 * Reject unreasonably high block number, prevent the
1064 * multiplication below from overflowing.
1065 */
1066 bp->b_error = EINVAL;
1067 bp->b_flags |= B_ERROR;
1068 goto bad;
1069 }
1070 blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk;
1064 nblocks = fd->ft->size;
1071 nblocks = fd->ft->size;
1072 bp->b_resid = 0;
1065 if (blknum + (bp->b_bcount / fdblk) > nblocks) {
1073 if (blknum + (bp->b_bcount / fdblk) > nblocks) {
1066 if (blknum == nblocks) {
1067 bp->b_resid = bp->b_bcount;
1074 if (blknum <= nblocks) {
1075 cando = (nblocks - blknum) * fdblk;
1076 bp->b_resid = bp->b_bcount - cando;
1077 if (cando == 0)
1078 goto bad; /* not actually bad but EOF */
1068 } else {
1079 } else {
1069 bp->b_error = ENOSPC;
1080 bp->b_error = EINVAL;
1070 bp->b_flags |= B_ERROR;
1081 bp->b_flags |= B_ERROR;
1082 goto bad;
1071 }
1083 }
1072 goto bad;
1073 }
1084 }
1074 bp->b_cylin = blknum / (fd->ft->sectrac * fd->ft->heads);
1075 bp->b_pblkno = bp->b_blkno;
1076 s = splbio();
1077 tqdisksort(&fdc->head, bp);
1078 untimeout(fd_turnoff, (caddr_t)fdu); /* a good idea */
1079 fdstart(fdcu);
1080 splx(s);
1081 return;
1082

--- 107 unchanged lines hidden (view full) ---

1190/***********************************************************************\
1191* The controller state machine. *
1192* if it returns a non zero value, it should be called again immediatly *
1193\***********************************************************************/
1194static int
1195fdstate(fdcu_t fdcu, fdc_p fdc)
1196{
1197 int read, format, head, sec = 0, sectrac, st0, cyl, st3;
1085 bp->b_pblkno = bp->b_blkno;
1086 s = splbio();
1087 tqdisksort(&fdc->head, bp);
1088 untimeout(fd_turnoff, (caddr_t)fdu); /* a good idea */
1089 fdstart(fdcu);
1090 splx(s);
1091 return;
1092

--- 107 unchanged lines hidden (view full) ---

1200/***********************************************************************\
1201* The controller state machine. *
1202* if it returns a non zero value, it should be called again immediatly *
1203\***********************************************************************/
1204static int
1205fdstate(fdcu_t fdcu, fdc_p fdc)
1206{
1207 int read, format, head, sec = 0, sectrac, st0, cyl, st3;
1198 unsigned long blknum;
1208 unsigned blknum = 0, b_cylinder = 0;
1199 fdu_t fdu = fdc->fdu;
1200 fd_p fd;
1201 register struct buf *bp;
1202 struct fd_formb *finfo = NULL;
1203 size_t fdblk;
1204
1205 bp = TAILQ_FIRST(&fdc->head);
1206 if(!bp) {

--- 16 unchanged lines hidden (view full) ---

1223 fd = fd_data + fdu;
1224 fdblk = 128 << fd->ft->secsize;
1225 if (fdc->fd && (fd != fdc->fd))
1226 {
1227 printf("fd%d: confused fd pointers\n", fdu);
1228 }
1229 read = bp->b_flags & B_READ;
1230 format = bp->b_flags & B_FORMAT;
1209 fdu_t fdu = fdc->fdu;
1210 fd_p fd;
1211 register struct buf *bp;
1212 struct fd_formb *finfo = NULL;
1213 size_t fdblk;
1214
1215 bp = TAILQ_FIRST(&fdc->head);
1216 if(!bp) {

--- 16 unchanged lines hidden (view full) ---

1233 fd = fd_data + fdu;
1234 fdblk = 128 << fd->ft->secsize;
1235 if (fdc->fd && (fd != fdc->fd))
1236 {
1237 printf("fd%d: confused fd pointers\n", fdu);
1238 }
1239 read = bp->b_flags & B_READ;
1240 format = bp->b_flags & B_FORMAT;
1231 if(format)
1241 if(format) {
1232 finfo = (struct fd_formb *)bp->b_un.b_addr;
1242 finfo = (struct fd_formb *)bp->b_un.b_addr;
1243 fd->skip = (char *)&(finfo->fd_formb_cylno(0))
1244 - (char *)finfo;
1245 }
1246 if (fdc->state == DOSEEK || fdc->state == SEEKCOMPLETE) {
1247 blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk +
1248 fd->skip/fdblk;
1249 b_cylinder = blknum / (fd->ft->sectrac * fd->ft->heads);
1250 }
1233 TRACE1("fd%d", fdu);
1234 TRACE1("[%s]", fdstates[fdc->state]);
1235 TRACE1("(0x%x)", fd->flags);
1236 untimeout(fd_turnoff, (caddr_t)fdu);
1237 timeout(fd_turnoff, (caddr_t)fdu, 4 * hz);
1238 switch (fdc->state)
1239 {
1240 case DEVIDLE:

--- 24 unchanged lines hidden (view full) ---

1265 }
1266 else /* at least make sure we are selected */
1267 {
1268 set_motor(fdcu, fd->fdsu, TURNON);
1269 }
1270 fdc->state = DOSEEK;
1271 break;
1272 case DOSEEK:
1251 TRACE1("fd%d", fdu);
1252 TRACE1("[%s]", fdstates[fdc->state]);
1253 TRACE1("(0x%x)", fd->flags);
1254 untimeout(fd_turnoff, (caddr_t)fdu);
1255 timeout(fd_turnoff, (caddr_t)fdu, 4 * hz);
1256 switch (fdc->state)
1257 {
1258 case DEVIDLE:

--- 24 unchanged lines hidden (view full) ---

1283 }
1284 else /* at least make sure we are selected */
1285 {
1286 set_motor(fdcu, fd->fdsu, TURNON);
1287 }
1288 fdc->state = DOSEEK;
1289 break;
1290 case DOSEEK:
1273 if (bp->b_cylin == fd->track)
1291 if (b_cylinder == (unsigned)fd->track)
1274 {
1275 fdc->state = SEEKCOMPLETE;
1276 break;
1277 }
1278 if (fd_cmd(fdcu, 3, NE7CMD_SEEK,
1292 {
1293 fdc->state = SEEKCOMPLETE;
1294 break;
1295 }
1296 if (fd_cmd(fdcu, 3, NE7CMD_SEEK,
1279 fd->fdsu, bp->b_cylin * fd->ft->steptrac,
1297 fd->fdsu, b_cylinder * fd->ft->steptrac,
1280 0))
1281 {
1282 /*
1283 * seek command not accepted, looks like
1284 * the FDC went off to the Saints...
1285 */
1286 fdc->retry = 6; /* try a reset */
1287 return(retrier(fdcu));

--- 5 unchanged lines hidden (view full) ---

1293 /* allow heads to settle */
1294 timeout(fd_pseudointr, (caddr_t)fdcu, hz / 16);
1295 fdc->state = SEEKCOMPLETE;
1296 return(0); /* will return later */
1297 case SEEKCOMPLETE : /* SEEK DONE, START DMA */
1298 /* Make sure seek really happened*/
1299 if(fd->track == FD_NO_TRACK)
1300 {
1298 0))
1299 {
1300 /*
1301 * seek command not accepted, looks like
1302 * the FDC went off to the Saints...
1303 */
1304 fdc->retry = 6; /* try a reset */
1305 return(retrier(fdcu));

--- 5 unchanged lines hidden (view full) ---

1311 /* allow heads to settle */
1312 timeout(fd_pseudointr, (caddr_t)fdcu, hz / 16);
1313 fdc->state = SEEKCOMPLETE;
1314 return(0); /* will return later */
1315 case SEEKCOMPLETE : /* SEEK DONE, START DMA */
1316 /* Make sure seek really happened*/
1317 if(fd->track == FD_NO_TRACK)
1318 {
1301 int descyl = bp->b_cylin * fd->ft->steptrac;
1319 int descyl = b_cylinder * fd->ft->steptrac;
1302 do {
1303 /*
1304 * This might be a "ready changed" interrupt,
1305 * which cannot really happen since the
1306 * RDY pin is hardwired to + 5 volts. This
1307 * generally indicates a "bouncing" intr
1308 * line, so do one of the following:
1309 *

--- 47 unchanged lines hidden (view full) ---

1357 {
1358 printf(
1359 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
1360 fdu, descyl, cyl, st0);
1361 return(retrier(fdcu));
1362 }
1363 }
1364
1320 do {
1321 /*
1322 * This might be a "ready changed" interrupt,
1323 * which cannot really happen since the
1324 * RDY pin is hardwired to + 5 volts. This
1325 * generally indicates a "bouncing" intr
1326 * line, so do one of the following:
1327 *

--- 47 unchanged lines hidden (view full) ---

1375 {
1376 printf(
1377 "fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
1378 fdu, descyl, cyl, st0);
1379 return(retrier(fdcu));
1380 }
1381 }
1382
1365 fd->track = bp->b_cylin;
1366 if(format)
1367 fd->skip = (char *)&(finfo->fd_formb_cylno(0))
1368 - (char *)finfo;
1383 fd->track = b_cylinder;
1369 isa_dmastart(bp->b_flags, bp->b_un.b_addr+fd->skip,
1370 format ? bp->b_bcount : fdblk, fdc->dmachan);
1384 isa_dmastart(bp->b_flags, bp->b_un.b_addr+fd->skip,
1385 format ? bp->b_bcount : fdblk, fdc->dmachan);
1371 blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/fdblk
1372 + fd->skip/fdblk;
1373 sectrac = fd->ft->sectrac;
1374 sec = blknum % (sectrac * fd->ft->heads);
1375 head = sec / sectrac;
1376 sec = sec % sectrac + 1;
1377 fd->hddrv = ((head&1)<<2)+fdu;
1378
1379 if(format || !read)
1380 {

--- 101 unchanged lines hidden (view full) ---

1482 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
1483 && fdc->status[2] & NE7_ST2_WC
1484 && fdc->retry < 3)
1485 fdc->retry = 3; /* force recalibrate */
1486 return(retrier(fdcu));
1487 }
1488 /* All OK */
1489 fd->skip += fdblk;
1386 sectrac = fd->ft->sectrac;
1387 sec = blknum % (sectrac * fd->ft->heads);
1388 head = sec / sectrac;
1389 sec = sec % sectrac + 1;
1390 fd->hddrv = ((head&1)<<2)+fdu;
1391
1392 if(format || !read)
1393 {

--- 101 unchanged lines hidden (view full) ---

1495 else if((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
1496 && fdc->status[2] & NE7_ST2_WC
1497 && fdc->retry < 3)
1498 fdc->retry = 3; /* force recalibrate */
1499 return(retrier(fdcu));
1500 }
1501 /* All OK */
1502 fd->skip += fdblk;
1490 if (!format && fd->skip < bp->b_bcount)
1503 if (!format && fd->skip < bp->b_bcount - bp->b_resid)
1491 {
1492 /* set up next transfer */
1504 {
1505 /* set up next transfer */
1493 blknum = (unsigned long)bp->b_blkno*DEV_BSIZE/fdblk
1494 + fd->skip/fdblk;
1495 bp->b_cylin =
1496 (blknum / (fd->ft->sectrac * fd->ft->heads));
1497 fdc->state = DOSEEK;
1498 }
1499 else
1500 {
1501 /* ALL DONE */
1502 fd->skip = 0;
1506 fdc->state = DOSEEK;
1507 }
1508 else
1509 {
1510 /* ALL DONE */
1511 fd->skip = 0;
1503 bp->b_resid = 0;
1504 TAILQ_REMOVE(&fdc->head, bp, b_act);
1505 biodone(bp);
1506 fdc->fd = (fd_p) 0;
1507 fdc->fdu = -1;
1508 fdc->state = FINDWORK;
1509 }
1510 return(1);
1511 case RESETCTLR:

--- 137 unchanged lines hidden (view full) ---

1649 fdc->status[3], fdc->status[4],
1650 fdc->status[5]);
1651 }
1652 else
1653 printf(" (No status)\n");
1654 }
1655 bp->b_flags |= B_ERROR;
1656 bp->b_error = EIO;
1512 TAILQ_REMOVE(&fdc->head, bp, b_act);
1513 biodone(bp);
1514 fdc->fd = (fd_p) 0;
1515 fdc->fdu = -1;
1516 fdc->state = FINDWORK;
1517 }
1518 return(1);
1519 case RESETCTLR:

--- 137 unchanged lines hidden (view full) ---

1657 fdc->status[3], fdc->status[4],
1658 fdc->status[5]);
1659 }
1660 else
1661 printf(" (No status)\n");
1662 }
1663 bp->b_flags |= B_ERROR;
1664 bp->b_error = EIO;
1657 bp->b_resid = bp->b_bcount - fdc->fd->skip;
1665 bp->b_resid += bp->b_bcount - fdc->fd->skip;
1658 TAILQ_REMOVE(&fdc->head, bp, b_act);
1659 fdc->fd->skip = 0;
1660 biodone(bp);
1661 fdc->state = FINDWORK;
1662 fdc->fd = (fd_p) 0;
1663 fdc->fdu = -1;
1664 /* XXX abort current command, if any. */
1665 return(1);

--- 217 unchanged lines hidden ---
1666 TAILQ_REMOVE(&fdc->head, bp, b_act);
1667 fdc->fd->skip = 0;
1668 biodone(bp);
1669 fdc->state = FINDWORK;
1670 fdc->fd = (fd_p) 0;
1671 fdc->fdu = -1;
1672 /* XXX abort current command, if any. */
1673 return(1);

--- 217 unchanged lines hidden ---