/*===========================================================================* * select_request_async * *===========================================================================*/ static int select_request_async(struct filp *f, int *ops, int block) { int r, rops, major; struct dmap *dp; rops = *ops; /* By default, nothing to do */ *ops = 0; if (!block && (f->filp_select_flags & FSF_BLOCKED)) { /* This filp is blocked waiting for a reply, but we don't want to * block ourselves. Unless we're awaiting the initial reply, these * operations won't be ready */ if (!(f->filp_select_flags & FSF_BUSY)) { if ((rops & SEL_RD) && (f->filp_select_flags & FSF_RD_BLOCK)) rops &= ~SEL_RD; if ((rops & SEL_WR) && (f->filp_select_flags & FSF_WR_BLOCK)) rops &= ~SEL_WR; if ((rops & SEL_ERR) && (f->filp_select_flags & FSF_ERR_BLOCK)) rops &= ~SEL_ERR; if (!(rops & (SEL_RD|SEL_WR|SEL_ERR))) return(OK); } } f->filp_select_flags |= FSF_UPDATE; if (block) { rops |= SEL_NOTIFY; if (rops & SEL_RD) f->filp_select_flags |= FSF_RD_BLOCK; if (rops & SEL_WR) f->filp_select_flags |= FSF_WR_BLOCK; if (rops & SEL_ERR) f->filp_select_flags |= FSF_ERR_BLOCK; } if (f->filp_select_flags & FSF_BUSY) return(SUSPEND); major = major(f->filp_vno->v_sdev); if (major < 0 || major >= NR_DEVICES) return(ENXIO); dp = &dmap[major]; if (dp->dmap_sel_filp) return(SUSPEND); f->filp_select_flags &= ~FSF_UPDATE; r = dev_io(VFS_DEV_SELECT, f->filp_vno->v_sdev, rops, NULL, cvu64(0), 0, 0, FALSE); if (r < 0 && r != SUSPEND) return(r); if (r != SUSPEND) panic("select_request_asynch: expected SUSPEND got: %d", r); dp->dmap_sel_filp = f; f->filp_select_flags |= FSF_BUSY; return(SUSPEND); }
/*===========================================================================* * select_request_sync * *===========================================================================*/ static int select_request_sync(struct filp *f, int *ops, int block) { int rops; rops = *ops; if (block) rops |= SEL_NOTIFY; *ops = dev_io(VFS_DEV_SELECT, f->filp_vno->v_sdev, rops, NULL, cvu64(0), 0, 0, FALSE); if (*ops < 0) return(*ops); return(OK); }
/*===========================================================================* * cdprobe * *===========================================================================*/ PUBLIC int cdprobe(void) { #define CD_SECTOR 2048 #define AT_MAJOR 3 #define AT_MINORS 4 int i, minors[AT_MINORS] = { 0, 5, 10, 15 }, dev = 0, found = 0; char pvd[CD_SECTOR]; printf("\nLooking for boot CD. This may take a minute.\n" "Please ignore any error messages.\n\n"); for(i = 0; i < AT_MINORS && !found; i++) { struct super_block probe_super; int r, minor; dev = (AT_MAJOR << MAJOR) | minors[i]; /* Open device readonly. (This fails if the device * is also writable, which a CD isn't.) */ if ((r = dev_open(dev, FS_PROC_NR, RO_BIT)) != OK) { continue; } if ((r = dev_io(DEV_READ, dev, FS_PROC_NR, pvd, 16*CD_SECTOR, sizeof(pvd), 0)) != sizeof(pvd)) { dev_close(dev); continue; } dev_close(dev); /* Check PVD ID. */ if (pvd[0] != 1 || pvd[1] != 'C' || pvd[2] != 'D' || pvd[3] != '0' || pvd[4] != '0' || pvd[5] != '1' || pvd[6] != 1 || strncmp(pvd + 40, "MINIX", 5)) { continue; } /* 3. Both c0dXp1 and p2 should have a superblock. */ for(minor = minors[i]+2; minor <= minors[i]+3; minor++) { dev = (AT_MAJOR << MAJOR) | minor; if ((r = dev_open(dev, FS_PROC_NR, R_BIT)) != OK) { break; } probe_super.s_dev = dev; r = read_super(&probe_super); dev_close(dev); if (r != OK) { break; } } if (minor > minors[i]+3) { /* Success? Then set dev to p1. */ dev = (AT_MAJOR << MAJOR) | (minors[i]+2); found = 1; break; } } if (!found) return NO_DEV; return dev; }