OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [scsi_proc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
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 neuffer@goofy.zdv.uni-mainz.de
10
 * Version: 0.99.8   last change: 95/09/13
11
 *
12
 * generic command parser provided by:
13
 * Andreas Heilwagen <crashcar@informatik.uni-koblenz.de>
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
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.