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 (seek(d->wren.fd, (vlong)b*RBUFSIZE, 0) < 0 || 95 read(d->wren.fd, c, RBUFSIZE) != RBUFSIZE) { 96 print("wrenread: error on %Z(%lld): %r\n", d, (Wideoff)b); 97 cons.nwrenre++; 98 r = 1; 99 } 100 return r; 101 } 102 103 int 104 wrenwrite(Device *d, Off b, void *c) 105 { 106 int r = 0; 107 Wren *dr = d->private; 108 109 if (dr == nil) 110 panic("wrenwrite: no drive (%Z) block %lld", d, (Wideoff)b); 111 if(b >= dr->max) { 112 print("wrenwrite: block out of range %Z(%lld)\n", 113 d, (Wideoff)b); 114 r = 0x040; 115 } else if (seek(d->wren.fd, (vlong)b*RBUFSIZE, 0) < 0 || 116 write(d->wren.fd, c, RBUFSIZE) != RBUFSIZE) { 117 print("wrenwrite: error on %Z(%lld): %r\n", d, (Wideoff)b); 118 cons.nwrenwe++; 119 r = 1; 120 } 121 return r; 122 } 123