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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* tc2550.c -- Tripace TC-2550x based PCI SCSI Adapter  SCSI driver
2
 * Created:D.Ravi jun 8 1998 at chennai lab of Tripace
3
 * Copyright 1998 Tripace Europe BV
4
 *
5
 * Driver version 1.00.000 (904)
6
 
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License as published by the
9
 * Free Software Foundation; either version 2, or (at your option) any
10
 * later version.
11
 
12
 * This program is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * General Public License for more details.
16
 
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 675 Mass Ave, Cambridge, MA 02139, USA.
20
 
21
 **************************************************************************
22
 
23
 DESCRIPTION:
24
 
25
 
26
 
27
 
28
 REFERENCES USED:
29
 
30
 1.0 Design Kit for the Tripace TC-2550x based PCI SCSI  Adapter
31
 
32
 2.0 Tripace IOLAYER document.
33
 
34
 3.0 LINUX driver sources in /usr/linux/drivers/scsi directory.
35
 
36
 
37
 ALPHA TESTERS:
38
 
39
 1.0 so far no external testers,only developer testing has been done.
40
 
41
 2.0 Testing with IBMHDD,Quantum HDD,zip drive and sony CDROM has been
42
 done.
43
 
44
 
45
 NOTES ON USER DEFINABLE OPTIONS:
46
 
47
 1.0 The following are the command line options that are possible for the
48
 TRIPACE TC-2550 PCI SCSI controller without BIOS.
49
 
50
 tripace=fast clock,discon,sync,tag
51
 
52
 
53
 The values for these four options can be either 0 or 1.
54
 If fast clock is set to 1 ,then the chip uses a 60mhz clock.If ultra
55
 scsi devices are used this should be set and the controller should have a
56
 60mhz crystal.
57
 
58
 if disconnect is 1 ,then disconnect/reconnect is allowed for all scsi
59
 devices connected to the controller.if it is 0 ,it is off.
60
 
61
 sync = 1 means that synchronous negotiation will be done with scsi
62
 devices.currently,though the flag is set ,the function is not implemented.
63
 
64
 Tag = 1 means that tagged queue commands can be sent to the scsi devices.
65
 This is not implemnted as yet in the driver.
66
 
67
 The default values are 0,1,1,1
68
 
69
 **************************************************************************/
70
 
71
#ifdef MODULE
72
#include <linux/module.h>
73
#endif
74
 
75
#include <linux/kernel.h>
76
#include <linux/malloc.h>
77
#include <linux/mm.h>
78
#include <linux/head.h>
79
#include <linux/sched.h>
80
#include <linux/types.h>
81
#include <asm/io.h>
82
#include <linux/blk.h>
83
#include "scsi.h"
84
#include "hosts.h"
85
#include "tripace.h"
86
#include <asm/system.h>
87
#include <asm/dma.h>
88
#include <linux/errno.h>
89
#include <linux/string.h>
90
#include <linux/ioport.h>
91
#include <linux/proc_fs.h>
92
#include <linux/bios32.h>
93
#include <linux/pci.h>
94
#include <linux/delay.h>
95
#include "tripace_mcode.h"
96
 
97
#define VERSION          "$Revision: 1.1 $"
98
 
99
/* #define DEBUG */
100
 
101
 
102
#define   MAXTARGET               8
103
#define   MAXSRBS                 16
104
 
105
#define   RISC_ENTRY1             0
106
 
107
#define   DEV_PARAM_REG_BASE      CFG_BASE+0x20
108
 
109
#define   SCSI_DMA_POINTER        CFG_BASE+0x40
110
#define   SCSI_DMA_COUNTER        CFG_BASE+0x44
111
#define   HOST_DMA_POINTER        CFG_BASE+0x48
112
#define   HOST_DMA_COUNTER        CFG_BASE+0x4c
113
#define   MBX_IN_BASE             CFG_BASE+0x50
114
#define   MBX_OUT_BASE            CFG_BASE+0x54
115
#define   DEV_HDR_BASE            CFG_BASE+0x58
116
#define   TASK_Q_BASE             CFG_BASE+0x5c
117
#define   CURRENT_DEV_PTR         CFG_BASE+0x60
118
#define   CURRENT_TASK_PTR        CFG_BASE+0x64
119
#define   SG_LIST_PTR             CFG_BASE+0x68
120
#define   ACC                     CFG_BASE+0x6c
121
#define   SCRATCHB                CFG_BASE+0x70
122
#define   CURRENT_INST            CFG_BASE+0x74
123
#define   FLAG                    CFG_BASE+0x78
124
#define   SCRATCHC                CFG_BASE+0x7a
125
#define   MBX_IN_INDEX            CFG_BASE+0x7b
126
#define   PC                      CFG_BASE+0x7c
127
#define   MBX_OUT_INDEX           CFG_BASE+0x7f
128
#define   PROGRAM_DATA_REG        CFG_BASE+0x80
129
#define   CONTROL_REG             CFG_BASE+0x84
130
#define   STATUS_INT_REG          CFG_BASE+0x86
131
#define   SCSI_DATA               CFG_BASE+0x88
132
#define   SCSI_CONTROL            CFG_BASE+0x8A
133
#define   SCSI_ID_REG             CFG_BASE+0x8b
134
 
135
#define   INFO_BASE               0x780
136
#define   SIG_BASE                0x7D4
137
 
138
#define   Q_FILE_SIZE             8192
139
#define   DEVHDR_SIZE              512
140
#define   MBOX_SIZE                 48
141
#define   BIOS_SIGNATURE          0x55AAC731
142
 
143
#define   PCI_1                   1
144
#define   PCI_2                   2
145
#define   MAX                     28
146
 
147
#define   PCI_BUS                 1
148
#define   PCI_INDEX_PORT          0xCF8
149
#define   PCI_INDEX               0xF0
150
#define   PCI_CONFIG              0xC000  /* this needs to include slot number */
151
 
152
#define   FAIL                   -1
153
/* #define   GOOD                 0 */
154
#define   ERR                     1
155
#define   DONE                    2
156
#define   INT_HALT             0xfe000000       /* interrupt code */
157
 
158
#define   SRB_DONE                0
159
#define   SRB_ACTIVE              2
160
#define   SRB_READY               1
161
#define   SRB_CLEAN               4
162
#define   SRB_ASSIGNED            8
163
#define   SRB_STOP                2
164
 
165
#define   STOP_RISC               2
166
#define   FIRST_CMD               1
167
#define   SPECIAL_CMD             1
168
#define   MAX_OFFSET             30
169
/* #define   MAX_PERIOD             12 */
170
#define   MAX_PERIOD             12
171
#define   W_MAX_OFFSET           14
172
 
173
/* msg */
174
#define   CMD_ABORT              0x6
175
#define   DEVICE_RESET           0xC
176
 
177
 
178
#define   CHECK_SYNC             0xA
179
#define   CHECK_WIDE             0xD
180
#define   SYNC_NORESPONSE        0x8
181
#define   SYNC_REJECTED          0x9
182
#define   SEL_TIME_OUT           0x11
183
#define   ERR_OVERRUN            0x12
184
#define   ERR_BUSFREE            0x13
185
#define   ERR_PHASE              0x14
186
#define   CHECK_COND             0x04
187
#define   ERR_PARITY             0x05
188
#define   ERR_MESSAGE            0x07
189
#define   WIDE_NORESPONSE        0x0b
190
#define   WIDE_REJECTED          0x0c
191
 
192
 
193
#define   DO_WIDE_NEGO           0x02
194
#define   DO_SYNC_NEGO           0x04
195
#define   FIRST_COMMAND          0x01
196
 
