1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
|
/*-
*********************************************************************
* FILE NAME : amd.h
* BY : C.L. Huang (ching@tekram.com.tw)
* Erich Chen (erich@tekram.com.tw)
* Description: Device Driver for the amd53c974 PCI Bus Master
* SCSI Host adapter found on cards such as
* the Tekram DC-390(T).
* (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*********************************************************************
* $FreeBSD$
*/
#ifndef AMD_H
#define AMD_H
#define AMD_TRANS_CUR 0x01 /* Modify current neogtiation status */
#define AMD_TRANS_ACTIVE 0x03 /* Assume this is the active target */
#define AMD_TRANS_GOAL 0x04 /* Modify negotiation goal */
#define AMD_TRANS_USER 0x08 /* Modify user negotiation settings */
/*
* Per target transfer parameters.
*/
struct amd_transinfo {
u_int8_t period;
u_int8_t offset;
};
struct amd_target_info {
/*
* Records the currently active and user/default settings for
* tagged queueing and disconnection for each target.
*/
u_int8_t disc_tag;
#define AMD_CUR_DISCENB 0x01
#define AMD_CUR_TAGENB 0x02
#define AMD_USR_DISCENB 0x04
#define AMD_USR_TAGENB 0x08
u_int8_t CtrlR1;
u_int8_t CtrlR3;
u_int8_t CtrlR4;
u_int8_t sync_period_reg;
u_int8_t sync_offset_reg;
/*
* Currently active transfer settings.
*/
struct amd_transinfo current;
/*
* Transfer settings we wish to achieve
* through negotiation.
*/
struct amd_transinfo goal;
/*
* User defined or default transfer settings.
*/
struct amd_transinfo user;
};
/*
* Scatter/Gather Segment entry.
*/
struct amd_sg {
u_int32_t SGXLen;
u_int32_t SGXPtr;
};
/*
* Chipset feature limits
*/
#define MAX_SCSI_ID 8
#define AMD_MAX_SYNC_OFFSET 15
#define AMD_TARGET_MAX 7
#define AMD_LUN_MAX 7
#define AMD_NSEG (btoc(MAXPHYS) + 1)
#define AMD_MAXTRANSFER_SIZE 0xFFFFFF /* restricted by 24 bit counter */
#define MAX_DEVICES 10
#define MAX_TAGS_CMD_QUEUE 256
#define MAX_CMD_PER_LUN 6
#define MAX_SRB_CNT 256
#define MAX_START_JOB 256
/*
* BIT position to integer mapping.
*/
#define BIT(N) (0x01 << N)
/*
* EEPROM storage offsets and data structures.
*/
typedef struct _EEprom {
u_int8_t EE_MODE1;
u_int8_t EE_SPEED;
u_int8_t xx1;
u_int8_t xx2;
} EEprom, *PEEprom;
#define EE_ADAPT_SCSI_ID 64
#define EE_MODE2 65
#define EE_DELAY 66
#define EE_TAG_CMD_NUM 67
#define EE_DATA_SIZE 128
#define EE_CHECKSUM 0x1234
/*
* EE_MODE1 bits definition
*/
#define PARITY_CHK BIT(0)
#define SYNC_NEGO BIT(1)
#define EN_DISCONNECT BIT(2)
#define SEND_START BIT(3)
#define TAG_QUEUING BIT(4)
/*
* EE_MODE2 bits definition
*/
#define MORE2_DRV BIT(0)
#define GREATER_1G BIT(1)
#define RST_SCSI_BUS BIT(2)
#define ACTIVE_NEGATION BIT(3)
#define NO_SEEK BIT(4)
#define LUN_CHECK BIT(5)
#define ENABLE_CE 1
#define DISABLE_CE 0
#define EEPROM_READ 0x80
#define AMD_TAG_WILDCARD ((u_int)(~0))
/*
* SCSI Request Block
*/
struct amd_srb {
TAILQ_ENTRY(amd_srb) links;
u_int8_t CmdBlock[12];
union ccb *pccb;
bus_dmamap_t dmamap;
struct amd_sg *pSGlist;
u_int32_t TotalXferredLen;
u_int32_t SGPhysAddr; /* a segment starting address */
u_int32_t SGToBeXferLen; /* to be xfer length */
u_int32_t Segment0[2];
u_int32_t Segment1[2];
struct amd_sg SGsegment[AMD_NSEG];
struct amd_sg Segmentx;/* a one entry of S/G list table */
u_int8_t *pMsgPtr;
u_int16_t SRBState;
u_int8_t AdaptStatus;
u_int8_t TargetStatus;
u_int8_t MsgCnt;
u_int8_t EndMessage;
u_int8_t TagNumber;
u_int8_t SGcount;
u_int8_t SGIndex;
u_int8_t IORBFlag; /* ;81h-Reset, 2-retry */
u_int8_t SRBStatus;
u_int8_t SRBFlag;
/* ; b0-AutoReqSense,b6-Read,b7-write */
/* ; b4-settimeout,b5-Residual valid */
u_int8_t ScsiCmdLen;
};
TAILQ_HEAD(srb_queue, amd_srb);
/*
* Per-adapter, software configuration.
*/
struct amd_softc {
device_t dev;
bus_space_tag_t tag;
bus_space_handle_t bsh;
bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
bus_dma_tag_t sense_dmat; /* dmat for sense buffer */
bus_dmamap_t sense_dmamap;
struct scsi_sense_data *sense_buffers;
bus_addr_t sense_busaddr;
int unit;
int last_phase;
int cur_target;
int cur_lun;
struct amd_srb *active_srb;
struct amd_srb *untagged_srbs[AMD_TARGET_MAX+1][AMD_LUN_MAX+1];
struct amd_target_info tinfo[AMD_TARGET_MAX+1];
u_int16_t disc_count[AMD_TARGET_MAX+1][AMD_LUN_MAX+1];
struct srb_queue free_srbs;
struct srb_queue waiting_srbs;
struct srb_queue running_srbs;
struct amd_srb *pTmpSRB;
u_int16_t SRBCount;
u_int16_t max_id;
u_int16_t max_lun;
/* Hooks into the CAM XPT */
struct cam_sim *psim;
struct cam_path *ppath;
u_int8_t msgin_buf[6];
u_int8_t msgout_buf[6];
u_int msgin_index;
u_int msgout_index;
u_int msgout_len;
u_int8_t status;
u_int8_t AdaptSCSIID; /* ; Adapter SCSI Target ID */
u_int8_t AdaptSCSILUN; /* ; Adapter SCSI LUN */
u_int8_t ACBFlag;
u_int8_t Gmode2;
u_int8_t HostID_Bit;
u_int8_t InitDCB_flag[8][8]; /* flag of initDCB for device */
struct amd_srb SRB_array[MAX_SRB_CNT]; /* +45Ch, Len= */
struct amd_srb TmpSRB;
/* Setup data stored in an 93c46 serial eeprom */
u_int8_t eepromBuf[EE_DATA_SIZE];
};
/*
* ----SRB State machine definition
*/
#define SRB_FREE 0
#define SRB_READY BIT(1)
#define SRB_MSGOUT BIT(2) /* ;arbitration+msg_out 1st byte */
#define SRB_MSGIN BIT(3)
#define SRB_MSGIN_MULTI BIT(4)
#define SRB_COMMAND BIT(5)
#define SRB_START BIT(6) /* ;arbitration+msg_out+command_out */
#define SRB_DISCONNECT BIT(7)
#define SRB_DATA_XFER BIT(8)
#define SRB_XFERPAD BIT(9)
#define SRB_STATUS BIT(10)
#define SRB_COMPLETED BIT(11)
#define SRB_ABORT_SENT BIT(12)
#define DO_SYNC_NEGO BIT(13)
#define SRB_UNEXPECT_RESEL BIT(14)
/*
* ---ACB Flag
*/
#define RESET_DEV BIT(0)
#define RESET_DETECT BIT(1)
#define RESET_DONE BIT(2)
/*
* ---DCB Flag
*/
#define ABORT_DEV_ BIT(0)
/*
* ---SRB status
*/
#define SRB_OK BIT(0)
#define ABORTION BIT(1)
#define OVER_RUN BIT(2)
#define UNDER_RUN BIT(3)
#define PARITY_ERROR BIT(4)
#define SRB_ERROR BIT(5)
/*
* ---SRB Flags
*/
#define DATAOUT BIT(7)
#define DATAIN BIT(6)
#define RESIDUAL_VALID BIT(5)
#define ENABLE_TIMER BIT(4)
#define RESET_DEV0 BIT(2)
#define ABORT_DEV BIT(1)
#define AUTO_REQSENSE BIT(0)
/*
* ---Adapter status
*/
#define H_STATUS_GOOD 0
#define H_SEL_TIMEOUT 0x11
#define H_OVER_UNDER_RUN 0x12
#define H_UNEXP_BUS_FREE 0x13
#define H_TARGET_PHASE_F 0x14
#define H_INVALID_CCB_OP 0x16
#define H_LINK_CCB_BAD 0x17
#define H_BAD_TARGET_DIR 0x18
#define H_DUPLICATE_CCB 0x19
#define H_BAD_CCB_OR_SG 0x1A
#define H_ABORT 0x0FF
/*
* AMD specific "status" codes returned in the SCSI status byte.
*/
#define AMD_SCSI_STAT_UNEXP_BUS_F 0xFD /* ; Unexpect Bus Free */
#define AMD_SCSI_STAT_BUS_RST_DETECT 0xFE /* ; Scsi Bus Reset detected */
#define AMD_SCSI_STAT_SEL_TIMEOUT 0xFF /* ; Selection Time out */
/*
* ---Sync_Mode
*/
#define SYNC_DISABLE 0
#define SYNC_ENABLE BIT(0)
#define SYNC_NEGO_DONE BIT(1)
#define WIDE_ENABLE BIT(2)
#define WIDE_NEGO_DONE BIT(3)
#define EN_TAG_QUEUING BIT(4)
#define EN_ATN_STOP BIT(5)
#define SYNC_NEGO_OFFSET 15
/*
* ---SCSI bus phase
*/
#define SCSI_DATA_OUT 0
#define SCSI_DATA_IN 1
#define SCSI_COMMAND 2
#define SCSI_STATUS 3
#define SCSI_NOP0 4
#define SCSI_ARBITRATING 5
#define SCSI_MSG_OUT 6
#define SCSI_MSG_IN 7
#define SCSI_BUS_FREE 8
/*
*==========================================================
* AMD 53C974 Registers bit Definition
*==========================================================
*/
/*
* ------SCSI Register-------
* Command Reg.(+0CH)
*/
#define DMA_COMMAND BIT(7)
#define NOP_CMD 0
#define CLEAR_FIFO_CMD 1
#define RST_DEVICE_CMD 2
#define RST_SCSI_BUS_CMD 3
#define INFO_XFER_CMD 0x10
#define INITIATOR_CMD_CMPLTE 0x11
#define MSG_ACCEPTED_CMD 0x12
#define XFER_PAD_BYTE 0x18
#define SET_ATN_CMD 0x1A
#define RESET_ATN_CMD 0x1B
#define SEL_W_ATN 0x42
#define SEL_W_ATN_STOP 0x43
#define EN_SEL_RESEL 0x44
#define SEL_W_ATN2 0x46
#define DATA_XFER_CMD INFO_XFER_CMD
/*
* ------SCSI Register-------
* SCSI Status Reg.(+10H)
*/
#define INTERRUPT BIT(7)
#define ILLEGAL_OP_ERR BIT(6)
#define PARITY_ERR BIT(5)
#define COUNT_2_ZERO BIT(4)
#define GROUP_CODE_VALID BIT(3)
#define SCSI_PHASE_MASK (BIT(2)+BIT(1)+BIT(0))
/*
* ------SCSI Register-------
* Interrupt Status Reg.(+14H)
*/
#define SCSI_RESET_ BIT(7)
#define INVALID_CMD BIT(6)
#define DISCONNECTED BIT(5)
#define SERVICE_REQUEST BIT(4)
#define SUCCESSFUL_OP BIT(3)
#define RESELECTED BIT(2)
#define SEL_ATTENTION BIT(1)
#define SELECTED BIT(0)
/*
* ------SCSI Register-------
* Internal State Reg.(+18H)
*/
#define SYNC_OFFSET_FLAG BIT(3)
#define INTRN_STATE_MASK (BIT(2)+BIT(1)+BIT(0))
/*
* ------SCSI Register-------
* Clock Factor Reg.(+24H)
*/
#define CLK_FREQ_40MHZ 0
#define CLK_FREQ_35MHZ (BIT(2)+BIT(1)+BIT(0))
#define CLK_FREQ_30MHZ (BIT(2)+BIT(1))
#define CLK_FREQ_25MHZ (BIT(2)+BIT(0))
#define CLK_FREQ_20MHZ BIT(2)
#define CLK_FREQ_15MHZ (BIT(1)+BIT(0))
#define CLK_FREQ_10MHZ BIT(1)
/*
* ------SCSI Register-------
* Control Reg. 1(+20H)
*/
#define EXTENDED_TIMING BIT(7)
#define DIS_INT_ON_SCSI_RST BIT(6)
#define PARITY_ERR_REPO BIT(4)
#define SCSI_ID_ON_BUS (BIT(2)+BIT(1)+BIT(0))
/*
* ------SCSI Register-------
* Control Reg. 2(+2CH)
*/
#define EN_FEATURE BIT(6)
#define EN_SCSI2_CMD BIT(3)
/*
* ------SCSI Register-------
* Control Reg. 3(+30H)
*/
#define ID_MSG_CHECK BIT(7)
#define EN_QTAG_MSG BIT(6)
#define EN_GRP2_CMD BIT(5)
#define FAST_SCSI BIT(4) /* ;10MB/SEC */
#define FAST_CLK BIT(3) /* ;25 - 40 MHZ */
/*
* ------SCSI Register-------
* Control Reg. 4(+34H)
*/
#define EATER_12NS 0
#define EATER_25NS BIT(7)
#define EATER_35NS BIT(6)
#define EATER_0NS (BIT(7)+BIT(6))
#define NEGATE_REQACKDATA BIT(2)
#define NEGATE_REQACK BIT(3)
/*
*========================================
* DMA Register
*========================================
*/
/*
* -------DMA Register--------
* DMA Command Reg.(+40H)
*/
#define READ_DIRECTION BIT(7)
#define WRITE_DIRECTION 0
#define EN_DMA_INT BIT(6)
#define MAP_TO_MDL BIT(5)
#define DMA_DIAGNOSTIC BIT(4)
#define DMA_IDLE_CMD 0
#define DMA_BLAST_CMD BIT(0)
#define DMA_ABORT_CMD BIT(1)
#define DMA_START_CMD (BIT(1)|BIT(0))
/*
* -------DMA Register--------
* DMA Status Reg.(+54H)
*/
#define PCI_MS_ABORT BIT(6)
#define BLAST_COMPLETE BIT(5)
#define SCSI_INTERRUPT BIT(4)
#define DMA_XFER_DONE BIT(3)
#define DMA_XFER_ABORT BIT(2)
#define DMA_XFER_ERROR BIT(1)
#define POWER_DOWN BIT(0)
/*
* -------DMA Register--------
* DMA SCSI Bus and Ctrl.(+70H)
* EN_INT_ON_PCI_ABORT
*/
/*
*==========================================================
* SCSI Chip register address offset
*==========================================================
*/
#define CTCREG_LOW 0x00 /* (R) current transfer count register low */
#define STCREG_LOW 0x00 /* (W) start transfer count register low */
#define CTCREG_MID 0x04 /* (R) current transfer count register
* middle */
#define STCREG_MID 0x04 /* (W) start transfer count register middle */
#define SCSIFIFOREG 0x08 /* (R/W) SCSI FIFO register */
#define SCSICMDREG 0x0C /* (R/W) SCSI command register */
#define SCSISTATREG 0x10 /* (R) SCSI status register */
#define SCSIDESTIDREG 0x10 /* (W) SCSI destination ID register */
#define INTSTATREG 0x14 /* (R) interrupt status register */
#define SCSITIMEOUTREG 0x14 /* (W) SCSI timeout register */
#define INTERNSTATREG 0x18 /* (R) internal state register */
#define SYNCPERIOREG 0x18 /* (W) synchronous transfer period register */
#define CURRENTFIFOREG 0x1C /* (R) current FIFO/internal state register */
#define SYNCOFFREG 0x1C/* (W) synchronous transfer period register */
#define CNTLREG1 0x20 /* (R/W) control register 1 */
#define CLKFACTREG 0x24 /* (W) clock factor register */
#define CNTLREG2 0x2C /* (R/W) control register 2 */
#define CNTLREG3 0x30 /* (R/W) control register 3 */
#define CNTLREG4 0x34 /* (R/W) control register 4 */
#define CURTXTCNTREG 0x38 /* (R) current transfer count register
* high/part-unique ID code */
#define STCREG_HIGH 0x38 /* (W) Start current transfer count register
* high */
/*
*********************************************************
*
* SCSI DMA register
*
*********************************************************
*/
#define DMA_Cmd 0x40 /* (R/W) command register */
#define DMA_XferCnt 0x44 /* (R/W) starting transfer count */
#define DMA_XferAddr 0x48 /* (R/W) starting Physical address */
#define DMA_Wk_ByteCntr 0x4C /* ( R ) working byte counter */
#define DMA_Wk_AddrCntr 0x50 /* ( R ) working address counter */
#define DMA_Status 0x54 /* ( R ) status register */
#define DMA_MDL_Addr 0x58 /* (R/W) starting memory descriptor list (MDL)
* address */
#define DMA_Wk_MDL_Cntr 0x5C /* ( R ) working MDL counter */
#define DMA_ScsiBusCtrl 0x70 /* (bits R/W) SCSI BUS and control */
/* ******************************************************* */
#define am_target SCSISTATREG
#define am_timeout INTSTATREG
#define am_seq_step SYNCPERIOREG
#define am_fifo_count SYNCOFFREG
#define amd_read8(amd, port) \
bus_space_read_1((amd)->tag, (amd)->bsh, port)
#define amd_read16(amd, port) \
bus_space_read_2((amd)->tag, (amd)->bsh, port)
#define amd_read32(amd, port) \
bus_space_read_4((amd)->tag, (amd)->bsh, port)
#define amd_write8(amd, port, value) \
bus_space_write_1((amd)->tag, (amd)->bsh, port, value)
#define amd_write8_multi(amd, port, ptr, len) \
bus_space_write_multi_1((amd)->tag, (amd)->bsh, port, ptr, len)
#define amd_write16(amd, port, value) \
bus_space_write_2((amd)->tag, (amd)->bsh, port, value)
#define amd_write32(amd, port, value) \
bus_space_write_4((amd)->tag, (amd)->bsh, port, value)
#endif /* AMD_H */
|