devicename.c revision 217044
1217044Snwhitehorn/*- 2217044Snwhitehorn * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3217044Snwhitehorn * All rights reserved. 4217044Snwhitehorn * 5217044Snwhitehorn * Redistribution and use in source and binary forms, with or without 6217044Snwhitehorn * modification, are permitted provided that the following conditions 7217044Snwhitehorn * are met: 8217044Snwhitehorn * 1. Redistributions of source code must retain the above copyright 9217044Snwhitehorn * notice, this list of conditions and the following disclaimer. 10217044Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright 11217044Snwhitehorn * notice, this list of conditions and the following disclaimer in the 12217044Snwhitehorn * documentation and/or other materials provided with the distribution. 13217044Snwhitehorn * 14217044Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15217044Snwhitehorn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16217044Snwhitehorn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17217044Snwhitehorn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18217044Snwhitehorn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19217044Snwhitehorn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20217044Snwhitehorn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21217044Snwhitehorn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22217044Snwhitehorn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23217044Snwhitehorn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24217044Snwhitehorn * SUCH DAMAGE. 25217044Snwhitehorn */ 26217044Snwhitehorn 27217044Snwhitehorn#include <sys/cdefs.h> 28217044Snwhitehorn__FBSDID("$FreeBSD: head/sys/boot/powerpc/ps3/devicename.c 217044 2011-01-06 04:12:29Z nwhitehorn $"); 29217044Snwhitehorn 30217044Snwhitehorn#include <sys/disklabel.h> 31217044Snwhitehorn 32217044Snwhitehorn#include <stand.h> 33217044Snwhitehorn#include <string.h> 34217044Snwhitehorn 35217044Snwhitehorn#include "bootstrap.h" 36217044Snwhitehorn 37217044Snwhitehornstatic int ps3_parsedev(struct devdesc **dev, const char *devspec, 38217044Snwhitehorn const char **path); 39217044Snwhitehorn 40217044Snwhitehorn/* 41217044Snwhitehorn * Point (dev) at an allocated device specifier for the device matching the 42217044Snwhitehorn * path in (devspec). If it contains an explicit device specification, 43217044Snwhitehorn * use that. If not, use the default device. 44217044Snwhitehorn */ 45217044Snwhitehornint 46217044Snwhitehornps3_getdev(void **vdev, const char *devspec, const char **path) 47217044Snwhitehorn{ 48217044Snwhitehorn struct devdesc **dev = (struct devdesc **)vdev; 49217044Snwhitehorn int rv = 0; 50217044Snwhitehorn 51217044Snwhitehorn /* 52217044Snwhitehorn * If it looks like this is just a path and no 53217044Snwhitehorn * device, go with the current device. 54217044Snwhitehorn */ 55217044Snwhitehorn if ((devspec == NULL) || (devspec[0] == '/') || 56217044Snwhitehorn (strchr(devspec, ':') == NULL)) { 57217044Snwhitehorn rv = ps3_parsedev(dev, getenv("currdev"), NULL); 58217044Snwhitehorn 59217044Snwhitehorn if (rv == 0 && path != NULL) 60217044Snwhitehorn *path = devspec; 61217044Snwhitehorn return(rv); 62217044Snwhitehorn } 63217044Snwhitehorn 64217044Snwhitehorn /* 65217044Snwhitehorn * Try to parse the device name off the beginning of the devspec. 66217044Snwhitehorn */ 67217044Snwhitehorn return (ps3_parsedev(dev, devspec, path)); 68217044Snwhitehorn} 69217044Snwhitehorn 70217044Snwhitehorn/* 71217044Snwhitehorn * Point (dev) at an allocated device specifier matching the string version 72217044Snwhitehorn * at the beginning of (devspec). Return a pointer to the remaining 73217044Snwhitehorn * text in (path). 74217044Snwhitehorn * 75217044Snwhitehorn * In all cases, the beginning of (devspec) is compared to the names 76217044Snwhitehorn * of known devices in the device switch, and then any following text 77217044Snwhitehorn * is parsed according to the rules applied to the device type. 78217044Snwhitehorn * 79217044Snwhitehorn * For disk-type devices, the syntax is: 80217044Snwhitehorn * 81217044Snwhitehorn * disk<unit>[<partition>]: 82217044Snwhitehorn * 83217044Snwhitehorn */ 84217044Snwhitehornstatic int 85217044Snwhitehornps3_parsedev(struct devdesc **dev, const char *devspec, const char **path) 86217044Snwhitehorn{ 87217044Snwhitehorn struct devdesc *idev; 88217044Snwhitehorn struct devsw *dv; 89217044Snwhitehorn char *cp; 90217044Snwhitehorn const char *np; 91217044Snwhitehorn int i, unit, pnum, ptype, err; 92217044Snwhitehorn 93217044Snwhitehorn /* minimum length check */ 94217044Snwhitehorn if (strlen(devspec) < 2) 95217044Snwhitehorn return(EINVAL); 96217044Snwhitehorn 97217044Snwhitehorn /* look for a device that matches */ 98217044Snwhitehorn for (i = 0, dv = NULL; devsw[i] != NULL; i++) { 99217044Snwhitehorn if (!strncmp(devspec, devsw[i]->dv_name, 100217044Snwhitehorn strlen(devsw[i]->dv_name))) { 101217044Snwhitehorn dv = devsw[i]; 102217044Snwhitehorn break; 103217044Snwhitehorn } 104217044Snwhitehorn } 105217044Snwhitehorn if (dv == NULL) 106217044Snwhitehorn return(ENOENT); 107217044Snwhitehorn idev = malloc(sizeof(struct devdesc)); 108217044Snwhitehorn err = 0; 109217044Snwhitehorn np = (devspec + strlen(dv->dv_name)); 110217044Snwhitehorn 111217044Snwhitehorn switch(dv->dv_type) { 112217044Snwhitehorn case DEVT_NONE: 113217044Snwhitehorn break; 114217044Snwhitehorn 115217044Snwhitehorn#ifdef NOTYET 116217044Snwhitehorn case DEVT_DISK: 117217044Snwhitehorn unit = -1; 118217044Snwhitehorn pnum = -1; 119217044Snwhitehorn ptype = -1; 120217044Snwhitehorn if (*np && (*np != ':')) { 121217044Snwhitehorn /* next comes the unit number */ 122217044Snwhitehorn unit = strtol(np, &cp, 10); 123217044Snwhitehorn if (cp == np) { 124217044Snwhitehorn err = EUNIT; 125217044Snwhitehorn goto fail; 126217044Snwhitehorn } 127217044Snwhitehorn if (*cp && (*cp != ':')) { 128217044Snwhitehorn /* get partition */ 129217044Snwhitehorn if (*cp == 'p' && *(cp + 1) && 130217044Snwhitehorn *(cp + 1) != ':') { 131217044Snwhitehorn pnum = strtol(cp + 1, &cp, 10); 132217044Snwhitehorn ptype = PTYPE_GPT; 133217044Snwhitehorn } else { 134217044Snwhitehorn pnum = *cp - 'a'; 135217044Snwhitehorn ptype = PTYPE_BSDLABEL; 136217044Snwhitehorn if ((pnum < 0) || 137217044Snwhitehorn (pnum >= MAXPARTITIONS)) { 138217044Snwhitehorn err = EPART; 139217044Snwhitehorn goto fail; 140217044Snwhitehorn } 141217044Snwhitehorn cp++; 142217044Snwhitehorn } 143217044Snwhitehorn } 144217044Snwhitehorn } 145217044Snwhitehorn if (*cp && (*cp != ':')) { 146217044Snwhitehorn err = EINVAL; 147217044Snwhitehorn goto fail; 148217044Snwhitehorn } 149217044Snwhitehorn 150217044Snwhitehorn idev->d_unit = unit; 151217044Snwhitehorn idev->d_disk.pnum = pnum; 152217044Snwhitehorn idev->d_disk.ptype = ptype; 153217044Snwhitehorn idev->d_disk.data = NULL; 154217044Snwhitehorn if (path != NULL) 155217044Snwhitehorn *path = (*cp == 0) ? cp : cp + 1; 156217044Snwhitehorn break; 157217044Snwhitehorn#endif 158217044Snwhitehorn 159217044Snwhitehorn case DEVT_NET: 160217044Snwhitehorn /* 161217044Snwhitehorn * PS3 only has one network interface (well, two, but 162217044Snwhitehorn * netbooting over wireless is not something I'm going 163217044Snwhitehorn * to worry about. 164217044Snwhitehorn */ 165217044Snwhitehorn 166217044Snwhitehorn idev->d_unit = 0; 167217044Snwhitehorn break; 168217044Snwhitehorn 169217044Snwhitehorn default: 170217044Snwhitehorn err = EINVAL; 171217044Snwhitehorn goto fail; 172217044Snwhitehorn } 173217044Snwhitehorn idev->d_dev = dv; 174217044Snwhitehorn idev->d_type = dv->dv_type; 175217044Snwhitehorn if (dev == NULL) { 176217044Snwhitehorn free(idev); 177217044Snwhitehorn } else { 178217044Snwhitehorn *dev = idev; 179217044Snwhitehorn } 180217044Snwhitehorn return (0); 181217044Snwhitehorn 182217044Snwhitehornfail: 183217044Snwhitehorn free(idev); 184217044Snwhitehorn return (err); 185217044Snwhitehorn} 186217044Snwhitehorn 187217044Snwhitehorn 188217044Snwhitehornchar * 189217044Snwhitehornps3_fmtdev(void *vdev) 190217044Snwhitehorn{ 191217044Snwhitehorn struct devdesc *dev = (struct devdesc *)vdev; 192217044Snwhitehorn char *cp; 193217044Snwhitehorn static char buf[128]; 194217044Snwhitehorn 195217044Snwhitehorn switch(dev->d_type) { 196217044Snwhitehorn case DEVT_NONE: 197217044Snwhitehorn strcpy(buf, "(no device)"); 198217044Snwhitehorn break; 199217044Snwhitehorn 200217044Snwhitehorn#ifdef NOTYET 201217044Snwhitehorn case DEVT_DISK: 202217044Snwhitehorn cp = buf; 203217044Snwhitehorn cp += sprintf(cp, "%s%d", dev->d_dev->dv_name, dev->d_unit); 204217044Snwhitehorn if (dev->d_kind.disk.pnum >= 0) { 205217044Snwhitehorn if (dev->d_kind.disk.ptype == PTYPE_BSDLABEL) 206217044Snwhitehorn cp += sprintf(cp, "%c", 207217044Snwhitehorn dev->d_kind.disk.pnum + 'a'); 208217044Snwhitehorn else if (dev->d_kind.disk.ptype == PTYPE_GPT) 209217044Snwhitehorn cp += sprintf(cp, "p%i", 210217044Snwhitehorn dev->d_kind.disk.pnum); 211217044Snwhitehorn } 212217044Snwhitehorn 213217044Snwhitehorn strcat(cp, ":"); 214217044Snwhitehorn break; 215217044Snwhitehorn#endif 216217044Snwhitehorn 217217044Snwhitehorn case DEVT_NET: 218217044Snwhitehorn sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit); 219217044Snwhitehorn break; 220217044Snwhitehorn } 221217044Snwhitehorn return(buf); 222217044Snwhitehorn} 223217044Snwhitehorn 224217044Snwhitehorn/* 225217044Snwhitehorn * Set currdev to suit the value being supplied in (value). 226217044Snwhitehorn */ 227217044Snwhitehornint 228217044Snwhitehornps3_setcurrdev(struct env_var *ev, int flags, const void *value) 229217044Snwhitehorn{ 230217044Snwhitehorn struct devdesc *ncurr; 231217044Snwhitehorn int rv; 232217044Snwhitehorn 233217044Snwhitehorn if ((rv = ps3_parsedev(&ncurr, value, NULL)) != 0) 234217044Snwhitehorn return (rv); 235217044Snwhitehorn free(ncurr); 236217044Snwhitehorn env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); 237217044Snwhitehorn return (0); 238217044Snwhitehorn} 239