197
#define   ENABLE_WIDE_BUS        0x100
198
#define   ENABLE_TAG_MSG         0x200
199
 
200
/*---------------------------------------------------------*
201
**  parameter in register definitions                      *
202
**                                                         *
203
**---------------------------------------------------------*/
204
/*
205
   status register (read only)
206
 */
207
#define      INTR_PENDING         0x01
208
#define      INTR_DIS             0x02
209
#define      SCAM_INTR_DIS        0x04
210
#define      POWER_SAVE_ON        0x08
211
#define      SCSI_RESET_OUT       0x10
212
#define      SCAM_INTR            0x20
213
#define      RISC_HALT            0x40
214
#define      SELECTION_TIMEOUT    0x80
215
#define      SCSI_PARITY_ERR      0x100
216
#define      SCSI_RESET_LAT       0x200
217
#define      STS_SCSI_RESET       0x400
218
#define      EEPROM_IN            0x800
219
#define      SCAM_ARB_WIN         0x1000
220
#define      EN_DMA               0x2000
221
#define      EN_ARB_SEL           0x4000
222
/*
223
   **   interrupt control register (write only)
224
 */
225
#define      RESET_INTR_LATCH     0x01
226
#define      DIS_INTR             0x02
227
#define      DIS_SCAM_INTR        0x04
228
#define      POWER_SAVE           0x08
229
#define      RESET_SCSI_BUS       0x10
230
/*ravi 10/3/98 changed for term power disable/enable in command line */
231
/*#define      EN_TERM_PWR          0x20 */
232
#define      TERM_PWR_EN            0x20
233
/*
234
   **   control register ( read/write )
235
 */
236
#define      RISC_CHIP_RESET      0x01
237
#define      RISC_SINGLE_SETP     0x02
238
#define      HALT_RISC            0x04
239
#define      EN_SCSI_SCAM         0x08
240
#define      DIS_SCSI_PARITY      0x10
241
#define      EN_TARGET_MODE       0x20
242
#define      FAST_CLOCK           0x40
243
#define      EN_MEMORY_WRITE      0x80
244
#define      DIS_PCI_BURST        0x100
245
#define      DIS_PCI_CACHE_LINE   0x200
246
#define      DIS_MUL_CACHE_LINE   0x400
247
#define      EEPROM_CLOCK         0x800
248
#define      EEPROM_DATA_OUT      0x1000
249
#define      EEPROM_CHIP_SEL      0x2000
250
#define      FAST_SELECTION       0x4000
251
#define      EN_SCAM_ARB          0x8000
252
 
253
#define      TASK_DONE            0x80
254
 
255
 
256
/***************************************************************************
257
**       filename: newtypes.h
258
**       usage   : type definition
259
****************************************************************************/
260
 
261
 
262
/***************************************************************************
263
**       filename: newtypes.h
264
**       usage   : type definition
265
****************************************************************************/
266
 
267
#define   MAX_Adapter   4       /* maximu adapters allow                */
268
 
269
/*
270
   **   command related structure (7 bytes)
271
 */
272
typedef struct _task_cmd
273
{
274
        u8 CmdInProcess;
275
        u8 * REQ_Header;
276
        void (*complete) (void);
277
}
278
TaskCmd, *PTaskCmd;
279
 
280
/*
281
   ** total 128 bytes
282
 */
283
typedef struct _HIM
284
{
285
        u8 status;              /* device status, 0xFF not installed    */
286
        u8 Target_ID;           /* target ID                            */
287
        u8 type;                /* target type mapped to device name    */
288
        u16 attrib;             /* lo 4bit: 1-Wide, 2-Sync, 4-Tag,      */
289
        /*          8-removable,                */
290
        /* hi 4bit: 10h do wide, 20h do sync,   */
291
        /*          40h do tag, 0x80h - disc    */
292
        /* bit 15: under BIOS, bit 8: > 1GB     */
293
         u8 op_param;           /* bit 7-5:period, bit4-0:offset        */
294
        u8 drv_num;             /* current ID --> 8x for BIOS used only */
295
        u8 sect_per_track;      /* sector per track                     */
296
        u8 head_per_cyl;        /* sector per track                     */
297
        u8 byte_per_sect;       /* byte per sector (BIOS is 512)        */
298
        u8 link_count;  /* SRB link count:                      */
299
        u8 * ASPICMDLink;       /* SRB link starting pointer            */
300
        TaskCmd task[16];       /* array structure for each task        */
301
 
302
}
303
DEVStruct;
304
 
305
/*
306
   ** total (4K+ 36) bytes for each adapter
307
 */
308
typedef struct _Adapter
309
{
310
        u16 IoPort;             /* I/O Port address, 0 notsupport       */
311
        u8 AdapterID;           /* Adapter scsi ID, default = 7         */
312
        u8 first_disk_num;      /* first disk number under BIOS (82->2) */
313
        u8 last_disk_num;       /* last disk number under BIOS          */
314
        u8 time_factor; /* used for device scam                 */
315
 
316
        u8 IntrNum;             /* -1 NotSupport, otherwise IRQ         */
317
        u16 hw_attr;            /* see eeprom def                       */
318
        u16 sw_attr;            /* see eeprom def                       */
319
        DEVStruct dev[16];      /* target device structure              */
320
        u16 mbx_out_ptr;        /* mail box out pointer                 */
321
        u8 HAParam[16]; /* host adapter parameters              */
322
        u8 bios_install;        /* adapter has BIOS installed           */
323
        u16 scam_type;          /* scam use              */
324
        u8 scam_assigned;       /* scam use              */
325
        u8 * Signature; /* BIOS signature & new manager address */
326
        u32 mbx_in_base;        /* mbx in base  logical address    */
327
        u32 mbx_out_base;       /* mbx out base logical address    */
328
        u32 devhdr_base;        /* devhdr base logical address     */
329
        u32 taskq_base; /* taskq base  logical address     */
330
        u32 ptaskq_base;        /* taskq base physical address     */
331
        u32 pdev_base;          /* taskq base physical address     */
332
        u32 pmbi_base;          /* taskq base physical address     */
333
        u32 pmbo_base;          /* taskq base physical address     */
334
}
335
Adapter, *PAdapter;
336
 
337
/*
338
   **  adapter information structure reserved for BIOS usage
339
 */
340
 
341
typedef struct _dev_parm
342
{
343
        u8 header;              /* header             */
344
        u8 sect_per_track;      /* sector per tarck   */
345
}
346
target_parm, *ptarget_parm;
347
/*
348
   **  This structure is for BIOS used and read by driver
349
 */
350
typedef struct _Ada_data
351
{
352
        u8 drv_start;           /* first drive           */
353
        u8 drv_end;             /* last drive            */
354
        u16 timfact;            /* timing factor         */
355
        u32 old_int13;          /* old int13 addr        */
356
        u8 drive_id[8]; /* index= (8x-drv_start) */
357
        u8 drive_num[16];       /* device number         */
358
        target_parm dev[16];    /* device parameters     */
359
        u8 allow_discon[16];    /* disconnect record     */
360
        u16 scam_type;          /* scam use              */
361
        u8 scam_assigned;       /* scam use              */
362
        u8 adapter_id;  /* scam use              */
363
        u32 signature;          /* BIOS signature        */
364
}
365
HA_data, *PHA_data;
366
 
367
 
368
typedef struct _ScatGath
369
{
370
        u32 sg_address; /* must be physical address */
371
        u32 sg_length;          /* sg length     */
372
}
373
ScatGath, *PScatGath;
374
 
