163c59e25SDavid du Colombier /* usb support */
263c59e25SDavid du Colombier
363c59e25SDavid du Colombier #include <u.h>
463c59e25SDavid du Colombier #include <libc.h>
563c59e25SDavid du Colombier #include <auth.h>
663c59e25SDavid du Colombier #include <fcall.h>
763c59e25SDavid du Colombier #include "../boot/boot.h"
863c59e25SDavid du Colombier
963c59e25SDavid du Colombier #define PARTSRV "partfs.sdXX"
1063c59e25SDavid du Colombier
1163c59e25SDavid du Colombier enum {
1263c59e25SDavid du Colombier Dontpost,
1363c59e25SDavid du Colombier Post,
1463c59e25SDavid du Colombier };
1563c59e25SDavid du Colombier
1663c59e25SDavid du Colombier static char usbdisk0[] = "/dev/sdU0.0";
1763c59e25SDavid du Colombier static char sdxxctl[] = "/dev/sdXX/ctl";
1863c59e25SDavid du Colombier
1963c59e25SDavid du Colombier /*
2063c59e25SDavid du Colombier * run argv[0] (short name is name) and wait awhile for file to appear.
2163c59e25SDavid du Colombier * file must be generated by running argv[0]; if it already exists, we're done.
2263c59e25SDavid du Colombier */
2363c59e25SDavid du Colombier static int
start(char * name,char ** argv,char * file)2463c59e25SDavid du Colombier start(char *name, char **argv, char *file)
2563c59e25SDavid du Colombier {
2663c59e25SDavid du Colombier int cnt;
2763c59e25SDavid du Colombier
2863c59e25SDavid du Colombier if(access(file, AEXIST) >= 0)
2963c59e25SDavid du Colombier return 0;
3063c59e25SDavid du Colombier if(access(argv[0], AEXIST) < 0) {
3163c59e25SDavid du Colombier fprint(2, "no %s...", argv[0]);
3263c59e25SDavid du Colombier return -1;
3363c59e25SDavid du Colombier }
3463c59e25SDavid du Colombier
35*217e9e83SDavid du Colombier dprint("%s...", name);
3663c59e25SDavid du Colombier runv(argv);
3763c59e25SDavid du Colombier for(cnt = 10; cnt > 0 && access(file, AEXIST) < 0; cnt--)
3863c59e25SDavid du Colombier sleep(100);
3963c59e25SDavid du Colombier if (cnt <= 0) {
40*217e9e83SDavid du Colombier dprint("no %s...", file);
4163c59e25SDavid du Colombier return -1;
4263c59e25SDavid du Colombier }
4363c59e25SDavid du Colombier return 0;
4463c59e25SDavid du Colombier }
4563c59e25SDavid du Colombier
4663c59e25SDavid du Colombier int
chmod(char * file,int mode)4763c59e25SDavid du Colombier chmod(char *file, int mode)
4863c59e25SDavid du Colombier {
4963c59e25SDavid du Colombier Dir *dir;
5063c59e25SDavid du Colombier
5163c59e25SDavid du Colombier dir = dirstat(file);
5263c59e25SDavid du Colombier if (dir == nil) {
53*217e9e83SDavid du Colombier dprint("can't stat %s: %r\n", file);
5463c59e25SDavid du Colombier return -1;
5563c59e25SDavid du Colombier }
5663c59e25SDavid du Colombier dir->mode &= ~0777;
5763c59e25SDavid du Colombier dir->mode |= mode & 0777;
5863c59e25SDavid du Colombier dirwstat("/srv/" PARTSRV, dir);
5963c59e25SDavid du Colombier free(dir);
6063c59e25SDavid du Colombier return 0;
6163c59e25SDavid du Colombier }
6263c59e25SDavid du Colombier
6328684b1dSDavid du Colombier /* start partfs on first usb disk, if any. optionally post partfs in /srv. */
6463c59e25SDavid du Colombier static int
startpartfs(int post)6563c59e25SDavid du Colombier startpartfs(int post)
6663c59e25SDavid du Colombier {
6763c59e25SDavid du Colombier int r, i;
6863c59e25SDavid du Colombier char *parts;
6963c59e25SDavid du Colombier char *partfsv[32];
7063c59e25SDavid du Colombier
7163c59e25SDavid du Colombier if(access(usbdisk0, AEXIST) < 0)
7263c59e25SDavid du Colombier return -1; /* can't run partfs until usbd is mounted */
7363c59e25SDavid du Colombier
7463c59e25SDavid du Colombier if (post)
7563c59e25SDavid du Colombier remove("/srv/" PARTSRV);
7663c59e25SDavid du Colombier
7763c59e25SDavid du Colombier i = 0;
7863c59e25SDavid du Colombier partfsv[i++] = "/boot/partfs";
7963c59e25SDavid du Colombier /*
8063c59e25SDavid du Colombier * hack for booting from usb: if /env/sdB0part (from 9load) exists,
8163c59e25SDavid du Colombier * pass it to partfs for sdXX.
8263c59e25SDavid du Colombier */
8363c59e25SDavid du Colombier parts = getenv("sdB0part");
8463c59e25SDavid du Colombier if (parts != nil) {
8563c59e25SDavid du Colombier partfsv[i++] = "-p";
8663c59e25SDavid du Colombier partfsv[i++] = parts;
8763c59e25SDavid du Colombier }
8863c59e25SDavid du Colombier if (post) {
8963c59e25SDavid du Colombier partfsv[i++] = "-s";
9063c59e25SDavid du Colombier partfsv[i++] = PARTSRV;
9163c59e25SDavid du Colombier }
9263c59e25SDavid du Colombier partfsv[i++] = usbdisk0;
9363c59e25SDavid du Colombier partfsv[i] = nil;
9463c59e25SDavid du Colombier r = start("partfs", partfsv, sdxxctl);
9563c59e25SDavid du Colombier
9663c59e25SDavid du Colombier if (post)
9763c59e25SDavid du Colombier chmod("/srv/" PARTSRV, 0666);
9863c59e25SDavid du Colombier return r;
9963c59e25SDavid du Colombier }
10063c59e25SDavid du Colombier
10163c59e25SDavid du Colombier static int
mountusb(void)10263c59e25SDavid du Colombier mountusb(void)
10363c59e25SDavid du Colombier {
10463c59e25SDavid du Colombier int fd;
10563c59e25SDavid du Colombier
106*217e9e83SDavid du Colombier dprint("mount usbd...");
10763c59e25SDavid du Colombier fd = open("/srv/usb", ORDWR);
10863c59e25SDavid du Colombier if(fd < 0)
10963c59e25SDavid du Colombier warning("can't open /srv/usb");
11063c59e25SDavid du Colombier else if(mount(fd, -1, "/dev", MBEFORE, "") < 0) {
11163c59e25SDavid du Colombier warning("mount -a /srv/usb /dev");
11263c59e25SDavid du Colombier close(fd);
11363c59e25SDavid du Colombier } else
11463c59e25SDavid du Colombier return 0; /* mount closed fd */
11563c59e25SDavid du Colombier return -1;
11663c59e25SDavid du Colombier }
11763c59e25SDavid du Colombier
11863c59e25SDavid du Colombier int
mountusbparts(void)11963c59e25SDavid du Colombier mountusbparts(void)
12063c59e25SDavid du Colombier {
12163c59e25SDavid du Colombier mountusb();
12263c59e25SDavid du Colombier return startpartfs(Post);
12363c59e25SDavid du Colombier }
12463c59e25SDavid du Colombier
12528684b1dSDavid du Colombier /*
12628684b1dSDavid du Colombier * start usbd, which mounts itself on /dev.
12728684b1dSDavid du Colombier * start partfs on first disk, if any, to permit nvram on usb.
12828684b1dSDavid du Colombier */
12963c59e25SDavid du Colombier void
usbinit(int post)13063c59e25SDavid du Colombier usbinit(int post)
13163c59e25SDavid du Colombier {
13263c59e25SDavid du Colombier int cnt;
13363c59e25SDavid du Colombier static char *usbdv[] = { "/boot/usbd", nil };
13463c59e25SDavid du Colombier
1359607627cSDavid du Colombier if(access("#u/usb/ctl", AEXIST) < 0 || bind("#u", "/dev", MAFTER) < 0)
13663c59e25SDavid du Colombier return;
137*217e9e83SDavid du Colombier dprint("usbinit...");
13863c59e25SDavid du Colombier start("usbd", usbdv, "/srv/usb");
13963c59e25SDavid du Colombier
14063c59e25SDavid du Colombier /* allow a little time for usbd's device discovery */
14163c59e25SDavid du Colombier for(cnt = 20; cnt > 0 && access(usbdisk0, AEXIST) < 0; cnt--)
14263c59e25SDavid du Colombier sleep(100);
14363c59e25SDavid du Colombier if(cnt > 0)
14463c59e25SDavid du Colombier startpartfs(post);
145*217e9e83SDavid du Colombier else
146*217e9e83SDavid du Colombier dprint("no usb disk...");
14763c59e25SDavid du Colombier }
148