1 /* usb support */
2
3 #include <u.h>
4 #include <libc.h>
5 #include <auth.h>
6 #include <fcall.h>
7 #include "../boot/boot.h"
8
9 #define PARTSRV "partfs.sdXX"
10
11 enum {
12 Dontpost,
13 Post,
14 };
15
16 static char usbdisk0[] = "/dev/sdU0.0";
17 static char sdxxctl[] = "/dev/sdXX/ctl";
18
19 /*
20 * run argv[0] (short name is name) and wait awhile for file to appear.
21 * file must be generated by running argv[0]; if it already exists, we're done.
22 */
23 static int
start(char * name,char ** argv,char * file)24 start(char *name, char **argv, char *file)
25 {
26 int cnt;
27
28 if(access(file, AEXIST) >= 0)
29 return 0;
30 if(access(argv[0], AEXIST) < 0) {
31 fprint(2, "no %s...", argv[0]);
32 return -1;
33 }
34
35 dprint("%s...", name);
36 runv(argv);
37 for(cnt = 10; cnt > 0 && access(file, AEXIST) < 0; cnt--)
38 sleep(100);
39 if (cnt <= 0) {
40 dprint("no %s...", file);
41 return -1;
42 }
43 return 0;
44 }
45
46 int
chmod(char * file,int mode)47 chmod(char *file, int mode)
48 {
49 Dir *dir;
50
51 dir = dirstat(file);
52 if (dir == nil) {
53 dprint("can't stat %s: %r\n", file);
54 return -1;
55 }
56 dir->mode &= ~0777;
57 dir->mode |= mode & 0777;
58 dirwstat("/srv/" PARTSRV, dir);
59 free(dir);
60 return 0;
61 }
62
63 /* start partfs on first usb disk, if any. optionally post partfs in /srv. */
64 static int
startpartfs(int post)65 startpartfs(int post)
66 {
67 int r, i;
68 char *parts;
69 char *partfsv[32];
70
71 if(access(usbdisk0, AEXIST) < 0)
72 return -1; /* can't run partfs until usbd is mounted */
73
74 if (post)
75 remove("/srv/" PARTSRV);
76
77 i = 0;
78 partfsv[i++] = "/boot/partfs";
79 /*
80 * hack for booting from usb: if /env/sdB0part (from 9load) exists,
81 * pass it to partfs for sdXX.
82 */
83 parts = getenv("sdB0part");
84 if (parts != nil) {
85 partfsv[i++] = "-p";
86 partfsv[i++] = parts;
87 }
88 if (post) {
89 partfsv[i++] = "-s";
90 partfsv[i++] = PARTSRV;
91 }
92 partfsv[i++] = usbdisk0;
93 partfsv[i] = nil;
94 r = start("partfs", partfsv, sdxxctl);
95
96 if (post)
97 chmod("/srv/" PARTSRV, 0666);
98 return r;
99 }
100
101 static int
mountusb(void)102 mountusb(void)
103 {
104 int fd;
105
106 dprint("mount usbd...");
107 fd = open("/srv/usb", ORDWR);
108 if(fd < 0)
109 warning("can't open /srv/usb");
110 else if(mount(fd, -1, "/dev", MBEFORE, "") < 0) {
111 warning("mount -a /srv/usb /dev");
112 close(fd);
113 } else
114 return 0; /* mount closed fd */
115 return -1;
116 }
117
118 int
mountusbparts(void)119 mountusbparts(void)
120 {
121 mountusb();
122 return startpartfs(Post);
123 }
124
125 /*
126 * start usbd, which mounts itself on /dev.
127 * start partfs on first disk, if any, to permit nvram on usb.
128 */
129 void
usbinit(int post)130 usbinit(int post)
131 {
132 int cnt;
133 static char *usbdv[] = { "/boot/usbd", nil };
134
135 if(access("#u/usb/ctl", AEXIST) < 0 || bind("#u", "/dev", MAFTER) < 0)
136 return;
137 dprint("usbinit...");
138 start("usbd", usbdv, "/srv/usb");
139
140 /* allow a little time for usbd's device discovery */
141 for(cnt = 20; cnt > 0 && access(usbdisk0, AEXIST) < 0; cnt--)
142 sleep(100);
143 if(cnt > 0)
144 startpartfs(post);
145 else
146 dprint("no usb disk...");
147 }
148