diff --git a/sys/kernel/rdisk.c b/sys/kernel/rdisk.c index 825b81b..9208f43 100644 --- a/sys/kernel/rdisk.c +++ b/sys/kernel/rdisk.c @@ -1,704 +1,704 @@ -#include "param.h" -#include "systm.h" -#include "buf.h" -#include "errno.h" -#include "dk.h" -#include "debug.h" -#include "ioctl.h" -#include "rdisk.h" -#include "conf.h" - -#define Q2(X) #X -#define QUOTE(X) Q2((X)) - -extern struct buf *getnewbuf(); - -/* - * Variable naming conventions - * - * root - this is the number of the device entry in the disks[] array - * part - the minor number of a device entry, which represents the partition - * number, or 0 for the whole disk - * unit - the physical device number of a specific device type. Equates - * to the .unit entry in the diskentry structure for a device. - */ - -extern int card_read(int unit, unsigned int offset, char *data, unsigned int bcount); -extern int card_write(int unit, unsigned int offset, char *data, unsigned int bcount); -extern int sdinit(int unit, int flag); -extern int sddeinit(int unit); -extern void sd_preinit(int unit); -extern int sdopen(int unit, int flags, int mode); -extern int sdsize(int unit); - -#ifdef SRAMC_ENABLED -#include -#endif -#ifdef SDRAMP_ENABLED -#include -#endif -#ifdef FLASH_ENABLED -#include -#endif -#ifdef MRAMS_ENABLED -#include -#endif - -int no_deinit(int u) { return 0; } -void no_preinit(int u) { return; } -int no_init(int u, int v) { return 0; } -int no_open(int u, int a, int b) { return 0; } -int no_size(int u) { return 0; } -int no_read(int u, unsigned int o, char *dat, unsigned int bs) { return 0; } -int no_write(int u, unsigned int o, char *dat, unsigned int bs) { return 0; } - -const struct devspec rd0devs[] = { { 0, "rd0" }, { 1, "rd0a" }, { 2, "rd0b" }, { 3, "rd0c" }, { 4, "rd0d" }, { 0, 0 } }; -const struct devspec rd1devs[] = { { 0, "rd1" }, { 1, "rd1a" }, { 2, "rd1b" }, { 3, "rd1c" }, { 4, "rd1d" }, { 0, 0 } }; -const struct devspec rd2devs[] = { { 0, "rd2" }, { 1, "rd2a" }, { 2, "rd2b" }, { 3, "rd2c" }, { 4, "rd2d" }, { 0, 0 } }; -const struct devspec rd3devs[] = { { 0, "rd3" }, { 1, "rd3a" }, { 2, "rd3b" }, { 3, "rd3c" }, { 4, "rd3d" }, { 0, 0 } }; - -// This is the list of physical storage devices on the system. -// Uncomment the ones you want below. Maximum 4 at the moment. -// They number, in the order of this list, rd0, rd1, rd2 and rd3. - -const struct diskentry disks[] = { - - {sd_preinit, sdinit, sddeinit, sdopen, sdsize, card_read, card_write, 0, RD_DEFAULT}, - -#ifdef SD1_PORT - {sd_preinit, sdinit, sddeinit, sdopen, sdsize, card_read, card_write, 1, RD_DEFAULT}, -#endif - -#ifdef SRAMC0_ENABLED - {sramc_init, no_init, no_deinit, sramc_open, sramc_size, sramc_read, sramc_write, 0, RD_PREPART}, -#endif - -#ifdef SRAMC1_ENABLED - {sramc_init, no_init, no_deinit, sramc_open, sramc_size, sramc_read, sramc_write, 1, RD_PREPART}, -#endif - -#ifdef SDRAMP_ENABLED - {sdramp_preinit, no_init, no_deinit, sdramp_open, sdramp_size, sdramp_read, sdramp_write, 0, RD_PREPART}, -#endif - -#ifdef FLASH_ENABLED - {flash_init, no_init, no_deinit, flash_open, flash_size, flash_read, flash_write, 0, RD_READONLY}, -#endif - -#ifdef MRAMS_ENABLED - {mrams_preinit, no_init, no_deinit, no_open, mrams_size, mrams_read, mrams_write, 0, RD_DEFAULT}, -#endif - -}; - -#define NRDSK sizeof(disks)/sizeof(struct diskentry) -#define MAXDEV NRDSK-1 - -#ifdef UCB_METER -int rddk = -1; -#endif - -struct diskflags dflags[NRDSK]; - -static inline struct buf *read_mbr(int root) -{ - if(root>MAXDEV) return NULL; - - int rv; - int unit = disks[root].unit; - - struct buf *bp = getnewbuf(); - - DEBUG8("rd%d: read mbr from device %d\n",root,unit); - rv = disks[root].read(unit,0,bp->b_addr,512); - if(rv==0) - { - DEBUG8("rd%d: mbr read FAIL\n",root); - brelse(buf); - return NULL; - } - DEBUG8("rd%d: mbr read OK\n",root); - - return bp; -} - - -static inline int init_device(int root,int flag) -{ - int i; - int e; - if(root>MAXDEV) return ENODEV; - - struct buf *bp; - struct mbr *mbr; - - int unit = disks[root].unit; - - e = disks[root].init(unit,flag); - - if(e!=0) - return e; - - DEBUG8("rd%d: about to read mbr\n",root); - bp = read_mbr(root); - if(!bp) - return ENXIO; - DEBUG8("rd%d: mbr read\n",root); - - mbr = (struct mbr *)bp->b_addr; - - DEBUG5("rd%d: partition types: %02X %02X %02X %02X\n",root, - mbr->partitions[0].type, - mbr->partitions[1].type, - mbr->partitions[2].type, - mbr->partitions[3].type - ); - DEBUG8("rd%d: partition 1 start: %p length: %p\n",root, - mbr->partitions[0].lbastart, mbr->partitions[0].lbalength - ); - DEBUG8("rd%d: partition 2 start: %p length: %p\n",root, - mbr->partitions[1].lbastart, mbr->partitions[1].lbalength - ); - DEBUG8("rd%d: partition 3 start: %p length: %p\n",root, - mbr->partitions[2].lbastart, mbr->partitions[2].lbalength - ); - DEBUG8("rd%d: partition 4 start: %p length: %p\n",root, - mbr->partitions[3].lbastart, mbr->partitions[3].lbalength - ); - - for(i=0; i<4; i++) - { - dflags[root].start[i] = mbr->partitions[i].lbastart>>1; - dflags[root].len[i] = mbr->partitions[i].lbalength>>1; - } - dflags[root].blocks = disks[root].size(unit); - brelse(bp); - return 0; -} - -static inline int deinit_device(int root) -{ - if(root>MAXDEV) return ENODEV; - return disks[root].deinit(disks[root].unit); -} - -static inline int open_device(int root, int flag) -{ - int e; - if(root>MAXDEV) return ENODEV; - - DEBUG3("rd%d: opening\n",root); - if(dflags[root].opens==0) - { - DEBUG3("rd%d: init device\n",root); - e = init_device(root, flag); - if(e!=0) - return e; - } - dflags[root].opens++; - - DEBUG3("rd%d: opened: %d\n",root,dflags[root].opens); - return 0; -} - -static inline int close_device(int root) -{ - if(root>MAXDEV) return ENODEV; - if(dflags[root].opens==0) - return ENXIO; - dflags[root].opens--; - if(dflags[root].opens==0) - { - deinit_device(root); - } - DEBUG3("rd%d: closed: %d\n",root,dflags[root].opens); - return 0; -} - -int rdopen(dev_t dev, int mode, int flag) -{ - int e; - int root = major(dev); - if(root>MAXDEV) return ENODEV; - - int unit = disks[root].unit; - - e=open_device(root,flag); - if(e!=0) - return e; - e=disks[root].open(unit,mode,flag); - if(e!=0) - return e; - - return 0; -} - -int rdclose(dev_t dev, int mode, int flag) -{ - int root = major(dev); - if(root>MAXDEV) return ENODEV; - close_device(root); - return 0; -} - -daddr_t rdsize(dev_t dev) -{ - int root = major(dev); - if(root>MAXDEV) return ENODEV; - - int part = minor(dev); - int unit = disks[root].unit; - unsigned int blocks; - - if(part==0) - { - return disks[root].size(unit); - } else { - if(rdopen(dev,0,S_SILENT)!=0) - return 0; - blocks=dflags[root].len[part-1]; - rdclose(dev,0,0); - DEBUG3("rd%d%c: get partition size: %d\n",root,part+'a'-1,blocks); - return blocks; - } -} - -void rdstrategy(register struct buf *bp) -{ - int root = major(bp->b_dev); - static int mutex = 0; - if(root>MAXDEV) return; - - mutex++; - if(mutex>1) - { - led_control(LED_SWAP,1); - } else { - led_control(LED_DISK,0); - } - - int part = minor(bp->b_dev); - int unit = disks[root].unit; - - int offset=0; - int s; - - if(part>0) - offset = dflags[root].start[part-1]; - - offset += (bp->b_blkno); - - if (bp->b_dev == swapdev) { - led_control(LED_SWAP,1); - } else { - led_control(LED_DISK,1); - } - - s = splbio(); - -#ifdef UCB_METER - if (rddk >= 0) { - dk_busy |= 1 << (rddk + root); - dk_xfer[rddk + root]++; - dk_bytes[rddk + root] += bp->b_bcount; - } -#endif - - - if (bp->b_flags & B_READ) { - disks[root].read(unit, offset, bp->b_addr, bp->b_bcount); - } else { - if(!(disks[root].settings & RD_READONLY)) - disks[root].write(unit, offset, bp->b_addr, bp->b_bcount); - } - - biodone(bp); - if (bp->b_dev == swapdev) { - led_control(LED_SWAP,0); - } else { - led_control(LED_DISK,0); - } - splx(s); - mutex--; -} - -void update_mbr(int unit) -{ - -} - -int rdioctl (dev_t dev, register u_int cmd, caddr_t addr, int flag) -{ - int *val; - - val = (int *)addr; - - if(cmd == RDGETMEDIASIZE) - { - *val = rdsize(dev); - } - if(cmd == RDREINIT) - { - bflush(major(dev)); - init_device(major(dev),S_SILENT); - - } - return 0; -} - -void rdisk_init() -{ - int i; - - //printf("Prepartition Schema: %s\n",prepartition_schema); - -#ifdef UCB_METER - dk_alloc(&rddk,NRDSK,"rd"); -#endif - - for(i=0; ib_addr; - for(j=1; j<5; j++) - { - if(mbr->partitions[j-1].type==type) - { - printf(" rd%d%c: %d KB\n",i,'a'+j-1,rdsize(makedev(i,j))); - } - } - brelse(bp); - } -} - -int rdisk_num_disks() -{ - return NRDSK; -} - -dev_t get_boot_device() -{ -// If a root device has been specified, then we can short cut all this and just -// use that device. -#ifdef ROOT - return ROOT; -#else - dev_t bd = -1; - int i,j,e; - struct buf *bp; - struct mbr *mbr; - - for(i=0; ib_addr; - - for(j=0; j<4; j++) - { - if(mbr->partitions[j].type==RDISK_FS) - { - if(mbr->partitions[j].status & P_ACTIVE) - { - brelse(bp); - rdclose(makedev(i,0),0,0); - return makedev(i,j+1); - } - } - } - brelse(bp); - } - rdclose(makedev(i,0),0,0); - } - } - - return bd; -#endif -} - -dev_t get_swap_device() -{ -// If a swap device has been specified, then we can short cut all this and just -// use that device. -#ifdef SWAP - return SWAP; -#else - - dev_t bd = -1; - int i,j,e; - unsigned int max_size = 0; - struct buf *bp; - struct mbr *mbr; - - // First we look for the first active swap device - - for(i=0; ib_addr; - - for(j=0; j<4; j++) - { - if(mbr->partitions[j].type==RDISK_SWAP) - { - // If this partition is the biggest so far - // then store it. We'll use this if - // there is no active partition. - if(mbr->partitions[j].lbalength>max_size) - { - max_size = mbr->partitions[j].lbalength; - bd = makedev(i,j+1); - } - - // If it is active, then use it. - if(mbr->partitions[j].status & P_ACTIVE) - { - brelse(bp); - rdclose(makedev(i,0),0,0); - return makedev(i,j+1); - } - } - } - brelse(bp); - } - rdclose(makedev(i,0),0,0); - } - } - - // There is no active partition, so we'll use the biggest one we found. - return bd; -#endif -} - -unsigned char partition_type(dev_t dev) -{ - struct buf *bp; - struct mbr *mbr; - unsigned char pt; - - if(minor(dev)<1 || minor(dev)>4) - return 0; - if(rdopen(dev,0,S_SILENT)==0) - { - bp = read_mbr(major(dev)); - rdclose(dev,0,0); - if(!bp) - { - brelse(bp); - return 0; - } - mbr = (struct mbr *)bp->b_addr; - pt = mbr->partitions[minor(dev)-1].type; - brelse(bp); - return pt; - } - return 0; -} - -int atoi(char *s) -{ - int i = 0; - char *q; - for(q=s; *q; q++) - { - if(*q < '0' || *q > '9') - { - return i; - } - i = i * 10; - i += *q - '0'; - } - return i; -} - -int strcmp(char *s1, char *s2) -{ - char *p1,*p2; - p1 = s1; - p2 = s2; - while(*p1 && *p2) - { - if(*p1 < *p2) return -1; - if(*p1 > *p2) return 1; - p1++; - p2++; - } - if(*p1 < *p2) return -1; - if(*p1 > *p2) return 1; - return 0; -} - -/* - -Prepartition format: - -mrams0:fs@1024,swap@2048,fs@1022 sdramp0:... - -*/ - -struct buf *prepartition_device(char *devname) -{ - -#ifndef PARTITION - char *prepartition_schema = ""; -#else - char *prepartition_schema = (char *)QUOTE(PARTITION); -#endif - char *p,*q; - struct buf *bp; - struct mbr *mbr; - int pnum = 0; - int start = 2; - char dev[9]; - int size; - int devsize = 0; - char *ptdata = NULL; - - char *ppstart = prepartition_schema; - - while (*ppstart == '(') { - ppstart++; - } - - printf("PP Schema: %s\n",prepartition_schema); - - printf("Attempting partition of %s...\n", devname); - - // Let's get the devname into the "dev" variable and append a ":" on the end of it. - q = dev; - for (p=devname; *p; p++) { - *q = *p; - q++; - devsize++; - } - *q++ = ':'; - *q = 0; - devsize++; - - printf("%%DBG-PPT: Device Name: %s (%d chars)\n", dev, devsize); - - // Now we want to scan the string to find the device name. It has to either - // be at the start of the string or be prefixed by a ' ' - for (p = ppstart; *(p+devsize); p++) { - if (strncmp(p, dev, devsize) == 0) { - printf("%%DBG-PPT: Device found.\n"); - ptdata = p + devsize; - break; - } - } - if (ptdata == NULL) { - printf("%%DBG-PPT: Device not in partition schema\n"); - return NULL; - } - - - // We must have a pointer to the start of the partition data in ptdata now. - // Now to scan through it and get the data into the structures. - - printf("%%DBG-PPT: We now like this bit: %s\n", ptdata); - - bp = getnewbuf(); - if(!bp) { - printf("%%DBG-PPT: Unable to allocate buffer!\n"); - return NULL; - } - - mbr = (struct mbr *)bp->b_addr; - - // Ok, let's scan through the data one character at a time until we hit either a - // space or a close-bracket (indicating the end of the data). - - p = ptdata; - pnum = 0; - while ((*p != ' ') && (*p != ')')) { - // First let's look to see if we have a valid partition type - it's 2 characters - // followed by an '@'. - - printf("%%DBG-PPT: Looking at: %s\n", p); - - // Active swap space - if (strncmp(p, "sa@", 3) == 0) { - mbr->partitions[pnum].type=RDISK_SWAP; - mbr->partitions[pnum].status = 0x80; - } else - - // Inactive swap space - if (strncmp(p, "sw@", 3) == 0) { - mbr->partitions[pnum].type=RDISK_SWAP; - } else - - // General UFS filesystem - if (strncmp(p, "fs@", 3) == 0) { - mbr->partitions[pnum].type=RDISK_FS; - } else { - printf("%%DBG-PPT: Error parsing partition data: %s\n", p); - brelse(bp); - return NULL; - } - - p+=3; - - size = 0; - while ((*p >= '0') && (*p <= '9')) { - size *= 10; - size += *p - '0'; - p++; - } - - mbr->partitions[pnum].lbastart = start; - mbr->partitions[pnum].lbalength = size << 1; - - printf("%%DBG-PPT: Added partition %d type %d size %d at offset %d\n", - pnum, - mbr->partitions[pnum].type, - mbr->partitions[pnum].lbalength, - mbr->partitions[pnum].lbastart - ); - start += (size << 1); - pnum++; - if (*p == ',') { - p++; - } - } - - if(pnum > 0) - { - mbr->bootsig = 0xAA55; - mbr->biosdrive = 0x80; - mbr->sig = 'R'<<24 | 'T'<<16 | 'E'<<8 | 'R'; - return bp; - } - - brelse(bp); - return NULL; -} +#include "param.h" +#include "systm.h" +#include "buf.h" +#include "errno.h" +#include "dk.h" +#include "debug.h" +#include "ioctl.h" +#include "rdisk.h" +#include "conf.h" + +#define Q2(X) #X +#define QUOTE(X) Q2((X)) + +extern struct buf *getnewbuf(); + +/* + * Variable naming conventions + * + * root - this is the number of the device entry in the disks[] array + * part - the minor number of a device entry, which represents the partition + * number, or 0 for the whole disk + * unit - the physical device number of a specific device type. Equates + * to the .unit entry in the diskentry structure for a device. + */ + +extern int card_read(int unit, unsigned int offset, char *data, unsigned int bcount); +extern int card_write(int unit, unsigned int offset, char *data, unsigned int bcount); +extern int sdinit(int unit, int flag); +extern int sddeinit(int unit); +extern void sd_preinit(int unit); +extern int sdopen(int unit, int flags, int mode); +extern int sdsize(int unit); + +#ifdef SRAMC_ENABLED +#include +#endif +#ifdef SDRAMP_ENABLED +#include +#endif +#ifdef FLASH_ENABLED +#include +#endif +#ifdef MRAMS_ENABLED +#include +#endif + +int no_deinit(int u) { return 0; } +void no_preinit(int u) { return; } +int no_init(int u, int v) { return 0; } +int no_open(int u, int a, int b) { return 0; } +int no_size(int u) { return 0; } +int no_read(int u, unsigned int o, char *dat, unsigned int bs) { return 0; } +int no_write(int u, unsigned int o, char *dat, unsigned int bs) { return 0; } + +const struct devspec rd0devs[] = { { 0, "rd0" }, { 1, "rd0a" }, { 2, "rd0b" }, { 3, "rd0c" }, { 4, "rd0d" }, { 0, 0 } }; +const struct devspec rd1devs[] = { { 0, "rd1" }, { 1, "rd1a" }, { 2, "rd1b" }, { 3, "rd1c" }, { 4, "rd1d" }, { 0, 0 } }; +const struct devspec rd2devs[] = { { 0, "rd2" }, { 1, "rd2a" }, { 2, "rd2b" }, { 3, "rd2c" }, { 4, "rd2d" }, { 0, 0 } }; +const struct devspec rd3devs[] = { { 0, "rd3" }, { 1, "rd3a" }, { 2, "rd3b" }, { 3, "rd3c" }, { 4, "rd3d" }, { 0, 0 } }; + +// This is the list of physical storage devices on the system. +// Uncomment the ones you want below. Maximum 4 at the moment. +// They number, in the order of this list, rd0, rd1, rd2 and rd3. + +const struct diskentry disks[] = { + + {sd_preinit, sdinit, sddeinit, sdopen, sdsize, card_read, card_write, 0, RD_DEFAULT}, + +#ifdef SD1_PORT + {sd_preinit, sdinit, sddeinit, sdopen, sdsize, card_read, card_write, 1, RD_DEFAULT}, +#endif + +#ifdef SRAMC0_ENABLED + {sramc_init, no_init, no_deinit, sramc_open, sramc_size, sramc_read, sramc_write, 0, RD_PREPART}, +#endif + +#ifdef SRAMC1_ENABLED + {sramc_init, no_init, no_deinit, sramc_open, sramc_size, sramc_read, sramc_write, 1, RD_PREPART}, +#endif + +#ifdef SDRAMP_ENABLED + {sdramp_preinit, no_init, no_deinit, sdramp_open, sdramp_size, sdramp_read, sdramp_write, 0, RD_PREPART}, +#endif + +#ifdef FLASH_ENABLED + {flash_init, no_init, no_deinit, flash_open, flash_size, flash_read, flash_write, 0, RD_READONLY}, +#endif + +#ifdef MRAMS_ENABLED + {mrams_preinit, no_init, no_deinit, no_open, mrams_size, mrams_read, mrams_write, 0, RD_DEFAULT}, +#endif + +}; + +#define NRDSK sizeof(disks)/sizeof(struct diskentry) +#define MAXDEV NRDSK-1 + +#ifdef UCB_METER +int rddk = -1; +#endif + +struct diskflags dflags[NRDSK]; + +static inline struct buf *read_mbr(int root) +{ + if(root>MAXDEV) return NULL; + + int rv; + int unit = disks[root].unit; + + struct buf *bp = getnewbuf(); + + DEBUG8("rd%d: read mbr from device %d\n",root,unit); + rv = disks[root].read(unit,0,bp->b_addr,512); + if(rv==0) + { + DEBUG8("rd%d: mbr read FAIL\n",root); + brelse(buf); + return NULL; + } + DEBUG8("rd%d: mbr read OK\n",root); + + return bp; +} + + +static inline int init_device(int root,int flag) +{ + int i; + int e; + if(root>MAXDEV) return ENODEV; + + struct buf *bp; + struct mbr *mbr; + + int unit = disks[root].unit; + + e = disks[root].init(unit,flag); + + if(e!=0) + return e; + + DEBUG8("rd%d: about to read mbr\n",root); + bp = read_mbr(root); + if(!bp) + return ENXIO; + DEBUG8("rd%d: mbr read\n",root); + + mbr = (struct mbr *)bp->b_addr; + + DEBUG5("rd%d: partition types: %02X %02X %02X %02X\n",root, + mbr->partitions[0].type, + mbr->partitions[1].type, + mbr->partitions[2].type, + mbr->partitions[3].type + ); + DEBUG8("rd%d: partition 1 start: %p length: %p\n",root, + mbr->partitions[0].lbastart, mbr->partitions[0].lbalength + ); + DEBUG8("rd%d: partition 2 start: %p length: %p\n",root, + mbr->partitions[1].lbastart, mbr->partitions[1].lbalength + ); + DEBUG8("rd%d: partition 3 start: %p length: %p\n",root, + mbr->partitions[2].lbastart, mbr->partitions[2].lbalength + ); + DEBUG8("rd%d: partition 4 start: %p length: %p\n",root, + mbr->partitions[3].lbastart, mbr->partitions[3].lbalength + ); + + for(i=0; i<4; i++) + { + dflags[root].start[i] = mbr->partitions[i].lbastart>>1; + dflags[root].len[i] = mbr->partitions[i].lbalength>>1; + } + dflags[root].blocks = disks[root].size(unit); + brelse(bp); + return 0; +} + +static inline int deinit_device(int root) +{ + if(root>MAXDEV) return ENODEV; + return disks[root].deinit(disks[root].unit); +} + +static inline int open_device(int root, int flag) +{ + int e; + if(root>MAXDEV) return ENODEV; + + DEBUG3("rd%d: opening\n",root); + if(dflags[root].opens==0) + { + DEBUG3("rd%d: init device\n",root); + e = init_device(root, flag); + if(e!=0) + return e; + } + dflags[root].opens++; + + DEBUG3("rd%d: opened: %d\n",root,dflags[root].opens); + return 0; +} + +static inline int close_device(int root) +{ + if(root>MAXDEV) return ENODEV; + if(dflags[root].opens==0) + return ENXIO; + dflags[root].opens--; + if(dflags[root].opens==0) + { + deinit_device(root); + } + DEBUG3("rd%d: closed: %d\n",root,dflags[root].opens); + return 0; +} + +int rdopen(dev_t dev, int mode, int flag) +{ + int e; + int root = major(dev); + if(root>MAXDEV) return ENODEV; + + int unit = disks[root].unit; + + e=open_device(root,flag); + if(e!=0) + return e; + e=disks[root].open(unit,mode,flag); + if(e!=0) + return e; + + return 0; +} + +int rdclose(dev_t dev, int mode, int flag) +{ + int root = major(dev); + if(root>MAXDEV) return ENODEV; + close_device(root); + return 0; +} + +daddr_t rdsize(dev_t dev) +{ + int root = major(dev); + if(root>MAXDEV) return ENODEV; + + int part = minor(dev); + int unit = disks[root].unit; + unsigned int blocks; + + if(part==0) + { + return disks[root].size(unit); + } else { + if(rdopen(dev,0,S_SILENT)!=0) + return 0; + blocks=dflags[root].len[part-1]; + rdclose(dev,0,0); + DEBUG3("rd%d%c: get partition size: %d\n",root,part+'a'-1,blocks); + return blocks; + } +} + +void rdstrategy(register struct buf *bp) +{ + int root = major(bp->b_dev); + static int mutex = 0; + if(root>MAXDEV) return; + + mutex++; + if(mutex>1) + { + led_control(LED_SWAP,1); + } else { + led_control(LED_DISK,0); + } + + int part = minor(bp->b_dev); + int unit = disks[root].unit; + + int offset=0; + int s; + + if(part>0) + offset = dflags[root].start[part-1]; + + offset += (bp->b_blkno); + + if (bp->b_dev == swapdev) { + led_control(LED_SWAP,1); + } else { + led_control(LED_DISK,1); + } + + s = splbio(); + +#ifdef UCB_METER + if (rddk >= 0) { + dk_busy |= 1 << (rddk + root); + dk_xfer[rddk + root]++; + dk_bytes[rddk + root] += bp->b_bcount; + } +#endif + + + if (bp->b_flags & B_READ) { + disks[root].read(unit, offset, bp->b_addr, bp->b_bcount); + } else { + if(!(disks[root].settings & RD_READONLY)) + disks[root].write(unit, offset, bp->b_addr, bp->b_bcount); + } + + biodone(bp); + if (bp->b_dev == swapdev) { + led_control(LED_SWAP,0); + } else { + led_control(LED_DISK,0); + } + splx(s); + mutex--; +} + +void update_mbr(int unit) +{ + +} + +int rdioctl (dev_t dev, register u_int cmd, caddr_t addr, int flag) +{ + int *val; + + val = (int *)addr; + + if(cmd == RDGETMEDIASIZE) + { + *val = rdsize(dev); + } + if(cmd == RDREINIT) + { + bflush(major(dev)); + init_device(major(dev),S_SILENT); + + } + return 0; +} + +void rdisk_init() +{ + int i; + + //printf("Prepartition Schema: %s\n",prepartition_schema); + +#ifdef UCB_METER + dk_alloc(&rddk,NRDSK,"rd"); +#endif + + for(i=0; ib_addr; + for(j=1; j<5; j++) + { + if(mbr->partitions[j-1].type==type) + { + printf(" rd%d%c: %d KB\n",i,'a'+j-1,rdsize(makedev(i,j))); + } + } + brelse(bp); + } +} + +int rdisk_num_disks() +{ + return NRDSK; +} + +dev_t get_boot_device() +{ +// If a root device has been specified, then we can short cut all this and just +// use that device. +#ifdef ROOT + return ROOT; +#else + dev_t bd = -1; + int i,j,e; + struct buf *bp; + struct mbr *mbr; + + for(i=0; ib_addr; + + for(j=0; j<4; j++) + { + if(mbr->partitions[j].type==RDISK_FS) + { + if(mbr->partitions[j].status & P_ACTIVE) + { + brelse(bp); + rdclose(makedev(i,0),0,0); + return makedev(i,j+1); + } + } + } + brelse(bp); + } + rdclose(makedev(i,0),0,0); + } + } + + return bd; +#endif +} + +dev_t get_swap_device() +{ +// If a swap device has been specified, then we can short cut all this and just +// use that device. +#ifdef SWAP + return SWAP; +#else + + dev_t bd = -1; + int i,j,e; + unsigned int max_size = 0; + struct buf *bp; + struct mbr *mbr; + + // First we look for the first active swap device + + for(i=0; ib_addr; + + for(j=0; j<4; j++) + { + if(mbr->partitions[j].type==RDISK_SWAP) + { + // If this partition is the biggest so far + // then store it. We'll use this if + // there is no active partition. + if(mbr->partitions[j].lbalength>max_size) + { + max_size = mbr->partitions[j].lbalength; + bd = makedev(i,j+1); + } + + // If it is active, then use it. + if(mbr->partitions[j].status & P_ACTIVE) + { + brelse(bp); + rdclose(makedev(i,0),0,0); + return makedev(i,j+1); + } + } + } + brelse(bp); + } + rdclose(makedev(i,0),0,0); + } + } + + // There is no active partition, so we'll use the biggest one we found. + return bd; +#endif +} + +unsigned char partition_type(dev_t dev) +{ + struct buf *bp; + struct mbr *mbr; + unsigned char pt; + + if(minor(dev)<1 || minor(dev)>4) + return 0; + if(rdopen(dev,0,S_SILENT)==0) + { + bp = read_mbr(major(dev)); + rdclose(dev,0,0); + if(!bp) + { + brelse(bp); + return 0; + } + mbr = (struct mbr *)bp->b_addr; + pt = mbr->partitions[minor(dev)-1].type; + brelse(bp); + return pt; + } + return 0; +} + +int atoi(char *s) +{ + int i = 0; + char *q; + for(q=s; *q; q++) + { + if(*q < '0' || *q > '9') + { + return i; + } + i = i * 10; + i += *q - '0'; + } + return i; +} + +int strcmp(char *s1, char *s2) +{ + char *p1,*p2; + p1 = s1; + p2 = s2; + while(*p1 && *p2) + { + if(*p1 < *p2) return -1; + if(*p1 > *p2) return 1; + p1++; + p2++; + } + if(*p1 < *p2) return -1; + if(*p1 > *p2) return 1; + return 0; +} + +/* + +Prepartition format: + +mrams0:fs@1024,swap@2048,fs@1022 sdramp0:... + +*/ + +struct buf *prepartition_device(char *devname) +{ + +#ifndef PARTITION + char *prepartition_schema = ""; +#else + char *prepartition_schema = (char *)QUOTE(PARTITION); +#endif + char *p,*q; + struct buf *bp; + struct mbr *mbr; + int pnum = 0; + int start = 2; + char dev[9]; + int size; + int devsize = 0; + char *ptdata = NULL; + + char *ppstart = prepartition_schema; + + while (*ppstart == '(') { + ppstart++; + } + + printf("PP Schema: %s\n",prepartition_schema); + + printf("Attempting partition of %s...\n", devname); + + // Let's get the devname into the "dev" variable and append a ":" on the end of it. + q = dev; + for (p=devname; *p; p++) { + *q = *p; + q++; + devsize++; + } + *q++ = ':'; + *q = 0; + devsize++; + + printf("%%DBG-PPT: Device Name: %s (%d chars)\n", dev, devsize); + + // Now we want to scan the string to find the device name. It has to either + // be at the start of the string or be prefixed by a ' ' + for (p = ppstart; *(p+devsize); p++) { + if (strncmp(p, dev, devsize) == 0) { + printf("%%DBG-PPT: Device found.\n"); + ptdata = p + devsize; + break; + } + } + if (ptdata == NULL) { + printf("%%DBG-PPT: Device not in partition schema\n"); + return NULL; + } + + + // We must have a pointer to the start of the partition data in ptdata now. + // Now to scan through it and get the data into the structures. + + printf("%%DBG-PPT: We now like this bit: %s\n", ptdata); + + bp = getnewbuf(); + if(!bp) { + printf("%%DBG-PPT: Unable to allocate buffer!\n"); + return NULL; + } + + mbr = (struct mbr *)bp->b_addr; + + // Ok, let's scan through the data one character at a time until we hit either a + // space or a close-bracket (indicating the end of the data). + + p = ptdata; + pnum = 0; + while ((*p != ' ') && (*p != ')')) { + // First let's look to see if we have a valid partition type - it's 2 characters + // followed by an '@'. + + printf("%%DBG-PPT: Looking at: %s\n", p); + + // Active swap space + if (strncmp(p, "sa@", 3) == 0) { + mbr->partitions[pnum].type=RDISK_SWAP; + mbr->partitions[pnum].status = 0x80; + } else + + // Inactive swap space + if (strncmp(p, "sw@", 3) == 0) { + mbr->partitions[pnum].type=RDISK_SWAP; + } else + + // General UFS filesystem + if (strncmp(p, "fs@", 3) == 0) { + mbr->partitions[pnum].type=RDISK_FS; + } else { + printf("%%DBG-PPT: Error parsing partition data: %s\n", p); + brelse(bp); + return NULL; + } + + p+=3; + + size = 0; + while ((*p >= '0') && (*p <= '9')) { + size *= 10; + size += *p - '0'; + p++; + } + + mbr->partitions[pnum].lbastart = start; + mbr->partitions[pnum].lbalength = size << 1; + + printf("%%DBG-PPT: Added partition %d type %d size %d at offset %d\n", + pnum, + mbr->partitions[pnum].type, + mbr->partitions[pnum].lbalength, + mbr->partitions[pnum].lbastart + ); + start += (size << 1); + pnum++; + if (*p == ',') { + p++; + } + } + + if(pnum > 0) + { + mbr->bootsig = 0xAA55; + mbr->biosdrive = 0x80; + mbr->sig = 'R'<<24 | 'T'<<16 | 'E'<<8 | 'R'; + return bp; + } + + brelse(bp); + return NULL; +}