375
/* length must be 32 bytes */
376
typedef struct _risc_srb
377
{
378
        u8 Tag_info;            /* Tag information */
379
        u8 SRB_flag;            /* SRB flag */
380
        u8 DEV_Status;  /* SRB status */
381
        u8 ScsiStatus;  /* scsi command status */
382
        u32 CDB;                /* SCSI Command Block */
383
        u32 CDBLength;          /* SCSI Command Length */
384
        u32 SenseDataPtr;       /* auto sense pointer */
385
        u32 Sense_Cmd_Ptr;      /* auto sense pointer */
386
        u32 SG_ListPtr; /* SG list  */
387
        u8 SGNum;               /* S/G number */
388
        u8 Identify;            /* Identify  message */
389
        u8 Sense_LUN;           /* lun               */
390
        u8 Sense_len;           /* sense len         */
391
        u32 Cmd_sg_addr;        /* cmr sg ptr point to cmd */
392
}
393
RISC_SRB, *PRISC_SRB;
394
 
395
 
396
typedef struct _SRB
397
{                               /* for SCSI */
398
        RISC_SRB *risc_srb;     /* structure of SRB in RISC */
399
        PAdapter AdapterPtr;    /* a pointer to adapter structure */
400
        u8 LUN;         /* lun number */
401
        u8 Tag_type;            /* tag type */
402
        u8 Request_type;        /* request type */
403
}
404
SRB, *PSRB;
405
 
406
typedef struct _sync_tbl
407
{
408
        int period;             /* parameter setting  */
409
        int f_factor;           /* fast clock factor  */
410
        int s_factor;           /* slow clock factor  */
411
}
412
sync_tbl;
413
 
414
/*
415
   **  total 12 bytes of sg header
416
 */
417
typedef struct _dma_hrd
418
{
419
        u32 size;               /* region size        */
420
        u32 offset;             /* offste             */
421
        u16 segment;            /* segment            */
422
        u16 revsed;             /* reserved           */
423
        u16 num_avail;          /* number available   */
424
        u16 num_used;           /* number used        */
425
}
426
DMA_HDR;
427
 
428
/*
429
   **  total 60 bytes (for each task in windows)
430
 */
431
typedef struct _dma_desc
432
{
433
        DMA_HDR dma_hdr;
434
        ScatGath sg_list[6];
435
}
436
dma_desc, *Pdma_desc;
437
 
438
/* Flags */
439
#define SRB_TOHOST    8
440
#define SRB_TOTARGET  0x10
441
#define SRB_NEEDSDT   0x20
442
#define SRB_SENSE     0x40      /* only for OSD      */
443
#define SIZE_OF_SG    0x3C      /* size of sg table (60 bytes)  */
444
 
445
/* 2. Target Error == SCSI Status */
446
 
447
/* ============ function definiton ============
448
   ** 1. INPUT:  PSRB
449
   **    Start a scsi command.
450
   * */
451
static void StartScsiCmd(PRISC_SRB);
452
 
453
#define  CMD_INPROGRESS      0x01
454
#define  CMD_DISCONCTED      0x02
455
#define  CMD_DATAXFERED      0x04
456
 
457
#define  TAR_TRUESG          0x01
458
#define  NEEDSDTN            0x10
459
 
460
#define  MSG_ABORT           0x06
461
#define  MSG_RESET           0x0C
462
#define  MSG_ALLOWDISC       0x40
463
#define  MSG_IDENTIFY        0x80
464
#define  MSG_EXTENDED        0x01
465
#define  MSG_NOMSG           0x08
466
#define  MSG_CMDCOMP         0x00
467
#define  MSG_DISC            0x04
468
#define  MSG_IGNWR           0x23
469
#define  MSG_RESTPTR         0x03
470
#define  MSG_SAVEPTR         0x02
471
#define  MSG_REJECTED        0x07
472
#define  MSG_INITRECVY       0x0f
473
#define  MSG_LNKCMD          0x0a
474
#define  MSG_LNKCMDTAG       0x0b
475
#define  MSG_SIMPLEQUE       0x20
476
#define  MSG_MDFDATPTR       0x00
477
#define  MSG_SDTREQ          0x01
478
#define  MSG_WDTREQ          0x03
479
 
480
#define  SECOND              18 //ticks per second
481
#define  DEV_EMPTY           0xFF
482
 
483
typedef struct _DEVHDR
484
{
485
        u32 Updatedmap; /* updated bitmap      */
486
        u32 Startedmap; /* start bitmap        */
487
        u32 Currentmap; /* current bitmap      */
488
        u8 Task_Index;  /* current task index  */
489
        u8 Request_type;        /* request type        */
490
        u8 SpCmddone;           /* special commad done */
491
        u8 Srb_loc;             /* location            */
492
        u8 TagCmdCnt;           /* Pending task count  */
493
        u8 ScsiID;              /* scsi ID             */
494
        u8 DeviceNum;           /* device number       */
495
        u8 WideMsg;             /* wide bus message    */
496
        u8 SyncPeriod;  /* sync period         */
497
        u8 SyncOffset;  /* sync offset         */
498
        u8 RtnWideMsg;  /* return wide bus msg */
499
        u8 RtnSyncPeriod;       /* Rtn sync period     */
500
        u8 RtnSyncOffset;       /* rtn sync offset     */
501
        u8 ChkSenseTask;        /* check sense task    */
502
        u8 SenseCmd[6]; /* sense command       */
503
}
504
DevHdr, *PDevHdr;
505
 
506
typedef struct _E2Prom
507
{
508
        u16 hw_parm;
509
        u16 sw_parm;
510
        u16 dev_parm[16];
511
}
512
E2prom, *PE2prom;
513
 
514
/* parameter setting for parameter */
515
#define         HW_ADAPTER_ID            0x0f
516
#define         HW_PARITY_DISABLE        0x10
517
#define         HW_TERMPWR_ENABLE        0x20
518
#define         HW_FAST_CLOCK            0x40
519
#define         HW_DIAG_ENABLE           0x80
520
#define         HW_BURST_DISABLE         0x100
521
#define         HW_CACHE_LINE_DISABLE    0x200
522
#define         HW_MULTI_CACHE_DISABLE   0x400
523
#define         HW_SCAM_ENABLE           0x800
524
#define         HW_CACHE_LINE_SIZE_4      0x1000
525
#define         HW_CACHE_LINE_SIZE_8      0x2000
526
#define         HW_CACHE_LINE_SIZE_16     0x3000
527
#define         HW_FAST_SELECTION        0x4000
528
#define         HW_BIOS_DISABLE          0x8000
529
 
530
 
531
/* software setting      */
532
#define         SW_REMOVABLE_SUPPORT     0x1
533
#define         SW_OVER_1GB              0x2
534
#define         SW_8_DRIVE_SUPPORT       0x4
535
#define         SW_MAX_ID                0x8
536
#define         SW_DEVICE_CHANGED        0x10
537
 
538
/* parameter setting     */
539
#define         PM_UNDER_BIOS            0x8000
540
#define         PM_BIOSSCAN_DISABLE      0x2000
541
#define         PM_NEED_STARTCMD         0x1000
542
#define         PM_DISCON_ENABLE         0x800
543
#define         PM_SYNC_ENABLE           0x400
544
#define         PM_TAG_ENABLE            0x200
545
#define         PM_WIDEBUS_ENABLE        0x100
546
#define         PM_TRANSFER_RATE         0xE0
547
#define         PM_TRANSFER_OFFSET       0x1F
548
 
549
/* ScsiFunc  */
550
#define         SUPPORT_MORETHAN16M  0x40
551
#define         SUPPORT_RESELECT     0x20
552
#define         SUPPORT_SYNC         0x10
553
#define         SUPPORT_LINKED       0x08
554
#define         SUPPORT_CMDQUEUE     0x02
555
#define         SUPPORT_SFTRE        0x01
556
#define         SUPPORT_WIDEHOST     0x04
557
#define         SUPPORT_PARCHK       0x80
558
 
