1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include "dat.h"
5 #include "protos.h"
6
7 typedef struct{
8 uchar aflag;
9 uchar feat;
10 uchar sectors;
11 uchar cmd;
12 uchar lba[6];
13 }Hdr;
14
15 enum{
16 Hsize = 10,
17 };
18
19 enum{
20 Oaflag,
21 Ocmd,
22 Ofeat,
23 Osectors,
24 Olba,
25
26 Ostat,
27 Oerr,
28 };
29
30 static Field p_fields[] =
31 {
32 {"aflag", Fnum, Oaflag, "aflag", },
33 {"cmd", Fnum, Ocmd, "command register", },
34 {"feat", Fnum, Ofeat, "features", },
35 {"sectors", Fnum, Osectors, "number of sectors", },
36 {"lba", Fnum, Olba, "lba", },
37 {"stat", Fnum, Ostat, "status", },
38 {"err", Fnum, Oerr, "error", },
39 {0}
40 };
41
42 static void
p_compile(Filter * f)43 p_compile(Filter *f)
44 {
45 if(f->op == '='){
46 compile_cmp(aoeata.name, f, p_fields);
47 return;
48 }
49 sysfatal("unknown aoeata field: %s", f->s);
50 }
51
52 uvlong
llba(uchar * c)53 llba(uchar *c)
54 {
55 uvlong l;
56
57 l = c[0];
58 l |= c[1]<<8;
59 l |= c[2]<<16;
60 l |= c[3]<<24;
61 l |= (uvlong)c[4]<<32;
62 l |= (uvlong)c[5]<<40;
63 return l;
64 }
65
66 static int
p_filter(Filter * f,Msg * m)67 p_filter(Filter *f, Msg *m)
68 {
69 Hdr *h;
70
71 if(m->pe - m->ps < Hsize)
72 return 0;
73
74 h = (Hdr*)m->ps;
75 m->ps += Hsize;
76
77 switch(f->subop){
78 case Oaflag:
79 return h->aflag == f->ulv;
80 case Ocmd:
81 return h->cmd == f->ulv;
82 case Ofeat:
83 return h->feat == f->ulv;
84 case Osectors:
85 return h->sectors == f->ulv;
86 case Olba:
87 return llba(h->lba) == f->vlv;
88
89 /* this is wrong, but we don't have access to the direction here */
90 case Ostat:
91 return h->cmd == f->ulv;
92 case Oerr:
93 return h->feat == f->ulv;
94 }
95 return 0;
96 }
97
98 static int
p_seprint(Msg * m)99 p_seprint(Msg *m)
100 {
101 Hdr *h;
102
103 if(m->pe - m->ps < Hsize)
104 return 0;
105
106 h = (Hdr*)m->ps;
107 m->ps += Hsize;
108
109 /* no next protocol */
110 m->pr = nil;
111
112 m->p = seprint(m->p, m->e, "aflag=%ux errfeat=%ux sectors=%ux cmdstat=%ux lba=%lld",
113 h->aflag, h->feat, h->sectors, h->cmd, llba(h->lba));
114 return 0;
115 }
116
117 Proto aoeata =
118 {
119 "aoeata",
120 p_compile,
121 p_filter,
122 p_seprint,
123 nil,
124 nil,
125 p_fields,
126 defaultframer,
127 };
128