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 --- |