559
 
560
static unsigned int port_base = 0;
561
static unsigned int CFG_BASE = 0;
562
static unsigned int interrupt_level = 0;
563
 
564
/* period table
565
 
566
   static sync_tbl  period_tbl[8]= {
567
   { 0, 12, 12,},
568
   { 1, 16, 18,},
569
   { 2, 20, 25,},
570
   { 3, 25, 31,},
571
   { 4, 29, 37,},
572
   { 5, 33, 43,},
573
   { 6, 50, 50,},
574
   { 7, 58, 75,},
575
   };
576
 */
577
 
578
/* pointer to scsi host struc for each HA */
579
/* needs change for multiple HA support */
580
 
581
static struct Scsi_Host *tripace_host;
582
 
583
/* Tc2550 mailbox data structures */
584
static unsigned char tcmbdata[Q_FILE_SIZE + DEVHDR_SIZE + MBOX_SIZE + 64];
585
/* static alloc of sg table for all tasks */
586
/* dynamic memory is giving problems */
587
static unsigned char table[8 * MAXSGENT * MAXSRBS * MAXTARGET + 4];
588
 
589
 
590
/* global variables */
591
/* logical addresses of mailbox in/out,dev header base,task que base */
592
 
593
static unsigned char *startsgptr;
594
static unsigned long pstartsgptr;
595
 
596
 
597
static u32 mbx_in_base, mbx_out_base, devhdr_base, taskq_base;
598
static u8 TargetID;
599
 
600
 
601
/* hostadapter structure-as of now we have a single adapter */
602
Adapter HostAdapter[1];
603
unsigned char ReqType, targetID, HANumber, Index, HostID;
604
 
605
/* variable for term power in case of /T option */
606
static unsigned short int EN_TERM_PWR = TERM_PWR_EN;
607
static unsigned short fast_clk = 0;
608
static unsigned short par_off = 0;
609
static unsigned short discon = 1;
610
static unsigned short syncflag = 1;
611
static unsigned short tagflag = 0;
612
 
613
 
614
static int makecode(unsigned, unsigned);
615
static void Init_struc(int);
616
static int download_RISC_code(void);
617
static void init_chip_reg(void);
618
 
619
static PRISC_SRB search(PAdapter);
620
u32 insert_bit(u32, short int);
621
static void Get_Base(Adapter *);
622
 
623
void tc2550_intr(int, void *, struct pt_regs *);
624
 
625
static void internal_done(Scsi_Cmnd *);
626
 
627
int tc2550_command(Scsi_Cmnd *);
628
 
629
static int tc2550_pci_bios_detect(int *irq, int *iobase)
630
{
631
        int error;
632
        unsigned char pci_bus, pci_dev_fn;      /* PCI bus & device function */
633
        unsigned char pci_irq;  /* PCI interrupt line */
634
        unsigned int pci_base;  /* PCI I/O base address */
635
        unsigned short pci_vendor, pci_device;  /* PCI vendor & device IDs */
636
 
637
 
638
        /* We will have to change this if more than 1 PCI bus is present and the
639
           tripace scsi host is not on the first bus (i.e., a PCI to PCI bridge,
640
           which is not supported by bios32 right now anyway). */
641
 
642
        pci_bus = 0;
643
 
644
        for (pci_dev_fn = 0x0; pci_dev_fn < 0xff; pci_dev_fn++)
645
        {
646
                pcibios_read_config_word(pci_bus,
647
                                         pci_dev_fn,
648
                                         PCI_VENDOR_ID,
649
                                         &pci_vendor);
650
 
651
                if (pci_vendor == 0x1190)
652
                {
653
                        pcibios_read_config_word(pci_bus,
654
                                                 pci_dev_fn,
655
                                                 PCI_DEVICE_ID,
656
                                                 &pci_device);
657
 
658
                        if (pci_device == 0xc731)
659
                        {
660
                                /* Break out once we have the correct device.  If othertrip
661
                                   PCI devices are added to this driver we will need to add
662
                                   an or of the other PCI_DEVICE_ID here. */
663
                                printk(KERN_INFO "Tripace TC-2550x based PCI SCSI Adapter detected\n");
664
                                break;
665
                        } else
666
                        {
667
                                /* If we can't finl an tripace scsi card we give up. */
668
                                return 0;
669
                        }
670
                }
671
        }
672
 
673
/* vendor id not found */
674
 
675
        if (pci_device != 0xc731)
676
        {
677
                printk(KERN_INFO "Tripace TC-2550x - No Host Adapter Detected \n");
678
                return (0);
679
        }
680
        /* We now have the appropriate device function for the tripace board so we
681
           just read the PCI config info from the registers.  */
682
 
683
        if ((error = pcibios_read_config_dword(pci_bus,
684
                                               pci_dev_fn,
685
                                               PCI_BASE_ADDRESS_0,
686
                                               &pci_base))
687
            || (error = pcibios_read_config_byte(pci_bus,
688
                                                 pci_dev_fn,
689
                                                 PCI_INTERRUPT_LINE,
690
                                                 &pci_irq)))
691
        {
692
                printk(KERN_ERR "Tripace TC-2550x not initializing"
693
                       " due to error reading configuration space\n");
694
                return 0;
695
        } else
696
        {
697
                printk(KERN_INFO "TC-2550x PCI: IRQ = %u, I/O base = %X\n",
698
                       pci_irq, pci_base);
699
 
700
                /* Now we have the I/O base address and interrupt from the PCI
701
                   configuration registers.
702
                 */
703
 
704
                *irq = pci_irq;
705
                *iobase = (pci_base & 0xfff8);
706
                CFG_BASE = *iobase;
707
 
708
                printk(KERN_INFO "TC-2550x Driver version 1.00.000 (904)\n");
709
                printk(KERN_INFO "TC-2550x: IRQ = %d, I/O base = 0x%X\n", *irq, *iobase);
710
                return 1;
711
        }
712
        return 0;
713
}
714
 
715
static void init_chip_reg(void)
716
{
717
        int i, val, base;
718
        unsigned long tick;
719
 
720
        outw(HALT_RISC, CONTROL_REG);
721
        base = CFG_BASE + 0x20;
722
        for (i = 0; i < 16; i++)
723
                outw(0, base + i * 2);
724
        outw(EN_TERM_PWR, STATUS_INT_REG);
725
        outw(RESET_SCSI_BUS, STATUS_INT_REG);
726
 
727
        udelay(50);             /*wait for 50 micro secs */
728
 
729
        outw(EN_TERM_PWR, STATUS_INT_REG);
730
        val = (HALT_RISC | RISC_CHIP_RESET);
731
        outw(val, CONTROL_REG);
732
        outw(HALT_RISC, CONTROL_REG);
733
        val = inw(STATUS_INT_REG);
734
        tick = 0;
735
        while ((val & 0x40) == 0 && tick < 0x3fff)
736
        {
737
                val = inw(STATUS_INT_REG);
738
                tick += 1;
739
        };
740
        if (tick == 0x3fff)
741
                printk(KERN_DEBUG "val= %x  \n\r", val);
742
        outw(EN_TERM_PWR, STATUS_INT_REG);
743
        outw(0, SCSI_CONTROL);
744
 
745
/* delay for 50 micro secs */
746
        udelay(50);
747
}
748
 
