Annotation of Gnu-Mach/linux/src/drivers/scsi/scsi_proc.c, revision 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.