Bug Summary

File:obj-scan-build/../linux/src/drivers/scsi/tmscsim.c
Location:line 1670, column 4
Description:Value stored to 'istatus' is never read

Annotated Source Code

1/***********************************************************************
2 * FILE NAME : TMSCSIM.C *
3 * BY : C.L. Huang, ching@tekram.com.tw *
4 * Description: Device Driver for Tekram DC-390(T) PCI SCSI *
5 * Bus Master Host Adapter *
6 * (C)Copyright 1995-1996 Tekram Technology Co., Ltd. *
7 ***********************************************************************/
8/* Minor enhancements and bugfixes by *
9 * Kurt Garloff <K.Garloff@ping.de> *
10 ***********************************************************************/
11/* HISTORY: *
12 * *
13 * REV# DATE NAME DESCRIPTION *
14 * 1.00 04/24/96 CLH First release *
15 * 1.01 06/12/96 CLH Fixed bug of Media Change for Removable *
16 * Device, scan all LUN. Support Pre2.0.10 *
17 * 1.02 06/18/96 CLH Fixed bug of Command timeout ... *
18 * 1.03 09/25/96 KG Added tmscsim_proc_info() *
19 * 1.04 10/11/96 CLH Updating for support KV 2.0.x *
20 * 1.05 10/18/96 KG Fixed bug in DC390_abort(null ptr deref)*
21 * 1.06 10/25/96 KG Fixed module support *
22 * 1.07 11/09/96 KG Fixed tmscsim_proc_info() *
23 * 1.08 11/18/96 KG Fixed null ptr in DC390_Disconnect() *
24 * 1.09 11/30/96 KG Added register the allocated IO space *
25 * 1.10 12/05/96 CLH Modified tmscsim_proc_info(), and reset *
26 * pending interrupt in DC390_detect() *
27 * 1.11 02/05/97 KG/CLH Fixeds problem with partitions greater *
28 * than 1GB *
29 ***********************************************************************/
30
31
32#define DC390_DEBUG
33
34#define SCSI_MALLOC
35
36#ifdef MODULE
37#include <linux/module.h>
38#endif
39
40#include <asm/dma.h>
41#include <asm/io.h>
42#include <asm/system.h>
43#include <linux/delay.h>
44#include <linux/signal.h>
45#include <linux/sched.h>
46#include <linux/errno.h>
47#include <linux/kernel.h>
48#include <linux/ioport.h>
49#include <linux/bios32.h>
50#include <linux/pci.h>
51#include <linux/proc_fs.h>
52#include <linux/string.h>
53#include <linux/mm.h>
54#include <linux/config.h>
55
56#include <linux/version.h>
57#if LINUX_VERSION_CODE131108 < 66354 /* 1.3.50 */
58#include "../block/blk.h"
59#else
60#include <linux/blk.h>
61#endif
62
63#include "scsi.h"
64#include "hosts.h"
65#include "tmscsim.h"
66#include "constants.h"
67#include "sd.h"
68#include <linux/stat.h>
69
70#include "dc390.h"
71
72#define PCI_DEVICE_ID_AMD53C9740x2020 PCI_DEVICE_ID_AMD_SCSI0x2020
73
74
75#ifndef VERSION_ELF_1_2_13
76struct proc_dir_entry proc_scsi_tmscsim ={
77 PROC_SCSI_DC390T, 7 ,"tmscsim",
78 S_IFDIR0040000 | S_IRUGO(00400|00040|00004) | S_IXUGO(00100|00010|00001), 2
79 };
80#endif
81
82static USHORT DC390_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB );
83static void DC390_DataOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
84static void DC390_DataIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
85static void DC390_Command_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
86static void DC390_Status_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
87static void DC390_MsgOut_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
88static void DC390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
89static void DC390_DataOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
90static void DC390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
91static void DC390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
92static void DC390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
93static void DC390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
94static void DC390_MsgInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus);
95static void DC390_Nop_0( PACB pACB, PSRB pSRB, PUCHAR psstatus);
96static void DC390_Nop_1( PACB pACB, PSRB pSRB, PUCHAR psstatus);
97
98static void SetXferRate( PACB pACB, PDCB pDCB );
99static void DC390_Disconnect( PACB pACB );
100static void DC390_Reselect( PACB pACB );
101static void SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB );
102static void DoingSRB_Done( PACB pACB );
103static void DC390_ScsiRstDetect( PACB pACB );
104static void DC390_ResetSCSIBus( PACB pACB );
105static void RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB );
106static void EnableMsgOut2( PACB pACB, PSRB pSRB );
107static void EnableMsgOut( PACB pACB, PSRB pSRB );
108static void DC390_InvalidCmd( PACB pACB );
109
110int DC390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index );
111void DC390_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd );
112
113#ifdef MODULE
114static int DC390_release(struct Scsi_Host *host);
115static int DC390_shutdown (struct Scsi_Host *host);
116#endif
117
118
119static PSHT pSHT_start = NULL((void *) 0);
120static PSH pSH_start = NULL((void *) 0);
121static PSH pSH_current = NULL((void *) 0);
122static PACB pACB_start= NULL((void *) 0);
123static PACB pACB_current = NULL((void *) 0);
124static PDCB pPrevDCB = NULL((void *) 0);
125static USHORT adapterCnt = 0;
126static USHORT InitialTime = 0;
127static USHORT CurrSyncOffset = 0;
128static ULONG mech1addr;
129static UCHAR mech2bus, mech2Agent, mech2CfgSPenR;
130
131static PVOID DC390_phase0[]={
132 DC390_DataOut_0,
133 DC390_DataIn_0,
134 DC390_Command_0,
135 DC390_Status_0,
136 DC390_Nop_0,
137 DC390_Nop_0,
138 DC390_MsgOut_0,
139 DC390_MsgIn_0,
140 DC390_Nop_1
141 };
142
143static PVOID DC390_phase1[]={
144 DC390_DataOutPhase,
145 DC390_DataInPhase,
146 DC390_CommandPhase,
147 DC390_StatusPhase,
148 DC390_Nop_0,
149 DC390_Nop_0,
150 DC390_MsgOutPhase,
151 DC390_MsgInPhase,
152 DC390_Nop_1,
153 };
154
155UCHAR eepromBuf[MAX_ADAPTER_NUM4][128];
156
157
158UCHAR clock_period1[] = {4, 5, 6, 7, 8, 10, 13, 20};
159
160UCHAR baddevname1[2][28] ={
161 "SEAGATE ST3390N 9546",
162 "HP C3323-300 4269"};
163
164#define BADDEVCNT2 2
165
166
167/***********************************************************************
168 *
169 *
170 *
171 **********************************************************************/
172static void
173QLinkcmd( PSCSICMD cmd, PDCB pDCB )
174{
175 ULONG flags;
176 PSCSICMD pcmd;
177
178 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
179 cli()__asm__ __volatile__ ("cli": : :"memory");
180
181 if( !pDCB->QIORBCnt )
182 {
183 pDCB->pQIORBhead = cmd;
184 pDCB->pQIORBtail = cmd;
185 pDCB->QIORBCnt++;
186 cmd->next = NULL((void *) 0);
187 }
188 else
189 {
190 pcmd = pDCB->pQIORBtail;
191 pcmd->next = cmd;
192 pDCB->pQIORBtail = cmd;
193 pDCB->QIORBCnt++;
194 cmd->next = NULL((void *) 0);
195 }
196
197 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
198}
199
200
201static PSCSICMD
202Getcmd( PDCB pDCB )
203{
204 ULONG flags;
205 PSCSICMD pcmd;
206
207 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
208 cli()__asm__ __volatile__ ("cli": : :"memory");
209
210 pcmd = pDCB->pQIORBhead;
211 pDCB->pQIORBhead = pcmd->next;
212 pcmd->next = NULL((void *) 0);
213 pDCB->QIORBCnt--;
214
215 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
216 return( pcmd );
217}
218
219
220static PSRB
221GetSRB( PACB pACB )
222{
223 ULONG flags;
224 PSRB pSRB;
225
226 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
227 cli()__asm__ __volatile__ ("cli": : :"memory");
228
229 pSRB = pACB->pFreeSRB;
230 if( pSRB )
231 {
232 pACB->pFreeSRB = pSRB->pNextSRB;
233 pSRB->pNextSRB = NULL((void *) 0);
234 }
235 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
236 return( pSRB );
237}
238
239
240static void
241RewaitSRB0( PDCB pDCB, PSRB pSRB )
242{
243 PSRB psrb1;
244 ULONG flags;
245
246 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
247 cli()__asm__ __volatile__ ("cli": : :"memory");
248
249 if( (psrb1 = pDCB->pWaitingSRB) )
250 {
251 pSRB->pNextSRB = psrb1;
252 pDCB->pWaitingSRB = pSRB;
253 }
254 else
255 {
256 pSRB->pNextSRB = NULL((void *) 0);
257 pDCB->pWaitingSRB = pSRB;
258 pDCB->pWaitLast = pSRB;
259 }
260 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
261}
262
263
264static void
265RewaitSRB( PDCB pDCB, PSRB pSRB )
266{
267 PSRB psrb1;
268 ULONG flags;
269 UCHAR bval;
270
271 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
272 cli()__asm__ __volatile__ ("cli": : :"memory");
273 pDCB->GoingSRBCnt--;
274 psrb1 = pDCB->pGoingSRB;
275 if( pSRB == psrb1 )
276 {
277 pDCB->pGoingSRB = psrb1->pNextSRB;
278 }
279 else
280 {
281 while( pSRB != psrb1->pNextSRB )
282 psrb1 = psrb1->pNextSRB;
283 psrb1->pNextSRB = pSRB->pNextSRB;
284 if( pSRB == pDCB->pGoingLast )
285 pDCB->pGoingLast = psrb1;
286 }
287 if( (psrb1 = pDCB->pWaitingSRB) )
288 {
289 pSRB->pNextSRB = psrb1;
290 pDCB->pWaitingSRB = pSRB;
291 }
292 else
293 {
294 pSRB->pNextSRB = NULL((void *) 0);
295 pDCB->pWaitingSRB = pSRB;
296 pDCB->pWaitLast = pSRB;
297 }
298
299 bval = pSRB->TagNumber;
300 pDCB->TagMask &= (~(1 << bval)); /* Free TAG number */
301 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
302}
303
304
305static void
306DoWaitingSRB( PACB pACB )
307{
308 ULONG flags;
309 PDCB ptr, ptr1;
310 PSRB pSRB;
311
312 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
313 cli()__asm__ __volatile__ ("cli": : :"memory");
314
315 if( !(pACB->pActiveDCB) && !(pACB->ACBFlag & (RESET_DETECT0x00000002+RESET_DONE0x00000004+RESET_DEV0x00000001) ) )
316 {
317 ptr = pACB->pDCBRunRobin;
318 if( !ptr )
319 {
320 ptr = pACB->pLinkDCB;
321 pACB->pDCBRunRobin = ptr;
322 }
323 ptr1 = ptr;
324 for( ;ptr1; )
325 {
326 pACB->pDCBRunRobin = ptr1->pNextDCB;
327 if( !( ptr1->MaxCommand > ptr1->GoingSRBCnt ) ||
328 !( pSRB = ptr1->pWaitingSRB ) )
329 {
330 if(pACB->pDCBRunRobin == ptr)
331 break;
332 ptr1 = ptr1->pNextDCB;
333 }
334 else
335 {
336 if( !DC390_StartSCSI(pACB, ptr1, pSRB) )
337 {
338 ptr1->GoingSRBCnt++;
339 if( ptr1->pWaitLast == pSRB )
340 {
341 ptr1->pWaitingSRB = NULL((void *) 0);
342 ptr1->pWaitLast = NULL((void *) 0);
343 }
344 else
345 {
346 ptr1->pWaitingSRB = pSRB->pNextSRB;
347 }
348 pSRB->pNextSRB = NULL((void *) 0);
349
350 if( ptr1->pGoingSRB )
351 ptr1->pGoingLast->pNextSRB = pSRB;
352 else
353 ptr1->pGoingSRB = pSRB;
354 ptr1->pGoingLast = pSRB;
355 }
356 break;
357 }
358 }
359 }
360 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
361 return;
362}
363
364
365static void
366SRBwaiting( PDCB pDCB, PSRB pSRB)
367{
368 if( pDCB->pWaitingSRB )
369 {
370 pDCB->pWaitLast->pNextSRB = pSRB;
371 pDCB->pWaitLast = pSRB;
372 pSRB->pNextSRB = NULL((void *) 0);
373 }
374 else
375 {
376 pDCB->pWaitingSRB = pSRB;
377 pDCB->pWaitLast = pSRB;
378 }
379}
380
381
382static void
383SendSRB( PSCSICMD pcmd, PACB pACB, PSRB pSRB )
384{
385 ULONG flags;
386 PDCB pDCB;
387
388 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
389 cli()__asm__ __volatile__ ("cli": : :"memory");
390
391 pDCB = pSRB->pSRBDCB;
392 if( !(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB) ||
393 (pACB->ACBFlag & (RESET_DETECT0x00000002+RESET_DONE0x00000004+RESET_DEV0x00000001)) )
394 {
395 SRBwaiting(pDCB, pSRB);
396 goto SND_EXIT;
397 }
398
399 if( pDCB->pWaitingSRB )
400 {
401 SRBwaiting(pDCB, pSRB);
402/* pSRB = GetWaitingSRB(pDCB); */
403 pSRB = pDCB->pWaitingSRB;
404 pDCB->pWaitingSRB = pSRB->pNextSRB;
405 pSRB->pNextSRB = NULL((void *) 0);
406 }
407
408 if( !DC390_StartSCSI(pACB, pDCB, pSRB) )
409 {
410 pDCB->GoingSRBCnt++;
411 if( pDCB->pGoingSRB )
412 {
413 pDCB->pGoingLast->pNextSRB = pSRB;
414 pDCB->pGoingLast = pSRB;
415 }
416 else
417 {
418 pDCB->pGoingSRB = pSRB;
419 pDCB->pGoingLast = pSRB;
420 }
421 }
422 else
423 RewaitSRB0( pDCB, pSRB );
424
425SND_EXIT:
426 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
427 return;
428}
429
430
431/***********************************************************************
432 * Function : static int DC390_queue_command (Scsi_Cmnd *cmd,
433 * void (*done)(Scsi_Cmnd *))
434 *
435 * Purpose : enqueues a SCSI command
436 *
437 * Inputs : cmd - SCSI command, done - function called on completion, with
438 * a pointer to the command descriptor.
439 *
440 * Returns : 0
441 *
442 ***********************************************************************/
443
444int
445DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
446{
447 USHORT ioport, i;
448 Scsi_Cmnd *pcmd;
449 struct Scsi_Host *psh;
450 PACB pACB;
451 PDCB pDCB;
452 PSRB pSRB;
453 ULONG flags;
454 PUCHAR ptr,ptr1;
455
456 psh = cmd->host;
457 pACB = (PACB ) psh->hostdata;
458 ioport = pACB->IOPortBase;
459
460#ifdef DC390_DEBUG0
461/* if(pACB->scan_devices) */
462 printk("Cmd=%2x,ID=%d,LUN=%d,",cmd->cmnd[0],cmd->target,cmd->lun);
463#endif
464
465 if( (pACB->scan_devices == END_SCAN2) && (cmd->cmnd[0] != INQUIRY0x12) )
466 {
467 pACB->scan_devices = 0;
468 pPrevDCB->pNextDCB = pACB->pLinkDCB;
469 }
470 else if( (pACB->scan_devices) && (cmd->cmnd[0] == 8) )
471 {
472 pACB->scan_devices = 0;
473 pPrevDCB->pNextDCB = pACB->pLinkDCB;
474 }
475
476 if ( ( cmd->target > pACB->max_id ) || (cmd->lun > pACB->max_lun) )
477 {
478/* printk("DC390: Ignore target %d lun %d\n",
479 cmd->target, cmd->lun); */
480 cmd->result = (DID_BAD_TARGET0x04 << 16);
481 done(cmd);
482 return( 0 );
483 }
484
485 if( (pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
486 {
487 if( pACB->DeviceCnt < MAX_DEVICES10 )
488 {
489 pACB->DCBmap[cmd->target] |= (1 << cmd->lun);
490 pDCB = pACB->pDCB_free;
491#ifdef DC390_DEBUG0
492 printk("pDCB=%8x,ID=%2x,", (UINT) pDCB, cmd->target);
493#endif
494 DC390_initDCB( pACB, pDCB, cmd );
495 }
496 else /* ???? */
497 {
498/* printk("DC390: Ignore target %d lun %d\n",
499 cmd->target, cmd->lun); */
500 cmd->result = (DID_BAD_TARGET0x04 << 16);
501 done(cmd);
502 return(0);
503 }
504 }
505 else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
506 {
507/* printk("DC390: Ignore target %d lun %d\n",
508 cmd->target, cmd->lun); */
509 cmd->result = (DID_BAD_TARGET0x04 << 16);
510 done(cmd);
511 return(0);
512 }
513 else
514 {
515 pDCB = pACB->pLinkDCB;
516 while( (pDCB->UnitSCSIID != cmd->target) ||
517 (pDCB->UnitSCSILUN != cmd->lun) )
518 {
519 pDCB = pDCB->pNextDCB;
520 }
521#ifdef DC390_DEBUG0
522 printk("pDCB=%8x,ID=%2x,", (UINT) pDCB, cmd->target);
523#endif
524 }
525
526 cmd->scsi_done = done;
527 cmd->result = 0;
528
529 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
530 cli()__asm__ __volatile__ ("cli": : :"memory");
531
532 if( pDCB->QIORBCnt )
533 {
534 QLinkcmd( cmd, pDCB );
535 pcmd = Getcmd( pDCB );
536 }
537 else
538 pcmd = cmd;
539
540 pSRB = GetSRB( pACB );
541
542 if( !pSRB )
543 {
544 QLinkcmd( pcmd, pDCB );
545 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
546 return(0);
547 }
548
549/* BuildSRB(pSRB); */
550
551 pSRB->pSRBDCB = pDCB;
552 pSRB->pcmd = pcmd;
553 ptr = (PUCHAR) pSRB->CmdBlock;
554 ptr1 = (PUCHAR) pcmd->cmnd;
555 pSRB->ScsiCmdLen = pcmd->cmd_len;
556 for(i=0; i< pcmd->cmd_len; i++)
557 {
558 *ptr = *ptr1;
559 ptr++;
560 ptr1++;
561 }
562 if( pcmd->use_sg )
563 {
564 pSRB->SGcount = (UCHAR) pcmd->use_sg;
565 pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
566 }
567 else if( pcmd->request_buffer )
568 {
569 pSRB->SGcount = 1;
570 pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
571 pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
572 pSRB->Segmentx.length = pcmd->request_bufflen;
573 }
574 else
575 pSRB->SGcount = 0;
576
577 pSRB->SGIndex = 0;
578 pSRB->AdaptStatus = 0;
579 pSRB->TargetStatus = 0;
580 pSRB->MsgCnt = 0;
581 if( pDCB->DevType != TYPE_TAPE0x01 )
582 pSRB->RetryCnt = 1;
583 else
584 pSRB->RetryCnt = 0;
585 pSRB->SRBStatus = 0;
586 pSRB->SRBFlag = 0;
587 pSRB->SRBState = 0;
588 pSRB->TotalXferredLen = 0;
589 pSRB->SGPhysAddr = 0;
590 pSRB->SGToBeXferLen = 0;
591 pSRB->ScsiPhase = 0;
592 pSRB->EndMessage = 0;
593 SendSRB( pcmd, pACB, pSRB );
594
595 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
596 return(0);
597}
598
599
600static void
601DoNextCmd( PACB pACB, PDCB pDCB )
602{
603 Scsi_Cmnd *pcmd;
604 PSRB pSRB;
605 ULONG flags;
606 PUCHAR ptr,ptr1;
607 USHORT i;
608
609
610 if( pACB->ACBFlag & (RESET_DETECT0x00000002+RESET_DONE0x00000004+RESET_DEV0x00000001) )
611 return;
612 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
613 cli()__asm__ __volatile__ ("cli": : :"memory");
614
615 pcmd = Getcmd( pDCB );
616 pSRB = GetSRB( pACB );
617 if( !pSRB )
618 {
619 QLinkcmd( pcmd, pDCB );
620 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
621 return;
622 }
623
624 pSRB->pSRBDCB = pDCB;
625 pSRB->pcmd = pcmd;
626 ptr = (PUCHAR) pSRB->CmdBlock;
627 ptr1 = (PUCHAR) pcmd->cmnd;
628 pSRB->ScsiCmdLen = pcmd->cmd_len;
629 for(i=0; i< pcmd->cmd_len; i++)
630 {
631 *ptr = *ptr1;
632 ptr++;
633 ptr1++;
634 }
635 if( pcmd->use_sg )
636 {
637 pSRB->SGcount = (UCHAR) pcmd->use_sg;
638 pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
639 }
640 else if( pcmd->request_buffer )
641 {
642 pSRB->SGcount = 1;
643 pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
644 pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
645 pSRB->Segmentx.length = pcmd->request_bufflen;
646 }
647 else
648 pSRB->SGcount = 0;
649
650 pSRB->SGIndex = 0;
651 pSRB->AdaptStatus = 0;
652 pSRB->TargetStatus = 0;
653 pSRB->MsgCnt = 0;
654 if( pDCB->DevType != TYPE_TAPE0x01 )
655 pSRB->RetryCnt = 1;
656 else
657 pSRB->RetryCnt = 0;
658 pSRB->SRBStatus = 0;
659 pSRB->SRBFlag = 0;
660 pSRB->SRBState = 0;
661 pSRB->TotalXferredLen = 0;
662 pSRB->SGPhysAddr = 0;
663 pSRB->SGToBeXferLen = 0;
664 pSRB->ScsiPhase = 0;
665 pSRB->EndMessage = 0;
666 SendSRB( pcmd, pACB, pSRB );
667
668 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
669 return;
670}
671
672
673/***********************************************************************
674 * Function:
675 * DC390_bios_param
676 *
677 * Description:
678 * Return the disk geometry for the given SCSI device.
679 ***********************************************************************/
680#ifdef VERSION_ELF_1_2_13
681int DC390_bios_param(Disk *disk, int devno, int geom[])
682#else
683int DC390_bios_param(Disk *disk, kdev_t devno, int geom[])
684#endif
685{
686 int heads, sectors, cylinders;
687 PACB pACB;
688
689 pACB = (PACB) disk->device->host->hostdata;
690 heads = 64;
691 sectors = 32;
692 cylinders = disk->capacity / (heads * sectors);
693
694 if ( (pACB->Gmode2 & GREATER_1G0x00000002) && (cylinders > 1024) )
695 {
696 heads = 255;
697 sectors = 63;
698 cylinders = disk->capacity / (heads * sectors);
699 }
700
701 geom[0] = heads;
702 geom[1] = sectors;
703 geom[2] = cylinders;
704
705 return (0);
706}
707
708
709/***********************************************************************
710 * Function : int DC390_abort (Scsi_Cmnd *cmd)
711 *
712 * Purpose : Abort an errant SCSI command
713 *
714 * Inputs : cmd - command to abort
715 *
716 * Returns : 0 on success, -1 on failure.
717 ***********************************************************************/
718
719int
720DC390_abort (Scsi_Cmnd *cmd)
721{
722 ULONG flags;
723 PACB pACB;
724 PDCB pDCB, pdcb;
725 PSRB pSRB, psrb;
726 USHORT count, i;
727 PSCSICMD pcmd, pcmd1;
728 int status;
729
730
731#ifdef DC390_DEBUG0
732 printk("DC390 : Abort Cmd.");
733#endif
734
735 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
736 cli()__asm__ __volatile__ ("cli": : :"memory");
737
738 pACB = (PACB) cmd->host->hostdata;
739 pDCB = pACB->pLinkDCB;
740 pdcb = pDCB;
741 while( (pDCB->UnitSCSIID != cmd->target) ||
742 (pDCB->UnitSCSILUN != cmd->lun) )
743 {
744 pDCB = pDCB->pNextDCB;
745 if( pDCB == pdcb )
746 goto NOT_RUN;
747 }
748
749 if( pDCB->QIORBCnt )
750 {
751 pcmd = pDCB->pQIORBhead;
752 if( pcmd == cmd )
753 {
754 pDCB->pQIORBhead = pcmd->next;
755 pcmd->next = NULL((void *) 0);
756 pDCB->QIORBCnt--;
757 status = SCSI_ABORT_SUCCESS1;
758 goto ABO_X;
759 }
760 for( count = pDCB->QIORBCnt, i=0; i<count-1; i++)
761 {
762 if( pcmd->next == cmd )
763 {
764 pcmd1 = pcmd->next;
765 pcmd->next = pcmd1->next;
766 pcmd1->next = NULL((void *) 0);
767 pDCB->QIORBCnt--;
768 status = SCSI_ABORT_SUCCESS1;
769 goto ABO_X;
770 }
771 else
772 {
773 pcmd = pcmd->next;
774 }
775 }
776 }
777
778 pSRB = pDCB->pWaitingSRB;
779 if( !pSRB )
780 goto ON_GOING;
781 if( pSRB->pcmd == cmd )
782 {
783 pDCB->pWaitingSRB = pSRB->pNextSRB;
784 goto IN_WAIT;
785 }
786 else
787 {
788 psrb = pSRB;
789 if( !(psrb->pNextSRB) )
790 goto ON_GOING;
791 while( psrb->pNextSRB->pcmd != cmd )
792 {
793 psrb = psrb->pNextSRB;
794 if( !(psrb->pNextSRB) )
795 goto ON_GOING;
796 }
797 pSRB = psrb->pNextSRB;
798 psrb->pNextSRB = pSRB->pNextSRB;
799 if( pSRB == pDCB->pWaitLast )
800 pDCB->pWaitLast = psrb; /* No check for psrb == NULL ? */
801IN_WAIT:
802 pSRB->pNextSRB = pACB->pFreeSRB;
803 pACB->pFreeSRB = pSRB;
804 cmd->next = NULL((void *) 0);
805 status = SCSI_ABORT_SUCCESS1;
806 goto ABO_X;
807 }
808
809ON_GOING:
810 pSRB = pDCB->pGoingSRB;
811 for( count = pDCB->GoingSRBCnt, i=0; i<count; i++)
812 {
813 if( pSRB->pcmd != cmd )
814 pSRB = pSRB->pNextSRB;
815 else
816 {
817 if( (pACB->pActiveDCB == pDCB) && (pDCB->pActiveSRB == pSRB) )
818 {
819 status = SCSI_ABORT_BUSY3;
820 goto ABO_X;
821 }
822 else
823 {
824 status = SCSI_ABORT_SNOOZE0;
825 goto ABO_X;
826 }
827 }
828 }
829
830NOT_RUN:
831 status = SCSI_ABORT_NOT_RUNNING4;
832
833ABO_X:
834 cmd->result = DID_ABORT0x05 << 16;
835 cmd->scsi_done(cmd);
836 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
837 return( status );
838}
839
840
841static void
842ResetDevParam( PACB pACB )
843{
844 PDCB pDCB, pdcb;
845
846 pDCB = pACB->pLinkDCB;
847 if( pDCB == NULL((void *) 0) )
848 return;
849 pdcb = pDCB;
850 do
851 {
852 pDCB->SyncMode &= ~SYNC_NEGO_DONE0x00000002;
853 pDCB->SyncPeriod = 0;
854 pDCB->SyncOffset = 0;
855 pDCB->CtrlR3 = FAST_CLK0x00000008;
856 pDCB->CtrlR4 &= NEGATE_REQACKDATA0x00000004;
857 pDCB->CtrlR4 |= EATER_25NS0x00000080;
858 pDCB = pDCB->pNextDCB;
859 }
860 while( pdcb != pDCB );
861}
862
863
864static void
865RecoverSRB( PACB pACB )
866{
867 PDCB pDCB, pdcb;
868 PSRB psrb, psrb2;
869 USHORT cnt, i;
870
871 pDCB = pACB->pLinkDCB;
872 if( pDCB == NULL((void *) 0) )
873 return;
874 pdcb = pDCB;
875 do
876 {
877 cnt = pdcb->GoingSRBCnt;
878 psrb = pdcb->pGoingSRB;
879 for (i=0; i<cnt; i++)
880 {
881 psrb2 = psrb;
882 psrb = psrb->pNextSRB;
883/* RewaitSRB( pDCB, psrb ); */
884 if( pdcb->pWaitingSRB )
885 {
886 psrb2->pNextSRB = pdcb->pWaitingSRB;
887 pdcb->pWaitingSRB = psrb2;
888 }
889 else
890 {
891 pdcb->pWaitingSRB = psrb2;
892 pdcb->pWaitLast = psrb2;
893 psrb2->pNextSRB = NULL((void *) 0);
894 }
895 }
896 pdcb->GoingSRBCnt = 0;
897 pdcb->pGoingSRB = NULL((void *) 0);
898 pdcb->TagMask = 0;
899 pdcb = pdcb->pNextDCB;
900 }
901 while( pdcb != pDCB );
902}
903
904
905/***********************************************************************
906 * Function : int DC390_reset (Scsi_Cmnd *cmd, ...)
907 *
908 * Purpose : perform a hard reset on the SCSI bus
909 *
910 * Inputs : cmd - command which caused the SCSI RESET
911 *
912 * Returns : 0 on success.
913 ***********************************************************************/
914
915#ifdef VERSION_2_0_0
916int DC390_reset(Scsi_Cmnd *cmd, unsigned int resetFlags)
917#else
918int DC390_reset (Scsi_Cmnd *cmd)
919#endif
920{
921 USHORT ioport;
922 unsigned long flags;
923 PACB pACB;
924 UCHAR bval;
925 USHORT i;
926
927
928#ifdef DC390_DEBUG1
929 printk("DC390: RESET,");
930#endif
931
932 pACB = (PACB ) cmd->host->hostdata;
933 ioport = pACB->IOPortBase;
934 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
935 cli()__asm__ __volatile__ ("cli": : :"memory");
936 bval = inb(ioport+CtrlReg1)((__builtin_constant_p((ioport+0x20)) && (ioport+0x20
) < 256) ? __inbc(ioport+0x20) : __inb(ioport+0x20))
;
937 bval |= DIS_INT_ON_SCSI_RST0x00000040;
938 outb(bval,ioport+CtrlReg1)((__builtin_constant_p((ioport+0x20)) && (ioport+0x20
) < 256) ? __outbc((bval),(ioport+0x20)) : __outb((bval),(
ioport+0x20)))
; /* disable interrupt */
939 DC390_ResetSCSIBus( pACB );
940 for( i=0; i<500; i++ )
941 udelay(1000)(__builtin_constant_p(1000) ? __const_udelay((1000) * 0x10c6ul
) : __udelay(1000))
;
942 bval = inb(ioport+CtrlReg1)((__builtin_constant_p((ioport+0x20)) && (ioport+0x20
) < 256) ? __inbc(ioport+0x20) : __inb(ioport+0x20))
;
943 bval &= ~DIS_INT_ON_SCSI_RST0x00000040;
944 outb(bval,ioport+CtrlReg1)((__builtin_constant_p((ioport+0x20)) && (ioport+0x20
) < 256) ? __outbc((bval),(ioport+0x20)) : __outb((bval),(
ioport+0x20)))
; /* re-enable interrupt */
945
946 bval = DMA_IDLE_CMD0;
947 outb(bval,ioport+DMA_Cmd)((__builtin_constant_p((ioport+0x40)) && (ioport+0x40
) < 256) ? __outbc((bval),(ioport+0x40)) : __outb((bval),(
ioport+0x40)))
;
948 bval = CLEAR_FIFO_CMD1;
949 outb(bval,ioport+ScsiCmd)((__builtin_constant_p((ioport+0x0C)) && (ioport+0x0C
) < 256) ? __outbc((bval),(ioport+0x0C)) : __outb((bval),(
ioport+0x0C)))
;
950
951 ResetDevParam( pACB );
952 DoingSRB_Done( pACB );
953 pACB->pActiveDCB = NULL((void *) 0);
954
955 pACB->ACBFlag = 0;
956 DoWaitingSRB( pACB );
957
958 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
959#ifdef DC390_DEBUG1
960 printk("DC390: RESET1,");
961#endif
962 return( SCSI_RESET_SUCCESS2 );
963}
964
965
966#include "scsiiom.c"
967
968
969/***********************************************************************
970 * Function : static void DC390_initDCB
971 *
972 * Purpose : initialize the internal structures for a given DCB
973 *
974 * Inputs : cmd - pointer to this scsi cmd request block structure
975 *
976 ***********************************************************************/
977void DC390_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd )
978{
979 PEEprom prom;
980 UCHAR bval;
981 USHORT index;
982
983 if( pACB->DeviceCnt == 0 )
984 {
985 pACB->pLinkDCB = pDCB;
986 pACB->pDCBRunRobin = pDCB;
987 pDCB->pNextDCB = pDCB;
988 pPrevDCB = pDCB;
989 }
990 else
991 pPrevDCB->pNextDCB = pDCB;
992
993 pDCB->pDCBACB = pACB;
994 pDCB->QIORBCnt = 0;
995 pDCB->UnitSCSIID = cmd->target;
996 pDCB->UnitSCSILUN = cmd->lun;
997 pDCB->pWaitingSRB = NULL((void *) 0);
998 pDCB->pGoingSRB = NULL((void *) 0);
999 pDCB->GoingSRBCnt = 0;
1000 pDCB->pActiveSRB = NULL((void *) 0);
1001 pDCB->TagMask = 0;
1002 pDCB->MaxCommand = 1;
1003 pDCB->AdaptIndex = pACB->AdapterIndex;
1004 index = pACB->AdapterIndex;
1005 pDCB->DCBFlag = 0;
1006
1007 prom = (PEEprom) &eepromBuf[index][cmd->target << 2];
1008 pDCB->DevMode = prom->EE_MODE1;
1009 pDCB->AdpMode = eepromBuf[index][EE_MODE265];
1010
1011 if( pDCB->DevMode & EN_DISCONNECT_0x00000004 )
1012 bval = 0xC0;
1013 else
1014 bval = 0x80;
1015 bval |= cmd->lun;
1016 pDCB->IdentifyMsg = bval;
1017
1018 pDCB->SyncMode = 0;
1019 if( pDCB->DevMode & SYNC_NEGO_0x00000002 )
1020 {
1021 if( !(cmd->lun) || CurrSyncOffset )
1022 pDCB->SyncMode = SYNC_ENABLE0x00000001;
1023 }
1024
1025 pDCB->SyncPeriod = 0;
1026 pDCB->SyncOffset = 0;
1027 pDCB->NegoPeriod = (clock_period1[prom->EE_SPEED] * 25) >> 2;
1028
1029 pDCB->CtrlR1 = pACB->AdaptSCSIID;
1030 if( pDCB->DevMode & PARITY_CHK_0x00000001 )
1031 pDCB->CtrlR1 |= PARITY_ERR_REPO0x00000010;
1032
1033 pDCB->CtrlR3 = FAST_CLK0x00000008;
1034
1035 pDCB->CtrlR4 = EATER_25NS0x00000080;
1036 if( pDCB->AdpMode & ACTIVE_NEGATION0x00000008)
1037 pDCB->CtrlR4 |= NEGATE_REQACKDATA0x00000004;
1038}
1039
1040
1041/***********************************************************************
1042 * Function : static void DC390_initSRB
1043 *
1044 * Purpose : initialize the internal structures for a given SRB
1045 *
1046 * Inputs : psrb - pointer to this scsi request block structure
1047 *
1048 ***********************************************************************/
1049void DC390_initSRB( PSRB psrb )
1050{
1051#ifndef VERSION_ELF_1_2_13
1052#ifdef DC390_DEBUG0
1053 printk("DC390 init: %08lx %08lx,",(ULONG)psrb,(ULONG)virt_to_busvirt_to_phys(psrb));
1054#endif
1055 psrb->PhysSRB = virt_to_busvirt_to_phys( psrb );
1056#else
1057 psrb->PhysSRB = (ULONG) psrb;
1058#endif
1059}
1060
1061
1062void DC390_linkSRB( PACB pACB )
1063{
1064 USHORT count, i;
1065 PSRB psrb;
1066
1067 count = pACB->SRBCount;
1068
1069 for( i=0; i< count; i++)
1070 {
1071 if( i != count - 1)
1072 pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
1073 else
1074 pACB->SRB_array[i].pNextSRB = NULL((void *) 0);
1075 psrb = (PSRB) &pACB->SRB_array[i];
1076 DC390_initSRB( psrb );
1077 }
1078}
1079
1080
1081/***********************************************************************
1082 * Function : static void DC390_initACB
1083 *
1084 * Purpose : initialize the internal structures for a given SCSI host
1085 *
1086 * Inputs : psh - pointer to this host adapter's structure
1087 *
1088 ***********************************************************************/
1089void DC390_initACB( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
1090{
1091 PACB pACB;
1092 USHORT i;
1093
1094 psh->can_queue = MAX_CMD_QUEUE20;
1095 psh->cmd_per_lun = MAX_CMD_PER_LUN8;
1096 psh->this_id = (int) eepromBuf[index][EE_ADAPT_SCSI_ID64];
1097 psh->io_port = io_port;
1098 psh->n_io_port = 0x80;
1099 psh->irq = Irq;
1100
1101 pACB = (PACB) psh->hostdata;
1102
1103#ifndef VERSION_ELF_1_2_13
1104 psh->max_id = 8;
1105#ifdef CONFIG_SCSI_MULTI_LUN
1106 if( eepromBuf[index][EE_MODE265] & LUN_CHECK0x00000020 )
1107 psh->max_lun = 8;
1108 else
1109#endif
1110 psh->max_lun = 1;
1111#endif
1112
1113 pACB->max_id = 7;
1114 if( pACB->max_id == eepromBuf[index][EE_ADAPT_SCSI_ID64] )
1115 pACB->max_id--;
1116#ifdef CONFIG_SCSI_MULTI_LUN
1117 if( eepromBuf[index][EE_MODE265] & LUN_CHECK0x00000020 )
1118 pACB->max_lun = 7;
1119 else
1120#endif
1121 pACB->max_lun = 0;
1122
1123 pACB->pScsiHost = psh;
1124 pACB->IOPortBase = (USHORT) io_port;
1125 pACB->pLinkDCB = NULL((void *) 0);
1126 pACB->pDCBRunRobin = NULL((void *) 0);
1127 pACB->pActiveDCB = NULL((void *) 0);
1128 pACB->pFreeSRB = pACB->SRB_array;
1129 pACB->SRBCount = MAX_SRB_CNT20 +4;
1130 pACB->AdapterIndex = index;
1131 pACB->status = 0;
1132 pACB->AdaptSCSIID = eepromBuf[index][EE_ADAPT_SCSI_ID64];
1133 pACB->HostID_Bit = (1 << pACB->AdaptSCSIID);
1134 pACB->AdaptSCSILUN = 0;
1135 pACB->DeviceCnt = 0;
1136 pACB->IRQLevel = Irq;
1137 pACB->TagMaxNum = eepromBuf[index][EE_TAG_CMD_NUM67] << 2;
1138 pACB->ACBFlag = 0;
1139 pACB->scan_devices = 1;
1140 pACB->Gmode2 = eepromBuf[index][EE_MODE265];
1141 if( eepromBuf[index][EE_MODE265] & LUN_CHECK0x00000020 )
1142 pACB->LUNchk = 1;
1143 pACB->pDCB_free = &pACB->DCB_array[0];
1144 DC390_linkSRB( pACB );
1145 pACB->pTmpSRB = &pACB->TmpSRB;
1146 DC390_initSRB( pACB->pTmpSRB );
1147 for(i=0; i<MAX_SCSI_ID8; i++)
1148 pACB->DCBmap[i] = 0;
1149}
1150
1151
1152/***********************************************************************
1153 * Function : static int DC390_initAdapter
1154 *
1155 * Purpose : initialize the SCSI chip ctrl registers
1156 *
1157 * Inputs : psh - pointer to this host adapter's structure
1158 *
1159 ***********************************************************************/
1160int DC390_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
1161{
1162 USHORT ioport;
1163 UCHAR bval;
1164 PACB pACB, pacb;
1165 USHORT used_irq = 0;
1166
1167 pacb = pACB_start;
1168 if( pacb != NULL((void *) 0) )
1169 {
1170 for ( ; (pacb != (PACB) -1) ; )
1171 {
1172 if( pacb->IRQLevel == Irq )
1173 {
1174 used_irq = 1;
1175 break;
1176 }
1177 else
1178 pacb = pacb->pNextACB;
1179 }
1180 }
1181
1182 if( !used_irq )
1183 {
1184#ifdef VERSION_ELF_1_2_13
1185 if( request_irq(Irq, DC390_Interrupt, SA_INTERRUPT0x20000000, "tmscsim"))
1186#else
1187 if( request_irq(Irq, DC390_Interrupt, SA_INTERRUPT0x20000000 | SA_SHIRQ0x04000000, "tmscsim", NULL((void *) 0)))
1188#endif
1189 {
1190 printk("DC390: register IRQ error!\n");
1191 return( -1 );
1192 }
1193 }
1194
1195 request_region(io_port,psh->n_io_port,"tmscsim");
1196
1197 ioport = (USHORT) io_port;
1198
1199 pACB = (PACB) psh->hostdata;
1200 bval = SEL_TIMEOUT153; /* 250ms selection timeout */
1201 outb(bval,ioport+Scsi_TimeOut)((__builtin_constant_p((ioport+0x14)) && (ioport+0x14
) < 256) ? __outbc((bval),(ioport+0x14)) : __outb((bval),(
ioport+0x14)))
;
1202
1203 bval = CLK_FREQ_40MHZ0; /* Conversion factor = 0 , 40MHz clock */
1204 outb(bval,ioport+Clk_Factor)((__builtin_constant_p((ioport+0x24)) && (ioport+0x24
) < 256) ? __outbc((bval),(ioport+0x24)) : __outb((bval),(
ioport+0x24)))
;
1205
1206 bval = NOP_CMD0; /* NOP cmd - clear command register */
1207 outb(bval,ioport+ScsiCmd)((__builtin_constant_p((ioport+0x0C)) && (ioport+0x0C
) < 256) ? __outbc((bval),(ioport+0x0C)) : __outb((bval),(
ioport+0x0C)))
;
1208
1209 bval = EN_FEATURE0x00000040+EN_SCSI2_CMD0x00000008; /* Enable Feature and SCSI-2 */
1210 outb(bval,ioport+CtrlReg2)((__builtin_constant_p((ioport+0x2C)) && (ioport+0x2C
) < 256) ? __outbc((bval),(ioport+0x2C)) : __outb((bval),(
ioport+0x2C)))
;
1211
1212 bval = FAST_CLK0x00000008; /* fast clock */
1213 outb(bval,ioport+CtrlReg3)((__builtin_constant_p((ioport+0x30)) && (ioport+0x30
) < 256) ? __outbc((bval),(ioport+0x30)) : __outb((bval),(
ioport+0x30)))
;
1214
1215 bval = EATER_25NS0x00000080;
1216 if( eepromBuf[index][EE_MODE265] & ACTIVE_NEGATION0x00000008 )
1217 bval |= NEGATE_REQACKDATA0x00000004;
1218 outb(bval,ioport+CtrlReg4)((__builtin_constant_p((ioport+0x34)) && (ioport+0x34
) < 256) ? __outbc((bval),(ioport+0x34)) : __outb((bval),(
ioport+0x34)))
;
1219
1220 bval = DIS_INT_ON_SCSI_RST0x00000040; /* Disable SCSI bus reset interrupt */
1221 outb(bval,ioport+CtrlReg1)((__builtin_constant_p((ioport+0x20)) && (ioport+0x20
) < 256) ? __outbc((bval),(ioport+0x20)) : __outb((bval),(
ioport+0x20)))
;
1222
1223 return(0);
1224}
1225
1226
1227void
1228DC390_EnableCfg( USHORT mechnum, UCHAR regval )
1229{
1230 ULONG wlval;
1231
1232 if(mechnum == 2)
1233 {
1234 outb(mech2bus, PCI_CFG2_FORWARD_REG)((__builtin_constant_p((0xcfa)) && (0xcfa) < 256) ?
__outbc((mech2bus),(0xcfa)) : __outb((mech2bus),(0xcfa)))
;
1235 outb(mech2CfgSPenR, PCI_CFG2_ENABLE_REG)((__builtin_constant_p((0xcf8)) && (0xcf8) < 256) ?
__outbc((mech2CfgSPenR),(0xcf8)) : __outb((mech2CfgSPenR),(0xcf8
)))
;
1236 }
1237 else
1238 {
1239 regval &= 0xFC;
1240 wlval = mech1addr;
1241 wlval |= (((ULONG)regval) & 0xff);
1242 outl(wlval, PCI_CFG1_ADDRESS_REG)((__builtin_constant_p((0xcf8)) && (0xcf8) < 256) ?
__outlc((wlval),(0xcf8)) : __outl((wlval),(0xcf8)))
;
1243 }
1244}
1245
1246
1247void
1248DC390_DisableCfg( USHORT mechnum )
1249{
1250
1251 if(mechnum == 2)
1252 outb(0, PCI_CFG2_ENABLE_REG)((__builtin_constant_p((0xcf8)) && (0xcf8) < 256) ?
__outbc((0),(0xcf8)) : __outb((0),(0xcf8)))
;
1253 else
1254 outl(0, PCI_CFG1_ADDRESS_REG)((__builtin_constant_p((0xcf8)) && (0xcf8) < 256) ?
__outlc((0),(0xcf8)) : __outl((0),(0xcf8)))
;
1255}
1256
1257
1258UCHAR
1259DC390_inByte( USHORT mechnum, UCHAR regval )
1260{
1261 UCHAR bval;
1262 ULONG wval;
1263 ULONG flags;
1264
1265 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
1266 cli()__asm__ __volatile__ ("cli": : :"memory");
1267 DC390_EnableCfg( mechnum, regval );
1268 if(mechnum == 2)
1269 {
1270 wval = mech2Agent;
1271 wval <<= 8;
1272 wval |= ((USHORT) regval) & 0xff;
1273 bval = inb(wval)((__builtin_constant_p((wval)) && (wval) < 256) ? __inbc
(wval) : __inb(wval))
;
1274 }
1275 else
1276 {
1277 regval &= 3;
1278 bval = inb(PCI_CFG1_DATA_REG | regval)((__builtin_constant_p((0xcfc | regval)) && (0xcfc | regval
) < 256) ? __inbc(0xcfc | regval) : __inb(0xcfc | regval))
;
1279 }
1280 DC390_DisableCfg(mechnum);
1281 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1282 return(bval);
1283}
1284
1285
1286USHORT
1287DC390_inWord( USHORT mechnum, UCHAR regval )
1288{
1289 USHORT wval;
1290 ULONG flags;
1291
1292 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
1293 cli()__asm__ __volatile__ ("cli": : :"memory");
1294 DC390_EnableCfg(mechnum,regval);
1295 if(mechnum == 2)
1296 {
1297 wval = mech2Agent;
1298 wval <<= 8;
1299 wval |= regval;
1300 wval = inw(wval)((__builtin_constant_p((wval)) && (wval) < 256) ? __inwc
(wval) : __inw(wval))
;
1301 }
1302 else
1303 {
1304 regval &= 3;
1305 wval = inw(PCI_CFG1_DATA_REG | regval)((__builtin_constant_p((0xcfc | regval)) && (0xcfc | regval
) < 256) ? __inwc(0xcfc | regval) : __inw(0xcfc | regval))
;
1306 }
1307 DC390_DisableCfg(mechnum);
1308 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1309 return(wval);
1310}
1311
1312
1313ULONG
1314DC390_inDword(USHORT mechnum, UCHAR regval )
1315{
1316 ULONG wlval;
1317 ULONG flags;
1318 USHORT wval;
1319
1320 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
1321 cli()__asm__ __volatile__ ("cli": : :"memory");
1322 DC390_EnableCfg(mechnum,regval);
1323 if(mechnum == 2)
1324 {
1325 wval = mech2Agent;
1326 wval <<= 8;
1327 wval |= regval;
1328 wlval = inl(wval)((__builtin_constant_p((wval)) && (wval) < 256) ? __inlc
(wval) : __inl(wval))
;
1329 }
1330 else
1331 {
1332 wlval = inl(PCI_CFG1_DATA_REG)((__builtin_constant_p((0xcfc)) && (0xcfc) < 256) ?
__inlc(0xcfc) : __inl(0xcfc))
;
1333 }
1334 DC390_DisableCfg(mechnum);
1335 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1336 return(wlval);
1337}
1338
1339
1340void
1341DC390_OutB(USHORT mechnum, UCHAR regval, UCHAR bval )
1342{
1343
1344 USHORT wval;
1345 ULONG flags;
1346
1347 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
1348 cli()__asm__ __volatile__ ("cli": : :"memory");
1349 DC390_EnableCfg(mechnum,regval);
1350 if(mechnum == 2)
1351 {
1352 wval = mech2Agent;
1353 wval <<= 8;
1354 wval |= regval;
1355 outb(bval, wval)((__builtin_constant_p((wval)) && (wval) < 256) ? __outbc
((bval),(wval)) : __outb((bval),(wval)))
;
1356 }
1357 else
1358 {
1359 regval &= 3;
1360 outb(bval, PCI_CFG1_DATA_REG | regval)((__builtin_constant_p((0xcfc | regval)) && (0xcfc | regval
) < 256) ? __outbc((bval),(0xcfc | regval)) : __outb((bval
),(0xcfc | regval)))
;
1361 }
1362 DC390_DisableCfg(mechnum);
1363 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1364}
1365
1366
1367void
1368DC390_EnDisableCE( UCHAR mode, USHORT mechnum, PUCHAR regval )
1369{
1370
1371 UCHAR bval;
1372
1373 bval = 0;
1374 if(mode == ENABLE_CE1)
1375 *regval = 0xc0;
1376 else
1377 *regval = 0x80;
1378 DC390_OutB(mechnum,*regval,bval);
1379 if(mode == DISABLE_CE0)
1380 DC390_OutB(mechnum,*regval,bval);
1381 udelay(160)(__builtin_constant_p(160) ? __const_udelay((160) * 0x10c6ul)
: __udelay(160))
;
1382}
1383
1384
1385void
1386DC390_EEpromOutDI( USHORT mechnum, PUCHAR regval, USHORT Carry )
1387{
1388 UCHAR bval;
1389
1390 bval = 0;
1391 if(Carry)
1392 {
1393 bval = 0x40;
1394 *regval = 0x80;
1395 DC390_OutB(mechnum,*regval,bval);
1396 }
1397 udelay(160)(__builtin_constant_p(160) ? __const_udelay((160) * 0x10c6ul)
: __udelay(160))
;
1398 bval |= 0x80;
1399 DC390_OutB(mechnum,*regval,bval);
1400 udelay(160)(__builtin_constant_p(160) ? __const_udelay((160) * 0x10c6ul)
: __udelay(160))
;
1401 bval = 0;
1402 DC390_OutB(mechnum,*regval,bval);
1403 udelay(160)(__builtin_constant_p(160) ? __const_udelay((160) * 0x10c6ul)
: __udelay(160))
;
1404}
1405
1406
1407UCHAR
1408DC390_EEpromInDO( USHORT mechnum )
1409{
1410 UCHAR bval,regval;
1411
1412 regval = 0x80;
1413 bval = 0x80;
1414 DC390_OutB(mechnum,regval,bval);
1415 udelay(160)(__builtin_constant_p(160) ? __const_udelay((160) * 0x10c6ul)
: __udelay(160))
;
1416 bval = 0x40;
1417 DC390_OutB(mechnum,regval,bval);
1418 udelay(160)(__builtin_constant_p(160) ? __const_udelay((160) * 0x10c6ul)
: __udelay(160))
;
1419 regval = 0x0;
1420 bval = DC390_inByte(mechnum,regval);
1421 if(bval == 0x22)
1422 return(1);
1423 else
1424 return(0);
1425}
1426
1427
1428USHORT
1429EEpromGetData1( USHORT mechnum )
1430{
1431 UCHAR i;
1432 UCHAR carryFlag;
1433 USHORT wval;
1434
1435 wval = 0;
1436 for(i=0; i<16; i++)
1437 {
1438 wval <<= 1;
1439 carryFlag = DC390_EEpromInDO(mechnum);
1440 wval |= carryFlag;
1441 }
1442 return(wval);
1443}
1444
1445
1446void
1447DC390_Prepare( USHORT mechnum, PUCHAR regval, UCHAR EEpromCmd )
1448{
1449 UCHAR i,j;
1450 USHORT carryFlag;
1451
1452 carryFlag = 1;
1453 j = 0x80;
1454 for(i=0; i<9; i++)
1455 {
1456 DC390_EEpromOutDI(mechnum,regval,carryFlag);
1457 carryFlag = (EEpromCmd & j) ? 1 : 0;
1458 j >>= 1;
1459 }
1460}
1461
1462
1463void
1464DC390_ReadEEprom( USHORT mechnum, USHORT index )
1465{
1466 UCHAR regval,cmd;
1467 PUSHORT ptr;
1468 USHORT i;
1469
1470 ptr = (PUSHORT) &eepromBuf[index][0];
1471 cmd = EEPROM_READ0x80;
1472 for(i=0; i<0x40; i++)
1473 {
1474 DC390_EnDisableCE(ENABLE_CE1, mechnum, &regval);
1475 DC390_Prepare(mechnum, &regval, cmd);
1476 *ptr = EEpromGetData1(mechnum);
1477 ptr++;
1478 cmd++;
1479 DC390_EnDisableCE(DISABLE_CE0,mechnum,&regval);
1480 }
1481}
1482
1483
1484USHORT
1485DC390_CheckEEpromCheckSum( USHORT MechNum, USHORT index )
1486{
1487 USHORT wval, rc, *ptr;
1488 UCHAR i;
1489
1490 DC390_ReadEEprom( MechNum, index );
1491 wval = 0;
1492 ptr = (PUSHORT) &eepromBuf[index][0];
1493 for(i=0; i<128 ;i+=2, ptr++)
1494 wval += *ptr;
1495 if( wval == 0x1234 )
1496 rc = 0;
1497 else
1498 rc = -1;
1499 return( rc );
1500}
1501
1502
1503USHORT
1504DC390_ToMech( USHORT Mechnum, USHORT BusDevFunNum )
1505{
1506 USHORT devnum;
1507
1508 devnum = BusDevFunNum;
1509
1510 if(Mechnum == 2)
1511 {
1512 if(devnum & 0x80)
1513 return(-1);
1514 mech2bus = (UCHAR)((devnum & 0xff00) >> 8); /* Bus num */
1515 mech2Agent = ((UCHAR)(devnum & 0xff)) >> 3; /* Dev num */
1516 mech2Agent |= 0xc0;
1517 mech2CfgSPenR = ((UCHAR)(devnum & 0xff)) & 0x07; /* Fun num */
1518 mech2CfgSPenR = (mech2CfgSPenR << 1) | 0x20;
1519 }
1520 else /* use mech #1 method */
1521 {
1522 mech1addr = 0x80000000 | ((ULONG)devnum << 8);
1523 }
1524 return(0);
1525}
1526
1527/***********************************************************************
1528 * Function : static int DC390_init (struct Scsi_Host *host)
1529 *
1530 * Purpose : initialize the internal structures for a given SCSI host
1531 *
1532 * Inputs : host - pointer to this host adapter's structure/
1533 *
1534 * Preconditions : when this function is called, the chip_type
1535 * field of the pACB structure MUST have been set.
1536 ***********************************************************************/
1537
1538static int
1539DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, USHORT index, USHORT MechNum)
1540{
1541 PSH psh;
1542 PACB pACB;
1543
1544 if( !DC390_CheckEEpromCheckSum( MechNum, index) )
1545 {
1546 psh = scsi_register( psht, sizeof(DC390_ACB) );
1547 if( !psh )
1548 return( -1 );
1549 if( !pSH_start )
1550 {
1551 pSH_start = psh;
1552 pSH_current = psh;
1553 }
1554 else
1555 {
1556 pSH_current->next = psh;
1557 pSH_current = psh;
1558 }
1559
1560#ifdef DC390_DEBUG0
1561 printk("DC390: pSH = %8x,", (UINT) psh);
1562 printk("DC390: Index %02i,", index);
1563#endif
1564
1565 DC390_initACB( psh, io_port, Irq, index );
1566 if( !DC390_initAdapter( psh, io_port, Irq, index ) )
1567 {
1568 pACB = (PACB) psh->hostdata;
1569 if( !pACB_start )
1570 {
1571 pACB_start = pACB;
1572 pACB_current = pACB;
1573 pACB->pNextACB = (PACB) -1;
1574 }
1575 else
1576 {
1577 pACB_current->pNextACB = pACB;
1578 pACB_current = pACB;
1579 pACB->pNextACB = (PACB) -1;
1580 }
1581
1582#ifdef DC390_DEBUG0
1583 printk("DC390: pACB = %8x, pDCB_array = %8x, pSRB_array = %8x\n",
1584 (UINT) pACB, (UINT) pACB->DCB_array, (UINT) pACB->SRB_array);
1585 printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",
1586 sizeof(DC390_ACB), sizeof(DC390_DCB), sizeof(DC390_SRB) );
1587#endif
1588
1589 }
1590 else
1591 {
1592 pSH_start = NULL((void *) 0);
1593 scsi_unregister( psh );
1594 return( -1 );
1595 }
1596 return( 0 );
1597 }
1598 else
1599 {
1600 printk("DC390_init: EEPROM reading error!\n");
1601 return( -1 );
1602 }
1603}
1604
1605
1606/***********************************************************************
1607 * Function : int DC390_detect(Scsi_Host_Template *psht)
1608 *
1609 * Purpose : detects and initializes AMD53C974 SCSI chips
1610 * that were autoprobed, overridden on the LILO command line,
1611 * or specified at compile time.
1612 *
1613 * Inputs : psht - template for this SCSI adapter
1614 *
1615 * Returns : number of host adapters detected
1616 *
1617 ***********************************************************************/
1618
1619int
1620DC390_detect(Scsi_Host_Template *psht)
1621{
1622#ifdef FOR_PCI_OK
1623 UCHAR pci_bus, pci_device_fn;
1624 int error = 0;
1625 USHORT chipType = 0;
1626 USHORT i;
1627#endif
1628
1629 UCHAR irq;
1630 UCHAR istatus;
1631#ifndef VERSION_ELF_1_2_13
1632 UINT io_port;
1633#else
1634 ULONG io_port;
1635#endif
1636 USHORT adaptCnt = 0; /* Number of boards detected */
1637 USHORT pci_index = 0; /* Device index to PCI BIOS calls */
1638 USHORT MechNum, BusDevFunNum;
1639 ULONG wlval;
1640
1641#ifndef VERSION_ELF_1_2_13
1642 psht->proc_dir = &proc_scsi_tmscsim;
1643#endif
1644
1645 InitialTime = 1;
1646 pSHT_start = psht;
1647 pACB_start = NULL((void *) 0);
1648
1649 MechNum = 1;
1650 for( ; (MechNum < 3) && (!adaptCnt); MechNum++)
1651 {
1652 BusDevFunNum = 0;
1653 for (; adaptCnt < MAX_ADAPTER_NUM4 ;)
1654 {
1655 if( !DC390_ToMech( MechNum, BusDevFunNum) )
1656 {
1657 wlval = DC390_inDword( MechNum, PCI_VENDOR_ID0x00);
1658 if(wlval == ( (PCI_DEVICE_ID_AMD53C9740x2020 << 16)+
1659 PCI_VENDOR_ID_AMD0x1022) )
1660 {
1661 io_port =DC390_inDword(MechNum,PCI_BASE_ADDRESS_00x10) & 0xFFFE;
1662 irq = DC390_inByte( MechNum, PCI_INTERRUPT_LINE0x3c);
1663#ifdef DC390_DEBUG0
1664 printk("DC390: IO_PORT=%4x,IRQ=%x,\n",(UINT) io_port, irq);
1665#endif
1666 if( !DC390_init(psht, io_port, irq, pci_index, MechNum) )
1667 {
1668 adaptCnt++;
1669 pci_index++;
1670 istatus = inb( (USHORT)io_port+INT_Status )((__builtin_constant_p(((USHORT)io_port+0x14)) && ((USHORT
)io_port+0x14) < 256) ? __inbc((USHORT)io_port+0x14) : __inb
((USHORT)io_port+0x14))
; /* Reset Pending INT */
Value stored to 'istatus' is never read
1671#ifdef DC390_DEBUG0
1672 printk("DC390: Mech=%2x,\n",(UCHAR) MechNum);
1673#endif
1674 }
1675 }
1676 }
1677 if( BusDevFunNum != 0xfff8 )
1678 BusDevFunNum += 8; /* next device # */
1679 else
1680 break;
1681 }
1682 }
1683
1684#ifdef FOR_PCI_OK
1685 if ( pcibios_present() )
1686 {
1687 for (i = 0; i < MAX_ADAPTER_NUM4; ++i)
1688 {
1689 if( !pcibios_find_device( PCI_VENDOR_ID_AMD0x1022,
1690 PCI_DEVICE_ID_AMD53C9740x2020,
1691 pci_index, &pci_bus, &pci_device_fn) )
1692 {
1693 chipType = PCI_DEVICE_ID_AMD53C9740x2020;
1694 pci_index++;
1695 }
1696
1697 if( chipType )
1698 {
1699
1700 error = pcibios_read_config_dword(pci_bus, pci_device_fn,
1701 PCI_BASE_ADDRESS_00x10, &io_port);
1702 error |= pcibios_read_config_byte(pci_bus, pci_device_fn,
1703 PCI_INTERRUPT_LINE0x3c, &irq);
1704 if( error )
1705 {
1706 printk("DC390_detect: reading configuration registers error!\n");
1707 InitialTime = 0;
1708 return( 0 );
1709 }
1710
1711 (USHORT) io_port = (USHORT) io_port & 0xFFFE;
1712#ifdef DC390_DEBUG0
1713 printk("DC390: IO_PORT=%4x,IRQ=%x,\n",(UINT) io_port, irq);
1714#endif
1715 if( !DC390_init(psht, io_port, irq, i) )
1716 adaptCnt++;
1717 chipType = 0;
1718 }
1719 else
1720 break;
1721 }
1722 }
1723#endif
1724
1725 InitialTime = 0;
1726 adapterCnt = adaptCnt;
1727 return( adaptCnt );
1728}
1729
1730
1731#ifndef VERSION_ELF_1_2_13
1732
1733/********************************************************************
1734 * Function: tmscsim_set_info()
1735 *
1736 * Purpose: Set adapter info (!)
1737 *
1738 * Not yet implemented
1739 *
1740 *******************************************************************/
1741
1742int tmscsim_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
1743{
1744 return(-ENOSYS38); /* Currently this is a no-op */
1745}
1746
1747/********************************************************************
1748 * Function: tmscsim_proc_info(char* buffer, char **start,
1749 * off_t offset, int length, int hostno, int inout)
1750 *
1751 * Purpose: return SCSI Adapter/Device Info
1752 *
1753 * Input: buffer: Pointer to a buffer where to write info
1754 * start :
1755 * offset:
1756 * hostno: Host adapter index
1757 * inout : Read (=0) or set(!=0) info
1758 *
1759 * Output: buffer: contains info
1760 * length; length of info in buffer
1761 *
1762 * return value: length
1763 *
1764 ********************************************************************/
1765
1766/* KG: proc_info taken from driver aha152x.c */
1767
1768#undef SPRINTF
1769#define SPRINTF(args...)pos += linux_sprintf(pos,args...) pos += sprintflinux_sprintf(pos, ## args)
1770
1771#define YESNO(YN)if (YN) pos += linux_sprintf(pos," Yes ");else pos += linux_sprintf
(pos," No ")
\
1772if (YN) SPRINTF(" Yes ")pos += linux_sprintf(pos," Yes ");\
1773else SPRINTF(" No ")pos += linux_sprintf(pos," No ")
1774
1775int tmscsim_proc_info(char *buffer, char **start,
1776 off_t offset, int length, int hostno, int inout)
1777{
1778 int dev, spd, spd1;
1779 char *pos = buffer;
1780 PSH shpnt;
1781 PACB acbpnt;
1782 PDCB dcbpnt;
1783 unsigned long flags;
1784/* Scsi_Cmnd *ptr; */
1785
1786 acbpnt = pACB_start;
1787
1788 while(acbpnt != (PACB)-1)
1789 {
1790 shpnt = acbpnt->pScsiHost;
1791 if (shpnt->host_no == hostno) break;
1792 acbpnt = acbpnt->pNextACB;
1793 }
1794
1795 if (acbpnt == (PACB)-1) return(-ESRCH3);
1796 if(!shpnt) return(-ESRCH3);
1797
1798 if(inout) /* Has data been written to the file ? */
1799 return(tmscsim_set_info(buffer, length, shpnt));
1800
1801 SPRINTF("Tekram DC390(T) PCI SCSI Host Adadpter, ")pos += linux_sprintf(pos,"Tekram DC390(T) PCI SCSI Host Adadpter, "
)
;
1802 SPRINTF("Driver Version 1.10, 1996/12/05\n")pos += linux_sprintf(pos,"Driver Version 1.10, 1996/12/05\n");
1803
1804 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
1805 cli()__asm__ __volatile__ ("cli": : :"memory");
1806
1807 SPRINTF("SCSI Host Nr %i, ", shpnt->host_no)pos += linux_sprintf(pos,"SCSI Host Nr %i, ", shpnt->host_no
)
;
1808 SPRINTF("DC390 Adapter Nr %i\n", acbpnt->AdapterIndex)pos += linux_sprintf(pos,"DC390 Adapter Nr %i\n", acbpnt->
AdapterIndex)
;
1809 SPRINTF("IOPortBase 0x%04x, ", acbpnt->IOPortBase)pos += linux_sprintf(pos,"IOPortBase 0x%04x, ", acbpnt->IOPortBase
)
;
1810 SPRINTF("IRQLevel 0x%02x\n", acbpnt->IRQLevel)pos += linux_sprintf(pos,"IRQLevel 0x%02x\n", acbpnt->IRQLevel
)
;
1811
1812 SPRINTF("MaxID %i, MaxLUN %i, ",acbpnt->max_id, acbpnt->max_lun)pos += linux_sprintf(pos,"MaxID %i, MaxLUN %i, ",acbpnt->max_id
, acbpnt->max_lun)
;
1813 SPRINTF("AdapterID %i, AdapterLUN %i\n", acbpnt->AdaptSCSIID, acbpnt->AdaptSCSILUN)pos += linux_sprintf(pos,"AdapterID %i, AdapterLUN %i\n", acbpnt
->AdaptSCSIID, acbpnt->AdaptSCSILUN)
;
1814
1815 SPRINTF("TagMaxNum %i, Status %i\n", acbpnt->TagMaxNum, acbpnt->status)pos += linux_sprintf(pos,"TagMaxNum %i, Status %i\n", acbpnt->
TagMaxNum, acbpnt->status)
;
1816
1817 SPRINTF("Nr of attached devices: %i\n", acbpnt->DeviceCnt)pos += linux_sprintf(pos,"Nr of attached devices: %i\n", acbpnt
->DeviceCnt)
;
1818
1819 SPRINTF("Un ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs\n")pos += linux_sprintf(pos,"Un ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs\n"
)
;
1820
1821 dcbpnt = acbpnt->pLinkDCB;
1822 for (dev = 0; dev < acbpnt->DeviceCnt; dev++)
1823 {
1824 SPRINTF("%02i %02i %02i ", dev, dcbpnt->UnitSCSIID, dcbpnt->UnitSCSILUN)pos += linux_sprintf(pos,"%02i %02i %02i ", dev, dcbpnt->
UnitSCSIID, dcbpnt->UnitSCSILUN)
;
1825 YESNO(dcbpnt->DevMode & PARITY_CHK_)if (dcbpnt->DevMode & 0x00000001) pos += linux_sprintf
(pos," Yes ");else pos += linux_sprintf(pos," No ")
;
1826 YESNO(dcbpnt->SyncMode & SYNC_NEGO_DONE)if (dcbpnt->SyncMode & 0x00000002) pos += linux_sprintf
(pos," Yes ");else pos += linux_sprintf(pos," No ")
;
1827 YESNO(dcbpnt->DevMode & EN_DISCONNECT_)if (dcbpnt->DevMode & 0x00000004) pos += linux_sprintf
(pos," Yes ");else pos += linux_sprintf(pos," No ")
;
1828 YESNO(dcbpnt->DevMode & SEND_START_)if (dcbpnt->DevMode & 0x00000008) pos += linux_sprintf
(pos," Yes ");else pos += linux_sprintf(pos," No ")
;
1829 YESNO(dcbpnt->SyncMode & EN_TAG_QUEUING)if (dcbpnt->SyncMode & 0x00000010) pos += linux_sprintf
(pos," Yes ");else pos += linux_sprintf(pos," No ")
;
1830 SPRINTF(" %03i ns ", (dcbpnt->NegoPeriod) << 2)pos += linux_sprintf(pos," %03i ns ", (dcbpnt->NegoPeriod
) << 2)
;
1831 if (dcbpnt->SyncOffset & 0x0f)
1832 {
1833 spd = 1000/(dcbpnt->NegoPeriod <<2);
1834 spd1 = 1000%(dcbpnt->NegoPeriod <<2);
1835 spd1 = (spd1 * 10)/(dcbpnt->NegoPeriod <<2);
1836 SPRINTF(" %2i.%1i M %02i\n", spd, spd1, (dcbpnt->SyncOffset & 0x0f))pos += linux_sprintf(pos," %2i.%1i M %02i\n", spd, spd1
, (dcbpnt->SyncOffset & 0x0f))
;
1837 }
1838 else SPRINTF("\n")pos += linux_sprintf(pos,"\n");
1839 /* Add more info ...*/
1840 dcbpnt = dcbpnt->pNextDCB;
1841 }
1842
1843 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1844 *start = buffer + offset;
1845
1846 if (pos - buffer < offset)
1847 return 0;
1848 else if (pos - buffer - offset < length)
1849 return pos - buffer - offset;
1850 else
1851 return length;
1852}
1853#endif /* VERSION_ELF_1_2_13 */
1854
1855
1856#ifdef MODULE
1857
1858/***********************************************************************
1859 * Function : static int DC390_shutdown (struct Scsi_Host *host)
1860 *
1861 * Purpose : does a clean (we hope) shutdown of the SCSI chip.
1862 * Use prior to dumping core, unloading the driver, etc.
1863 *
1864 * Returns : 0 on success
1865 ***********************************************************************/
1866static int
1867DC390_shutdown (struct Scsi_Host *host)
1868{
1869 UCHAR bval;
1870 USHORT ioport;
1871 unsigned long flags;
1872 PACB pACB = (PACB)(host->hostdata);
1873
1874 ioport = (unsigned int) pACB->IOPortBase;
1875
1876 save_flags (flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
1877 cli()__asm__ __volatile__ ("cli": : :"memory");
1878
1879/* pACB->soft_reset(host); */
1880
1881#ifdef DC390_DEBUG0
1882 printk("DC390: shutdown,");
1883#endif
1884
1885 bval = inb(ioport+CtrlReg1)((__builtin_constant_p((ioport+0x20)) && (ioport+0x20
) < 256) ? __inbc(ioport+0x20) : __inb(ioport+0x20))
;
1886 bval |= DIS_INT_ON_SCSI_RST0x00000040;
1887 outb(bval,ioport+CtrlReg1)((__builtin_constant_p((ioport+0x20)) && (ioport+0x20
) < 256) ? __outbc((bval),(ioport+0x20)) : __outb((bval),(
ioport+0x20)))
; /* disable interrupt */
1888 DC390_ResetSCSIBus( pACB );
1889
1890 restore_flags (flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
1891 return( 0 );
1892}
1893
1894
1895int DC390_release(struct Scsi_Host *host)
1896{
1897 int irq_count;
1898 struct Scsi_Host *tmp;
1899
1900 DC390_shutdown (host);
1901
1902 if (host->irq != IRQ_NONE255)
1903 {
1904 for (irq_count = 0, tmp = pSH_start; tmp; tmp = tmp->next)
1905 {
1906 if ( tmp->irq == host->irq )
1907 ++irq_count;
1908 }
1909 if (irq_count == 1)
1910 {
1911#ifdef DC390_DEBUG0
1912 printk("DC390: Free IRQ %i.",host->irq);
1913#endif
1914#ifndef VERSION_ELF_1_2_13
1915 free_irq(host->irq,NULL((void *) 0));
1916#else
1917 free_irq(host->irq);
1918#endif
1919 }
1920 }
1921
1922 release_region(host->io_port,host->n_io_port);
1923
1924 return( 1 );
1925}
1926
1927Scsi_Host_Template driver_template = DC390_T;
1928#include "scsi_module.c"
1929#endif /* def MODULE */
1930