749
static int download_RISC_code(void)
750
{
751
        unsigned short i, j, fast = 0;
752
        unsigned short hi, low, base;
753
        long tmp;
754
        unsigned long start_time;
755
 
756
        i = inw(CONTROL_REG);
757
        if (i & 0x40)
758
                fast = 1;
759
        outw(HALT_RISC, CONTROL_REG);
760
 
761
/* Ravi modified for sanity check dec 17 1998 */
762
        start_time = jiffies;
763
 
764
        do
765
        {
766
                if ((jiffies - start_time) > 5 * HZ)
767
                {
768
                        printk(KERN_ERR "tc2550: Download failure.\n");
769
                        return 1;
770
                }
771
                i = inw(STATUS_INT_REG);
772
        }
773
        while ((i & 0x40) == 0);
774
 
775
        outw(HALT_RISC + EN_MEMORY_WRITE, CONTROL_REG);
776
        outw(EN_TERM_PWR + DIS_INTR, STATUS_INT_REG);
777
 
778
        /*  download load RISC code
779
         */
780
        outw(0, PC);
781
        for (i = 0; i < ucode_size; i++)
782
                outl(ucode_instruction[i], CURRENT_INST);
783
        /*
784
           //  checksum checking (word)
785
         */
786
        base = 0;
787
        for (i = 0; i < ucode_size; i++)
788
        {
789
                outw(i * 4, PC);
790
                tmp = inl(PROGRAM_DATA_REG);
791
                hi = tmp >> 16;
792
                low = (tmp & 0xffff);
793
                base = base + (hi + low);
794
        }
795
        outw(HALT_RISC + RISC_CHIP_RESET, CONTROL_REG);
796
        outw(HALT_RISC, CONTROL_REG);
797
        if (fast_clk)
798
                outw((HALT_RISC | FAST_CLOCK), CONTROL_REG);
799
        if (par_off)
800
        {
801
                i = inw(CONTROL_REG);
802
                outw((i | DIS_SCSI_PARITY), CONTROL_REG);
803
        }
804
        outw(EN_TERM_PWR, STATUS_INT_REG);
805
        /*ravi
806
         */
807
        if ((unsigned short) (ucode_checksum + base) != 0)
808
        {
809
                printk(KERN_ERR "tc2550: Checksum Error During Code Download\n");
810
                return (1);
811
        };
812
        /*
813
           load vector table
814
         */
815
        j = 0;
816
        base = CFG_BASE;
817
        for (i = 0, j = 0; i < 15; i++, j = j + 2)
818
                outw(ucode_vector[i], (base + j));
819
        outw(0, SCSI_CONTROL);
820
        return (0);
821
}
822
 
823
int tc2550_detect(Scsi_Host_Template * tpnt)
824
{
825
        int flag = 0;
826
        int retcode;
827
        struct Scsi_Host *shpnt;
828
        unsigned long flags;
829
        unsigned int mod4;
830
 
831
 
832
        flag = tc2550_pci_bios_detect(&interrupt_level, &port_base);
833
        if (!flag)
834
                return (0);
835
 
836
        init_chip_reg();        /* chip Tc-2550 initialize */
837
        flag = download_RISC_code();
838
        if (flag == 0)
839
        {
840
                printk(KERN_INFO "tc2550: Successful F/W download on TC-2550x\n");
841
        }
842
/* now do a scsi register and get scsi host ptr */
843
 
844
        shpnt = scsi_register(tpnt, 0);
845
 
846
        save_flags(flags);
847
        cli();
848
        retcode = request_irq(interrupt_level,
849
                              tc2550_intr, SA_INTERRUPT, "tripace", NULL);
850
        if (retcode)
851
        {
852
                printk(KERN_ERR "tc2550: Unable to allocate IRQ for Tripace TC-2550x based SCSI Host Adapter.\n");
853
                goto unregister;
854
        }
855
        /* For multiple HA we need to change all this */
856
 
857
 
858
        tripace_host = shpnt;
859
        shpnt->io_port = CFG_BASE;
860
        shpnt->n_io_port = 0xfc;        /* Number of bytes of I/O space used */
861
        shpnt->dma_channel = 0;
862
        shpnt->irq = interrupt_level;
863
 
864
        restore_flags(flags);
865
 
866
 
867
        /* log i/o ports with the kernel */
868
        request_region(port_base, 0xfc, "tripace");
869
 
870
/* when we support multiple HA ,we need to modify */
871
        Init_struc(0);           /* init mailboxes for one adapter */
872
/* sg table init */
873
 
874
        /*  get physical address */
875
        startsgptr = (unsigned char *) table;
876
        pstartsgptr = virt_to_phys((unsigned char *) table);
877
        mod4 = pstartsgptr % 4;
878
        if (mod4)
879
        {
880
                pstartsgptr += (4 - mod4);
881
                startsgptr += (4 - mod4);
882
        }
883
        return (0);
884
 
885
 
886
unregister:
887
        scsi_unregister(shpnt);
888
        return (0);
889
}
890
 
891
/****************************************************************************
892
**   Init chip registers and allocate required memory space
893
****************************************************************************/
894
 
895
static void Init_struc(int id)
896
{
897
        u32 pmbx_in_base, pmbx_out_base, pdevhdr_base, ptaskq_base;
898
        unsigned long paddr;
899
        char *laddr;
900
        unsigned short modulo;
901
 
902
/* setup ioport address and irq */
903
 
904
        HostAdapter[id].IoPort = (u16) CFG_BASE;
905
        HostAdapter[id].IntrNum = (u8) interrupt_level;
906
 
907
        laddr = tcmbdata;
908
        paddr = virt_to_phys(tcmbdata);
909
/* adjust phys address to 32 byte boundary */
910
        modulo = paddr % 32;
911
        if (modulo)
912
        {
913
                paddr = paddr + 32 - modulo;
914
                laddr = laddr + 32 - modulo;
915
        }
916
        /*  logical address  */
917
        mbx_in_base = (u32) laddr;
918
        pmbx_in_base = paddr;
919
        HostAdapter[id].mbx_in_base = mbx_in_base;
920
 
921
        laddr += 32;
922
        paddr += 32;
923
        mbx_out_base = (u32) laddr;
924
        pmbx_out_base = paddr;
925
        HostAdapter[id].mbx_out_base = mbx_out_base;
926
        memset((char *) mbx_in_base, 0, 48);
927
 
928
        laddr += 32;
929
        paddr += 32;
930
        devhdr_base = (u32) laddr;
931
        pdevhdr_base = paddr;
932
        HostAdapter[id].devhdr_base = devhdr_base;
933
        memset((char *) devhdr_base, 0, 512);
934
 
935
 
936
        laddr += 512;
937
        paddr += 512;
938
 
939
        taskq_base = (u32) laddr;
940
        ptaskq_base = paddr;
941
        HostAdapter[id].taskq_base = taskq_base;
942
        memset((char *) taskq_base, 0, Q_FILE_SIZE);
943
 
944
        HostAdapter[id].ptaskq_base = (u32) ptaskq_base;
945
        HostAdapter[id].pdev_base = (u32) pdevhdr_base;
946
        HostAdapter[id].pmbi_base = (u32) pmbx_in_base;
947
        HostAdapter[id].pmbo_base = (u32) pmbx_out_base;
948
 
949
        outl(pmbx_in_base, MBX_IN_BASE);
950
        outl(pmbx_out_base, MBX_OUT_BASE);
951
        outl(pdevhdr_base, DEV_HDR_BASE);
952
        outl(ptaskq_base, TASK_Q_BASE);
953
        outb(0, MBX_IN_INDEX);
954
        outb(0, MBX_OUT_INDEX);
955
        /* clear mailbox out pointer */
956
        HostAdapter[id].mbx_out_ptr = 0;
957
}
958
 
959
 
