diff options
Diffstat (limited to 'sys/boot/ofw/libofw/ofw_disk.c')
-rw-r--r-- | sys/boot/ofw/libofw/ofw_disk.c | 218 |
1 files changed, 18 insertions, 200 deletions
diff --git a/sys/boot/ofw/libofw/ofw_disk.c b/sys/boot/ofw/libofw/ofw_disk.c index 1327f18..c1d01ab 100644 --- a/sys/boot/ofw/libofw/ofw_disk.c +++ b/sys/boot/ofw/libofw/ofw_disk.c @@ -41,147 +41,28 @@ #include "bootstrap.h" #include "libofw.h" -#define DISKSECSZ 512 - static int ofwd_init(void); static int ofwd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf, size_t *rsize); static int ofwd_open(struct open_file *f, ...); static int ofwd_close(struct open_file *f); +static int ofwd_ioctl(struct open_file *f, u_long cmd, void *data); static void ofwd_print(int verbose); -static char * ofwd_getdevpath(int unit); -int readdisklabel(struct ofw_devdesc *); struct devsw ofwdisk = { - "disk", + "block", DEVT_DISK, ofwd_init, ofwd_strategy, ofwd_open, ofwd_close, - noioctl, + ofwd_ioctl, ofwd_print }; -static struct ofwdinfo { - int ofwd_unit; - char ofwd_path[255]; -} ofwdinfo[MAXDEV]; -static int nofwdinfo = 0; -static int probed; - -#define OFDP_FOUND 0 -#define OFDP_NOTFOUND 1 -#define OFDP_TERMINATE 2 - -#define MAXDEV_IDE 4 -#define MAXDEV_DEFAULT 16 /* SCSI etc. */ - -void -ofwd_enter_dev(const char *devpath) -{ - char *p; - int n; - - if (ofwd_getunit(devpath) != -1) - return; - if ((p = strrchr(devpath, ',')) != NULL) - n = p - devpath; - else - n = strlen(devpath); - ofwdinfo[nofwdinfo].ofwd_unit = nofwdinfo; - strncpy(ofwdinfo[nofwdinfo].ofwd_path, devpath, n); - ofwdinfo[nofwdinfo].ofwd_path[n] = '\0'; - printf("disk%d is %s\n", nofwdinfo, ofwdinfo[nofwdinfo].ofwd_path); - nofwdinfo++; -} - -static int -ofwd_probe_dev(char *devpath) -{ - ihandle_t instance; - int rv; - - /* Is the device already in the list? */ - if (ofwd_getunit(devpath) != -1) - return OFDP_FOUND; - instance = OF_open(devpath); - if (instance != -1) { - ofwd_enter_dev(devpath); - OF_close(instance); - } else - return OFDP_NOTFOUND; - if (nofwdinfo > MAXDEV) { - printf("Hit MAXDEV probing disks.\n"); - return OFDP_TERMINATE; - } - return OFDP_FOUND; -} - -static int -ofwd_probe_devs(void) -{ - int ret; - char devpath[255]; -#ifdef __sparc64__ - int i, n; - char cdevpath[255]; -#endif - - probed = 1; - ofw_devsearch_init(); - while ((ret = ofw_devsearch("block", devpath)) != 0) { - devpath[sizeof devpath - 1] = 0; - if (ret == -1) - return 1; -#ifdef DEBUG - printf("devpath=\"%s\" ret=%d\n", devpath, ret); -#endif - - if (strstr(devpath, "cdrom") != 0) - continue; - -#ifdef __sparc64__ - /* - * sparc64 machines usually only have a single disk node as - * child of the controller (in the ATA case, there may exist - * an additional cdrom node, which we ignore above, since - * booting from it is special, and it can also be used as a - * disk node). - * Devices are accessed by using disk@unit; when no unit - * number is given, 0 is assumed. - * There is no way we can enumerate the existing disks except - * trying to open them, which unfortunately creates some deleays - * and spurioius warnings printed by the prom, which we can't - * do much about. The search may not stop on the first - * unsuccessful attempt, because that would cause disks that - * follow one with an invalid label (like CD-ROMS) would not - * be detected this way. - * Try to at least be a bit smart and only probe 4 devices in - * the IDE case. - */ - if (strstr(devpath, "/ide@") != NULL) - n = MAXDEV_IDE; - else - n = MAXDEV_DEFAULT; - for (i = 0; i < n; i++) { - sprintf(cdevpath, "%s@%d", devpath, i); - if (ofwd_probe_dev(cdevpath) == OFDP_TERMINATE) - return 1; - } -#else - if (ofwd_probe_dev(devpath) == OFDP_TERMINATE) - return 1; -#endif - } - - return 0; -} - static int ofwd_init(void) { - /* Short-circuit the device probing, since it takes too long. */ return 0; } @@ -194,18 +75,14 @@ ofwd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf, int n; int i, j; - pos = (dp->d_kind.ofwdisk.partoff + dblk) * dp->d_kind.ofwdisk.bsize; - + pos = dblk * 512; do { - if (OF_seek(dp->d_kind.ofwdisk.handle, pos) < 0) { + if (OF_seek(dp->d_handle, pos) < 0) return EIO; - } - n = OF_read(dp->d_kind.ofwdisk.handle, buf, size); - if (n < 0 && n != -2) { + n = OF_read(dp->d_handle, buf, size); + if (n < 0 && n != -2) return EIO; - } } while (n == -2); - *rsize = size; return 0; } @@ -213,55 +90,18 @@ ofwd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf, static int ofwd_open(struct open_file *f, ...) { - va_list vl; struct ofw_devdesc *dp; - char *devpath; - phandle_t diskh; - char buf[256]; - int i, j; + phandle_t handle; + va_list vl; va_start(vl, f); dp = va_arg(vl, struct ofw_devdesc *); va_end(vl); - - /* - * The unit number is really an index into our device array. - * If it is not in the list, we may need to probe now. - */ - if (!probed && dp->d_kind.ofwdisk.unit >= nofwdinfo) - ofwd_probe_devs(); - if (dp->d_kind.ofwdisk.unit >= nofwdinfo) - return 1; - devpath = ofwdinfo[dp->d_kind.ofwdisk.unit].ofwd_path; - sprintf(buf, "%s,%d:%c", devpath, dp->d_kind.ofwdisk.slice, - 'a' + dp->d_kind.ofwdisk.partition); - if ((diskh = OF_open(buf)) == -1) { - printf("ofwd_open: Could not open %s\n", buf); + if ((handle = OF_open(dp->d_path)) == -1) { + printf("ofwd_open: Could not open %s\n", dp->d_path); return 1; } - dp->d_kind.ofwdisk.bsize = DISKSECSZ; - dp->d_kind.ofwdisk.handle = diskh; - readdisklabel(dp); - - return 0; -} - -int -readdisklabel(struct ofw_devdesc *dp) -{ - char buf[DISKSECSZ]; - struct disklabel *lp; - size_t size; - int i; - - dp->d_kind.ofwdisk.partoff = 0; - dp->d_dev->dv_strategy(dp, 0, LABELSECTOR, sizeof(buf), buf, &size); - i = dp->d_kind.ofwdisk.partition; - if (i >= MAXPARTITIONS) - return 1; - - lp = (struct disklabel *)(buf + LABELOFFSET); - dp->d_kind.ofwdisk.partoff = lp->d_partitions[i].p_offset; + dp->d_handle = handle; return 0; } @@ -269,41 +109,19 @@ static int ofwd_close(struct open_file *f) { struct ofw_devdesc *dev = f->f_devdata; - OF_close(dev->d_kind.ofwdisk.handle); + OF_close(dev->d_handle); return 0; } -static void -ofwd_print(int verbose) +static int +ofwd_ioctl(struct open_file *f, u_long cmd, void *data) { - int i; - char line[80]; - if (!probed) - ofwd_probe_devs(); - for (i = 0; i < nofwdinfo; i++) { - sprintf(line, " disk%d: %s", i, ofwdinfo[i].ofwd_path); - pager_output(line); - pager_output("\n"); - } - return; + return (EINVAL); } -int -ofwd_getunit(const char *path) +static void +ofwd_print(int verbose) { - char *p; - int i, n; - - if ((p = strrchr(path, ',')) != NULL) - n = p - path; - else - n = strlen(path); - for (i = 0; i < nofwdinfo; i++) { - if (strncmp(path, ofwdinfo[i].ofwd_path, n) == 0) - return i; - } - - return -1; } |