Annotation of Gnu-Mach/linux/src/drivers/scsi/scsi_proc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * linux/drivers/scsi/scsi_proc.c
                      3:  *
                      4:  * The functions in this file provide an interface between
                      5:  * the PROC file system and the SCSI device drivers
                      6:  * It is mainly used for debugging, statistics and to pass 
                      7:  * information directly to the lowlevel driver.
                      8:  *
                      9:  * (c) 1995 Michael Neuffer [email protected] 
                     10:  * Version: 0.99.8   last change: 95/09/13
                     11:  * 
                     12:  * generic command parser provided by: 
                     13:  * Andreas Heilwagen <[email protected]>
                     14:  */
                     15: 
                     16: /*
                     17:  * Don't import our own symbols, as this would severely mess up our
                     18:  * symbol tables.
                     19:  */
                     20: #define _SCSI_SYMS_VER_
                     21: #define __NO_VERSION__
                     22: #include <linux/module.h>
                     23: 
                     24: #include <linux/string.h>
                     25: #include <linux/mm.h>
                     26: #include <linux/malloc.h>
                     27: #include <linux/proc_fs.h>
                     28: #include <linux/errno.h>
                     29: #include <linux/stat.h>
                     30: #include <linux/blk.h>
                     31: #include "scsi.h"
                     32: #include "hosts.h"
                     33: 
                     34: #ifndef TRUE
                     35: #define TRUE  1
                     36: #define FALSE 0
                     37: #endif
                     38: 
                     39: extern int scsi_proc_info(char *, char **, off_t, int, int, int);
                     40:  
                     41: struct scsi_dir {
                     42:     struct proc_dir_entry entry;
                     43:     char name[4];
                     44: };
                     45: 
                     46: 
                     47: /* generic_proc_info
                     48:  * Used if the driver currently has no own support for /proc/scsi
                     49:  */
                     50: int generic_proc_info(char *buffer, char **start, off_t offset, 
                     51:                     int length, int inode, int inout)
                     52: {
                     53:     int len, pos, begin;
                     54: 
                     55:     if(inout == TRUE)
                     56:        return(-ENOSYS);  /* This is a no-op */
                     57:     
                     58:     begin = 0;
                     59:     pos = len = sprintf(buffer, 
                     60:                        "The driver does not yet support the proc-fs\n");
                     61:     if(pos < offset) {
                     62:        len = 0;
                     63:        begin = pos;
                     64:     }
                     65:     
                     66:     *start = buffer + (offset - begin);   /* Start of wanted data */
                     67:     len -= (offset - begin);
                     68:     if(len > length)
                     69:        len = length;
                     70:     
                     71:     return(len);
                     72: }
                     73: 
                     74: /* dispatch_scsi_info is the central dispatcher 
                     75:  * It is the interface between the proc-fs and the SCSI subsystem code
                     76:  */
                     77: extern int dispatch_scsi_info(int ino, char *buffer, char **start, 
                     78:                              off_t offset, int length, int func)
                     79: {
                     80:     struct Scsi_Host *hpnt = scsi_hostlist;
                     81:     
                     82:     if(ino == PROC_SCSI_SCSI) {            
                     83:         /*
                     84:          * This is for the scsi core, rather than any specific
                     85:          * lowlevel driver.
                     86:          */
                     87:         return(scsi_proc_info(buffer, start, offset, length, 0, func));
                     88:     }
                     89:     
                     90:     while(hpnt) {
                     91:         if (ino == (hpnt->host_no + PROC_SCSI_FILE)) {
                     92:             if(hpnt->hostt->proc_info == NULL)
                     93:                 return generic_proc_info(buffer, start, offset, length, 
                     94:                                          hpnt->host_no, func);
                     95:             else
                     96:                 return(hpnt->hostt->proc_info(buffer, start, offset, 
                     97:                                               length, hpnt->host_no, func));
                     98:         }
                     99:         hpnt = hpnt->next;
                    100:     }
                    101:     return(-EBADF);
                    102: }
                    103: 
                    104: void build_proc_dir_entries(Scsi_Host_Template *tpnt)
                    105: {
                    106:     struct Scsi_Host *hpnt;
                    107: 
                    108:     struct scsi_dir *scsi_hba_dir;
                    109: 
                    110:     proc_scsi_register(0, tpnt->proc_dir);
                    111:     
                    112:     hpnt = scsi_hostlist;
                    113:     while (hpnt) {
                    114:         if (tpnt == hpnt->hostt) {
                    115:             scsi_hba_dir = scsi_init_malloc(sizeof(struct scsi_dir), GFP_KERNEL);
                    116:             if(scsi_hba_dir == NULL)
                    117:                 panic("Not enough memory to register SCSI HBA in /proc/scsi !\n");
                    118:             memset(scsi_hba_dir, 0, sizeof(struct scsi_dir));
                    119:             scsi_hba_dir->entry.low_ino = PROC_SCSI_FILE + hpnt->host_no;
                    120:             scsi_hba_dir->entry.namelen = sprintf(scsi_hba_dir->name,"%d",
                    121:                                                     hpnt->host_no);
                    122:             scsi_hba_dir->entry.name = scsi_hba_dir->name;
                    123:             scsi_hba_dir->entry.mode = S_IFREG | S_IRUGO | S_IWUSR;
                    124:             proc_scsi_register(tpnt->proc_dir, &scsi_hba_dir->entry);
                    125:         }
                    126:         hpnt = hpnt->next;
                    127:     }
                    128: }
                    129: 
                    130: /*
                    131:  *  parseHandle *parseInit(char *buf, char *cmdList, int cmdNum); 
                    132:  *             gets a pointer to a null terminated data buffer
                    133:  *             and a list of commands with blanks as delimiter 
                    134:  *      in between. 
                    135:  *      The commands have to be alphanumerically sorted. 
                    136:  *      cmdNum has to contain the number of commands.
                    137:  *             On success, a pointer to a handle structure
                    138:  *             is returned, NULL on failure
                    139:  *
                    140:  *     int parseOpt(parseHandle *handle, char **param);
                    141:  *             processes the next parameter. On success, the
                    142:  *             index of the appropriate command in the cmdList
                    143:  *             is returned, starting with zero.
                    144:  *             param points to the null terminated parameter string.
                    145:  *             On failure, -1 is returned.
                    146:  *
                    147:  *     The databuffer buf may only contain pairs of commands
                    148:  *         options, separated by blanks:
                    149:  *             <Command> <Parameter> [<Command> <Parameter>]*
                    150:  */
                    151: 
                    152: typedef struct
                    153: {
                    154:     char *buf,                            /* command buffer  */
                    155:         *cmdList,                         /* command list    */
                    156:         *bufPos,                          /* actual position */
                    157:         **cmdPos,                         /* cmdList index   */
                    158:         cmdNum;                           /* cmd number      */
                    159: } parseHandle;
                    160:        
                    161: 
                    162: inline int parseFree (parseHandle *handle)               /* free memory     */
                    163: {
                    164:     kfree (handle->cmdPos);
                    165:     kfree (handle);
                    166:     
                    167:     return(-1);
                    168: }
                    169: 
                    170:        
                    171: parseHandle *parseInit(char *buf, char *cmdList, int cmdNum)
                    172: {
                    173:     char        *ptr;                               /* temp pointer    */
                    174:     parseHandle *handle;                            /* new handle      */
                    175:     
                    176:     if (!buf || !cmdList)                           /* bad input ?     */
                    177:        return(NULL);
                    178:     if ((handle = (parseHandle*) kmalloc(sizeof(parseHandle), GFP_KERNEL)) == 0)
                    179:        return(NULL);                               /* out of memory   */
                    180:     if ((handle->cmdPos = (char**) kmalloc(sizeof(int) * cmdNum, GFP_KERNEL)) == 0) {
                    181:        kfree(handle);
                    182:        return(NULL);                               /* out of memory   */
                    183:     }
                    184:     
                    185:     handle->buf     = handle->bufPos = buf;         /* init handle     */
                    186:     handle->cmdList = cmdList;
                    187:     handle->cmdNum  = cmdNum;
                    188:     
                    189:     handle->cmdPos[cmdNum = 0] = cmdList;
                    190:     for (ptr = cmdList; *ptr; ptr++) {          /* scan command string */
                    191:        if(*ptr == ' ') {                       /* and insert zeroes   */
                    192:            *ptr++ = 0;
                    193:            handle->cmdPos[++cmdNum] = ptr++;
                    194:        } 
                    195:     }
                    196:     return(handle);
                    197: }
                    198: 
                    199: 
                    200: int parseOpt(parseHandle *handle, char **param)
                    201: {
                    202:     int  cmdIndex = 0, 
                    203:         cmdLen = 0;
                    204:     char *startPos;
                    205:     
                    206:     if (!handle)                                    /* invalid handle  */
                    207:        return(parseFree(handle));
                    208:     /* skip spaces     */  
                    209:     for (; *(handle->bufPos) && *(handle->bufPos) == ' '; handle->bufPos++);
                    210:     if (!*(handle->bufPos))
                    211:        return(parseFree(handle));                  /* end of data     */
                    212:     
                    213:     startPos = handle->bufPos;                      /* store cmd start */
                    214:     for (; handle->cmdPos[cmdIndex][cmdLen] && *(handle->bufPos); handle->bufPos++)
                    215:     {                                               /* no string end?  */
                    216:        for (;;)
                    217:        {
                    218:            if (*(handle->bufPos) == handle->cmdPos[cmdIndex][cmdLen])
                    219:                break;                              /* char matches ?  */
                    220:            else
                    221:                if (memcmp(startPos, (char*)(handle->cmdPos[++cmdIndex]), cmdLen))
                    222:                    return(parseFree(handle));      /* unknown command */
                    223:            
                    224:            if (cmdIndex >= handle->cmdNum)
                    225:                return(parseFree(handle));          /* unknown command */     
                    226:        }
                    227:        
                    228:        cmdLen++;                                   /* next char       */
                    229:     }
                    230:     
                    231:     /* Get param. First skip all blanks, then insert zero after param  */
                    232:     
                    233:     for (; *(handle->bufPos) && *(handle->bufPos) == ' '; handle->bufPos++);
                    234:     *param = handle->bufPos; 
                    235:     
                    236:     for (; *(handle->bufPos) && *(handle->bufPos) != ' '; handle->bufPos++);
                    237:     *(handle->bufPos++) = 0;
                    238:     
                    239:     return(cmdIndex);
                    240: }
                    241: 
                    242: void proc_print_scsidevice(Scsi_Device *scd, char *buffer, int *size, int len)
                    243: {          
                    244:     int x, y = *size;
                    245:     
                    246:     y = sprintf(buffer + len, 
                    247:                    "Host: scsi%d Channel: %02d Id: %02d Lun: %02d\n  Vendor: ",
                    248:                    scd->host->host_no, scd->channel, scd->id, scd->lun);
                    249:     for (x = 0; x < 8; x++) {
                    250:        if (scd->vendor[x] >= 0x20)
                    251:            y += sprintf(buffer + len + y, "%c", scd->vendor[x]);
                    252:        else
                    253:            y += sprintf(buffer + len + y," ");
                    254:     }
                    255:     y += sprintf(buffer + len + y, " Model: ");
                    256:     for (x = 0; x < 16; x++) {
                    257:        if (scd->model[x] >= 0x20)
                    258:            y +=  sprintf(buffer + len + y, "%c", scd->model[x]);
                    259:        else
                    260:            y += sprintf(buffer + len + y, " ");
                    261:     }
                    262:     y += sprintf(buffer + len + y, " Rev: ");
                    263:     for (x = 0; x < 4; x++) {
                    264:        if (scd->rev[x] >= 0x20)
                    265:            y += sprintf(buffer + len + y, "%c", scd->rev[x]);
                    266:        else
                    267:            y += sprintf(buffer + len + y, " ");
                    268:     }
                    269:     y += sprintf(buffer + len + y, "\n");
                    270:     
                    271:     y += sprintf(buffer + len + y, "  Type:   %s ",
                    272:                     scd->type < MAX_SCSI_DEVICE_CODE ? 
                    273:                     scsi_device_types[(int)scd->type] : "Unknown          " );
                    274:     y += sprintf(buffer + len + y, "               ANSI"
                    275:                     " SCSI revision: %02x", (scd->scsi_level < 3)?1:2);
                    276:     if (scd->scsi_level == 2)
                    277:        y += sprintf(buffer + len + y, " CCS\n");
                    278:     else
                    279:        y += sprintf(buffer + len + y, "\n");
                    280: 
                    281:     *size = y; 
                    282:     return;
                    283: }
                    284: 
                    285: /*
                    286:  * Overrides for Emacs so that we get a uniform tabbing style.
                    287:  * Emacs will notice this stuff at the end of the file and automatically
                    288:  * adjust the settings for this buffer only.  This must remain at the end
                    289:  * of the file.
                    290:  * ---------------------------------------------------------------------------
                    291:  * Local variables:
                    292:  * c-indent-level: 4
                    293:  * c-brace-imaginary-offset: 0
                    294:  * c-brace-offset: -4
                    295:  * c-argdecl-indent: 4
                    296:  * c-label-offset: -4
                    297:  * c-continued-statement-offset: 4
                    298:  * c-continued-brace-offset: 0
                    299:  * indent-tabs-mode: nil
                    300:  * tab-width: 8
                    301:  * End:
                    302:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.