960
/***************************************************************************
961
**   adjust bitmap position
962
**   Input : old bitmap,  new bit location
963
**   Output: return with new  bitmap layout
964
****************************************************************************/
965
 
966
extern __inline__ u32 insert_bit(u32 bits, short int loc)
967
{
968
        u32 lo = 0;
969
 
970
        lo = 1;
971
        lo <<= loc;
972
 
973
 
974
        return ((lo | bits));
975
}
976
 
977
 
978
/***************************************************************************
979
**   Get the base address and structures of current host adapter
980
**   Input  : adapter structure pointer
981
**   Output : none
982
****************************************************************************/
983
 
984
static void Get_Base(Adapter * padapter)
985
{
986
 
987
        CFG_BASE = padapter->IoPort;
988
        interrupt_level = (u16) padapter->IntrNum;
989
        mbx_in_base = padapter->mbx_in_base;
990
        mbx_out_base = padapter->mbx_out_base;
991
        devhdr_base = padapter->devhdr_base;
992
        taskq_base = padapter->taskq_base;
993
 
994
}
995
 
996
 
997
 
998
/***************************************************************************
999
**  name   : search()
1000
**  Desc   : search an available SRB from taskQ
1001
**  Input  : adapter structure pointer
1002
**  Output : 1. a risc structure space pointer or 0 for non available
1003
**           2. index of task location
1004
****************************************************************************/
1005
static PRISC_SRB search(PAdapter pa)
1006
{
1007
        PRISC_SRB rsrb;
1008
        short int i;
1009
        unsigned long flags;
1010
 
1011
        Get_Base(pa);
1012
        rsrb = (PRISC_SRB) (taskq_base + TargetID * 16 * sizeof(RISC_SRB));
1013
        /* check attrib in case drive doesn't support SYNC xfer */
1014
 
1015
        if ((pa->dev[TargetID].attrib & DO_SYNC_NEGO) == 0)
1016
                ReqType = 0;
1017
        save_flags(flags);
1018
        cli();
1019
 
1020
        Index = 0;
1021
        for (i = 0; i < 16; i++, rsrb++)
1022
                if (rsrb->SRB_flag == SRB_DONE)
1023
                        break;
1024
        if (i == 16)
1025
        {
1026
                restore_flags(flags);
1027
                return (0);
1028
        }
1029
        Index = i;
1030
        restore_flags(flags);
1031
        memset((char *) rsrb, 0, 32);
1032
        rsrb->SRB_flag = SRB_ASSIGNED;  /* mark for use */
1033
        if ((pa->dev[TargetID].attrib & 0x44) == 0x44)
1034
                rsrb->Tag_info = 0x20;
1035
        return (rsrb);
1036
}
1037
 
1038
/***************************************************************************
1039
**  Name   : StartSCSICmd()
1040
**  func   : 1. all commands passed through here are regular
1041
**           2. fill in device structure bitmap && start RISC
1042
**  Input  : risc srb structure, Index, ReqType
1043
**  Output : none
1044
****************************************************************************/
1045
static void StartScsiCmd(PRISC_SRB rsrb)
1046
{
1047
        DevHdr *dev;
1048
        u16 status;
1049
        PAdapter pa;
1050
        unsigned short val;
1051
        u8 t, find_id, find_last, ch = 0;
1052
        char *mptr;
1053
/* Request sense CDB */
1054
        char RequestSense[6] =
1055
        {0x03, 0x00, 0x00, 0x00, 0x0e, 0};
1056
 
1057
        pa = (PAdapter) & HostAdapter[HANumber];
1058
        pa->dev[TargetID].task[Index].CmdInProcess = 1;         /* command in process */
1059
        dev = (DevHdr *) (devhdr_base + TargetID * sizeof(DevHdr));
1060
        dev->Srb_loc = Index;
1061
        dev->Request_type = ReqType;    /* set request type */
1062
        dev->Updatedmap = insert_bit(dev->Updatedmap, Index);
1063
        for (val = 0; val < 6; val++)
1064
                dev->SenseCmd[val] = RequestSense[val];
1065
        rsrb->Sense_Cmd_Ptr = virt_to_phys(&dev->SenseCmd[0]);
1066
 
1067
        if (ReqType >= 2)
1068
        {
1069
                if (ReqType & 0x2)
1070
                        dev->WideMsg = 0x1;
1071
                else
1072
                {
1073
/*        printf("firing sync nego");
1074
   //ravi 10/3/98 -ultra support in parse
1075
 
1076
   if(fast_clk)
1077
   dev->SyncPeriod =   period_tbl[(ultra[TargetID])].f_factor;
1078
   else
1079
   dev->SyncPeriod =   period_tbl[(ultra[TargetID])].s_factor;
1080
 */
1081
 
1082
                        if (pa->dev[TargetID].attrib & 0x1)
1083
                                dev->SyncOffset = W_MAX_OFFSET;
1084
                        else
1085
                                dev->SyncOffset = MAX_OFFSET;
1086
                }
1087
        }
1088
        mptr = (char *) mbx_in_base;
1089
        find_id = 0xff;
1090
        find_last = 0xff;
1091
        for (t = 0; t < 15; t++)
1092
        {
1093
                ch = *mptr++;
1094
                if ((ch & 0xf) == TargetID)
1095
                {
1096
                        find_id = t;
1097
                        break;
1098
                }
1099
        }
1100
 
1101
        mptr = (char *) mbx_in_base;
1102
        for (t = 0; t < 15; t++)
1103
        {
1104
                ch = *mptr++;
1105
                if (ch & 0x80)
1106
                {
1107
                        find_last = t;
1108
                        break;
1109
                }
1110
        }
1111
        val = inw(STATUS_INT_REG);
1112
        mptr = (char *) mbx_in_base;
1113
        if (find_id != 0xff && find_last != 0xff)
1114
        {
1115
                if (find_id < find_last)
1116
                        *(char *) (mptr + find_id) |= 0x10;
1117
                else
1118
                {
1119
                        *(char *) (mptr + find_last) &= 0x7f;
1120
                        *(char *) (mptr + find_id) |= 0x90;
1121
                }
1122
        } else if (find_last != 0xff && find_id == 0xff)
1123
        {
1124
                *(char *) (mptr + find_last) &= 0x7f;
1125
                find_last = find_last + 1;
1126
                *(char *) (mptr + find_last) = (0x90 | TargetID);
1127
        } else if (find_last == 0xff)
1128
                *(char *) mptr = (0x90 | TargetID);
1129
 
1130
 
1131
        ReqType = 0;
1132
        /*
1133
           //  restart the RISC if it is halted before
1134
         */
1135
 
1136
        rsrb->SRB_flag = SRB_READY;
1137
 
1138
 
1139
        if (val & RISC_HALT)
1140
        {
1141
                outw(ucode_start, PC);  /* set pc counter */
1142
                status = inw(CONTROL_REG);      /* clear halt status */
1143
                outw((status & ~HALT_RISC), CONTROL_REG);
1144
        }
1145
#ifdef DEBUG
1146
        printk(KERN_DEBUG " start scsi issued \n");
1147
#endif
1148
 
1149
}
1150
 
1151
static void internal_done(Scsi_Cmnd * SCpnt)
1152
{
1153
        SCpnt->SCp.Status++;
1154
}
1155
 
1156
int tc2550_command(Scsi_Cmnd * SCpnt)
1157
{
1158
        tc2550_queue(SCpnt, internal_done);
1159
 
1160
        SCpnt->SCp.Status = 0;
1161
        while (!SCpnt->SCp.Status)
1162
                barrier();
1163
        return SCpnt->result;
1164
}
1165
 
