|
|
1.1 root 1: /***********************************************************************
2: * FILE NAME : TMSCSIW.C *
3: * BY : C.L. Huang ([email protected]) *
4: * Description: Device Driver for Tekram DC-390W/U/F (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 <[email protected]> *
10: ***********************************************************************/
11: /* HISTORY: *
12: * *
13: * REV# DATE NAME DESCRIPTION *
14: * 1.00 04/03/96 CLH First release *
15: * 1.01 04/11/96 CLH Maximum support up to 4 Adapters, *
16: * support KV 1_3_85 *
17: * 1.02 04/26/96 CLH fixed bug about EEpromBuf when >1 HA *
18: * 1.03 06/12/96 CLH fixed bug of Media Change for Removable *
19: * Device, scan all LUN. Support Pre2.0.10 *
20: * 1.04 06/18/96 CLH fixed bug of Command timeout .... *
21: * 1.05 10/04/96 CLH Updating for support KV 2.0.0, 2.0.20 *
22: * 1.06 10/30/96 KG Fixed bug in DC390W_abort(), module *
23: * support, added tmscsiw_proc_info() *
24: * 1.07 11/09/96 KG Fixed bug in tmscsiw_proc_info() *
25: * 1.08 11/18/96 CLH/KG ditto, null ptr in DC390W_Disconnect() *
26: * 1.09 11/30/96 KG Fixed bug in CheckEEpromCheckSum(), *
27: * add register the allocated IO space *
28: * 1.10 12/05/96 CLH Modify in tmscsiw_proc_info() and add *
29: * in DC390W_initAdapter() for 53C875 *
30: * Rev. F with double clock. *
31: * 1.11 02/04/97 CLH Fixed bug of Formatting a partition that*
32: * across 1GB boundary, with bad sector *
33: * checking. *
34: * 1.12 02/17/97 CLH Fixed bug in CheckEEpromCheckSum() *
35: ***********************************************************************/
36:
37:
38: #define DC390W_DEBUG
39: /* #define CHK_UNDER_RUN */
40:
41: #define SCSI_MALLOC
42:
43: #ifdef MODULE
44: #include <linux/module.h>
45: #endif
46:
47: #include <asm/dma.h>
48: #include <asm/io.h>
49: #include <asm/system.h>
50: #include <linux/delay.h>
51: #include <linux/signal.h>
52: #include <linux/sched.h>
53: #include <linux/errno.h>
54: #include <linux/kernel.h>
55: #include <linux/ioport.h>
56: #include <linux/bios32.h>
57: #include <linux/pci.h>
58: #include <linux/proc_fs.h>
59: #include <linux/string.h>
60: #include <linux/mm.h>
61: #include <linux/config.h>
62:
63: #include <linux/version.h>
64: #if LINUX_VERSION_CODE < 66354 /* 1.3.50 */
65: #include "../block/blk.h"
66: #else
67: #include <linux/blk.h>
68: #endif
69:
70: #include "scsi.h"
71: #include "hosts.h"
72: #include "tmscsiw.h"
73: #include "constants.h"
74: #include "sd.h"
75: #include "scripts.h"
76: #include <linux/stat.h>
77:
78: #include "dc390w.h"
79:
80: #ifndef VERSION_ELF_1_2_13
81: struct proc_dir_entry proc_scsi_tmscsiw ={
82: PROC_SCSI_DC390WUF, 7 ,"tmscsiw",
83: S_IFDIR | S_IRUGO | S_IXUGO, 2
84: };
85: #endif
86:
87: static void DC390W_StartSCSI( PACB pACB, PDCB pDCB, PSRB pSRB );
88: static void PrepareSG( PACB pACB, PDCB pDCB, PSRB pSRB );
89: static void DoingSRB_Done( PACB pACB );
90: static void ExceptionHandler(ULONG wlval, PACB pACB, PDCB pDCB);
91: static void ParityError( PACB pACB, PDCB pDCB );
92: static void PhaseMismatch( PACB pACB );
93: static void DC390W_ScsiRstDetect( PACB pACB );
94: static void DC390W_ResetSCSIBus( PACB pACB );
95: static void DC390W_ResetSCSIBus2( PACB pACB );
96: static void AdjustTemp( PACB pACB, PDCB pDCB, PSRB pSRB );
97: static void SetXferRate( PACB pACB, PDCB pDCB );
98: static void DataIOcommon( PACB pACB, ULONG Swlval, ULONG Cwlval );
99: static void SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB );
100: static void RequestSense( PACB pACB, PDCB pDCB, PSRB pSRB );
101:
102: static void DC390W_CmdCompleted( PACB pACB );
103: static void DC390W_Reselected( PACB pACB );
104: static void DC390W_Reselected1( PACB pACB );
105: static void DC390W_ReselectedT( PACB pACB );
106: static void DC390W_Disconnected( PACB pACB );
107: static void DC390W_MessageExtnd( PACB pACB );
108: static void DC390W_Signal( PACB pACB );
109: static void DC390W_UnknownMsg( PACB pACB );
110: static void DC390W_MessageOut( PACB pACB );
111: static void DC390W_FatalError( PACB pACB );
112: static void DC390W_MessageSync( PACB pACB );
113: static void DC390W_MessageWide( PACB pACB );
114: static void DC390W_RestorePtr( PACB pACB );
115: static void DC390W_MsgReject( PACB pACB );
116: static void DC390W_Debug( PACB pACB );
117: static void DC390W_download_script (struct Scsi_Host *host);
118:
119: int DC390W_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index);
120: void DC390W_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd );
121: void MyDelay( void );
122: void EnDisableCE( UCHAR Flag, USHORT scsiIOPort );
123: void EEpromOutDI( USHORT Carry, USHORT scsiIOPort );
124: void EEpromPrepare( UCHAR EEpromCmd, USHORT scsiIOPort );
125: void ReadEEprom( PUCHAR EEpromBuf, USHORT scsiIOPort );
126: UCHAR EEpromInDo(USHORT scsiIOPort);
127: USHORT EEpromGetData(USHORT scsiIOPort);
128: USHORT CheckEEpromCheckSum( PUCHAR EEpromBuf, USHORT scsiIOPort);
129:
130: #ifdef MODULE
131: static int DC390W_release(struct Scsi_Host *host);
132: static int DC390W_shutdown (struct Scsi_Host *host);
133: #endif
134:
135:
136: static ULONG jmp_table16;
137: static ULONG jmp_din16;
138: static ULONG jmp_dout16;
139: static PSHT pSHT_start = NULL;
140: static PSH pSH_start = NULL;
141: static PSH pSH_current = NULL;
142: static PACB pACB_start= NULL;
143: static PACB pACB_current = NULL;
144: static PDCB pPrevDCB = NULL;
145: static USHORT adapterCnt = 0;
146: static USHORT InitialTime = 0;
147: static USHORT CurrDCBscntl3 = 0;
148: static UCHAR pad_buffer[128];
149:
150: static PVOID IntVector[]={
151: DC390W_CmdCompleted,
152: DC390W_Reselected,
153: DC390W_Reselected1,
154: DC390W_ReselectedT,
155: DC390W_Disconnected,
156: DC390W_MessageExtnd,
157: DC390W_Signal,
158: DC390W_UnknownMsg,
159: DC390W_MessageOut,
160: DC390W_FatalError,
161: DC390W_MessageSync,
162: DC390W_MessageWide,
163: DC390W_RestorePtr,
164: DC390W_MsgReject,
165: DC390W_Debug,
166: DC390W_FatalError
167: };
168:
169: UCHAR eepromBuf[MAX_ADAPTER_NUM][128];
170:
171: UCHAR clock_period[12] = {25, 31, 37, 43, 50, 62, 75, 125, 12, 15, 18, 21};
172: UCHAR baddevname[2][28] ={
173: "SEAGATE ST3390N 9546",
174: "SEAGATE ST3390N ??? 0399"};
175:
176: #define BADDEVCNT 2
177:
178: /***********************************************************************
179: *
180: *
181: *
182: **********************************************************************/
183: static void
184: QLinkcmd( PSCSICMD cmd, PDCB pDCB )
185: {
186: ULONG flags;
187: PSCSICMD pcmd;
188:
189: save_flags(flags);
190: cli();
191:
192: if( !pDCB->QIORBCnt )
193: {
194: pDCB->pQIORBhead = cmd;
195: pDCB->pQIORBtail = cmd;
196: pDCB->QIORBCnt++;
197: cmd->next = NULL;
198: }
199: else
200: {
201: pcmd = pDCB->pQIORBtail;
202: pcmd->next = cmd;
203: pDCB->pQIORBtail = cmd;
204: pDCB->QIORBCnt++;
205: cmd->next = NULL;
206: }
207:
208: restore_flags(flags);
209: }
210:
211:
212: static PSCSICMD
213: Getcmd( PDCB pDCB )
214: {
215: ULONG flags;
216: PSCSICMD pcmd;
217:
218: save_flags(flags);
219: cli();
220:
221: pcmd = pDCB->pQIORBhead;
222: pDCB->pQIORBhead = pcmd->next;
223: pcmd->next = NULL;
224: pDCB->QIORBCnt--;
225:
226: restore_flags(flags);
227: return( pcmd );
228: }
229:
230:
231: static PSRB
232: GetSRB( PACB pACB )
233: {
234: ULONG flags;
235: PSRB pSRB;
236:
237: save_flags(flags);
238: cli();
239:
240: pSRB = pACB->pFreeSRB;
241: if( pSRB )
242: {
243: pACB->pFreeSRB = pSRB->pNextSRB;
244: pSRB->pNextSRB = NULL;
245: }
246: restore_flags(flags);
247: return( pSRB );
248: }
249:
250:
251: static void
252: RewaitSRB( PDCB pDCB, PSRB pSRB )
253: {
254: PSRB psrb1;
255: ULONG flags;
256: UCHAR bval;
257:
258: save_flags(flags);
259: cli();
260: pDCB->GoingSRBCnt--;
261: psrb1 = pDCB->pGoingSRB;
262: if( pSRB == psrb1 )
263: {
264: pDCB->pGoingSRB = psrb1->pNextSRB;
265: }
266: else
267: {
268: while( pSRB != psrb1->pNextSRB )
269: psrb1 = psrb1->pNextSRB;
270: psrb1->pNextSRB = pSRB->pNextSRB;
271: if( pSRB == pDCB->pGoingLast )
272: pDCB->pGoingLast = psrb1;
273: }
274: if( (psrb1 = pDCB->pWaitingSRB) )
275: {
276: pSRB->pNextSRB = psrb1;
277: pDCB->pWaitingSRB = pSRB;
278: }
279: else
280: {
281: pSRB->pNextSRB = NULL;
282: pDCB->pWaitingSRB = pSRB;
283: pDCB->pWaitLast = pSRB;
284: }
285:
286: bval = pSRB->TagNumber;
287: pDCB->TagMask &= (~(1 << bval)); /* Free TAG number */
288: restore_flags(flags);
289: }
290:
291:
292: static void
293: DoWaitingSRB( PACB pACB )
294: {
295: ULONG flags;
296: PDCB ptr, ptr1;
297: PSRB pSRB;
298:
299: save_flags(flags);
300: cli();
301:
302: if( !(pACB->pActiveDCB) && !(pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) ) )
303: {
304: ptr = pACB->pDCBRunRobin;
305: if( !ptr )
306: {
307: ptr = pACB->pLinkDCB;
308: pACB->pDCBRunRobin = ptr;
309: }
310: ptr1 = ptr;
311: for( ;ptr1; )
312: {
313: pACB->pDCBRunRobin = ptr1->pNextDCB;
314: if( !( ptr1->MaxCommand > ptr1->GoingSRBCnt ) ||
315: !( pSRB = ptr1->pWaitingSRB ) )
316: {
317: if(pACB->pDCBRunRobin == ptr)
318: break;
319: ptr1 = ptr1->pNextDCB;
320: }
321: else
322: {
323: DC390W_StartSCSI(pACB, ptr1, pSRB);
324: ptr1->GoingSRBCnt++;
325: if( ptr1->pWaitLast == pSRB )
326: {
327: ptr1->pWaitingSRB = NULL;
328: ptr1->pWaitLast = NULL;
329: }
330: else
331: {
332: ptr1->pWaitingSRB = pSRB->pNextSRB;
333: }
334: pSRB->pNextSRB = NULL;
335:
336: if( ptr1->pGoingSRB )
337: ptr1->pGoingLast->pNextSRB = pSRB;
338: else
339: ptr1->pGoingSRB = pSRB;
340: ptr1->pGoingLast = pSRB;
341:
342: break;
343: }
344: }
345: }
346: restore_flags(flags);
347: return;
348: }
349:
350:
351: static void
352: SRBwaiting( PDCB pDCB, PSRB pSRB)
353: {
354: if( pDCB->pWaitingSRB )
355: {
356: pDCB->pWaitLast->pNextSRB = pSRB;
357: pDCB->pWaitLast = pSRB;
358: pSRB->pNextSRB = NULL;
359: }
360: else
361: {
362: pDCB->pWaitingSRB = pSRB;
363: pDCB->pWaitLast = pSRB;
364: }
365: }
366:
367:
368: static void
369: SendSRB( PSCSICMD pcmd, PACB pACB, PSRB pSRB )
370: {
371: ULONG flags;
372: PDCB pDCB;
373:
374: save_flags(flags);
375: cli();
376:
377: pDCB = pSRB->pSRBDCB;
378: PrepareSG( pACB, pDCB, pSRB );
379: if( !(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB) ||
380: (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV)) )
381: {
382: SRBwaiting(pDCB, pSRB);
383: goto SND_EXIT;
384: }
385:
386: if( pDCB->pWaitingSRB )
387: {
388: SRBwaiting(pDCB, pSRB);
389: /* pSRB = GetWaitingSRB(pDCB); */
390: pSRB = pDCB->pWaitingSRB;
391: pDCB->pWaitingSRB = pSRB->pNextSRB;
392: pSRB->pNextSRB = NULL;
393: }
394:
395: DC390W_StartSCSI(pACB, pDCB, pSRB);
396: pDCB->GoingSRBCnt++;
397: if( pDCB->pGoingSRB )
398: {
399: pDCB->pGoingLast->pNextSRB = pSRB;
400: pDCB->pGoingLast = pSRB;
401: }
402: else
403: {
404: pDCB->pGoingSRB = pSRB;
405: pDCB->pGoingLast = pSRB;
406: }
407:
408: SND_EXIT:
409: restore_flags(flags);
410: return;
411: }
412:
413:
414: /***********************************************************************
415: * Function : static int DC390W_queue_command (Scsi_Cmnd *cmd,
416: * void (*done)(Scsi_Cmnd *))
417: *
418: * Purpose : enqueues a SCSI command
419: *
420: * Inputs : cmd - SCSI command, done - function called on completion, with
421: * a pointer to the command descriptor.
422: *
423: * Returns : 0
424: *
425: ***********************************************************************/
426:
427: int
428: DC390W_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
429: {
430: USHORT ioport, i;
431: Scsi_Cmnd *pcmd;
432: struct Scsi_Host *psh;
433: PACB pACB;
434: PDCB pDCB;
435: PSRB pSRB;
436: ULONG flags;
437: PUCHAR ptr,ptr1;
438:
439: psh = cmd->host;
440: pACB = (PACB ) psh->hostdata;
441: ioport = pACB->IOPortBase;
442:
443: #ifdef DC390W_DEBUG0
444: printk("Cmd=%x,",cmd->cmnd[0]);
445: #endif
446:
447: if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) )
448: {
449: pACB->scan_devices = 0;
450: pPrevDCB->pNextDCB = pACB->pLinkDCB;
451: }
452: else if( (pACB->scan_devices) && (cmd->cmnd[0] == 8) )
453: {
454: pACB->scan_devices = 0;
455: pPrevDCB->pNextDCB = pACB->pLinkDCB;
456: }
457:
458: if ( ( cmd->target > pACB->max_id ) || (cmd->lun > pACB->max_lun) )
459: {
460: /* printk("DC390W: Ignore target %d lun %d\n",
461: cmd->target, cmd->lun); */
462: cmd->result = (DID_BAD_TARGET << 16);
463: done(cmd);
464: return( 0 );
465: }
466:
467: if( (pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
468: {
469: if( pACB->DeviceCnt < MAX_DEVICES )
470: {
471: pACB->DCBmap[cmd->target] |= (1 << cmd->lun);
472: pDCB = pACB->pDCB_free;
473: #ifdef DC390W_DEBUG0
474: printk("pDCB=%8x,ID=%2x,", (UINT) pDCB, cmd->target);
475: #endif
476: DC390W_initDCB( pACB, pDCB, cmd );
477: }
478: else /* ???? */
479: {
480: /* printk("DC390W: Ignore target %d lun %d\n",
481: cmd->target, cmd->lun); */
482: cmd->result = (DID_BAD_TARGET << 16);
483: done(cmd);
484: return(0);
485: }
486: }
487: else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->target] & (1 << cmd->lun)) )
488: {
489: /* printk("DC390W: Ignore target %d lun %d\n",
490: cmd->target, cmd->lun); */
491: cmd->result = (DID_BAD_TARGET << 16);
492: done(cmd);
493: return(0);
494: }
495: else
496: {
497: pDCB = pACB->pLinkDCB;
498: while( (pDCB->UnitSCSIID != cmd->target) ||
499: (pDCB->UnitSCSILUN != cmd->lun) )
500: {
501: pDCB = pDCB->pNextDCB;
502: }
503: #ifdef DC390W_DEBUG0
504: printk("pDCB=%8x,ID=%2x,Scan=%1x", (UINT) pDCB, cmd->target,
505: pACB->scan_devices);
506: #endif
507: }
508:
509: cmd->scsi_done = done;
510: cmd->result = 0;
511:
512: save_flags(flags);
513: cli();
514:
515: if( pDCB->QIORBCnt )
516: {
517: QLinkcmd( cmd, pDCB );
518: pcmd = Getcmd( pDCB );
519: }
520: else
521: pcmd = cmd;
522:
523: pSRB = GetSRB( pACB );
524:
525: if( !pSRB )
526: {
527: QLinkcmd( pcmd, pDCB );
528: restore_flags(flags);
529: return(0);
530: }
531:
532: /* BuildSRB(pSRB); */
533:
534: pSRB->pSRBDCB = pDCB;
535: pSRB->pcmd = pcmd;
536: ptr = (PUCHAR) pSRB->CmdBlock;
537: ptr1 = (PUCHAR) pcmd->cmnd;
538: (UCHAR) pSRB->__command[0] = pcmd->cmd_len;
539: for(i=0; i< pcmd->cmd_len; i++)
540: {
541: *ptr = *ptr1;
542: ptr++;
543: ptr1++;
544: }
545: if( pcmd->use_sg )
546: {
547: pSRB->SGcount = (UCHAR) pcmd->use_sg;
548: pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
549: }
550: else if( pcmd->request_buffer )
551: {
552: pSRB->SGcount = 1;
553: pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
554: pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
555: pSRB->Segmentx.length = pcmd->request_bufflen;
556: }
557: else
558: pSRB->SGcount = 0;
559:
560: pSRB->AdaptStatus = 0;
561: pSRB->TargetStatus = 0;
562: pSRB->MsgCnt = 0;
563: if( pDCB->DevType != TYPE_TAPE )
564: pSRB->RetryCnt = 1;
565: else
566: pSRB->RetryCnt = 0;
567: pSRB->SRBStatus = 0;
568: pSRB->SRBFlag = 0;
569: pSRB->ScratchABuf = 0;
570: pSRB->SRBState = 0;
571: pSRB->RemainSegPtr = 0;
572: pSRB->XferredLen = 0;
573: SendSRB( pcmd, pACB, pSRB );
574:
575: restore_flags(flags);
576: return(0);
577: }
578:
579:
580: static void
581: DoNextCmd( PACB pACB, PDCB pDCB )
582: {
583: Scsi_Cmnd *pcmd;
584: PSRB pSRB;
585: ULONG flags;
586: PUCHAR ptr,ptr1;
587: USHORT i;
588:
589:
590: if( pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV) )
591: return;
592: save_flags(flags);
593: cli();
594:
595: pcmd = Getcmd( pDCB );
596: pSRB = GetSRB( pACB );
597: if( !pSRB )
598: {
599: QLinkcmd( pcmd, pDCB );
600: restore_flags(flags);
601: return;
602: }
603:
604: pSRB->pSRBDCB = pDCB;
605: pSRB->pcmd = pcmd;
606: ptr = (PUCHAR) pSRB->CmdBlock;
607: ptr1 = (PUCHAR) pcmd->cmnd;
608: (UCHAR) pSRB->__command[0] = pcmd->cmd_len;
609: for(i=0; i< pcmd->cmd_len; i++)
610: {
611: *ptr = *ptr1;
612: ptr++;
613: ptr1++;
614: }
615: if( pcmd->use_sg )
616: {
617: pSRB->SGcount = (UCHAR) pcmd->use_sg;
618: pSRB->pSegmentList = (PSGL) pcmd->request_buffer;
619: }
620: else if( pcmd->request_buffer )
621: {
622: pSRB->SGcount = 1;
623: pSRB->pSegmentList = (PSGL) &pSRB->Segmentx;
624: pSRB->Segmentx.address = (PUCHAR) pcmd->request_buffer;
625: pSRB->Segmentx.length = pcmd->request_bufflen;
626: }
627: else
628: pSRB->SGcount = 0;
629:
630: pSRB->AdaptStatus = 0;
631: pSRB->TargetStatus = 0;
632: pSRB->MsgCnt = 0;
633: if( pDCB->DevType != TYPE_TAPE )
634: pSRB->RetryCnt = 1;
635: else
636: pSRB->RetryCnt = 0;
637: pSRB->SRBStatus = 0;
638: pSRB->SRBFlag = 0;
639: pSRB->ScratchABuf = 0;
640: pSRB->SRBState = 0;
641: SendSRB( pcmd, pACB, pSRB );
642:
643: restore_flags(flags);
644: return;
645: }
646:
647:
648: /***********************************************************************
649: * Function:
650: * DC390W_bios_param
651: *
652: * Description:
653: * Return the disk geometry for the given SCSI device.
654: ***********************************************************************/
655: #ifdef VERSION_ELF_1_2_13
656: int DC390W_bios_param(Disk *disk, int devno, int geom[])
657: #else
658: int DC390W_bios_param(Disk *disk, kdev_t devno, int geom[])
659: #endif
660: {
661: int heads, sectors, cylinders;
662: PACB pACB;
663:
664: pACB = (PACB) disk->device->host->hostdata;
665: heads = 64;
666: sectors = 32;
667: cylinders = disk->capacity / (heads * sectors);
668:
669: if ( (pACB->Gmode2 & GREATER_1G) && (cylinders > 1024) )
670: {
671: heads = 255;
672: sectors = 63;
673: cylinders = disk->capacity / (heads * sectors);
674: }
675:
676: geom[0] = heads;
677: geom[1] = sectors;
678: geom[2] = cylinders;
679:
680: return (0);
681: }
682:
683:
684: /***********************************************************************
685: * Function : int DC390W_abort (Scsi_Cmnd *cmd)
686: *
687: * Purpose : Abort an errant SCSI command
688: *
689: * Inputs : cmd - command to abort
690: *
691: * Returns : 0 on success, -1 on failure.
692: ***********************************************************************/
693:
694: int
695: DC390W_abort (Scsi_Cmnd *cmd)
696: {
697: ULONG flags;
698: PACB pACB;
699: PDCB pDCB, pdcb;
700: PSRB pSRB, psrb;
701: USHORT count, i;
702: PSCSICMD pcmd, pcmd1;
703: int status;
704:
705:
706: #ifdef DC390W_DEBUG0
707: printk("DC390W : Abort Cmd.");
708: #endif
709:
710: save_flags(flags);
711: cli();
712:
713: pACB = (PACB) cmd->host->hostdata;
714: pDCB = pACB->pLinkDCB;
715: pdcb = pDCB;
716: while( (pDCB->UnitSCSIID != cmd->target) ||
717: (pDCB->UnitSCSILUN != cmd->lun) )
718: {
719: pDCB = pDCB->pNextDCB;
720: if( pDCB == pdcb )
721: goto NOT_RUN;
722: }
723:
724: if( pDCB->QIORBCnt )
725: {
726: pcmd = pDCB->pQIORBhead;
727: if( pcmd == cmd )
728: {
729: pDCB->pQIORBhead = pcmd->next;
730: pcmd->next = NULL;
731: pDCB->QIORBCnt--;
732: status = SCSI_ABORT_SUCCESS;
733: goto ABO_X;
734: }
735: for( count = pDCB->QIORBCnt, i=0; i<count-1; i++)
736: {
737: if( pcmd->next == cmd )
738: {
739: pcmd1 = pcmd->next;
740: pcmd->next = pcmd1->next;
741: pcmd1->next = NULL;
742: pDCB->QIORBCnt--;
743: status = SCSI_ABORT_SUCCESS;
744: goto ABO_X;
745: }
746: else
747: {
748: pcmd = pcmd->next;
749: }
750: }
751: }
752:
753: pSRB = pDCB->pWaitingSRB;
754: if( !pSRB )
755: goto ON_GOING;
756: if( pSRB->pcmd == cmd )
757: {
758: pDCB->pWaitingSRB = pSRB->pNextSRB;
759: goto IN_WAIT;
760: }
761: else
762: {
763: psrb = pSRB;
764: if( !(psrb->pNextSRB) )
765: goto ON_GOING;
766: while( psrb->pNextSRB->pcmd != cmd )
767: {
768: psrb = psrb->pNextSRB;
769: if( !(psrb->pNextSRB) )
770: goto ON_GOING;
771: }
772: pSRB = psrb->pNextSRB;
773: psrb->pNextSRB = pSRB->pNextSRB;
774: if( pSRB == pDCB->pWaitLast )
775: pDCB->pWaitLast = psrb;
776: IN_WAIT:
777: pSRB->pNextSRB = pACB->pFreeSRB;
778: pACB->pFreeSRB = pSRB;
779: cmd->next = NULL;
780: status = SCSI_ABORT_SUCCESS;
781: goto ABO_X;
782: }
783:
784: ON_GOING:
785: pSRB = pDCB->pGoingSRB;
786: for( count = pDCB->GoingSRBCnt, i=0; i<count; i++)
787: {
788: if( pSRB->pcmd != cmd )
789: pSRB = pSRB->pNextSRB;
790: else
791: {
792: if( (pACB->pActiveDCB == pDCB) && (pDCB->pActiveSRB == pSRB) )
793: {
794: status = SCSI_ABORT_BUSY;
795: goto ABO_X;
796: }
797: else
798: {
799: status = SCSI_ABORT_SNOOZE;
800: goto ABO_X;
801: }
802: }
803: }
804:
805: NOT_RUN:
806: status = SCSI_ABORT_NOT_RUNNING;
807:
808: ABO_X:
809: cmd->result = DID_ABORT << 16;
810: cmd->scsi_done(cmd);
811: restore_flags(flags);
812: return( status );
813: }
814:
815:
816: static void
817: ResetDevParam( PACB pACB )
818: {
819: PDCB pDCB, pdcb;
820:
821: pDCB = pACB->pLinkDCB;
822: if( pDCB == NULL )
823: return;
824: pdcb = pDCB;
825: do
826: {
827: if( pACB->AdaptType == DC390W )
828: pdcb->DCBscntl3 = SYNC_CLK_F2+ASYNC_CLK_F2;
829: else
830: pdcb->DCBscntl3 = SYNC_CLK_F4+ASYNC_CLK_F4;
831: pdcb->DCBsxfer = 0;
832: pdcb = pdcb->pNextDCB;
833: }
834: while( pdcb != pDCB );
835: }
836:
837:
838: static void
839: RecoverSRB( PACB pACB )
840: {
841: PDCB pDCB, pdcb;
842: PSRB psrb, psrb2;
843: USHORT cnt, i;
844:
845: pDCB = pACB->pLinkDCB;
846: if( pDCB == NULL )
847: return;
848: pdcb = pDCB;
849: do
850: {
851: cnt = pdcb->GoingSRBCnt;
852: psrb = pdcb->pGoingSRB;
853: for (i=0; i<cnt; i++)
854: {
855: PrepareSG( pACB, pdcb, psrb );
856: psrb2 = psrb;
857: psrb = psrb->pNextSRB;
858: /* RewaitSRB( pDCB, psrb ); */
859: if( pdcb->pWaitingSRB )
860: {
861: psrb2->pNextSRB = pdcb->pWaitingSRB;
862: pdcb->pWaitingSRB = psrb2;
863: }
864: else
865: {
866: pdcb->pWaitingSRB = psrb2;
867: pdcb->pWaitLast = psrb2;
868: psrb2->pNextSRB = NULL;
869: }
870: }
871: pdcb->GoingSRBCnt = 0;
872: pdcb->pGoingSRB = NULL;
873: pdcb->TagMask = 0;
874: pdcb = pdcb->pNextDCB;
875: }
876: while( pdcb != pDCB );
877: }
878:
879:
880: /***********************************************************************
881: * Function : int DC390W_reset (Scsi_Cmnd *cmd, ...)
882: *
883: * Purpose : perform a hard reset on the SCSI bus( and NCR chip).
884: *
885: * Inputs : cmd - command which caused the SCSI RESET
886: *
887: * Returns : 0 on success.
888: ***********************************************************************/
889:
890: #ifdef VERSION_2_0_0
891: int DC390W_reset(Scsi_Cmnd *cmd, unsigned int resetFlags)
892: #else
893: int DC390W_reset (Scsi_Cmnd *cmd)
894: #endif
895: {
896: USHORT ioport;
897: unsigned long flags;
898: PACB pACB;
899: ULONG wlval;
900: UCHAR bval;
901: USHORT wval;
902: USHORT i;
903:
904:
905: #ifdef DC390W_DEBUG0
906: printk("DC390W : Reset Cmd0,");
907: #endif
908:
909: pACB = (PACB ) cmd->host->hostdata;
910: ioport = pACB->IOPortBase;
911: save_flags(flags);
912: cli();
913: bval = inb(ioport+DCNTL);
914: bval |= IRQ_DISABLE;
915: outb(bval,ioport+DCNTL); /* disable interrupt */
916: DC390W_ResetSCSIBus( pACB );
917: for( i=0; i<500; i++ )
918: udelay(1000);
919: for(;;)
920: {
921: bval = inb(ioport+ISTAT);
922: if( bval & SCSI_INT_PENDING )
923: {
924: wval = inw( ioport+SIST0 );
925: if( wval & (SCSI_RESET+SCSI_GERROR) )
926: break;
927: }
928: if(bval & DMA_INT_PENDING)
929: {
930: bval = inb(ioport+DSTAT);
931: if(bval & ABORT_)
932: {
933: wval = inw( ioport+SIST0 );
934: break;
935: }
936: }
937: }
938: bval = inb(ioport+DCNTL);
939: bval &= ~IRQ_DISABLE;
940: outb(bval,ioport+DCNTL); /* re-enable interrupt */
941:
942: ioport = pACB->IOPortBase;
943: bval = inb(ioport+STEST3);
944: bval |= CLR_SCSI_FIFO;
945: outb(bval,ioport+STEST3);
946: bval = CLR_DMA_FIFO;
947: outb(bval,ioport+CTEST3);
948: ResetDevParam( pACB );
949: DoingSRB_Done( pACB );
950: pACB->pActiveDCB = NULL;
951: wlval = pACB->jmp_reselect;
952: outl(wlval,(ioport+DSP));
953:
954: pACB->ACBFlag = 0;
955: DoWaitingSRB( pACB );
956: restore_flags(flags);
957: return( SCSI_RESET_SUCCESS );
958: }
959:
960:
961: #include "scsiio.c"
962:
963:
964: /***********************************************************************
965: * Function : static void DC390W_initDCB
966: *
967: * Purpose : initialize the internal structures for a given DCB
968: *
969: * Inputs : cmd - pointer to this scsi cmd request block structure
970: *
971: ***********************************************************************/
972: void DC390W_initDCB( PACB pACB, PDCB pDCB, PSCSICMD cmd )
973: {
974: PEEprom prom;
975: UCHAR bval;
976: USHORT index;
977:
978: if( pACB->DeviceCnt == 0 )
979: {
980: pACB->pLinkDCB = pDCB;
981: pACB->pDCBRunRobin = pDCB;
982: pDCB->pNextDCB = pDCB;
983: pPrevDCB = pDCB;
984: }
985: else
986: pPrevDCB->pNextDCB = pDCB;
987:
988: pDCB->pDCBACB = pACB;
989: pDCB->QIORBCnt = 0;
990: pDCB->DCBselect = 0;
991: pDCB->DCBsxfer = 0;
992: pDCB->DCBsdid = cmd->target;
993: pDCB->UnitSCSIID = cmd->target;
994: pDCB->UnitSCSILUN = cmd->lun;
995: pDCB->pWaitingSRB = NULL;
996: pDCB->GoingSRBCnt = 0;
997: pDCB->TagMask = 0;
998:
999: pDCB->MaxCommand = 1;
1000: pDCB->AdaptIndex = pACB->AdapterIndex;
1001: index = pACB->AdapterIndex;
1002:
1003: prom = (PEEprom) &eepromBuf[index][cmd->target << 2];
1004: pDCB->DevMode = prom->EE_MODE1;
1005: pDCB->NegoPeriod = clock_period[prom->EE_SPEED];
1006:
1007: if( pACB->AdaptType == DC390W )
1008: pDCB->DCBscntl3 = SYNC_CLK_F2+ASYNC_CLK_F2;
1009: else
1010: pDCB->DCBscntl3 = SYNC_CLK_F4+ASYNC_CLK_F4;
1011:
1012: if( pDCB->DevMode & PARITY_CHK_ )
1013: pDCB->DCBscntl0 = EN_PARITY_CHK+SATN_IF_PARITY_ERR+FULL_ARBITRATION;
1014: else
1015: pDCB->DCBscntl0 = FULL_ARBITRATION;
1016:
1017: pDCB->AdpMode = eepromBuf[index][EE_MODE2];
1018:
1019: if( pDCB->DevMode & EN_DISCONNECT_ )
1020: bval = 0xC0;
1021: else
1022: bval = 0x80;
1023: bval |= cmd->lun;
1024: pDCB->IdentifyMsg = bval;
1025:
1026: if( pDCB->DevMode & SYNC_NEGO_ )
1027: {
1028: pDCB->SyncMode = SYNC_ENABLE;
1029: pDCB->SyncOffset = SYNC_NEGO_OFFSET;
1030: }
1031:
1032: if( pDCB->DevMode & WIDE_NEGO_ )
1033: {
1034: if( cmd->lun )
1035: {
1036: if( !(CurrDCBscntl3 & EN_WIDE_SCSI) )
1037: pDCB->DevMode &= ~WIDE_NEGO_;
1038: }
1039: else
1040: CurrDCBscntl3 = 0;
1041: }
1042: pDCB->DCBFlag = 0;
1043: }
1044:
1045:
1046: /***********************************************************************
1047: * Function : static void DC390W_initSRB
1048: *
1049: * Purpose : initialize the internal structures for a given SRB
1050: *
1051: * Inputs : psrb - pointer to this scsi request block structure
1052: *
1053: ***********************************************************************/
1054: void DC390W_initSRB( PSRB psrb )
1055: {
1056: #ifndef VERSION_ELF_1_2_13
1057: psrb->PhysSRB = virt_to_phys( psrb );
1058: psrb->__command[1] = virt_to_phys( psrb->CmdBlock );
1059: psrb->__msgout0[0] = 1;
1060: psrb->__msgout0[1] = virt_to_phys( psrb->MsgOutBuf );
1061: psrb->SegmentPad[0] = 16;
1062: psrb->SegmentPad[1] = virt_to_phys( pad_buffer );
1063: #else
1064: psrb->PhysSRB = (ULONG) psrb;
1065: psrb->__command[1] = (ULONG) psrb->CmdBlock;
1066: psrb->__msgout0[0] = 1;
1067: psrb->__msgout0[1] = (ULONG) psrb->MsgOutBuf;
1068: psrb->SegmentPad[0] = 16;
1069: psrb->SegmentPad[1] = (ULONG) pad_buffer;
1070: #endif
1071: }
1072:
1073:
1074: void DC390W_linkSRB( PACB pACB )
1075: {
1076: USHORT count, i;
1077: PSRB psrb;
1078:
1079: count = pACB->SRBCount;
1080:
1081: for( i=0; i< count; i++)
1082: {
1083: if( i != count - 1)
1084: pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
1085: else
1086: pACB->SRB_array[i].pNextSRB = NULL;
1087: psrb = (PSRB) &pACB->SRB_array[i];
1088: DC390W_initSRB( psrb );
1089: }
1090: }
1091:
1092:
1093: /***********************************************************************
1094: * Function : static void DC390W_initACB
1095: *
1096: * Purpose : initialize the internal structures for a given SCSI host
1097: *
1098: * Inputs : psh - pointer to this host adapter's structure
1099: *
1100: ***********************************************************************/
1101: void DC390W_initACB( PSH psh, USHORT chipType, ULONG io_port, UCHAR Irq, USHORT index )
1102: {
1103: PACB pACB;
1104: USHORT i;
1105: UCHAR adaptType, bval;
1106:
1107:
1108: psh->can_queue = MAX_CMD_QUEUE;
1109: psh->cmd_per_lun = MAX_CMD_PER_LUN;
1110: psh->this_id = (int) eepromBuf[index][EE_ADAPT_SCSI_ID];
1111: psh->io_port = io_port;
1112: psh->n_io_port = 0x80;
1113: psh->irq = Irq;
1114:
1115: if( chipType == PCI_DEVICE_ID_NCR53C825A )
1116: adaptType = DC390W;
1117: else
1118: {
1119: outb( 2, io_port+GPREG );
1120: bval = inb( io_port+GPREG );
1121: if( bval & 8 )
1122: adaptType = DC390U;
1123: else
1124: adaptType = DC390F;
1125: }
1126:
1127: pACB = (PACB) psh->hostdata;
1128:
1129: #ifndef VERSION_ELF_1_2_13
1130: if( adaptType == DC390U )
1131: {
1132: psh->max_id = 8;
1133: pACB->max_id = 7;
1134: }
1135: else
1136: {
1137: psh->max_id = 16;
1138: pACB->max_id = 15;
1139: }
1140:
1141: #ifdef CONFIG_SCSI_MULTI_LUN
1142: if( eepromBuf[index][EE_MODE2] & LUN_CHECK )
1143: psh->max_lun = 8;
1144: else
1145: #endif
1146: psh->max_lun = 1;
1147:
1148: #else
1149: pACB->max_id = 7;
1150: #endif
1151: if( pACB->max_id == eepromBuf[index][EE_ADAPT_SCSI_ID] )
1152: pACB->max_id--;
1153:
1154: #ifdef CONFIG_SCSI_MULTI_LUN
1155: if( eepromBuf[index][EE_MODE2] & LUN_CHECK )
1156: pACB->max_lun = 7;
1157: else
1158: #endif
1159: pACB->max_lun = 0;
1160:
1161: pACB->pScsiHost = psh;
1162: pACB->IOPortBase = (USHORT) io_port;
1163: pACB->pLinkDCB = NULL;
1164: pACB->pDCBRunRobin = NULL;
1165: pACB->pActiveDCB = NULL;
1166: pACB->pFreeSRB = pACB->SRB_array;
1167: pACB->SRBCount = MAX_SRB_CNT;
1168: pACB->AdapterIndex = index;
1169: pACB->status = 0;
1170: pACB->AdaptSCSIID = eepromBuf[index][EE_ADAPT_SCSI_ID];
1171: pACB->AdaptSCSILUN = 0;
1172: pACB->DeviceCnt = 0;
1173: pACB->IRQLevel = Irq;
1174: pACB->AdaptType = adaptType;
1175: pACB->TagMaxNum = eepromBuf[index][EE_TAG_CMD_NUM] << 2;
1176: pACB->ACBFlag = 0;
1177: pACB->scan_devices = 1;
1178: pACB->Gmode2 = eepromBuf[index][EE_MODE2];
1179: if( eepromBuf[index][EE_MODE2] & LUN_CHECK )
1180: pACB->LUNchk = 1;
1181: pACB->pDCB_free = &pACB->DCB_array[0];
1182: DC390W_linkSRB( pACB );
1183: for(i=0; i<MAX_SCSI_ID; i++)
1184: pACB->DCBmap[i] = 0;
1185: }
1186:
1187:
1188: /***********************************************************************
1189: * Function : static int DC390W_initAdapter
1190: *
1191: * Purpose : initialize the SCSI chip ctrl registers
1192: *
1193: * Inputs : psh - pointer to this host adapter's structure
1194: *
1195: ***********************************************************************/
1196: int DC390W_initAdapter( PSH psh, ULONG io_port, UCHAR Irq, USHORT index )
1197: {
1198: USHORT ioport, wval;
1199: UCHAR bval;
1200: PACB pACB, pacb;
1201: USHORT used_irq = 0;
1202:
1203: pacb = pACB_start;
1204: if( pacb != NULL )
1205: {
1206: for ( ; (pacb != (PACB) -1) ; )
1207: {
1208: if( pacb->IRQLevel == Irq )
1209: {
1210: used_irq = 1;
1211: break;
1212: }
1213: else
1214: pacb = pacb->pNextACB;
1215: }
1216: }
1217:
1218: if( !used_irq )
1219: {
1220: #ifdef VERSION_ELF_1_2_13
1221: if( request_irq(Irq, DC390W_Interrupt, SA_INTERRUPT, "tmscsiw"))
1222: #else
1223: if( request_irq(Irq, DC390W_Interrupt, SA_INTERRUPT | SA_SHIRQ, "tmscsiw", NULL))
1224: #endif
1225: {
1226: printk("DC390W : register IRQ error!\n");
1227: return( -1 );
1228: }
1229: }
1230: request_region(io_port,psh->n_io_port,"tmscsiw");
1231:
1232: ioport = (USHORT) io_port;
1233: outb(IRQ_DISABLE, ioport+DCNTL);
1234: outb(ABORT_OP, ioport+ISTAT);
1235: udelay(100000);
1236: outb(0, ioport+ISTAT);
1237: bval = inb(ioport+DSTAT);
1238: bval = inb(ioport+ISTAT);
1239: wval = inw(ioport+SIST0);
1240:
1241: pACB = (PACB) psh->hostdata;
1242: bval = pACB->AdaptSCSIID;
1243: bval |= ENABLE_RESEL;
1244: outb(bval,ioport+SCID);
1245:
1246: if(pACB->AdaptType == DC390W)
1247: bval = SYNC_CLK_F2+ASYNC_CLK_F2;
1248: else
1249: { /* @1.09 */
1250: bval = inb(ioport+CTEST3);
1251: if( (bval & CHIP_REV_MASK) < 0x30 ) /* 53C875 Rev. F or later ? */
1252: goto REVF;
1253: bval = inb(ioport+STEST1);
1254: if( (bval & 0x0C) == 0x0C ) /* double clock already enable ? */
1255: goto REVF;
1256: outb(8,ioport+STEST1); /* enable clock doubler */
1257: udelay(20);
1258: outb(HALT_SCSI_CLK,ioport+STEST3); /* halt clock */
1259: outb(0x0C,ioport+STEST1); /* select double SCSI clock */
1260: outb(0,ioport+STEST3); /* re-enable clock */
1261: REVF:
1262: bval = SYNC_CLK_F4+ASYNC_CLK_F4;
1263: }
1264: outb(bval,ioport+SCNTL3);
1265:
1266: bval = SYNC_PERIOD_F4+ASYNCHRONOUS; /* set to async */
1267: outb(bval,ioport+SXFER);
1268:
1269: bval = WRT_EN_INVALIDATE; /* Enable write and invalidate */
1270: outb(bval,ioport+CTEST3);
1271:
1272: bval = EN_DMA_FIFO_536+BURST_LEN_MSB; /* select 536 bytes DMA FIFO, burst len bit2=1 */
1273: outb(bval,ioport+CTEST5);
1274:
1275: bval = BURST_LEN8+EN_READ_LINE+EN_READ_MULTIPLE+BURST_OPCODE_FETCH+AUTO_START; /* set DMA parameter */
1276: outb(bval,ioport+DMODE);
1277:
1278: bval = EN_ABORTED+EN_SCRIPT_INT+EN_ILLEGAL_INST; /* enable DMA interrupt */
1279: outb(bval,ioport+DIEN);
1280:
1281: bval = EN_CACHE_LINE_SIZE+EN_PRE_FETCH+TOTEM_POLE_IRQ+COMPATIBLE_700;
1282: outb(bval,ioport+DCNTL);
1283:
1284: bval = EN_PHASE_MISMATCH+EN_SCSI_GERROR+EN_UNEXPECT_DISC+EN_SCSI_RESET+EN_PARITY_ERROR;
1285: outb(bval,ioport+SIEN0);
1286:
1287: bval = EN_SEL_TIMEOUT+EN_GENERAL_TIMEOUT;
1288: outb(bval,ioport+SIEN1);
1289:
1290: bval = SEL_TO_204ms; /* 250ms selection timeout */
1291: outb(bval,ioport+STIME0);
1292:
1293: wval = 1 << (eepromBuf[index][EE_ADAPT_SCSI_ID]); /* @1.11 */
1294: outw(wval,ioport+RESPID0);
1295:
1296: bval = DIS_SINGLE_INIT;
1297: if( eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION )
1298: bval |= ACTIVE_NEGATION_;
1299: outb(bval,ioport+STEST3);
1300:
1301: return(0);
1302: }
1303:
1304:
1305: /***********************************************************************
1306: * Function : static int DC390W_init (struct Scsi_Host *host)
1307: *
1308: * Purpose : initialize the internal structures for a given SCSI host
1309: *
1310: * Inputs : host - pointer to this host adapter's structure/
1311: *
1312: * Preconditions : when this function is called, the chip_type
1313: * field of the pACB structure MUST have been set.
1314: ***********************************************************************/
1315:
1316: static int
1317: DC390W_init (PSHT psht, USHORT chipType, ULONG io_port, UCHAR Irq, USHORT index)
1318: {
1319: PSH psh;
1320: PACB pACB;
1321:
1322: if( ! CheckEEpromCheckSum( &eepromBuf[index][0], (USHORT) io_port) )
1323: {
1324: psh = scsi_register( psht, sizeof(DC390W_ACB) );
1325: if( !psh )
1326: return( -1 );
1327: if( !pSH_start )
1328: {
1329: pSH_start = psh;
1330: pSH_current = psh;
1331: }
1332: else
1333: {
1334: pSH_current->next = psh;
1335: pSH_current = psh;
1336: }
1337:
1338: #ifdef DC390W_DEBUG0
1339: printk("DC390W : pSH = %8x,", (UINT) psh);
1340: #endif
1341:
1342: DC390W_initACB( psh, chipType, io_port, Irq, index );
1343: if( !DC390W_initAdapter( psh, io_port, Irq, index ) )
1344: {
1345: pACB = (PACB) psh->hostdata;
1346: if( !pACB_start )
1347: {
1348: pACB_start = pACB;
1349: pACB_current = pACB;
1350: pACB->pNextACB = (PACB) -1;
1351: }
1352: else
1353: {
1354: pACB_current->pNextACB = pACB;
1355: pACB_current = pACB;
1356: pACB->pNextACB = (PACB) -1;
1357: }
1358:
1359: #ifdef DC390W_DEBUG0
1360: printk("DC390W : pACB = %8x, pDCB_array = %8x, pSRB_array = %8x\n",
1361: (UINT) pACB, (UINT) pACB->DCB_array, (UINT) pACB->SRB_array);
1362: printk("DC390W : ACB size= %4x, DCB size= %4x, SRB size= %4x\n",
1363: sizeof(DC390W_ACB), sizeof(DC390W_DCB), sizeof(DC390W_SRB) );
1364: #endif
1365:
1366: }
1367: else
1368: {
1369: pSH_start = NULL;
1370: scsi_unregister( psh );
1371: return( -1 );
1372: }
1373: DC390W_download_script( psh );
1374: return( 0 );
1375: }
1376: else
1377: {
1378: printk("DC390W_init: EEPROM reading error!\n");
1379: return( -1 );
1380: }
1381: }
1382:
1383:
1384: void MyDelay( void )
1385: {
1386: UCHAR i,j;
1387:
1388: j = inb(0x61) & 0x10;
1389:
1390: for(;;)
1391: {
1392: i = inb(0x61) & 0x10;
1393: if( j ^ i)
1394: break;
1395: }
1396: }
1397:
1398:
1399: void EnDisableCE( UCHAR Flag, USHORT scsiIOPort )
1400: {
1401:
1402: UCHAR bval;
1403: USHORT port;
1404:
1405: port = (scsiIOPort & 0xff00) + GPREG;
1406: if(Flag == ENABLE_CE)
1407: bval = 0x10;
1408: else
1409: bval = 0x00;
1410: outb(bval,port);
1411: udelay(8); /* Delay();*/
1412: }
1413:
1414:
1415: void EEpromOutDI( USHORT Carry, USHORT scsiIOPort )
1416: {
1417: UCHAR bval;
1418: USHORT port;
1419:
1420: port = (scsiIOPort & 0xff00) + GPREG;
1421: bval = 0x10;
1422: if(Carry)
1423: bval |= 0x02; /* SK=0, DI */
1424: outb(bval,port);
1425: udelay(8); /* Delay();*/
1426: bval |= 0x04; /* SK=1, DI */
1427: outb(bval,port);
1428: udelay(8); /* Delay();*/
1429: bval &= 0xfb; /* SK=0, DI */
1430: outb(bval,port);
1431: udelay(8); /* Delay();*/
1432: }
1433:
1434:
1435: void EEpromPrepare( UCHAR EEpromCmd, USHORT scsiIOPort )
1436: {
1437: UCHAR i,j;
1438: USHORT carryFlag;
1439:
1440: carryFlag = 1;
1441: j = 0x80;
1442: for(i=0;i<9;i++)
1443: {
1444: EEpromOutDI(carryFlag,scsiIOPort);
1445: carryFlag = (EEpromCmd & j) ? 1 : 0;
1446: j >>= 1;
1447: }
1448: }
1449:
1450:
1451: UCHAR EEpromInDo(USHORT scsiIOPort)
1452: {
1453: UCHAR bval;
1454: USHORT port;
1455:
1456: port = (scsiIOPort & 0xff00) + GPREG;
1457: bval = 0x14; /* SK=1 */
1458: outb(bval,port);
1459: udelay(8); /* Delay();*/
1460: bval = 0x10; /* SK=0 */
1461: outb(bval,port);
1462: udelay(8); /* Delay();*/
1463: bval = inb(port);
1464: if(bval & 0x01)
1465: return( 1 );
1466: else
1467: return( 0 );
1468: }
1469:
1470:
1471: USHORT EEpromGetData(USHORT scsiIOPort)
1472: {
1473: UCHAR i;
1474: UCHAR carryFlag;
1475: USHORT wval;
1476:
1477: wval = 0;
1478: for(i=0;i<16;i++)
1479: {
1480: wval <<= 1;
1481: carryFlag = EEpromInDo(scsiIOPort);
1482: wval |= carryFlag;
1483: }
1484: return( wval );
1485: }
1486:
1487:
1488: void ReadEEprom( PUCHAR EEpromBuf, USHORT scsiIOPort )
1489: {
1490: UCHAR cmd;
1491:
1492: cmd = EEPROM_READ;
1493: loop_rd:
1494: EnDisableCE(ENABLE_CE, scsiIOPort);
1495: EEpromPrepare(cmd, scsiIOPort);
1496: *((PUSHORT)EEpromBuf) = EEpromGetData(scsiIOPort);
1497: EEpromBuf++;
1498: EEpromBuf++;
1499: cmd++;
1500: EnDisableCE(DISABLE_CE, scsiIOPort);
1501: if(cmd & 0x3f)
1502: goto loop_rd;
1503: }
1504:
1505:
1506: USHORT CheckEEpromCheckSum( PUCHAR EEpromBuf, USHORT scsiIOPort)
1507: {
1508: USHORT wval,port, *ptr;
1509: UCHAR i,bval;
1510:
1511: port = (scsiIOPort & 0xff00) + GPCNTL;
1512: bval = 0x09; /* configure IO Pin */
1513: outb(bval,port);
1514: ReadEEprom(EEpromBuf,scsiIOPort); /* read eeprom data */
1515: wval = 0;
1516: ptr = (PUSHORT) EEpromBuf;
1517: for(i=0; i<128 ;i+=2, ptr++)
1518: wval += *ptr;
1519: return( (wval == 0x1234) ? 0 : -1);
1520: }
1521:
1522:
1523:
1524: static void
1525: DC390W_download_script (struct Scsi_Host *host)
1526: {
1527: ULONG wlval, wlval1, length, alignm;
1528: USHORT j, k, m;
1529: USHORT ioport;
1530: UCHAR bval;
1531: PACB pACB;
1532: PSRB pSRB;
1533: void *pSrc, *pSrc1;
1534: ULONG *pStart;
1535: ULONG Ent_reselected;
1536: ULONG Ent_reselecttag;
1537: ULONG Ent_select0;
1538: ULONG Ent_select1;
1539: ULONG Ent_check_phase;
1540: ULONG Ent_status1_phase;
1541: ULONG Ent_command_phase;
1542: ULONG Ent_jump_table0;
1543: ULONG Ent_din_phaseB;
1544: ULONG Ent_dout_phaseB;
1545: ULONG Ent_din_pad_0;
1546: ULONG Ent_dout_pad_0;
1547: ULONG Ent_jump_tablew;
1548: ULONG Ent_din_pad_1;
1549: ULONG Ent_dout_pad_1;
1550: ULONG Ent_mout_phase;
1551: ULONG Ent_status_phase;
1552: ULONG Ent_min_phase;
1553: ULONG Ent_jump_msgok;
1554: ULONG Ent_msg__1;
1555: ULONG Ent_msg___3;
1556: ULONG Ent_msg___2;
1557: ULONG Ent_set_atn;
1558: ULONG Ent_msg__a;
1559: ULONG Ent_msg__23;
1560: ULONG Ent_msg__3;
1561: ULONG Ent_msg__4;
1562: ULONG Ent_clr_atn;
1563: ULONG Ent_din_phaseW;
1564: ULONG Ent_dout_phaseW;
1565: ULONG Ent_din_pad_addrB;
1566: ULONG Ent_dout_pad_addrB;
1567: ULONG Ent_din_pad_addrW;
1568: ULONG Ent_dout_pad_addrW;
1569:
1570:
1571: pACB = (PACB) host->hostdata;
1572: ioport = pACB->IOPortBase;
1573: bval = SCRATCHAB_AS_BASE; /* set scratchB contains 4K RAM base address */
1574: outb(bval,ioport+CTEST2);
1575:
1576: wlval = inl((ioport+SCRATCHB)); /* get starting address of 4K RAM */
1577: /* wlval += 0x800; */ /* point to Upper 2K RAM */
1578: DesPhysAddr[0] = wlval; /* destination address */
1579:
1580: #ifdef DC390W_DEBUG0
1581: printk("DesAddr=%8x,",(UINT) wlval);
1582: #endif
1583: bval = 0; /* set Scratch_A and Scratch_B to normal mode */
1584: outb(bval,ioport+CTEST2);
1585:
1586: /*-------------------------------------------------------------------
1587: * patch the label in jump instruction: using offset relative
1588: * to start_script
1589: *------------------------------------------------------------------*/
1590:
1591: Ent_reselected = (ULONG) reselected - (ULONG) start_script;
1592: Ent_reselecttag = (ULONG) reselecttag - (ULONG) start_script;
1593: Ent_select0 = (ULONG) select0 - (ULONG) start_script;
1594: Ent_select1 = (ULONG) select1 - (ULONG) start_script;
1595: Ent_check_phase = (ULONG) check_phase - (ULONG) start_script;
1596: Ent_status1_phase = (ULONG) status1_phase - (ULONG) start_script;
1597: Ent_command_phase = (ULONG) command_phase - (ULONG) start_script;
1598: Ent_din_phaseB = (ULONG) din_phaseB - (ULONG) start_script;
1599: Ent_dout_phaseB = (ULONG) dout_phaseB - (ULONG) start_script;
1600: Ent_din_phaseW = (ULONG) din_phaseW - (ULONG) start_script;
1601: Ent_dout_phaseW = (ULONG) dout_phaseW - (ULONG) start_script;
1602: Ent_jump_table0 = (ULONG) jump_table0 - (ULONG) start_script;
1603: Ent_din_pad_0 = (ULONG) din_pad_0 - (ULONG) start_script;
1604: Ent_din_pad_addrB = (ULONG) din_pad_addrB - (ULONG) start_script;
1605: Ent_dout_pad_0 = (ULONG) dout_pad_0 - (ULONG) start_script;
1606: Ent_dout_pad_addrB = (ULONG) dout_pad_addrB - (ULONG) start_script;
1607: Ent_jump_tablew = (ULONG) jump_tablew - (ULONG) start_script;
1608: Ent_din_pad_1 = (ULONG) din_pad_1 - (ULONG) start_script;
1609: Ent_din_pad_addrW = (ULONG) din_pad_addrW - (ULONG) start_script;
1610: Ent_dout_pad_1 = (ULONG) dout_pad_1 - (ULONG) start_script;
1611: Ent_dout_pad_addrW = (ULONG) dout_pad_addrW - (ULONG) start_script;
1612: Ent_mout_phase = (ULONG) mout_phase - (ULONG) start_script;
1613: Ent_status_phase = (ULONG) status_phase - (ULONG) start_script;
1614: Ent_min_phase = (ULONG) min_phase - (ULONG) start_script;
1615: Ent_jump_msgok = (ULONG) jump_msgok - (ULONG) start_script;
1616: Ent_msg__1 = (ULONG) msg__1 - (ULONG) start_script;
1617: Ent_msg___3 = (ULONG) msg___3 - (ULONG) start_script;
1618: Ent_msg___2 = (ULONG) msg___2 - (ULONG) start_script;
1619: Ent_set_atn = (ULONG) set_atn - (ULONG) start_script;
1620: Ent_msg__a = (ULONG) msg__a - (ULONG) start_script;
1621: Ent_msg__23 = (ULONG) msg__23 - (ULONG) start_script;
1622: Ent_msg__3 = (ULONG) msg__3 - (ULONG) start_script;
1623: Ent_msg__4 = (ULONG) msg__4 - (ULONG) start_script;
1624: Ent_clr_atn = (ULONG) clr_atn - (ULONG) start_script;
1625:
1626: jmp_select0[0] = Ent_select0 + wlval;
1627: jmp_reselected[0] = Ent_reselected + wlval;
1628: jmp_check_phase[0] = Ent_check_phase + wlval;
1629: jmp_check_phase1[0] = Ent_check_phase + wlval;
1630: jmp_check_phase2[0] = Ent_check_phase + wlval;
1631: jmp_check_phase3[0] = Ent_check_phase + wlval;
1632: jmp_check_phase4[0] = Ent_check_phase + wlval;
1633: jmp_check_phase5[0] = Ent_check_phase + wlval;
1634: jmp_check_phase6[0] = Ent_check_phase + wlval;
1635: jmp_status1_phase[0] = Ent_status1_phase + wlval;
1636: jmp_status1_phase1[0] = Ent_status1_phase + wlval;
1637: jmp_status1_phase2[0] = Ent_status1_phase + wlval;
1638: jmp_status1_phase3[0] = Ent_status1_phase + wlval;
1639: jmp_command_phase[0] = Ent_command_phase + wlval;
1640: for(j=0,k=1,m=0; j< (MAX_SG_LIST_BUF+1); j++)
1641: {
1642: jmp_dio_phaseB[k] = Ent_din_phaseB + m + wlval;
1643: jmp_dio_phaseW[k] = Ent_din_phaseW + m + wlval;
1644: k += 2;
1645: jmp_dio_phaseB[k] = Ent_dout_phaseB + m + wlval;
1646: jmp_dio_phaseW[k] = Ent_dout_phaseW + m + wlval;
1647: k += 2;
1648: m += 8;
1649: }
1650: jmp_din_pad_0[0] = Ent_din_pad_0 + wlval;
1651: jmp_dout_pad_0[0] = Ent_dout_pad_0 + wlval;
1652: jmp_din_pad_addrB[0] = Ent_din_pad_addrB + wlval;
1653: jmp_dout_pad_addrB[0] = Ent_dout_pad_addrB + wlval;
1654: jmp_din_pad_addrW[0] = Ent_din_pad_addrW + wlval;
1655: jmp_dout_pad_addrW[0] = Ent_dout_pad_addrW + wlval;
1656: jmp_din_pad_1[0] = Ent_din_pad_1 + wlval;
1657: jmp_dout_pad_1[0] = Ent_dout_pad_1 + wlval;
1658: jmp_status_phase[0] = Ent_status_phase + wlval;
1659: jmp_min_phase[0] = Ent_min_phase + wlval;
1660: jmp_mout_phase[0] = Ent_mout_phase + wlval;
1661: jmp_jump_msgok[0] = Ent_jump_msgok + wlval;
1662: jmp_msg__1[0] = Ent_msg__1 + wlval;
1663: jmp_msg___3[0] = Ent_msg___3 + wlval;
1664: jmp_msg___2[0] = Ent_msg___2 + wlval;
1665: jmp_msg__a[0] = Ent_msg__a + wlval;
1666: jmp_msg__a1[0] = Ent_msg__a + wlval;
1667: jmp_msg__a2[0] = Ent_msg__a + wlval;
1668: jmp_msg__23[0] = Ent_msg__23 + wlval;
1669: jmp_msg__3[0] = Ent_msg__3 + wlval;
1670: jmp_msg__4[0] = Ent_msg__4 + wlval;
1671:
1672: /*--------------------------------------------------------------------
1673: // patch the element in ACB struct: using Physical address
1674: //-------------------------------------------------------------------*/
1675:
1676: #ifndef VERSION_ELF_1_2_13
1677: wlval1 = virt_to_phys( pACB->msgin123 );
1678: #else
1679: wlval1 = (ULONG) pACB->msgin123;
1680: #endif
1681: ACB_msgin123_1[0] = wlval1;
1682: ACB_msgin123_2[0] = wlval1;
1683: ACB_msgin123_3[0] = wlval1;
1684: ACB_msgin123_4[0] = wlval1;
1685: ACB_msgin123_5[0] = wlval1;
1686: ACB_msgin123_6[0] = wlval1;
1687: ACB_msgin123_7[0] = wlval1;
1688:
1689: #ifndef VERSION_ELF_1_2_13
1690: ACB_status[0] = virt_to_phys( &pACB->status );
1691: #else
1692: ACB_status[0] = (ULONG) &pACB->status;
1693: #endif
1694: /*--------------------------------------------------------------------
1695: // patch the element in SRB struct: using offset in struct
1696: //-------------------------------------------------------------------*/
1697:
1698: pSRB = (PSRB) pACB->SRB_array;
1699: select1[0] = (select1[0] & 0xffff0000) + ((ULONG) &pSRB->__select - (ULONG) &pSRB->CmdBlock);
1700: SRB_msgout0[0] = (ULONG) &pSRB->__msgout0 - (ULONG) &pSRB->CmdBlock;
1701: SRB_msgout01[0] = (ULONG) &pSRB->__msgout0 - (ULONG) &pSRB->CmdBlock;
1702: SRB_command[0] = (ULONG) &pSRB->__command - (ULONG) &pSRB->CmdBlock;
1703: SRB_SegmentPad[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock;
1704: SRB_SegmentPad1[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock;
1705: SRB_SegmentPad2[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock;
1706: SRB_SegmentPad3[0] = (ULONG) &pSRB->SegmentPad - (ULONG) &pSRB->CmdBlock;
1707: wlval = (ULONG) &pSRB->Segment0 - (ULONG) &pSRB->CmdBlock;
1708: for(j=0,k=1; j<(MAX_SG_LIST_BUF+1); j++)
1709: {
1710: din_phaseB[k] = wlval;
1711: dout_phaseB[k] = wlval;
1712: din_phaseW[k] = wlval;
1713: dout_phaseW[k] = wlval;
1714: k += 2;
1715: wlval += 8;
1716: }
1717:
1718:
1719: bval = inb(ioport+DCNTL);
1720: bval |= IRQ_DISABLE;
1721: outb(bval,ioport+DCNTL); /* disable interrupt */
1722:
1723: /* pSrc = scsi_init_malloc( 2048, GFP_ATOMIC); */
1724: pSrc = scsi_init_malloc( 4096, GFP_ATOMIC); /* 1.11 */
1725: #ifdef DC390W_DEBUG0
1726: printk("SrcAlloc=%8x,",(UINT) pSrc);
1727: #endif
1728: alignm = 4 - (((ULONG) pSrc) & 3);
1729: pSrc1 = (void *)(((ULONG) pSrc) + alignm);
1730: length = (ULONG) end_script - (ULONG) start_script;
1731: memcpy( pSrc1, (void *) start_script, length);
1732: pStart = (ULONG *) ((ULONG) start_mov - (ULONG) start_script);
1733: pStart =(ULONG *) (((ULONG) pStart) + ((ULONG) pSrc1));
1734:
1735: #ifdef DC390W_DEBUG0
1736: printk("SrcAddr=%8x,\n",(UINT) pSrc1);
1737: #endif
1738: #ifndef VERSION_ELF_1_2_13
1739: (ULONG *)pStart[1] = virt_to_phys( pSrc1 );
1740: #else
1741: (ULONG *)pStart[1] = (ULONG) pSrc1;
1742: #endif
1743:
1744: /* wlval = virt_to_phys( start_script ); */ /* physical address of start_script */
1745: /* SrcPhysAddr[0] = wlval; */ /* sources address */
1746:
1747: /* start to download SCRIPT instruction to the RAM of NCR53c825A,875 */
1748:
1749: /* wlval = virt_to_phys( start_mov ); */
1750:
1751: #ifndef VERSION_ELF_1_2_13
1752: wlval = virt_to_phys( pStart );
1753: #else
1754: wlval = (ULONG) pStart;
1755: #endif
1756:
1757: outl(wlval,ioport+DSP);
1758:
1759: bval = inb(ioport+ISTAT);
1760: while(!(bval & DMA_INT_PENDING)) /* check load start_script is finished? */
1761: bval = inb(ioport+ISTAT);
1762:
1763: bval = inb(ioport+DSTAT); /* clear interrupt */
1764:
1765: bval = inb(ioport+DCNTL);
1766: bval &= ~IRQ_DISABLE;
1767: outb(bval,ioport+DCNTL); /* re-enable interrupt */
1768:
1769: scsi_init_free((char *) pSrc, 4096);
1770:
1771: wlval = DesPhysAddr[0]; /* starting addr of RAM */
1772: wlval -= (ULONG) start_script;
1773:
1774: pACB->jmp_reselect = wlval + (ULONG) start_script;
1775: pACB->jmp_select = wlval + (ULONG) select1;
1776: pACB->jmp_table8 = wlval + (ULONG) jump_table0;
1777: pACB->jmp_set_atn = wlval + (ULONG) set_atn;
1778: pACB->jmp_clear_ack = wlval + (ULONG) msg__a;
1779: pACB->jmp_next = wlval + (ULONG) check_phase;
1780: pACB->jmp_din8 = wlval + (ULONG) din_phaseB+8;
1781: pACB->jmp_dout8 = wlval + (ULONG) dout_phaseB+8;
1782: pACB->jmp_clear_atn = wlval + (ULONG) clr_atn;
1783: pACB->jmp_reselecttag = wlval + (ULONG) reselecttag;
1784:
1785: wlval = pACB->jmp_reselect;
1786: outl(wlval,(ioport+DSP));
1787: return;
1788: }
1789:
1790:
1791: /***********************************************************************
1792: * Function : int DC390W_detect(Scsi_Host_Template *psht)
1793: *
1794: * Purpose : detects and initializes NCR53c825A,875 SCSI chips
1795: * that were autoprobed, overridden on the LILO command line,
1796: * or specified at compile time.
1797: *
1798: * Inputs : psht - template for this SCSI adapter
1799: *
1800: * Returns : number of host adapters detected
1801: *
1802: ***********************************************************************/
1803:
1804: int
1805: DC390W_detect(Scsi_Host_Template *psht)
1806: {
1807: UCHAR pci_bus, pci_device_fn, irq;
1808: #ifndef VERSION_ELF_1_2_13
1809: UINT io_port, ram_base;
1810: #else
1811: ULONG io_port, ram_base;
1812: #endif
1813: USHORT i;
1814: int error = 0;
1815: USHORT adaptCnt = 0; /* Number of boards detected */
1816: USHORT pci_index = 0; /* Device index to PCI BIOS calls */
1817: USHORT pci_index2 = 0; /* Device index to PCI BIOS calls */
1818: USHORT chipType = 0;
1819:
1820:
1821: #ifndef VERSION_ELF_1_2_13
1822: psht->proc_dir = &proc_scsi_tmscsiw;
1823: #endif
1824:
1825: InitialTime = 1;
1826: pSHT_start = psht;
1827: jmp_table16 = (ULONG) jump_tablew - (ULONG) jump_table0;
1828: jmp_din16 = (ULONG) din_phaseW - (ULONG) din_phaseB;
1829: jmp_dout16 = (ULONG) dout_phaseW - (ULONG) dout_phaseB;
1830: pACB_start = NULL;
1831:
1832: if ( pcibios_present() )
1833: {
1834: for (i = 0; i < MAX_ADAPTER_NUM; ++i)
1835: {
1836: if( !pcibios_find_device( PCI_VENDOR_ID_NCR,
1837: PCI_DEVICE_ID_NCR53C825A,
1838: pci_index, &pci_bus, &pci_device_fn) )
1839: {
1840: chipType = PCI_DEVICE_ID_NCR53C825A;
1841: pci_index++;
1842: }
1843: else if( !pcibios_find_device( PCI_VENDOR_ID_NCR,
1844: PCI_DEVICE_ID_NCR53C875,
1845: pci_index2, &pci_bus, &pci_device_fn) )
1846: {
1847: chipType = PCI_DEVICE_ID_NCR53C875;
1848: pci_index2++;
1849: }
1850:
1851: if( chipType )
1852: {
1853: error = pcibios_read_config_dword(pci_bus, pci_device_fn,
1854: PCI_BASE_ADDRESS_0, &io_port);
1855: error |= pcibios_read_config_dword(pci_bus, pci_device_fn,
1856: PCI_BASE_ADDRESS_2, &ram_base);
1857: error |= pcibios_read_config_byte(pci_bus, pci_device_fn,
1858: PCI_INTERRUPT_LINE, &irq);
1859: if( error )
1860: {
1861: printk("DC390W_detect: reading configuration registers error!\n");
1862: InitialTime = 0;
1863: return( 0 );
1864: }
1865:
1866: (USHORT) io_port = (USHORT) io_port & 0xFFFE;
1867: #ifdef DC390W_DEBUG0
1868: printk("DC390W : IO_PORT=%4x,RAM_BASE=%8x,IRQ=%x,CHIPID=%x,\n",
1869: (UINT) io_port, (UINT) ram_base, irq, (UCHAR)chipType);
1870: #endif
1871:
1872: if( !DC390W_init(psht, chipType, io_port, irq, i) )
1873: adaptCnt++;
1874: chipType = 0;
1875: }
1876: else
1877: break;
1878: }
1879: }
1880: InitialTime = 0;
1881: adapterCnt = adaptCnt;
1882: return( adaptCnt );
1883: }
1884:
1885: #ifndef VERSION_ELF_1_2_13
1886:
1887: /********************************************************************
1888: * Function: tmscsiw_set_info()
1889: *
1890: * Purpose: Set adapter info (!)
1891: *
1892: * Not yet implemented
1893: *
1894: *******************************************************************/
1895:
1896: int tmscsiw_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
1897: {
1898: return(-ENOSYS); /* Currently this is a no-op */
1899: }
1900:
1901: /********************************************************************
1902: * Function: tmscsiw_proc_info(char* buffer, char **start,
1903: * off_t offset, int length, int hostno, int inout)
1904: *
1905: * Purpose: return SCSI Adapter/Device Info
1906: *
1907: * Input: buffer: Pointer to a buffer where to write info
1908: * start :
1909: * offset:
1910: * hostno: Host adapter index
1911: * inout : Read (=0) or set(!=0) info
1912: *
1913: * Output: buffer: contains info
1914: * length; length of info in buffer
1915: *
1916: * return value: length
1917: *
1918: ********************************************************************/
1919:
1920: /* KG: proc_info taken from driver aha152x.c */
1921:
1922: #undef SPRINTF
1923: #define SPRINTF(args...) pos += sprintf(pos, ## args)
1924:
1925: #define YESNO(YN)\
1926: if (YN) SPRINTF(" Yes ");\
1927: else SPRINTF(" No ")
1928:
1929: int tmscsiw_proc_info(char *buffer, char **start,
1930: off_t offset, int length, int hostno, int inout)
1931: {
1932: int dev, spd, spd1;
1933: char *pos = buffer;
1934: PSH shpnt;
1935: PACB acbpnt;
1936: PDCB dcbpnt;
1937: unsigned long flags;
1938: /* Scsi_Cmnd *ptr; */
1939:
1940: acbpnt = pACB_start;
1941:
1942: while(acbpnt != (PACB)-1)
1943: {
1944: shpnt = acbpnt->pScsiHost;
1945: if (shpnt->host_no == hostno) break;
1946: acbpnt = acbpnt->pNextACB;
1947: }
1948:
1949: if (acbpnt == (PACB)-1) return(-ESRCH);
1950: if (!shpnt) return(-ESRCH);
1951:
1952: if(inout) /* Has data been written to the file ? */
1953: return(tmscsiw_set_info(buffer, length, shpnt));
1954:
1955: SPRINTF("Tekram DC390W/U/F (T) PCI SCSI Host Adadpter, ");
1956: SPRINTF("Driver Version 1.12, 1997/02/17\n");
1957:
1958: save_flags(flags);
1959: cli();
1960:
1961: SPRINTF("SCSI Host Nr %i, ", hostno);
1962: SPRINTF("DC390WUF Adapter Nr %i\n", acbpnt->AdapterIndex);
1963: SPRINTF("IOPortBase 0x%04x, ", acbpnt -> IOPortBase);
1964: SPRINTF("IRQLevel 0x%02x\n",acbpnt -> IRQLevel);
1965:
1966: SPRINTF("Adapter Type: ");
1967: switch(acbpnt->AdaptType)
1968: {
1969: case DC390W: SPRINTF("DC390W, Fast Wide SCSI \n"); break;
1970: case DC390U: SPRINTF("DC390U, Ultra SCSI\n"); break;
1971: case DC390F: SPRINTF("DC390F, Ultra Wide SCSI\n"); break;
1972: default: SPRINTF("Unknown !\n");
1973: }
1974:
1975: SPRINTF("MaxID %i, MaxLUN %i, ", acbpnt->max_id, acbpnt->max_lun);
1976: SPRINTF("AdapterID %i, AdapterLUN %i\n", acbpnt->AdaptSCSIID, acbpnt->AdaptSCSILUN);
1977:
1978: SPRINTF("TagMaxNum %i, Status %i\n", acbpnt->TagMaxNum, acbpnt->status);
1979:
1980: SPRINTF("Nr of attached devices: %i\n", acbpnt->DeviceCnt);
1981:
1982: SPRINTF("Un ID LUN Prty Sync DsCn SndS TagQ Wide NegoPeriod SyncSpeed SyncOffs\n");
1983: dcbpnt = acbpnt->pLinkDCB;
1984:
1985: for (dev = 0; dev < acbpnt->DeviceCnt; dev++)
1986: {
1987: SPRINTF("%02i %02i %02i ", dev, dcbpnt->UnitSCSIID, dcbpnt->UnitSCSILUN);
1988: YESNO(dcbpnt->DevMode & PARITY_CHK_);
1989: YESNO(dcbpnt->DCBsxfer & OFFSET_MASK);
1990: YESNO(dcbpnt->DevMode & EN_DISCONNECT_);
1991: YESNO(dcbpnt->DevMode & SEND_START_);
1992: YESNO(dcbpnt->MaxCommand > 1);
1993: YESNO(dcbpnt->DCBscntl3 & EN_WIDE_SCSI);
1994: SPRINTF(" %03i ns ", (dcbpnt->NegoPeriod) << 2);
1995: if (dcbpnt->DCBsxfer & OFFSET_MASK)
1996: {
1997: spd = 1000/(dcbpnt->SyncPeriod <<2);
1998: spd1 = 1000%(dcbpnt->SyncPeriod <<2);
1999: spd1 = (spd1 * 10)/(dcbpnt->SyncPeriod <<2);
2000: SPRINTF(" %2i.%1i M %02i\n", spd, spd1, dcbpnt->DCBsxfer & OFFSET_MASK);
2001: }
2002: else SPRINTF("\n");
2003: /* Add more info ...*/
2004: dcbpnt = dcbpnt->pNextDCB;
2005: }
2006:
2007: restore_flags(flags);
2008: *start = buffer + offset;
2009:
2010: if (pos - buffer < offset)
2011: return 0;
2012: else if (pos - buffer - offset < length)
2013: return pos - buffer - offset;
2014: else
2015: return length;
2016: }
2017: #endif /* VERSION_ELF_1_2_13 */
2018:
2019: #ifdef MODULE
2020:
2021: /***********************************************************************
2022: * Function : static int DC390W_shutdown (struct Scsi_Host *host)
2023: *
2024: * Purpose : does a clean (we hope) shutdown of the NCR SCSI chip.
2025: * Use prior to dumping core, unloading the NCR driver, etc.
2026: *
2027: * Returns : 0 on success
2028: ***********************************************************************/
2029: static int
2030: DC390W_shutdown (struct Scsi_Host *host)
2031: {
2032: USHORT ioport;
2033: unsigned long flags;
2034: PACB pACB = (PACB) host->hostdata;
2035:
2036: ioport = (unsigned int) pACB->IOPortBase;
2037:
2038: save_flags (flags);
2039: cli();
2040:
2041: /* pACB->soft_reset(host); */
2042: /*
2043: * For now, we take the simplest solution : reset the SCSI bus. Eventually,
2044: * - If a command is connected, kill it with an ABORT message
2045: * - If commands are disconnected, connect to each target/LUN and
2046: * do a ABORT, followed by a SOFT reset, followed by a hard
2047: * reset.
2048: */
2049:
2050: #ifdef DC390W_DEBUG0
2051: printk("DC390W: shutdown,");
2052: #endif
2053: outb(ASSERT_RST, ioport+SCNTL1);
2054: udelay(25); /* Minimum amount of time to assert RST */
2055: outb(0, ioport+SCNTL1);
2056: restore_flags (flags);
2057: return( 0 );
2058: }
2059:
2060:
2061: int DC390W_release(struct Scsi_Host *host)
2062: {
2063: int irq_count;
2064: struct Scsi_Host *tmp;
2065:
2066: DC390W_shutdown (host);
2067:
2068: if (host->irq != IRQ_NONE)
2069: {
2070: for (irq_count = 0, tmp = pSH_start; tmp; tmp = tmp->next)
2071: {
2072: if ( tmp->irq == host->irq )
2073: ++irq_count;
2074: }
2075: if (irq_count == 1)
2076: {
2077: #ifdef DC390W_DEBUG0
2078: printk("DC390W: Free IRQ %i.",host->irq);
2079: #endif
2080: #ifndef VERSION_ELF_1_2_13
2081: free_irq(host->irq,NULL);
2082: #else
2083: free_irq(host->irq);
2084: #endif
2085: }
2086: }
2087:
2088: release_region(host->io_port,host->n_io_port);
2089:
2090: return( 1 );
2091: }
2092:
2093: Scsi_Host_Template driver_template = DC390WUF;
2094: #include "scsi_module.c"
2095: #endif /* def MODULE */
2096:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.