#include "all.h" typedef struct Wren Wren; struct Wren { long block; /* size of a block -- from config */ Devsize nblock; /* number of blocks -- from config */ long mult; /* multiplier to get physical blocks */ Devsize max; /* number of logical blocks */ }; void wreninit(Device *d) { int s; uchar cmd[10], buf[8]; Wren *dr; dr = d->private; if(dr) return; dr = ialloc(sizeof(Wren), 0); d->private = dr; loop: memset(cmd, 0, sizeof(cmd)); cmd[0] = 0x25; /* read capacity */ s = scsiio(d, SCSIread, cmd, sizeof(cmd), buf, sizeof(buf)); if(s) { print("wreninit: %Z bad status %.4x\n", d, s); delay(1000); goto loop; } dr->nblock = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | (buf[3]<<0); dr->block = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | (buf[7]<<0); if(dr->block <= 0 || dr->block >= 16*1024) { print(" wreninit %Z block size %ld setting to 512\n", d, dr->block); dr->block = 512; } dr->mult = (RBUFSIZE + dr->block - 1) / dr->block; dr->max = (dr->nblock + 1) / dr->mult; print(" drive %Z:\n", d); print(" %lld blocks at %ld bytes each\n", (Wideoff)dr->nblock, dr->block); print(" %lld logical blocks at %d bytes each\n", (Wideoff)dr->max, RBUFSIZE); print(" %ld multiplier\n", dr->mult); } Devsize wrensize(Device *d) { Wren *dr; dr = d->private; return dr->max; } int wreniocmd(Device *d, int io, Off b, void *c) { Off l, m; uchar cmd[10]; Wren *dr; dr = d->private; if(d == 0) { print("wreniocmd: no drive - a=%Z b=%lld\n", d, (Wideoff)b); return 0x40; } if(b >= dr->max) { print("wreniocmd out of range a=%Z b=%lld\n", d, (Wideoff)b); return 0x40; } memset(cmd, 0, sizeof(cmd)); cmd[0] = 0x28; /* extended read */ if(io != SCSIread) cmd[0] = 0x2a; /* extended write */ m = dr->mult; l = b * m; cmd[2] = l>>24; cmd[3] = l>>16; cmd[4] = l>>8; cmd[5] = l; cmd[7] = m>>8; cmd[8] = m; return scsiio(d, io, cmd, sizeof(cmd), c, RBUFSIZE); } int wrenread(Device *d, Off b, void *c) { int s; s = wreniocmd(d, SCSIread, b, c); if(s) { print("wrenread: %Z(%lld) bad status %.4x\n", d, (Wideoff)b, s); cons.nwormre++; return 1; } return 0; } int wrenwrite(Device *d, Off b, void *c) { int s; s = wreniocmd(d, SCSIwrite, b, c); if(s) { print("wrenwrite: %Z(%lld) bad status %.4x\n", d, (Wideoff)b, s); cons.nwormwe++; return 1; } return 0; }