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 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 */ |
100#define FD_NO_CHLINE 0x10 /* drive does not support changeline 101 * aka. unit attention */ |
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 *); |
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"); |
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 } |
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) { |
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) |
848 return (fdc_biodone(fdc, 0)); |
849 return (1); |
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 */ |
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 |
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]); |
1370 return (-1); |
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) { |
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 } |
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 --- |