This source file includes following definitions.
- seagate_st0x_detect
- seagate_st0x_info
- seagate_st0x_command
- seagate_st0x_abort
- seagate_st0x_reset
1
2
3
4
5
6
7
8
9 #include <linux/config.h>
10
11 #ifdef CONFIG_SCSI_SEAGATE
12 #include <linux/sched.h>
13
14 #include "seagate.h"
15 #include "scsi.h"
16 #include "hosts.h"
17
18 static int incommand;
19
20
21
22
23 static void *base_address = NULL;
24
25
26
27
28 static volatile int abort_confirm = 0;
29
30 volatile void *st0x_cr_sr;
31
32
33
34
35
36
37
38
39
40
41 static volatile void *st0x_dr;
42
43
44
45
46
47 static volatile int st0x_aborted=0;
48
49
50
51
52
53
54
55
56
57
58 #define retcode(result) (((result) << 16) | (message << 8) | status)
59 #define STATUS (*(unsigned char *) st0x_cr_sr)
60 #define CONTROL STATUS
61 #define DATA (*(unsigned char *) st0x_dr)
62
63 #ifndef OVERRIDE
64 static const char * seagate_bases[] = {(char *) 0xc8000, (char *) 0xca000, (char *) 0xcc000, (char *) 0xce000, (char *) 0xce000,
65 (char *) 0xdc000, (char *) 0xde000};
66 typedef struct
67 {
68 char *signature ;
69 unsigned offset;
70 unsigned length;
71 } Signature;
72
73 static const Signature signatures[] = {
74 {"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40},
75 {"SEAGATE SCSI BIOS ",16, 17},
76 {"SEAGATE SCSI BIOS ",17, 17}};
77
78
79
80
81
82
83
84
85
86 #define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
87 #endif
88
89 int seagate_st0x_detect (int hostnum)
90 {
91 #ifndef OVERRIDE
92 int i,j;
93 #endif
94
95
96
97
98 #ifdef DEBUG
99 printk("Autodetecting seagate ST0x\n");
100 #endif
101
102 base_address = NULL;
103 #ifdef OVERRIDE
104 base_address = (void *) OVERRIDE;
105 #ifdef DEBUG
106 printk("Base address overridden to %x\n", base_address);
107 #endif
108 #else
109
110
111
112
113
114
115 for (i = 0; i < (sizeof (seagate_bases) / sizeof (char * )); ++i)
116 for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
117 if (!memcmp ((void *) (seagate_bases[i] +
118 signatures[j].offset), (void *) signatures[j].signature,
119 signatures[j].length))
120 base_address = (void *) seagate_bases[i];
121 #endif
122
123 if (base_address)
124 {
125 st0x_cr_sr =(void *) (((unsigned char *) base_address) + 0x1a00);
126 st0x_dr = (void *) (((unsigned char *) base_address )+ 0x1c00);
127 #ifdef DEBUG
128 printk("ST0x detected. Base address = %x, cr = %x, dr = %x\n", base_address, st0x_cr_sr, st0x_dr);
129 #endif
130 return -1;
131 }
132 else
133 {
134 #ifdef DEBUG
135 printk("ST0x not detected.\n");
136 #endif
137 return 0;
138 }
139 }
140
141
142
143 char *seagate_st0x_info(void)
144 {
145 static char buffer[] = "Seagate ST-0X SCSI driver by Drew Eckhardt \n"
146 "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/seagate.c,v 1.1 1992/04/24 18:01:50 root Exp root $\n";
147 return buffer;
148 }
149
150
151
152 int seagate_st0x_command(unsigned char target, const void *cmnd,
153 void *buff, int bufflen)
154 {
155 int len;
156 unsigned char *data;
157
158 int clock;
159
160
161
162 #if (DEBUG & PHASE_SELECTION)
163 int temp;
164 #endif
165
166 #if (DEBUG & PHASE_EXIT)
167 void *retaddr, *realretaddr;
168 #endif
169
170 #if ((DEBUG & PHASE_ETC) || (DEBUG & PRINT_COMMAND) || (DEBUG & PHASE_EXIT))
171 int i;
172 #endif
173
174 #if (DEBUG & PHASE_ETC)
175 int phase=0, newphase;
176 #endif
177
178 int done = 0;
179 unsigned char status = 0;
180 unsigned char message = 0;
181 register unsigned char status_read;
182
183 #if (DEBUG & PHASE_EXIT)
184 __asm__("
185 movl 4(%%ebp), %%eax
186 ":"=a" (realretaddr):);
187 printk("return address = %08x\n", realretaddr);
188 #endif
189
190
191 len=bufflen;
192 data=(unsigned char *) buff;
193
194 incommand = 0;
195 st0x_aborted = 0;
196
197 #if (DEBUG & PRINT_COMMAND)
198 printk ("seagate_st0x_command, target = %d, command = ", target);
199 for (i = 0; i < COMMAND_SIZE(((unsigned char *)cmnd)[0]); ++i)
200 printk("%02x ", ((unsigned char *) cmnd)[i]);
201 printk("\n");
202 #endif
203
204 if (target > 6)
205 return DID_BAD_TARGET;
206
207
208 #if (DEBUG & PHASE_BUS_FREE)
209 printk ("SCSI PHASE = BUS FREE \n");
210 #endif
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226 clock = jiffies + ST0X_BUS_FREE_DELAY;
227
228 while (((STATUS | STATUS | STATUS) &
229 (STAT_BSY | STAT_SEL)) &&
230 (!st0x_aborted) && (jiffies < clock));
231
232 if (jiffies > clock)
233 return retcode(DID_BUS_BUSY);
234 else if (st0x_aborted)
235 return retcode(st0x_aborted);
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251 #if (DEBUG & PHASE_SELECTION)
252 printk("SCSI PHASE = SELECTION\n");
253 #endif
254
255 clock = jiffies + ST0X_SELECTION_DELAY;
256 DATA = (unsigned char) (1 << target);
257
258 CONTROL = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL;
259
260
261
262
263 while (!((status_read = STATUS) & STAT_BSY) && (jiffies < clock) && !st0x_aborted)
264
265 #if (DEBUG & PHASE_SELECTION)
266 {
267 temp = clock - jiffies;
268
269 if (!(jiffies % 5))
270 printk("seagate_st0x_timeout : %d \r",temp);
271
272 }
273 printk("Done. \n\r");
274 printk("Status = %02x, seagate_st0x_timeout = %d, aborted = %02x \n", status_read, temp,
275 st0x_aborted);
276 #else
277 ;
278 #endif
279
280
281 if ((jiffies > clock) || (!st0x_aborted & !(status_read & STAT_BSY)))
282 {
283 #if (DEBUG & PHASE_SELECT)
284 printk ("NO CONNECT with target %d, status = %x \n", target, STATUS);
285 #endif
286 return retcode(DID_NO_CONNECT);
287 }
288
289
290
291
292
293
294
295 if (st0x_aborted)
296 {
297 CONTROL = BASE_CMD;
298 if (STATUS & STAT_BSY)
299 {
300 seagate_st0x_reset();
301 return retcode(DID_RESET);
302 }
303
304 return retcode(st0x_aborted);
305 }
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320 #if (DEBUG & PHASE_ETC)
321 printk("PHASE = information transfer\n");
322 #endif
323
324 incommand = 1;
325
326
327
328
329
330 CONTROL = BASE_CMD | CMD_DRVR_ENABLE;
331
332
333
334
335
336
337
338
339
340 while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done)
341 {
342 #ifdef PARITY
343 if (status_read & STAT_PARITY)
344 {
345 done = 1;
346 st0x_aborted = DID_PARITY;
347 }
348 #endif
349
350 if (status_read & STAT_REQ)
351 {
352 #if (DEBUG & PHASE_ETC)
353 if ((newphase = (status_read & REQ_MASK)) != phase)
354 {
355 phase = newphase;
356 switch (phase)
357 {
358 case REQ_DATAOUT : printk("SCSI PHASE = DATA OUT\n"); break;
359 case REQ_DATAIN : printk("SCSI PHASE = DATA IN\n"); break;
360 case REQ_CMDOUT : printk("SCSI PHASE = COMMAND OUT\n"); break;
361 case REQ_STATIN : printk("SCSI PHASE = STATUS IN\n"); break;
362 case REQ_MSGOUT : printk("SCSI PHASE = MESSAGE OUT\n"); break;
363 case REQ_MSGIN : printk("SCSI PHASE = MESSAGE IN\n"); break;
364 default : printk("UNKNOWN PHASE"); st0x_aborted = 1; done = 1;
365 }
366 }
367 #endif
368
369 switch (status_read & REQ_MASK)
370 {
371 case REQ_DATAOUT :
372
373
374
375
376
377 __asm__ ("
378
379
380
381
382
383
384
385
386
387
388 movl %0, %%esi
389 movl %1, %%ecx
390 orl %%ecx, %%ecx
391 jz 2f
392
393 cld
394
395 movl _st0x_cr_sr, %%ebx
396 movl _st0x_dr, %%edi
397
398 1: movb (%%ebx), %%al
399
400
401
402
403 test $1, %%al
404 jz 2f
405
406
407
408
409 test $0xe, %%al
410 jnz 2f
411
412
413
414 test $0x10, %%al
415 jz 1b
416 lodsb
417 movb %%al, (%%edi)
418 loop 1b
419
420 2:
421 movl %%esi, %2
422 movl %%ecx, %3
423 ":
424
425 "=r" (data), "=r" (len) :
426
427 "0" (data), "1" (len) :
428
429 "ebx", "ecx", "edi", "esi");
430
431 break;
432
433 case REQ_DATAIN :
434
435
436
437
438
439 __asm__ ("
440
441
442
443
444
445
446
447
448
449
450 movl %0, %%edi
451 movl %1, %%ecx
452 orl %%ecx, %%ecx
453 jz 2f
454
455 cld
456 movl _st0x_cr_sr, %%esi
457 movl _st0x_dr, %%ebx
458
459 1: movb (%%esi), %%al
460
461
462
463
464 test $1, %%al
465 jz 2f
466
467
468
469
470 movb $0xe, %%ah
471 andb %%al, %%ah
472 cmpb $0x04, %%ah
473 jne 2f
474
475
476
477
478 test $0x10, %%al
479 jz 1b
480
481 movb (%%ebx), %%al
482 stosb
483 loop 1b
484
485 2: movl %%edi, %2
486 movl %%ecx, %3
487 ":
488
489 "=r" (data), "=r" (len) :
490
491 "0" (data), "1" (len) :
492
493 "ebx", "ecx", "edi", "esi");
494 break;
495
496 case REQ_CMDOUT :
497 while (((status_read = STATUS) & STAT_BSY) && ((status_read & REQ_MASK) ==
498 REQ_CMDOUT))
499 DATA = *(unsigned char *) cmnd ++;
500 break;
501
502 case REQ_STATIN :
503 status = DATA;
504 break;
505
506 case REQ_MSGOUT :
507 DATA = MESSAGE_REJECT;
508 break;
509
510 case REQ_MSGIN :
511 if ((message = DATA) == COMMAND_COMPLETE)
512 done=1;
513
514 break;
515
516 default : printk("UNKNOWN PHASE"); st0x_aborted = DID_ERROR;
517 }
518 }
519
520 }
521
522 #if (DEBUG & (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT))
523 printk("Transfered %d bytes, allowed %d additional bytes\n", (bufflen - len), len);
524 #endif
525
526 #if (DEBUG & PHASE_EXIT)
527 printk("Buffer : \n");
528 for (i = 0; i < 20; ++i)
529 printk ("%02x ", ((unsigned char *) buff)[i]);
530 printk("\n");
531 printk("Status = %02x, message = %02x\n", status, message);
532 #endif
533
534
535 if (st0x_aborted)
536 {
537 if (STATUS & STAT_BSY)
538 {
539 seagate_st0x_reset();
540 st0x_aborted = DID_RESET;
541 }
542 abort_confirm = 1;
543 }
544
545 CONTROL = BASE_CMD;
546
547 #if (DEBUG & PHASE_EXIT)
548 __asm__("
549 mov 4(%%ebp), %%eax
550 ":"=a" (retaddr):);
551
552 printk("Exiting seagate_st0x_command() - return address is %08x \n", retaddr);
553 if (retaddr != realretaddr)
554 panic ("Corrupted stack : return address on entry != return address on exit.\n");
555
556 #endif
557
558 return retcode (st0x_aborted);
559 }
560
561 int seagate_st0x_abort (int code)
562 {
563 if (code)
564 st0x_aborted = code;
565 else
566 st0x_aborted = DID_ABORT;
567
568 return 0;
569 }
570
571
572
573
574
575 int seagate_st0x_reset (void)
576 {
577 unsigned clock;
578
579
580
581
582
583 #ifdef DEBUG
584 printk("In seagate_st0x_reset()\n");
585 #endif
586
587
588
589
590 CONTROL = BASE_CMD | CMD_RST;
591 clock=jiffies+2;
592
593
594
595
596 while (jiffies < clock);
597
598 CONTROL = BASE_CMD;
599
600 st0x_aborted = DID_RESET;
601
602 #ifdef DEBUG
603 printk("SCSI bus reset.\n");
604 #endif
605 return 0;
606 }
607 #endif