1166
int tc2550_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
1167
{
1168
 
1169
        PAdapter pa;
1170
        PRISC_SRB rsrb;
1171
        int val;
1172
        struct scatterlist *sgpnt;
1173
 
1174
 
1175
        ScatGath *riscsgptr;
1176
 
1177
 
1178
        int i;
1179
        unsigned int nentries;
1180
 
1181
        pa = (PAdapter) & HostAdapter[HANumber];
1182
        Get_Base(pa);
1183
        val = 0xaa;
1184
        TargetID = SCpnt->target;
1185
        HostID = 7;
1186
        /* the following code is for corel compatibility */
1187
        if (SCpnt->lun != 0 ||
1188
            (TargetID == HostID))
1189
        {
1190
                SCpnt->result = DID_BAD_TARGET << 16;
1191
                done(SCpnt);
1192
                return (0);
1193
        };
1194
        /* Error if more than 16 tasks /target if no space is available  */
1195
 
1196
        if ((rsrb = search(pa)) == 0)
1197
        {
1198
                SCpnt->result = DID_ERROR << 16;
1199
                done(SCpnt);
1200
                return (0);
1201
        };
1202
 
1203
/*Ravi -modified for hostid 16/12/98 */
1204
        outb((u8) ((TargetID << 4) | HostID), SCSI_ID_REG);
1205
 
1206
 
1207
        rsrb->CDBLength = SCpnt->cmd_len;
1208
/* get the physical address of CDB */
1209
        rsrb->CDB = virt_to_phys((unsigned char *) SCpnt->cmnd);
1210
 
1211
 
1212
        if (discon)
1213
 
1214
                rsrb->Identify = 0xC0;
1215
        else
1216
                rsrb->Identify = 0x80;
1217
 
1218
/* scatter gather processing */
1219
 
1220
        nentries = SCpnt->use_sg;
1221
        if (nentries == 0)
1222
                nentries = 1;
1223
        rsrb->SGNum = nentries;
1224
 
1225
#ifdef DEBUG
1226
        printk(KERN_DEBUG "sgentries = %d\n", nentries);
1227
#endif
1228
 
1229
/*allocate mem for scatter gather table at 32bit boundary */
1230
        SCpnt->host_scribble = startsgptr + 8 * MAXSGENT * MAXSRBS * TargetID;
1231
 
1232
        /*(unsigned char *)scsi_malloc(4096); */
1233
 
1234
        sgpnt = (struct scatterlist *) SCpnt->request_buffer;
1235
 
1236
        riscsgptr = (PScatGath) (SCpnt->host_scribble);
1237
        if (riscsgptr == NULL)
1238
                panic("tripace: unable to allocate DMA memory\n");
1239
 
1240
 
1241
        /* fill physical address of scatter-gather list */
1242
        rsrb->SG_ListPtr = virt_to_phys(SCpnt->host_scribble);
1243
        rsrb->Cmd_sg_addr = virt_to_phys(rsrb + 4);
1244
 
1245
        if (SCpnt->use_sg)
1246
        {
1247
                for (i = 0; i < SCpnt->use_sg; i++)
1248
                {
1249
                        if (sgpnt[i].length == 0 || SCpnt->use_sg > 255)
1250
                        {
1251
                                unsigned char *ptr;
1252
                                printk(KERN_ERR "tc2550: Bad segment list supplied to Tripace.c (%d, %d)\n", SCpnt->use_sg, i);
1253
                                for (i = 0; i < SCpnt->use_sg; i++)
1254
                                {
1255
                                        printk(KERN_ERR "%d: %x %x %d\n", i, (unsigned int) sgpnt[i].address, (unsigned int) sgpnt[i].alt_address,
1256
                                               sgpnt[i].length);
1257
                                };
1258
                                printk(KERN_ERR "RISCGPTR %x: ", (unsigned int) riscsgptr);
1259
                                ptr = (unsigned char *) &riscsgptr[i];
1260
                                for (i = 0; i < 18; i++)
1261
                                        printk("%02x ", ptr[i]);
1262
                                panic("Tripace tc-2550x driver!");
1263
                        };
1264
 
1265
                        riscsgptr[i].sg_address = (u32) sgpnt[i].address;
1266
                        riscsgptr[i].sg_length = sgpnt[i].length;
1267
                };
1268
        } else
1269
        {
1270
                riscsgptr[0].sg_address = (u32) SCpnt->request_buffer;
1271
                riscsgptr[0].sg_length = SCpnt->request_bufflen;
1272
        };
1273
 
1274
 
1275
/* fill sense data pointer and len */
1276
 
1277
        rsrb->Sense_len = sizeof(SCpnt->sense_buffer);
1278
        rsrb->SenseDataPtr = virt_to_phys(SCpnt->sense_buffer);
1279
 
1280
/* store scsi command pointer for use in intr routine */
1281
        pa->dev[TargetID].task[Index].REQ_Header = (u8 *) SCpnt;
1282
        SCpnt->scsi_done = done;
1283
 
1284
        /* pa->dev[TargetID].task[Index].complete = CompleteIORequest; */
1285
        ReqType = 0;
1286
        StartScsiCmd(rsrb);
1287
        return 0;
1288
}
1289
 
1290
int tc2550_reset(Scsi_Cmnd * SCpnt)
1291
{
1292
        return 0;
1293
 
1294
}
1295
 
1296
#include "sd.h"
1297
 
1298
int tc2550_biosparam(Scsi_Disk * disk, int dev, int *info_array)
1299
{
1300
        return 0;
1301
 
1302
}
1303
 
1304
int tc2550_abort(Scsi_Cmnd * SCpnt)
1305
{
1306
 
1307
        return 0;
1308
}
1309
 
1310
 
1311
const char *tc2550_info(struct Scsi_Host *ignore)
1312
{
1313
 
1314
        return 0;
1315
}
1316
 
