1532111f7SDavid du Colombier /* usb support */
2532111f7SDavid du Colombier
3532111f7SDavid du Colombier #include <u.h>
4532111f7SDavid du Colombier #include <libc.h>
5532111f7SDavid du Colombier #include <auth.h>
6532111f7SDavid du Colombier #include <fcall.h>
7532111f7SDavid du Colombier #include "../boot/boot.h"
8532111f7SDavid du Colombier
9532111f7SDavid du Colombier #define PARTSRV "partfs.sdXX"
10532111f7SDavid du Colombier
11532111f7SDavid du Colombier enum {
12532111f7SDavid du Colombier Dontpost,
13532111f7SDavid du Colombier Post,
14532111f7SDavid du Colombier };
15532111f7SDavid du Colombier
16532111f7SDavid du Colombier static char usbdisk0[] = "/dev/sdU0.0";
17532111f7SDavid du Colombier static char sdxxctl[] = "/dev/sdXX/ctl";
18532111f7SDavid du Colombier
19532111f7SDavid du Colombier /*
20532111f7SDavid du Colombier * run argv[0] (short name is name) and wait awhile for file to appear.
21532111f7SDavid du Colombier * file must be generated by running argv[0]; if it already exists, we're done.
22532111f7SDavid du Colombier */
23532111f7SDavid du Colombier static int
start(char * name,char ** argv,char * file)24532111f7SDavid du Colombier start(char *name, char **argv, char *file)
25532111f7SDavid du Colombier {
26532111f7SDavid du Colombier int cnt;
27532111f7SDavid du Colombier
28532111f7SDavid du Colombier if(access(file, AEXIST) >= 0)
29532111f7SDavid du Colombier return 0;
30532111f7SDavid du Colombier if(access(argv[0], AEXIST) < 0) {
31532111f7SDavid du Colombier fprint(2, "no %s...", argv[0]);
32532111f7SDavid du Colombier return -1;
33532111f7SDavid du Colombier }
34532111f7SDavid du Colombier
35532111f7SDavid du Colombier dprint("%s...", name);
36532111f7SDavid du Colombier runv(argv);
37532111f7SDavid du Colombier for(cnt = 10; cnt > 0 && access(file, AEXIST) < 0; cnt--)
38532111f7SDavid du Colombier sleep(100);
39532111f7SDavid du Colombier if (cnt <= 0) {
40532111f7SDavid du Colombier dprint("no %s...", file);
41532111f7SDavid du Colombier return -1;
42532111f7SDavid du Colombier }
43532111f7SDavid du Colombier return 0;
44532111f7SDavid du Colombier }
45532111f7SDavid du Colombier
46532111f7SDavid du Colombier int
chmod(char * file,int mode)47532111f7SDavid du Colombier chmod(char *file, int mode)
48532111f7SDavid du Colombier {
49532111f7SDavid du Colombier Dir *dir;
50532111f7SDavid du Colombier
51532111f7SDavid du Colombier dir = dirstat(file);
52532111f7SDavid du Colombier if (dir == nil) {
53532111f7SDavid du Colombier dprint("can't stat %s: %r\n", file);
54532111f7SDavid du Colombier return -1;
55532111f7SDavid du Colombier }
56532111f7SDavid du Colombier dir->mode &= ~0777;
57532111f7SDavid du Colombier dir->mode |= mode & 0777;
58532111f7SDavid du Colombier dirwstat("/srv/" PARTSRV, dir);
59532111f7SDavid du Colombier free(dir);
60532111f7SDavid du Colombier return 0;
61532111f7SDavid du Colombier }
62532111f7SDavid du Colombier
63532111f7SDavid du Colombier /* start partfs on first usb disk, if any. optionally post partfs in /srv. */
64532111f7SDavid du Colombier static int
startpartfs(int post)65532111f7SDavid du Colombier startpartfs(int post)
66532111f7SDavid du Colombier {
67532111f7SDavid du Colombier int r, i;
68532111f7SDavid du Colombier char *parts;
69532111f7SDavid du Colombier char *partfsv[32];
70532111f7SDavid du Colombier
71532111f7SDavid du Colombier if(access(usbdisk0, AEXIST) < 0)
72532111f7SDavid du Colombier return -1; /* can't run partfs until usbd is mounted */
73532111f7SDavid du Colombier
74532111f7SDavid du Colombier if (post)
75532111f7SDavid du Colombier remove("/srv/" PARTSRV);
76532111f7SDavid du Colombier
77532111f7SDavid du Colombier i = 0;
78532111f7SDavid du Colombier partfsv[i++] = "/boot/partfs";
79532111f7SDavid du Colombier /*
80532111f7SDavid du Colombier * hack for booting from usb: if /env/sdB0part (from 9load) exists,
81532111f7SDavid du Colombier * pass it to partfs for sdXX.
82532111f7SDavid du Colombier */
83532111f7SDavid du Colombier parts = getenv("sdB0part");
84532111f7SDavid du Colombier if (parts != nil) {
85532111f7SDavid du Colombier partfsv[i++] = "-p";
86532111f7SDavid du Colombier partfsv[i++] = parts;
87532111f7SDavid du Colombier }
88532111f7SDavid du Colombier if (post) {
89532111f7SDavid du Colombier partfsv[i++] = "-s";
90532111f7SDavid du Colombier partfsv[i++] = PARTSRV;
91532111f7SDavid du Colombier }
92532111f7SDavid du Colombier partfsv[i++] = usbdisk0;
93532111f7SDavid du Colombier partfsv[i] = nil;
94532111f7SDavid du Colombier r = start("partfs", partfsv, sdxxctl);
95532111f7SDavid du Colombier
96532111f7SDavid du Colombier if (post)
97532111f7SDavid du Colombier chmod("/srv/" PARTSRV, 0666);
98532111f7SDavid du Colombier return r;
99532111f7SDavid du Colombier }
100532111f7SDavid du Colombier
101532111f7SDavid du Colombier static int
mountusb(void)102532111f7SDavid du Colombier mountusb(void)
103532111f7SDavid du Colombier {
104532111f7SDavid du Colombier int fd;
105532111f7SDavid du Colombier
106532111f7SDavid du Colombier dprint("mount usbd...");
107532111f7SDavid du Colombier fd = open("/srv/usb", ORDWR);
108532111f7SDavid du Colombier if(fd < 0)
109*9737c4beSDavid du Colombier dprint("can't open /srv/usb");
110532111f7SDavid du Colombier else if(mount(fd, -1, "/dev", MBEFORE, "") < 0) {
111532111f7SDavid du Colombier warning("mount -a /srv/usb /dev");
112532111f7SDavid du Colombier close(fd);
113532111f7SDavid du Colombier } else
114532111f7SDavid du Colombier return 0; /* mount closed fd */
115532111f7SDavid du Colombier return -1;
116532111f7SDavid du Colombier }
117532111f7SDavid du Colombier
118532111f7SDavid du Colombier int
mountusbparts(void)119532111f7SDavid du Colombier mountusbparts(void)
120532111f7SDavid du Colombier {
121532111f7SDavid du Colombier mountusb();
122532111f7SDavid du Colombier return startpartfs(Post);
123532111f7SDavid du Colombier }
124532111f7SDavid du Colombier
125532111f7SDavid du Colombier /*
126532111f7SDavid du Colombier * start usbd, which mounts itself on /dev.
127532111f7SDavid du Colombier * start partfs on first disk, if any, to permit nvram on usb.
128532111f7SDavid du Colombier */
129532111f7SDavid du Colombier void
usbinit(int post)130532111f7SDavid du Colombier usbinit(int post)
131532111f7SDavid du Colombier {
132532111f7SDavid du Colombier int cnt;
133532111f7SDavid du Colombier static char *usbdv[] = { "/boot/usbd", nil };
134532111f7SDavid du Colombier
135532111f7SDavid du Colombier if(access("#u/usb/ctl", AEXIST) < 0 || bind("#u", "/dev", MAFTER) < 0)
136532111f7SDavid du Colombier return;
137532111f7SDavid du Colombier dprint("usbinit...");
138532111f7SDavid du Colombier start("usbd", usbdv, "/srv/usb");
139532111f7SDavid du Colombier
140532111f7SDavid du Colombier /* allow a little time for usbd's device discovery */
141532111f7SDavid du Colombier for(cnt = 20; cnt > 0 && access(usbdisk0, AEXIST) < 0; cnt--)
142532111f7SDavid du Colombier sleep(100);
143532111f7SDavid du Colombier if(cnt > 0)
144532111f7SDavid du Colombier startpartfs(post);
145532111f7SDavid du Colombier else
146532111f7SDavid du Colombier dprint("no usb disk...");
147532111f7SDavid du Colombier }
148