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$"); 29217044Snwhitehorn 30217044Snwhitehorn#include <sys/disklabel.h> 31217044Snwhitehorn 32217044Snwhitehorn#include <stand.h> 33217044Snwhitehorn#include <string.h> 34217044Snwhitehorn 35217044Snwhitehorn#include "bootstrap.h" 36224106Snwhitehorn#include "ps3.h" 37224106Snwhitehorn#include "ps3devdesc.h" 38217044Snwhitehorn 39224106Snwhitehornstatic int ps3_parsedev(struct ps3_devdesc **dev, const char *devspec, 40217044Snwhitehorn const char **path); 41217044Snwhitehorn 42217044Snwhitehorn/* 43217044Snwhitehorn * Point (dev) at an allocated device specifier for the device matching the 44217044Snwhitehorn * path in (devspec). If it contains an explicit device specification, 45217044Snwhitehorn * use that. If not, use the default device. 46217044Snwhitehorn */ 47217044Snwhitehornint 48217044Snwhitehornps3_getdev(void **vdev, const char *devspec, const char **path) 49217044Snwhitehorn{ 50224106Snwhitehorn struct ps3_devdesc **dev = (struct ps3_devdesc **)vdev; 51217044Snwhitehorn int rv = 0; 52217044Snwhitehorn 53217044Snwhitehorn /* 54217044Snwhitehorn * If it looks like this is just a path and no 55217044Snwhitehorn * device, go with the current device. 56217044Snwhitehorn */ 57217044Snwhitehorn if ((devspec == NULL) || (devspec[0] == '/') || 58217044Snwhitehorn (strchr(devspec, ':') == NULL)) { 59217044Snwhitehorn rv = ps3_parsedev(dev, getenv("currdev"), NULL); 60217044Snwhitehorn 61217044Snwhitehorn if (rv == 0 && path != NULL) 62217044Snwhitehorn *path = devspec; 63217044Snwhitehorn return(rv); 64217044Snwhitehorn } 65217044Snwhitehorn 66217044Snwhitehorn /* 67217044Snwhitehorn * Try to parse the device name off the beginning of the devspec. 68217044Snwhitehorn */ 69217044Snwhitehorn return (ps3_parsedev(dev, devspec, path)); 70217044Snwhitehorn} 71217044Snwhitehorn 72217044Snwhitehorn/* 73217044Snwhitehorn * Point (dev) at an allocated device specifier matching the string version 74217044Snwhitehorn * at the beginning of (devspec). Return a pointer to the remaining 75217044Snwhitehorn * text in (path). 76217044Snwhitehorn * 77217044Snwhitehorn * In all cases, the beginning of (devspec) is compared to the names 78217044Snwhitehorn * of known devices in the device switch, and then any following text 79217044Snwhitehorn * is parsed according to the rules applied to the device type. 80217044Snwhitehorn * 81217044Snwhitehorn * For disk-type devices, the syntax is: 82217044Snwhitehorn * 83217044Snwhitehorn * disk<unit>[<partition>]: 84217044Snwhitehorn * 85217044Snwhitehorn */ 86217044Snwhitehornstatic int 87224106Snwhitehornps3_parsedev(struct ps3_devdesc **dev, const char *devspec, const char **path) 88217044Snwhitehorn{ 89224106Snwhitehorn struct ps3_devdesc *idev; 90217044Snwhitehorn struct devsw *dv; 91217044Snwhitehorn char *cp; 92217044Snwhitehorn const char *np; 93217044Snwhitehorn int i, unit, pnum, ptype, err; 94217044Snwhitehorn 95217044Snwhitehorn /* minimum length check */ 96217044Snwhitehorn if (strlen(devspec) < 2) 97217044Snwhitehorn return(EINVAL); 98217044Snwhitehorn 99217044Snwhitehorn /* look for a device that matches */ 100217044Snwhitehorn for (i = 0, dv = NULL; devsw[i] != NULL; i++) { 101217044Snwhitehorn if (!strncmp(devspec, devsw[i]->dv_name, 102217044Snwhitehorn strlen(devsw[i]->dv_name))) { 103217044Snwhitehorn dv = devsw[i]; 104217044Snwhitehorn break; 105217044Snwhitehorn } 106217044Snwhitehorn } 107217044Snwhitehorn if (dv == NULL) 108217044Snwhitehorn return(ENOENT); 109224106Snwhitehorn idev = malloc(sizeof(struct ps3_devdesc)); 110217044Snwhitehorn err = 0; 111217044Snwhitehorn np = (devspec + strlen(dv->dv_name)); 112217044Snwhitehorn 113217044Snwhitehorn switch(dv->dv_type) { 114217044Snwhitehorn case DEVT_NONE: 115217044Snwhitehorn break; 116217044Snwhitehorn 117217044Snwhitehorn case DEVT_DISK: 118217044Snwhitehorn unit = -1; 119217044Snwhitehorn pnum = -1; 120217044Snwhitehorn ptype = -1; 121217044Snwhitehorn if (*np && (*np != ':')) { 122217044Snwhitehorn /* next comes the unit number */ 123217044Snwhitehorn unit = strtol(np, &cp, 10); 124217044Snwhitehorn if (cp == np) { 125217044Snwhitehorn err = EUNIT; 126217044Snwhitehorn goto fail; 127217044Snwhitehorn } 128217044Snwhitehorn if (*cp && (*cp != ':')) { 129217044Snwhitehorn /* get partition */ 130217044Snwhitehorn if (*cp == 'p' && *(cp + 1) && 131217044Snwhitehorn *(cp + 1) != ':') { 132217044Snwhitehorn pnum = strtol(cp + 1, &cp, 10); 133217044Snwhitehorn ptype = PTYPE_GPT; 134217044Snwhitehorn } else { 135217044Snwhitehorn pnum = *cp - 'a'; 136217044Snwhitehorn ptype = PTYPE_BSDLABEL; 137217044Snwhitehorn if ((pnum < 0) || 138217044Snwhitehorn (pnum >= MAXPARTITIONS)) { 139217044Snwhitehorn err = EPART; 140217044Snwhitehorn goto fail; 141217044Snwhitehorn } 142217044Snwhitehorn cp++; 143217044Snwhitehorn } 144217044Snwhitehorn } 145217044Snwhitehorn } 146217044Snwhitehorn if (*cp && (*cp != ':')) { 147217044Snwhitehorn err = EINVAL; 148217044Snwhitehorn goto fail; 149217044Snwhitehorn } 150217044Snwhitehorn 151217044Snwhitehorn idev->d_unit = unit; 152217044Snwhitehorn idev->d_disk.pnum = pnum; 153217044Snwhitehorn idev->d_disk.ptype = ptype; 154217044Snwhitehorn idev->d_disk.data = NULL; 155217044Snwhitehorn if (path != NULL) 156217044Snwhitehorn *path = (*cp == 0) ? cp : cp + 1; 157217044Snwhitehorn break; 158217044Snwhitehorn 159217044Snwhitehorn case DEVT_NET: 160224857Snwhitehorn case DEVT_CD: 161217044Snwhitehorn /* 162217044Snwhitehorn * PS3 only has one network interface (well, two, but 163217044Snwhitehorn * netbooting over wireless is not something I'm going 164217044Snwhitehorn * to worry about. 165217044Snwhitehorn */ 166217044Snwhitehorn 167217044Snwhitehorn idev->d_unit = 0; 168217044Snwhitehorn break; 169217044Snwhitehorn 170217044Snwhitehorn default: 171217044Snwhitehorn err = EINVAL; 172217044Snwhitehorn goto fail; 173217044Snwhitehorn } 174217044Snwhitehorn idev->d_dev = dv; 175217044Snwhitehorn idev->d_type = dv->dv_type; 176217044Snwhitehorn if (dev == NULL) { 177217044Snwhitehorn free(idev); 178217044Snwhitehorn } else { 179217044Snwhitehorn *dev = idev; 180217044Snwhitehorn } 181217044Snwhitehorn return (0); 182217044Snwhitehorn 183217044Snwhitehornfail: 184217044Snwhitehorn free(idev); 185217044Snwhitehorn return (err); 186217044Snwhitehorn} 187217044Snwhitehorn 188217044Snwhitehorn 189217044Snwhitehornchar * 190217044Snwhitehornps3_fmtdev(void *vdev) 191217044Snwhitehorn{ 192224106Snwhitehorn struct ps3_devdesc *dev = (struct ps3_devdesc *)vdev; 193217044Snwhitehorn char *cp; 194217044Snwhitehorn static char buf[128]; 195217044Snwhitehorn 196217044Snwhitehorn switch(dev->d_type) { 197217044Snwhitehorn case DEVT_NONE: 198217044Snwhitehorn strcpy(buf, "(no device)"); 199217044Snwhitehorn break; 200217044Snwhitehorn 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 216217044Snwhitehorn case DEVT_NET: 217224857Snwhitehorn case DEVT_CD: 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{ 230224106Snwhitehorn struct ps3_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