1317
void tc2550_intr(int irq, void *dev_id, struct pt_regs *regs)
1318
{
1319
        void (*my_done) (Scsi_Cmnd *) = NULL;
1320
 
1321
        int val, id, map = 0, tmap, mbx_out_ptr;
1322
        u8 loc = 0;
1323
        PRISC_SRB rsrb;
1324
        DevHdr *dev;
1325
        char *ptr0;
1326
        PAdapter padapter;
1327
/*
1328
   int i ;
1329
   unsigned long flags ;
1330
 */
1331
        unsigned int memsize;
1332
        Scsi_Cmnd *SCtmp;
1333
        unsigned devstat = 0;
1334
        unsigned scsistat = 0;
1335
        long start_time;
1336
 
1337
#ifdef DEBUG
1338
        printk("interrupt registered \n");
1339
#endif
1340
 
1341
/*
1342
   save_flags(flags);
1343
   cli();
1344
 */
1345
 
1346
        /* multiple HA? not supported now! */
1347
        HANumber = 0;
1348
        padapter = (PAdapter) & HostAdapter[HANumber];
1349
        Get_Base(padapter);
1350
 
1351
/* disable interrupts */
1352
        val = inw(STATUS_INT_REG);
1353
 
1354
        udelay(10);
1355
 
1356
        val |= 0x20;            /* clear interrupt pending */
1357
        outw(val, STATUS_INT_REG);
1358
 
1359
        udelay(10);
1360
 
1361
        val |= 0x22;            /* disable interrupt */
1362
 
1363
        outw(val, STATUS_INT_REG);
1364
        /*
1365
           // if RISC is in halt state then find out why ?
1366
         */
1367
        tmap = inw(STATUS_INT_REG);
1368
/* The following code needs to be added when we intro sync /wide nego */
1369
/*
1370
   if(tmap & RISC_HALT) {
1371
   tmap= risc_halt_check();
1372
   if(tmap) return(0xff);
1373
   };
1374
 */
1375
 
1376
 
1377
        mbx_out_ptr = padapter->mbx_out_ptr;
1378
 
1379
        val = *(u16 *) (mbx_out_base + mbx_out_ptr);
1380
 
1381
        while (val & 0x80)
1382
        {
1383
                loc = (char) (val & 0x7f);
1384
                id = val & 0xff00;
1385
                id >>= 8;
1386
                TargetID = id;
1387
                dev = (DevHdr *) (devhdr_base + TargetID * sizeof(DevHdr));
1388
                /*(u16  *)(mbx_out_base+ mbx_out_ptr)= (val& 0xff7f); */
1389
                rsrb = (PRISC_SRB) (taskq_base + (id * 16 + loc) * sizeof(RISC_SRB));
1390
                Index = loc;
1391
                devstat = rsrb->DEV_Status;
1392
                scsistat = rsrb->ScsiStatus;
1393
 
1394
/*      (*padapter->dev[TargetID].task[loc].complete)(rsrb); */
1395
 
1396
                *(u16 *) (mbx_out_base + mbx_out_ptr) = (val & 0xff7f);
1397
 
1398
                padapter->dev[TargetID].task[loc].CmdInProcess = 0;
1399
                mbx_out_ptr += 2;
1400
                if (mbx_out_ptr == 32)
1401
                        mbx_out_ptr = 0;
1402
                padapter->mbx_out_ptr = mbx_out_ptr;
1403
                /*
1404
                 *      Clear init bimap if no more tasks are waiting
1405
                 */
1406
                map = 1;
1407
                dev->Updatedmap = (dev->Updatedmap ^ (map << loc));
1408
                if ((dev->Updatedmap & 0x0000ffff) == 0)
1409
                {
1410
                        ptr0 = (char *) mbx_in_base;
1411
                        for (map = 0; map < 16; map++)
1412
                                if ((*ptr0 & 0xf) == (char) id)
1413
                                {
1414
                                        *ptr0 = (*ptr0 & 0xef);
1415
                                        break;
1416
                                } else
1417
                                        ptr0++;
1418
                }
1419
                val = *(u16 *) (mbx_out_base + mbx_out_ptr);
1420
 
1421
                rsrb->SRB_flag = SRB_DONE;      /* mark done */
1422
        }
1423
 
1424
        /* stop RISC if mailbox is empty  */
1425
 
1426
        ptr0 = (char *) mbx_in_base;
1427
        for (map = 0; map < 16; map++)
1428
                if (*ptr0 & 0x10)
1429
                        break;
1430
        if (map == 16)
1431
        {
1432
                tmap = inw(CONTROL_REG);
1433
                outw((tmap | HALT_RISC), CONTROL_REG);
1434
 
1435
/*Ravi modified to introduce sanity check&time out dec 16 1998 */
1436
 
1437
                start_time = jiffies;
1438
 
1439
                do
1440
                {
1441
                        if ((start_time - jiffies) > 5 * HZ)
1442
                        {
1443
                                printk(KERN_ERR "tc2550: TC-2550x Controller Failure\n");
1444
                                return;
1445
                        }
1446
                        tmap = inw(STATUS_INT_REG);
1447
                }
1448
                while((tmap & RISC_HALT) == 0);
1449
        }
1450
        SCtmp = (Scsi_Cmnd *) padapter->dev[TargetID].task[loc].REQ_Header;
1451
 
1452
        if (!SCtmp || !SCtmp->scsi_done)
1453
        {
1454
                printk(KERN_ERR "tc2550: Tripace_Intr_Handle: Unexpected Interrupt\n");
1455
                return;
1456
        }
1457
        memsize = 255 * sizeof(struct _ScatGath) + 4;
1458
        my_done = SCtmp->scsi_done;
1459
        /*if (SCtmp->host_scribble)
1460
           scsi_free(SCtmp->host_scribble,4096); */
1461
 
1462
 
1463
        padapter->dev[TargetID].task[loc].REQ_Header = NULL;
1464
        SCtmp->result = makecode(devstat, scsistat);
1465
/*enable chip interrupt signal */
1466
        val = inw(STATUS_INT_REG);
1467
        udelay(25);             /* delay for 25 micros */
1468
 
1469
        val &= 0xfd;            /* enable interrupt-bit1=0 in status-int reg */
1470
        outw(val, STATUS_INT_REG);
1471
 
1472
        my_done(SCtmp);         /* inform mid layer that scsi command is over */
1473
/*
1474
   restore_flags(flags);
1475
 */
1476
 
1477
}
1478
 
1479
/* called from init/main.c */
1480
void tripace_setup(char *str, int *ints)
1481
{
1482
        switch (ints[0])
1483
        {
1484
 
1485
        case 0:
1486
 
1487
                printk(KERN_INFO "tc2550: No Arguments In Command Line:Assuming Defaults\n");
1488
                break;
1489
 
1490
        case 1:
1491
                fast_clk = ints[1];
1492
                break;
1493
 
1494
        case 2:
1495
                fast_clk = ints[1];
1496
                discon = ints[2];
1497
                break;
1498
 
1499
        case 3:
1500
                fast_clk = ints[1];
1501
                discon = ints[2];
1502
                syncflag = ints[3];
1503
                break;
1504
 
1505
        case 4:
1506
                fast_clk = ints[1];
1507
                discon = ints[2];
1508
                syncflag = ints[3];
1509
                tagflag = ints[4];
1510
        }
1511
 
1512
#ifdef DEBUG
1513
        printk("fast_clk = %d,discon = %d,syncflag =%d,tagflag=%d\n",
1514
               fast_clk, discon, syncflag, tagflag);
1515
        printk("fast_clk = %d,discon = %d,syncflag =%d,tagflag=%d\n",
1516
               fast_clk, discon, syncflag, tagflag);
1517
        printk("fast_clk = %d,discon = %d,syncflag =%d,tagflag=%d\n",
1518
               fast_clk, discon, syncflag, tagflag);
1519
        printk("fast_clk = %d,discon = %d,syncflag =%d,tagflag=%d\n",
1520
               fast_clk, discon, syncflag, tagflag);
1521
#endif
1522
 
1523
}
1524
 
1525
static int makecode(unsigned hosterr, unsigned scsierr)
1526
{
1527
        switch (hosterr)
1528
        {
1529
        case 0x0:
1530
                hosterr = 0;
1531
                break;
1532
 
1533
        case SEL_TIME_OUT:      /* Selection time out-The initiator selection or target
1534
                                   reselection was not complete within the SCSI Time out period */
1535
                hosterr = DID_TIME_OUT;
1536
                break;
1537
 
1538
        case ERR_PARITY:        /* parity error */
1539
 
1540
                hosterr = DID_PARITY;
1541
                break;
1542
 
1543
        case ERR_OVERRUN:       /* Data overrun/underrun-The target attempted to transfer more data
1544
                                   than was allocated by the Data Length field or the sum of the
1545
                                   Scatter / Gather Data Length fields. */
1546
 
1547
        case ERR_BUSFREE:       /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
1548
 
1549
 
1550
        case ERR_PHASE: /* Target bus phase sequence failure-An invalid bus phase or bus
1551
                                   phase sequence was requested by the target. */
1552
 
1553
                hosterr = DID_ERROR;    /* Couldn't find any better */
1554
                break;
1555
 
1556
        default:
1557
                hosterr = DID_ERROR;
1558
                printk(KERN_ERR "tc2550: Makecode: Unknown Hoststatus %x\n", hosterr);
1559
                break;
1560
        }
1561
        return scsierr | (hosterr << 16);
1562
}

powered by: WebSVN 2.1.0

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