fdc.c (175230) | fdc.c (184976) |
---|---|
1/*- 2 * Copyright (c) 2004 Poul-Henning Kamp 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Don Ahn. 8 * --- 37 unchanged lines hidden (view full) --- 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * 49 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 50 * 51 */ 52 53#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2004 Poul-Henning Kamp 3 * Copyright (c) 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Don Ahn. 8 * --- 37 unchanged lines hidden (view full) --- 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47 * SUCH DAMAGE. 48 * 49 * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 50 * 51 */ 52 53#include <sys/cdefs.h> |
54__FBSDID("$FreeBSD: head/sys/dev/fdc/fdc.c 175230 2008-01-11 16:50:52Z kib $"); | 54__FBSDID("$FreeBSD: head/sys/dev/fdc/fdc.c 184976 2008-11-15 01:43:34Z jkim $"); |
55 56#include "opt_fdc.h" 57 58#include <sys/param.h> 59#include <sys/bio.h> 60#include <sys/bus.h> 61#include <sys/devicestat.h> 62#include <sys/disk.h> --- 29 unchanged lines hidden (view full) --- 92 * Runtime configuration hints/flags 93 */ 94 95/* configuration flags for fd */ 96#define FD_TYPEMASK 0x0f /* drive type, matches enum 97 * fd_drivetype; on i386 machines, if 98 * given as 0, use RTC type for fd0 99 * and fd1 */ | 55 56#include "opt_fdc.h" 57 58#include <sys/param.h> 59#include <sys/bio.h> 60#include <sys/bus.h> 61#include <sys/devicestat.h> 62#include <sys/disk.h> --- 29 unchanged lines hidden (view full) --- 92 * Runtime configuration hints/flags 93 */ 94 95/* configuration flags for fd */ 96#define FD_TYPEMASK 0x0f /* drive type, matches enum 97 * fd_drivetype; on i386 machines, if 98 * given as 0, use RTC type for fd0 99 * and fd1 */ |
100#define FD_NO_CHLINE 0x10 /* drive does not support changeline 101 * aka. unit attention */ |
|
100#define FD_NO_PROBE 0x20 /* don't probe drive (seek test), just 101 * assume it is there */ 102 103/* 104 * Things that could conceiveably considered parameters or tweakables 105 */ 106 107/* --- 150 unchanged lines hidden (view full) --- 258 struct bio_queue_head fd_bq; 259}; 260 261#define FD_NOT_VALID -2 262 263static driver_intr_t fdc_intr; 264static driver_filter_t fdc_intr_fast; 265static void fdc_reset(struct fdc_data *); | 102#define FD_NO_PROBE 0x20 /* don't probe drive (seek test), just 103 * assume it is there */ 104 105/* 106 * Things that could conceiveably considered parameters or tweakables 107 */ 108 109/* --- 150 unchanged lines hidden (view full) --- 260 struct bio_queue_head fd_bq; 261}; 262 263#define FD_NOT_VALID -2 264 265static driver_intr_t fdc_intr; 266static driver_filter_t fdc_intr_fast; 267static void fdc_reset(struct fdc_data *); |
268static int fd_probe_disk(struct fd_data *, int *); |
|
266 267SYSCTL_NODE(_debug, OID_AUTO, fdc, CTLFLAG_RW, 0, "fdc driver"); 268 269static int fifo_threshold = 8; 270SYSCTL_INT(_debug_fdc, OID_AUTO, fifo, CTLFLAG_RW, &fifo_threshold, 0, 271 "FIFO threshold setting"); 272 273static int debugflags = 0; --- 489 unchanged lines hidden (view full) --- 763 764 /* Have we exhausted our retries ? */ 765 bp = fdc->bp; 766 fd = fdc->fd; 767 if (bp != NULL && 768 (fdc->retry >= retries || (fd->options & FDOPT_NORETRY))) { 769 if ((debugflags & 4)) 770 printf("Too many retries (EIO)\n"); | 269 270SYSCTL_NODE(_debug, OID_AUTO, fdc, CTLFLAG_RW, 0, "fdc driver"); 271 272static int fifo_threshold = 8; 273SYSCTL_INT(_debug_fdc, OID_AUTO, fifo, CTLFLAG_RW, &fifo_threshold, 0, 274 "FIFO threshold setting"); 275 276static int debugflags = 0; --- 489 unchanged lines hidden (view full) --- 766 767 /* Have we exhausted our retries ? */ 768 bp = fdc->bp; 769 fd = fdc->fd; 770 if (bp != NULL && 771 (fdc->retry >= retries || (fd->options & FDOPT_NORETRY))) { 772 if ((debugflags & 4)) 773 printf("Too many retries (EIO)\n"); |
771 mtx_lock(&fdc->fdc_mtx); 772 fd->flags |= FD_EMPTY; 773 mtx_unlock(&fdc->fdc_mtx); | 774 if (fdc->flags & FDC_NEEDS_RESET) { 775 mtx_lock(&fdc->fdc_mtx); 776 fd->flags |= FD_EMPTY; 777 mtx_unlock(&fdc->fdc_mtx); 778 } |
774 return (fdc_biodone(fdc, EIO)); 775 } 776 777 /* Disable ISADMA if we bailed while it was active */ 778 if (fd != NULL && (fd->flags & FD_ISADMA)) { 779 mtx_lock(&Giant); 780 isa_dmadone( 781 bp->bio_cmd & BIO_READ ? ISADMA_READ : ISADMA_WRITE, --- 49 unchanged lines hidden (view full) --- 831 /* Select drive, setup params */ 832 fd_select(fd); 833 if (fdc->fdct == FDC_ENHANCED) 834 fddsr_wr(fdc, fd->ft->trans); 835 else 836 fdctl_wr(fdc, fd->ft->trans); 837 838 if (bp->bio_cmd & BIO_PROBE) { | 779 return (fdc_biodone(fdc, EIO)); 780 } 781 782 /* Disable ISADMA if we bailed while it was active */ 783 if (fd != NULL && (fd->flags & FD_ISADMA)) { 784 mtx_lock(&Giant); 785 isa_dmadone( 786 bp->bio_cmd & BIO_READ ? ISADMA_READ : ISADMA_WRITE, --- 49 unchanged lines hidden (view full) --- 836 /* Select drive, setup params */ 837 fd_select(fd); 838 if (fdc->fdct == FDC_ENHANCED) 839 fddsr_wr(fdc, fd->ft->trans); 840 else 841 fdctl_wr(fdc, fd->ft->trans); 842 843 if (bp->bio_cmd & BIO_PROBE) { |
839 840 if (!(fdin_rd(fdc) & FDI_DCHG) && !(fd->flags & FD_EMPTY)) | 844 if ((!(device_get_flags(fd->dev) & FD_NO_CHLINE) && 845 !(fdin_rd(fdc) & FDI_DCHG) && 846 !(fd->flags & FD_EMPTY)) || 847 fd_probe_disk(fd, &need_recal) == 0) |
841 return (fdc_biodone(fdc, 0)); | 848 return (fdc_biodone(fdc, 0)); |
842 843 /* 844 * Try to find out if we have a disk in the drive 845 * 846 * First recal, then seek to cyl#1, this clears the 847 * old condition on the disk change line so we can 848 * examine it for current status 849 */ 850 if (debugflags & 0x40) 851 printf("New disk in probe\n"); 852 mtx_lock(&fdc->fdc_mtx); 853 fd->flags |= FD_NEWDISK; 854 mtx_unlock(&fdc->fdc_mtx); 855 retry_line = __LINE__; 856 if (fdc_cmd(fdc, 2, NE7CMD_RECAL, fd->fdsu, 0)) 857 return (1); 858 tsleep(fdc, PRIBIO, "fdrecal", hz); 859 retry_line = __LINE__; 860 if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 861 return (1); /* XXX */ 862 retry_line = __LINE__; 863 if ((st0 & 0xc0) || cyl != 0) 864 return (1); 865 866 /* Seek to track 1 */ 867 retry_line = __LINE__; 868 if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fd->fdsu, 1, 0)) 869 return (1); 870 tsleep(fdc, PRIBIO, "fdseek", hz); 871 retry_line = __LINE__; 872 if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 873 return (1); /* XXX */ 874 need_recal |= (1 << fd->fdsu); 875 if (fdin_rd(fdc) & FDI_DCHG) { 876 if (debugflags & 0x40) 877 printf("Empty in probe\n"); 878 mtx_lock(&fdc->fdc_mtx); 879 fd->flags |= FD_EMPTY; 880 mtx_unlock(&fdc->fdc_mtx); 881 } else { 882 if (debugflags & 0x40) 883 printf("Got disk in probe\n"); 884 mtx_lock(&fdc->fdc_mtx); 885 fd->flags &= ~FD_EMPTY; 886 mtx_unlock(&fdc->fdc_mtx); 887 retry_line = __LINE__; 888 if(fdc_sense_drive(fdc, &st3) != 0) 889 return (1); 890 mtx_lock(&fdc->fdc_mtx); 891 if(st3 & NE7_ST3_WP) 892 fd->flags |= FD_WP; 893 else 894 fd->flags &= ~FD_WP; 895 mtx_unlock(&fdc->fdc_mtx); 896 } 897 return (fdc_biodone(fdc, 0)); | 849 return (1); |
898 } 899 900 /* 901 * If we are dead just flush the requests 902 */ 903 if (fd->flags & FD_EMPTY) 904 return (fdc_biodone(fdc, ENXIO)); 905 --- 327 unchanged lines hidden (view full) --- 1233 /* Queue it on the drive until the motor has started */ 1234 bioq_insert_tail(&fd->fd_bq, bp); 1235 if (!(fd->flags & FD_MOTORWAIT)) 1236 fd_motor(fd, 1); 1237 } 1238 mtx_unlock(&fdc->fdc_mtx); 1239} 1240 | 850 } 851 852 /* 853 * If we are dead just flush the requests 854 */ 855 if (fd->flags & FD_EMPTY) 856 return (fdc_biodone(fdc, ENXIO)); 857 --- 327 unchanged lines hidden (view full) --- 1185 /* Queue it on the drive until the motor has started */ 1186 bioq_insert_tail(&fd->fd_bq, bp); 1187 if (!(fd->flags & FD_MOTORWAIT)) 1188 fd_motor(fd, 1); 1189 } 1190 mtx_unlock(&fdc->fdc_mtx); 1191} 1192 |
1193/* 1194 * Try to find out if we have a disk in the drive. 1195 */ |
|
1241static int | 1196static int |
1197fd_probe_disk(struct fd_data *fd, int *recal) 1198{ 1199 struct fdc_data *fdc; 1200 int st0, st3, cyl; 1201 int oopts, ret; 1202 1203 fdc = fd->fdc; 1204 oopts = fd->options; 1205 fd->options |= FDOPT_NOERRLOG | FDOPT_NORETRY; 1206 ret = 1; 1207 1208 /* 1209 * First recal, then seek to cyl#1, this clears the old condition on 1210 * the disk change line so we can examine it for current status. 1211 */ 1212 if (debugflags & 0x40) 1213 printf("New disk in probe\n"); 1214 mtx_lock(&fdc->fdc_mtx); 1215 fd->flags |= FD_NEWDISK; 1216 mtx_unlock(&fdc->fdc_mtx); 1217 if (fdc_cmd(fdc, 2, NE7CMD_RECAL, fd->fdsu, 0)) 1218 goto done; 1219 tsleep(fdc, PRIBIO, "fdrecal", hz); 1220 if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 1221 goto done; /* XXX */ 1222 if ((st0 & 0xc0) || cyl != 0) 1223 goto done; 1224 1225 /* Seek to track 1 */ 1226 if (fdc_cmd(fdc, 3, NE7CMD_SEEK, fd->fdsu, 1, 0)) 1227 goto done; 1228 tsleep(fdc, PRIBIO, "fdseek", hz); 1229 if (fdc_sense_int(fdc, &st0, &cyl) == FD_NOT_VALID) 1230 goto done; /* XXX */ 1231 *recal |= (1 << fd->fdsu); 1232 if (fdin_rd(fdc) & FDI_DCHG) { 1233 if (debugflags & 0x40) 1234 printf("Empty in probe\n"); 1235 mtx_lock(&fdc->fdc_mtx); 1236 fd->flags |= FD_EMPTY; 1237 mtx_unlock(&fdc->fdc_mtx); 1238 } else { 1239 if (fdc_sense_drive(fdc, &st3) != 0) 1240 goto done; 1241 if (debugflags & 0x40) 1242 printf("Got disk in probe\n"); 1243 mtx_lock(&fdc->fdc_mtx); 1244 fd->flags &= ~FD_EMPTY; 1245 if (st3 & NE7_ST3_WP) 1246 fd->flags |= FD_WP; 1247 else 1248 fd->flags &= ~FD_WP; 1249 mtx_unlock(&fdc->fdc_mtx); 1250 } 1251 ret = 0; 1252 1253done: 1254 fd->options = oopts; 1255 return (ret); 1256} 1257 1258static int |
|
1242fdmisccmd(struct fd_data *fd, u_int cmd, void *data) 1243{ 1244 struct bio *bp; 1245 struct fd_formb *finfo; 1246 struct fdc_readid *idfield; 1247 int error; 1248 1249 bp = malloc(sizeof(struct bio), M_TEMP, M_WAITOK | M_ZERO); --- 95 unchanged lines hidden (view full) --- 1345 break; 1346 } 1347 1348 fd->options = oopts; 1349 if (fdtp->heads == 0) { 1350 if (debugflags & 0x40) 1351 device_printf(fd->dev, "autoselection failed\n"); 1352 fdsettype(fd, fd_native_types[fd->type]); | 1259fdmisccmd(struct fd_data *fd, u_int cmd, void *data) 1260{ 1261 struct bio *bp; 1262 struct fd_formb *finfo; 1263 struct fdc_readid *idfield; 1264 int error; 1265 1266 bp = malloc(sizeof(struct bio), M_TEMP, M_WAITOK | M_ZERO); --- 95 unchanged lines hidden (view full) --- 1362 break; 1363 } 1364 1365 fd->options = oopts; 1366 if (fdtp->heads == 0) { 1367 if (debugflags & 0x40) 1368 device_printf(fd->dev, "autoselection failed\n"); 1369 fdsettype(fd, fd_native_types[fd->type]); |
1353 return (0); | 1370 return (-1); |
1354 } else { 1355 if (debugflags & 0x40) { 1356 device_printf(fd->dev, 1357 "autoselected %d KB medium\n", fd->ft->size / 2); 1358 fdprinttype(fd->ft); 1359 } 1360 return (0); 1361 } --- 44 unchanged lines hidden (view full) --- 1406 1407 busy = 0; 1408 if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) { 1409 if (fdmisccmd(fd, BIO_PROBE, NULL)) 1410 return (ENXIO); 1411 if (fd->flags & FD_EMPTY) 1412 return (ENXIO); 1413 if (fd->flags & FD_NEWDISK) { | 1371 } else { 1372 if (debugflags & 0x40) { 1373 device_printf(fd->dev, 1374 "autoselected %d KB medium\n", fd->ft->size / 2); 1375 fdprinttype(fd->ft); 1376 } 1377 return (0); 1378 } --- 44 unchanged lines hidden (view full) --- 1423 1424 busy = 0; 1425 if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) { 1426 if (fdmisccmd(fd, BIO_PROBE, NULL)) 1427 return (ENXIO); 1428 if (fd->flags & FD_EMPTY) 1429 return (ENXIO); 1430 if (fd->flags & FD_NEWDISK) { |
1414 fdautoselect(fd); | 1431 if (fdautoselect(fd) != 0 && 1432 (device_get_flags(fd->dev) & FD_NO_CHLINE)) { 1433 mtx_lock(&fdc->fdc_mtx); 1434 fd->flags |= FD_EMPTY; 1435 mtx_unlock(&fdc->fdc_mtx); 1436 return (ENXIO); 1437 } |
1415 mtx_lock(&fdc->fdc_mtx); 1416 fd->flags &= ~FD_NEWDISK; 1417 mtx_unlock(&fdc->fdc_mtx); 1418 } 1419 device_busy(fd->dev); 1420 busy = 1; 1421 } 1422 --- 634 unchanged lines hidden --- | 1438 mtx_lock(&fdc->fdc_mtx); 1439 fd->flags &= ~FD_NEWDISK; 1440 mtx_unlock(&fdc->fdc_mtx); 1441 } 1442 device_busy(fd->dev); 1443 busy = 1; 1444 } 1445 --- 634 unchanged lines hidden --- |