1 /* 2 * drive disks 3 * used to be just scsi disks, and issued scsi commands directly to the host 4 * adapter, but now it just does normal i/o. 5 */ 6 #include "all.h" 7 8 enum { Sectorsz = 512, }; /* usual disk sector size */ 9 10 typedef struct Wren Wren; 11 struct Wren 12 { 13 long block; /* size of a block -- from config */ 14 Devsize nblock; /* number of blocks -- from config */ 15 long mult; /* multiplier to get physical blocks */ 16 Devsize max; /* number of logical blocks */ 17 18 // char *sddir; /* /dev/sdXX name */ 19 }; 20 21 char * 22 dataof(char *file) 23 { 24 char *datanm; 25 Dir *dir; 26 27 dir = dirstat(file); 28 if (dir != nil && dir->mode & DMDIR) 29 datanm = smprint("%s/data", file); 30 else 31 datanm = strdup(file); 32 free(dir); 33 return datanm; 34 } 35 36 void 37 wreninit(Device *d) 38 { 39 Wren *dr; 40 Dir *dir; 41 42 if(d->private) 43 return; 44 d->private = dr = malloc(sizeof(Wren)); 45 46 if (d->wren.file) 47 d->wren.sddata = dataof(d->wren.file); 48 else { 49 d->wren.sddir = sdof(d); 50 d->wren.sddata = smprint("%s/data", d->wren.sddir); 51 } 52 53 assert(d->wren.fd <= 0); 54 d->wren.fd = open(d->wren.sddata, ORDWR); 55 if (d->wren.fd < 0) 56 panic("wreninit: can't open %s for %Z: %r", d->wren.sddata, d); 57 58 dr->block = inqsize(d->wren.sddata); 59 if(dr->block <= 0 || dr->block >= 16*1024) { 60 print("\twreninit %Z block size %ld, setting to %d\n", 61 d, dr->block, Sectorsz); 62 dr->block = Sectorsz; 63 } 64 65 dir = dirfstat(d->wren.fd); 66 dr->nblock = dir->length / dr->block; 67 free(dir); 68 69 dr->mult = (RBUFSIZE + dr->block - 1) / dr->block; 70 dr->max = (dr->nblock + 1) / dr->mult; 71 print("\tdisk drive %Z: %,lld %ld-byte sectors, ", 72 d, (Wideoff)dr->nblock, dr->block); 73 print("%,lld %d-byte blocks\n", (Wideoff)dr->max, RBUFSIZE); 74 print("\t\t%ld multiplier\n", dr->mult); 75 } 76 77 Devsize 78 wrensize(Device *d) 79 { 80 return ((Wren *)d->private)->max; 81 } 82 83 int 84 wrenread(Device *d, Off b, void *c) 85 { 86 int r = 0; 87 Wren *dr = d->private; 88 89 if (dr == nil) 90 panic("wrenread: no drive (%Z) block %lld", d, (Wideoff)b); 91 if(b >= dr->max) { 92 print("wrenread: block out of range %Z(%lld)\n", d, (Wideoff)b); 93 r = 0x040; 94 } else if (pread(d->wren.fd, c, RBUFSIZE, (vlong)b*RBUFSIZE) != RBUFSIZE) { 95 print("wrenread: error on %Z(%lld): %r\n", d, (Wideoff)b); 96 cons.nwrenre++; 97 r = 1; 98 } 99 return r; 100 } 101 102 int 103 wrenwrite(Device *d, Off b, void *c) 104 { 105 int r = 0; 106 Wren *dr = d->private; 107 108 if (dr == nil) 109 panic("wrenwrite: no drive (%Z) block %lld", d, (Wideoff)b); 110 if(b >= dr->max) { 111 print("wrenwrite: block out of range %Z(%lld)\n", 112 d, (Wideoff)b); 113 r = 0x040; 114 } else if (pwrite(d->wren.fd, c, RBUFSIZE, (vlong)b*RBUFSIZE) != RBUFSIZE) { 115 print("wrenwrite: error on %Z(%lld): %r\n", d, (Wideoff)b); 116 cons.nwrenwe++; 117 r = 1; 118 } 119 return r; 120 } 121