]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/boot/pc/pxe.c
9boot: increase timeout, do less printing
[plan9front.git] / sys / src / boot / pc / pxe.c
index 13a1a413d3c0ece4ba865bd204be590874680493..a950b2579b34b1db74b450db2696927abdc48c09 100644 (file)
@@ -32,6 +32,7 @@ struct Tftp
        char *rp;
        char *ep;
 
+       int seq;
        int eof;
        
        char pkt[2+2+Segsize];
@@ -56,6 +57,7 @@ struct Dhcp
        char bootfile[128];
 };
 
+int pxeinit(void);
 int pxecall(int op, void *buf);
 
 static void*
@@ -104,6 +106,23 @@ moveip(IP4 d, IP4 s)
        memmove(d, s, sizeof(d));
 }
 
+void
+unload(void)
+{
+       struct {
+               uchar status[2];
+               uchar junk[10];
+       } buf;
+       static uchar shutdown[] = { 0x05, 0x070, 0x02, 0 };
+       uchar *o;
+
+       for(o = shutdown; *o; o++){ 
+               memset(&buf, 0, sizeof(buf));
+               if(pxecall(*o, &buf))
+                       break;
+       }
+}
+
 static int
 getip(IP4 yip, IP4 sip, IP4 gip, char mac[16])
 {
@@ -152,7 +171,7 @@ udpopen(IP4 sip)
 static int
 udpclose(void)
 {
-       char status[2];
+       uchar status[2];
        puts(status, 0);
        return pxecall(0x31, status);
 }
@@ -217,14 +236,9 @@ int
 read(void *f, void *data, int len)
 {
        Tftp *t = f;
-       int n;
+       int seq, n;
 
-       if(!t->eof && t->rp >= t->ep){
-               if(t->rp){
-                       hnputs(t->pkt, Tftp_ACK);
-                       udpwrite(t->dip, t->gip, t->sport, t->dport, 4, t->pkt);
-                       t->rp = t->ep = 0;
-               }
+       while(!t->eof && t->rp >= t->ep){
                for(;;){
                        n = sizeof(t->pkt);
                        if(udpread(t->dip, t->sip, &t->dport, t->sport, &n, t->pkt))
@@ -234,6 +248,15 @@ read(void *f, void *data, int len)
                }
                switch(nhgets(t->pkt)){
                case Tftp_DATA:
+                       seq = nhgets(t->pkt+2);
+                       if(seq <= t->seq){
+                               putc('@');
+                               continue;
+                       }
+                       hnputs(t->pkt, Tftp_ACK);
+                       while(udpwrite(t->dip, t->gip, t->sport, t->dport, 4, t->pkt))
+                               putc('!');
+                       t->seq = seq;
                        t->rp = t->pkt + 4;
                        t->ep = t->pkt + n;
                        t->eof = n < Segsize;
@@ -245,6 +268,7 @@ read(void *f, void *data, int len)
                        t->eof = 1;
                        return -1;
                }
+               break;
        }
        n = t->ep - t->rp;
        if(len > n)
@@ -262,6 +286,7 @@ close(void *f)
        udpclose();
 }
 
+
 static int
 tftpopen(Tftp *t, char *path, IP4 sip, IP4 dip, IP4 gip)
 {
@@ -275,6 +300,7 @@ tftpopen(Tftp *t, char *path, IP4 sip, IP4 dip, IP4 gip)
        t->sport = xport++;
        t->dport = 0;
        t->rp = t->ep = 0;
+       t->seq = -1;
        t->eof = 0;
        t->nul = 0;
        if(r = udpopen(t->sip))
@@ -304,6 +330,10 @@ start(void *)
        void *f;
        Tftp t;
 
+       if(pxeinit()){
+               print("pxe init\r\n");
+               halt();
+       }
        if(getip(yip, sip, gip, mac)){
                print("bad dhcp\r\n");
                halt();