diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/scsi/aic7xxx_old/aic7xxx_proc.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/scsi/aic7xxx_old/aic7xxx_proc.c')
-rw-r--r-- | drivers/scsi/aic7xxx_old/aic7xxx_proc.c | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/drivers/scsi/aic7xxx_old/aic7xxx_proc.c b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c new file mode 100644 index 000000000000..3bf334931a8a --- /dev/null +++ b/drivers/scsi/aic7xxx_old/aic7xxx_proc.c | |||
@@ -0,0 +1,374 @@ | |||
1 | /*+M************************************************************************* | ||
2 | * Adaptec AIC7xxx device driver proc support for Linux. | ||
3 | * | ||
4 | * Copyright (c) 1995, 1996 Dean W. Gehnert | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2, or (at your option) | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; see the file COPYING. If not, write to | ||
18 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | * ---------------------------------------------------------------- | ||
21 | * o Modified from the EATA-DMA /proc support. | ||
22 | * o Additional support for device block statistics provided by | ||
23 | * Matthew Jacob. | ||
24 | * o Correction of overflow by Heinz Mauelshagen | ||
25 | * o Adittional corrections by Doug Ledford | ||
26 | * | ||
27 | * Dean W. Gehnert, deang@teleport.com, 05/01/96 | ||
28 | * | ||
29 | * $Id: aic7xxx_proc.c,v 4.1 1997/06/97 08:23:42 deang Exp $ | ||
30 | *-M*************************************************************************/ | ||
31 | |||
32 | #include <linux/config.h> | ||
33 | |||
34 | #define BLS (&aic7xxx_buffer[size]) | ||
35 | #define HDRB \ | ||
36 | " 0 - 4K 4 - 16K 16 - 64K 64 - 256K 256K - 1M 1M+" | ||
37 | |||
38 | #ifdef PROC_DEBUG | ||
39 | extern int vsprintf(char *, const char *, va_list); | ||
40 | |||
41 | static void | ||
42 | proc_debug(const char *fmt, ...) | ||
43 | { | ||
44 | va_list ap; | ||
45 | char buf[256]; | ||
46 | |||
47 | va_start(ap, fmt); | ||
48 | vsprintf(buf, fmt, ap); | ||
49 | printk(buf); | ||
50 | va_end(ap); | ||
51 | } | ||
52 | #else /* PROC_DEBUG */ | ||
53 | # define proc_debug(fmt, args...) | ||
54 | #endif /* PROC_DEBUG */ | ||
55 | |||
56 | static int aic7xxx_buffer_size = 0; | ||
57 | static char *aic7xxx_buffer = NULL; | ||
58 | |||
59 | |||
60 | /*+F************************************************************************* | ||
61 | * Function: | ||
62 | * aic7xxx_set_info | ||
63 | * | ||
64 | * Description: | ||
65 | * Set parameters for the driver from the /proc filesystem. | ||
66 | *-F*************************************************************************/ | ||
67 | static int | ||
68 | aic7xxx_set_info(char *buffer, int length, struct Scsi_Host *HBAptr) | ||
69 | { | ||
70 | proc_debug("aic7xxx_set_info(): %s\n", buffer); | ||
71 | return (-ENOSYS); /* Currently this is a no-op */ | ||
72 | } | ||
73 | |||
74 | |||
75 | /*+F************************************************************************* | ||
76 | * Function: | ||
77 | * aic7xxx_proc_info | ||
78 | * | ||
79 | * Description: | ||
80 | * Return information to handle /proc support for the driver. | ||
81 | *-F*************************************************************************/ | ||
82 | int | ||
83 | aic7xxx_proc_info ( struct Scsi_Host *HBAptr, char *buffer, char **start, off_t offset, int length, | ||
84 | int inout) | ||
85 | { | ||
86 | struct aic7xxx_host *p; | ||
87 | struct aic_dev_data *aic_dev; | ||
88 | struct scsi_device *sdptr; | ||
89 | int size = 0; | ||
90 | unsigned char i; | ||
91 | unsigned char tindex; | ||
92 | |||
93 | for(p=first_aic7xxx; p && p->host != HBAptr; p=p->next) | ||
94 | ; | ||
95 | |||
96 | if (!p) | ||
97 | { | ||
98 | size += sprintf(buffer, "Can't find adapter for host number %d\n", HBAptr->host_no); | ||
99 | if (size > length) | ||
100 | { | ||
101 | return (size); | ||
102 | } | ||
103 | else | ||
104 | { | ||
105 | return (length); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | if (inout == TRUE) /* Has data been written to the file? */ | ||
110 | { | ||
111 | return (aic7xxx_set_info(buffer, length, HBAptr)); | ||
112 | } | ||
113 | |||
114 | p = (struct aic7xxx_host *) HBAptr->hostdata; | ||
115 | |||
116 | /* | ||
117 | * It takes roughly 1K of space to hold all relevant card info, not | ||
118 | * counting any proc stats, so we start out with a 1.5k buffer size and | ||
119 | * if proc_stats is defined, then we sweep the stats structure to see | ||
120 | * how many drives we will be printing out for and add 384 bytes per | ||
121 | * device with active stats. | ||
122 | * | ||
123 | * Hmmmm...that 1.5k seems to keep growing as items get added so they | ||
124 | * can be easily viewed for debugging purposes. So, we bumped that | ||
125 | * 1.5k to 4k so we can quit having to bump it all the time. | ||
126 | */ | ||
127 | |||
128 | size = 4096; | ||
129 | list_for_each_entry(aic_dev, &p->aic_devs, list) | ||
130 | size += 512; | ||
131 | if (aic7xxx_buffer_size != size) | ||
132 | { | ||
133 | if (aic7xxx_buffer != NULL) | ||
134 | { | ||
135 | kfree(aic7xxx_buffer); | ||
136 | aic7xxx_buffer_size = 0; | ||
137 | } | ||
138 | aic7xxx_buffer = kmalloc(size, GFP_KERNEL); | ||
139 | } | ||
140 | if (aic7xxx_buffer == NULL) | ||
141 | { | ||
142 | size = sprintf(buffer, "AIC7xxx - kmalloc error at line %d\n", | ||
143 | __LINE__); | ||
144 | return size; | ||
145 | } | ||
146 | aic7xxx_buffer_size = size; | ||
147 | |||
148 | size = 0; | ||
149 | size += sprintf(BLS, "Adaptec AIC7xxx driver version: "); | ||
150 | size += sprintf(BLS, "%s/", AIC7XXX_C_VERSION); | ||
151 | size += sprintf(BLS, "%s", AIC7XXX_H_VERSION); | ||
152 | size += sprintf(BLS, "\n"); | ||
153 | size += sprintf(BLS, "Adapter Configuration:\n"); | ||
154 | size += sprintf(BLS, " SCSI Adapter: %s\n", | ||
155 | board_names[p->board_name_index]); | ||
156 | if (p->flags & AHC_TWIN) | ||
157 | size += sprintf(BLS, " Twin Channel Controller "); | ||
158 | else | ||
159 | { | ||
160 | char *channel = ""; | ||
161 | char *ultra = ""; | ||
162 | char *wide = "Narrow "; | ||
163 | if (p->flags & AHC_MULTI_CHANNEL) | ||
164 | { | ||
165 | channel = " Channel A"; | ||
166 | if (p->flags & (AHC_CHNLB|AHC_CHNLC)) | ||
167 | channel = (p->flags & AHC_CHNLB) ? " Channel B" : " Channel C"; | ||
168 | } | ||
169 | if (p->features & AHC_WIDE) | ||
170 | wide = "Wide "; | ||
171 | if (p->features & AHC_ULTRA3) | ||
172 | { | ||
173 | switch(p->chip & AHC_CHIPID_MASK) | ||
174 | { | ||
175 | case AHC_AIC7892: | ||
176 | case AHC_AIC7899: | ||
177 | ultra = "Ultra-160/m LVD/SE "; | ||
178 | break; | ||
179 | default: | ||
180 | ultra = "Ultra-3 LVD/SE "; | ||
181 | break; | ||
182 | } | ||
183 | } | ||
184 | else if (p->features & AHC_ULTRA2) | ||
185 | ultra = "Ultra-2 LVD/SE "; | ||
186 | else if (p->features & AHC_ULTRA) | ||
187 | ultra = "Ultra "; | ||
188 | size += sprintf(BLS, " %s%sController%s ", | ||
189 | ultra, wide, channel); | ||
190 | } | ||
191 | switch(p->chip & ~AHC_CHIPID_MASK) | ||
192 | { | ||
193 | case AHC_VL: | ||
194 | size += sprintf(BLS, "at VLB slot %d\n", p->pci_device_fn); | ||
195 | break; | ||
196 | case AHC_EISA: | ||
197 | size += sprintf(BLS, "at EISA slot %d\n", p->pci_device_fn); | ||
198 | break; | ||
199 | default: | ||
200 | size += sprintf(BLS, "at PCI %d/%d/%d\n", p->pci_bus, | ||
201 | PCI_SLOT(p->pci_device_fn), PCI_FUNC(p->pci_device_fn)); | ||
202 | break; | ||
203 | } | ||
204 | if( !(p->maddr) ) | ||
205 | { | ||
206 | size += sprintf(BLS, " Programmed I/O Base: %lx\n", p->base); | ||
207 | } | ||
208 | else | ||
209 | { | ||
210 | size += sprintf(BLS, " PCI MMAPed I/O Base: 0x%lx\n", p->mbase); | ||
211 | } | ||
212 | if( (p->chip & (AHC_VL | AHC_EISA)) ) | ||
213 | { | ||
214 | size += sprintf(BLS, " BIOS Memory Address: 0x%08x\n", p->bios_address); | ||
215 | } | ||
216 | size += sprintf(BLS, " Adapter SEEPROM Config: %s\n", | ||
217 | (p->flags & AHC_SEEPROM_FOUND) ? "SEEPROM found and used." : | ||
218 | ((p->flags & AHC_USEDEFAULTS) ? "SEEPROM not found, using defaults." : | ||
219 | "SEEPROM not found, using leftover BIOS values.") ); | ||
220 | size += sprintf(BLS, " Adaptec SCSI BIOS: %s\n", | ||
221 | (p->flags & AHC_BIOS_ENABLED) ? "Enabled" : "Disabled"); | ||
222 | size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); | ||
223 | size += sprintf(BLS, " SCBs: Active %d, Max Active %d,\n", | ||
224 | p->activescbs, p->max_activescbs); | ||
225 | size += sprintf(BLS, " Allocated %d, HW %d, " | ||
226 | "Page %d\n", p->scb_data->numscbs, p->scb_data->maxhscbs, | ||
227 | p->scb_data->maxscbs); | ||
228 | if (p->flags & AHC_EXTERNAL_SRAM) | ||
229 | size += sprintf(BLS, " Using External SCB SRAM\n"); | ||
230 | size += sprintf(BLS, " Interrupts: %ld", p->isr_count); | ||
231 | if (p->chip & AHC_EISA) | ||
232 | { | ||
233 | size += sprintf(BLS, " %s\n", | ||
234 | (p->pause & IRQMS) ? "(Level Sensitive)" : "(Edge Triggered)"); | ||
235 | } | ||
236 | else | ||
237 | { | ||
238 | size += sprintf(BLS, "\n"); | ||
239 | } | ||
240 | size += sprintf(BLS, " BIOS Control Word: 0x%04x\n", | ||
241 | p->bios_control); | ||
242 | size += sprintf(BLS, " Adapter Control Word: 0x%04x\n", | ||
243 | p->adapter_control); | ||
244 | size += sprintf(BLS, " Extended Translation: %sabled\n", | ||
245 | (p->flags & AHC_EXTEND_TRANS_A) ? "En" : "Dis"); | ||
246 | size += sprintf(BLS, "Disconnect Enable Flags: 0x%04x\n", p->discenable); | ||
247 | if (p->features & (AHC_ULTRA | AHC_ULTRA2)) | ||
248 | { | ||
249 | size += sprintf(BLS, " Ultra Enable Flags: 0x%04x\n", p->ultraenb); | ||
250 | } | ||
251 | size += sprintf(BLS, "Default Tag Queue Depth: %d\n", aic7xxx_default_queue_depth); | ||
252 | size += sprintf(BLS, " Tagged Queue By Device array for aic7xxx host " | ||
253 | "instance %d:\n", p->instance); | ||
254 | size += sprintf(BLS, " {"); | ||
255 | for(i=0; i < (MAX_TARGETS - 1); i++) | ||
256 | size += sprintf(BLS, "%d,",aic7xxx_tag_info[p->instance].tag_commands[i]); | ||
257 | size += sprintf(BLS, "%d}\n",aic7xxx_tag_info[p->instance].tag_commands[i]); | ||
258 | |||
259 | size += sprintf(BLS, "\n"); | ||
260 | size += sprintf(BLS, "Statistics:\n\n"); | ||
261 | list_for_each_entry(aic_dev, &p->aic_devs, list) | ||
262 | { | ||
263 | sdptr = aic_dev->SDptr; | ||
264 | tindex = sdptr->channel << 3 | sdptr->id; | ||
265 | size += sprintf(BLS, "(scsi%d:%d:%d:%d)\n", | ||
266 | p->host_no, sdptr->channel, sdptr->id, sdptr->lun); | ||
267 | size += sprintf(BLS, " Device using %s/%s", | ||
268 | (aic_dev->cur.width == MSG_EXT_WDTR_BUS_16_BIT) ? | ||
269 | "Wide" : "Narrow", | ||
270 | (aic_dev->cur.offset != 0) ? | ||
271 | "Sync transfers at " : "Async transfers.\n" ); | ||
272 | if (aic_dev->cur.offset != 0) | ||
273 | { | ||
274 | struct aic7xxx_syncrate *sync_rate; | ||
275 | unsigned char options = aic_dev->cur.options; | ||
276 | int period = aic_dev->cur.period; | ||
277 | int rate = (aic_dev->cur.width == | ||
278 | MSG_EXT_WDTR_BUS_16_BIT) ? 1 : 0; | ||
279 | |||
280 | sync_rate = aic7xxx_find_syncrate(p, &period, 0, &options); | ||
281 | if (sync_rate != NULL) | ||
282 | { | ||
283 | size += sprintf(BLS, "%s MByte/sec, offset %d\n", | ||
284 | sync_rate->rate[rate], | ||
285 | aic_dev->cur.offset ); | ||
286 | } | ||
287 | else | ||
288 | { | ||
289 | size += sprintf(BLS, "3.3 MByte/sec, offset %d\n", | ||
290 | aic_dev->cur.offset ); | ||
291 | } | ||
292 | } | ||
293 | size += sprintf(BLS, " Transinfo settings: "); | ||
294 | size += sprintf(BLS, "current(%d/%d/%d/%d), ", | ||
295 | aic_dev->cur.period, | ||
296 | aic_dev->cur.offset, | ||
297 | aic_dev->cur.width, | ||
298 | aic_dev->cur.options); | ||
299 | size += sprintf(BLS, "goal(%d/%d/%d/%d), ", | ||
300 | aic_dev->goal.period, | ||
301 | aic_dev->goal.offset, | ||
302 | aic_dev->goal.width, | ||
303 | aic_dev->goal.options); | ||
304 | size += sprintf(BLS, "user(%d/%d/%d/%d)\n", | ||
305 | p->user[tindex].period, | ||
306 | p->user[tindex].offset, | ||
307 | p->user[tindex].width, | ||
308 | p->user[tindex].options); | ||
309 | if(sdptr->simple_tags) | ||
310 | { | ||
311 | size += sprintf(BLS, " Tagged Command Queueing Enabled, Ordered Tags %s, Depth %d/%d\n", sdptr->ordered_tags ? "Enabled" : "Disabled", sdptr->queue_depth, aic_dev->max_q_depth); | ||
312 | } | ||
313 | if(aic_dev->barrier_total) | ||
314 | size += sprintf(BLS, " Total transfers %ld:\n (%ld/%ld/%ld/%ld reads/writes/REQ_BARRIER/Ordered Tags)\n", | ||
315 | aic_dev->r_total+aic_dev->w_total, aic_dev->r_total, aic_dev->w_total, | ||
316 | aic_dev->barrier_total, aic_dev->ordered_total); | ||
317 | else | ||
318 | size += sprintf(BLS, " Total transfers %ld:\n (%ld/%ld reads/writes)\n", | ||
319 | aic_dev->r_total+aic_dev->w_total, aic_dev->r_total, aic_dev->w_total); | ||
320 | size += sprintf(BLS, "%s\n", HDRB); | ||
321 | size += sprintf(BLS, " Reads:"); | ||
322 | for (i = 0; i < ARRAY_SIZE(aic_dev->r_bins); i++) | ||
323 | { | ||
324 | size += sprintf(BLS, " %10ld", aic_dev->r_bins[i]); | ||
325 | } | ||
326 | size += sprintf(BLS, "\n"); | ||
327 | size += sprintf(BLS, " Writes:"); | ||
328 | for (i = 0; i < ARRAY_SIZE(aic_dev->w_bins); i++) | ||
329 | { | ||
330 | size += sprintf(BLS, " %10ld", aic_dev->w_bins[i]); | ||
331 | } | ||
332 | size += sprintf(BLS, "\n"); | ||
333 | size += sprintf(BLS, "\n\n"); | ||
334 | } | ||
335 | if (size >= aic7xxx_buffer_size) | ||
336 | { | ||
337 | printk(KERN_WARNING "aic7xxx: Overflow in aic7xxx_proc.c\n"); | ||
338 | } | ||
339 | |||
340 | if (offset > size - 1) | ||
341 | { | ||
342 | kfree(aic7xxx_buffer); | ||
343 | aic7xxx_buffer = NULL; | ||
344 | aic7xxx_buffer_size = length = 0; | ||
345 | *start = NULL; | ||
346 | } | ||
347 | else | ||
348 | { | ||
349 | *start = buffer; | ||
350 | length = min_t(int, length, size - offset); | ||
351 | memcpy(buffer, &aic7xxx_buffer[offset], length); | ||
352 | } | ||
353 | |||
354 | return (length); | ||
355 | } | ||
356 | |||
357 | /* | ||
358 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
359 | * Emacs will notice this stuff at the end of the file and automatically | ||
360 | * adjust the settings for this buffer only. This must remain at the end | ||
361 | * of the file. | ||
362 | * --------------------------------------------------------------------------- | ||
363 | * Local variables: | ||
364 | * c-indent-level: 2 | ||
365 | * c-brace-imaginary-offset: 0 | ||
366 | * c-brace-offset: -2 | ||
367 | * c-argdecl-indent: 2 | ||
368 | * c-label-offset: -2 | ||
369 | * c-continued-statement-offset: 2 | ||
370 | * c-continued-brace-offset: 0 | ||
371 | * indent-tabs-mode: nil | ||
372 | * tab-width: 8 | ||
373 | * End: | ||
374 | */ | ||