Do a major clean-up of the BUSDMA architecture. A large number of
[dragonfly.git] / sys / dev / disk / trm / trm.c
CommitLineData
984263bc
MD
1/*
2 * O.S : FreeBSD CAM
3 * FILE NAME : trm.c
4 * BY : C.L. Huang (ching@tekram.com.tw)
5 * Erich Chen (erich@tekram.com.tw)
6 * Description: Device Driver for Tekram DC395U/UW/F ,DC315/U
7 * PCI SCSI Bus Master Host Adapter
8 * (SCSI chip set used Tekram ASIC TRM-S1040)
9 * (C)Copyright 1995-1999 Tekram Technology Co., Ltd.
10 */
11
12/*
13 * HISTORY:
14 *
15 * REV# DATE NAME DESCRIPTION
16 * 1.05 05/01/1999 ERICH CHEN First released for 3.x.x (CAM)
17 * 1.06 07/29/1999 ERICH CHEN Modify for NEW PCI
18 * 1.07 12/12/1999 ERICH CHEN Modify for 3.3.x ,DCB no free
19 * 1.08 06/12/2000 ERICH CHEN Modify for 4.x.x
20 */
21
22/*
23 *
24 *
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
27 * are met:
28 * 1. Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
33 * 3. The name of the author may not be used to endorse or promote products
34 * derived from this software without specific prior written permission.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
37 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
39 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
40 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
45 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 *
1de703da 47 * $FreeBSD: src/sys/dev/trm/trm.c,v 1.2.2.2 2002/12/19 20:34:45 cognet Exp $
1f7ab7c9 48 * $DragonFly: src/sys/dev/disk/trm/trm.c,v 1.13 2006/10/25 20:55:54 dillon Exp $
984263bc
MD
49 */
50
51/*
52 * Imported into FreeBSD source repository, and updated to compile under
53 * FreeBSD-3.0-DEVELOPMENT, by Stefan Esser <se@FreeBSD.Org>, 1996-12-17
54 */
55
56/*
57 * Updated to compile under FreeBSD 5.0-CURRENT by Olivier Houchard
58 * <doginou@ci0.org>, 2002-03-04
59 */
60
984263bc
MD
61#include <sys/param.h>
62
63#include <sys/systm.h>
64#include <sys/malloc.h>
65#include <sys/queue.h>
84754cd0 66#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
984263bc
MD
67#include <sys/bio.h>
68#endif
69#include <sys/buf.h>
70#include <sys/bus.h>
71#include <sys/kernel.h>
d9ed64be 72#include <sys/thread2.h>
984263bc
MD
73
74#include <vm/vm.h>
75#include <vm/pmap.h>
76
1f2de5d4
MD
77#include <bus/pci/pcivar.h>
78#include <bus/pci/pcireg.h>
984263bc
MD
79#include <machine/clock.h>
80#include <sys/rman.h>
81
1f2de5d4
MD
82#include <bus/cam/cam.h>
83#include <bus/cam/cam_ccb.h>
84#include <bus/cam/cam_sim.h>
85#include <bus/cam/cam_xpt_sim.h>
86#include <bus/cam/cam_debug.h>
984263bc 87
1f2de5d4 88#include <bus/cam/scsi/scsi_all.h>
984263bc 89
1f2de5d4 90#include "trm.h"
984263bc
MD
91
92#define trm_reg_read8(reg) bus_space_read_1(pACB->tag, pACB->bsh, reg)
93#define trm_reg_read16(reg) bus_space_read_2(pACB->tag, pACB->bsh, reg)
94#define trm_reg_read32(reg) bus_space_read_4(pACB->tag, pACB->bsh, reg)
95#define trm_reg_write8(value,reg) bus_space_write_1(pACB->tag, pACB->bsh,\
96 reg, value)
97#define trm_reg_write16(value,reg) bus_space_write_2(pACB->tag, pACB->bsh,\
98 reg, value)
99#define trm_reg_write32(value,reg) bus_space_write_4(pACB->tag, pACB->bsh,\
100 reg, value)
101
102#define PCI_Vendor_ID_TEKRAM 0x1DE1
103#define PCI_Device_ID_TRM_S1040 0x0391
104#define PCI_DEVICEID_TRMS1040 0x03911DE1
105
106#ifdef trm_DEBUG1
107#define TRM_DPRINTF(fmt, arg...) printf("trm: " fmt, ##arg)
108#else
109#define TRM_DPRINTF(fmt, arg...) {}
110#endif /* TRM_DEBUG */
111
112static void trm_check_eeprom(PNVRAMTYPE pEEpromBuf,PACB pACB);
113static void TRM_read_all(PNVRAMTYPE pEEpromBuf,PACB pACB);
114static u_int8_t TRM_get_data(PACB pACB, u_int8_t bAddr);
115static void TRM_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB);
116static void TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData);
117static void TRM_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr);
118static void TRM_wait_30us(PACB pACB);
119
120static void trm_Interrupt(void *vpACB);
121static void trm_DataOutPhase0(PACB pACB, PSRB pSRB,
122 u_int8_t * pscsi_status);
123static void trm_DataInPhase0(PACB pACB, PSRB pSRB,
124 u_int8_t * pscsi_status);
125static void trm_CommandPhase0(PACB pACB, PSRB pSRB,
126 u_int8_t * pscsi_status);
127static void trm_StatusPhase0(PACB pACB, PSRB pSRB,
128 u_int8_t * pscsi_status);
129static void trm_MsgOutPhase0(PACB pACB, PSRB pSRB,
130 u_int8_t * pscsi_status);
131static void trm_MsgInPhase0(PACB pACB, PSRB pSRB,
132 u_int8_t * pscsi_status);
133static void trm_DataOutPhase1(PACB pACB, PSRB pSRB,
134 u_int8_t * pscsi_status);
135static void trm_DataInPhase1(PACB pACB, PSRB pSRB,
136 u_int8_t * pscsi_status);
137static void trm_CommandPhase1(PACB pACB, PSRB pSRB,
138 u_int8_t * pscsi_status);
139static void trm_StatusPhase1(PACB pACB, PSRB pSRB,
140 u_int8_t * pscsi_status);
141static void trm_MsgOutPhase1(PACB pACB, PSRB pSRB,
142 u_int8_t * pscsi_status);
143static void trm_MsgInPhase1(PACB pACB, PSRB pSRB,
144 u_int8_t * pscsi_status);
145static void trm_Nop0(PACB pACB, PSRB pSRB, u_int8_t * pscsi_status);
146static void trm_Nop1(PACB pACB, PSRB pSRB, u_int8_t * pscsi_status);
147static void trm_SetXferRate(PACB pACB, PSRB pSRB,PDCB pDCB);
148static void trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir);
149static void trm_Disconnect(PACB pACB);
150static void trm_Reselect(PACB pACB);
151static void trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB);
152static void trm_DoingSRB_Done(PACB pACB);
153static void trm_ScsiRstDetect(PACB pACB);
154static void trm_ResetSCSIBus(PACB pACB);
155static void trm_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB);
156static void trm_EnableMsgOutAbort2(PACB pACB, PSRB pSRB);
157static void trm_EnableMsgOutAbort1(PACB pACB, PSRB pSRB);
158static void trm_SendSRB(PACB pACB, PSRB pSRB);
159static int trm_probe(device_t tag);
160static int trm_attach(device_t tag);
161static void trm_reset(PACB pACB);
162
163static u_int16_t trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB);
164
165static int trm_initAdapter(PACB pACB, u_int16_t unit,
166 device_t pci_config_id);
167static void trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,
168 u_int32_t i, u_int32_t j);
169static void trm_initSRB(PSRB psrb);
170static void trm_linkSRB(PACB pACB);
171static void trm_initACB(PACB pACB, u_int16_t unit);
172/* CAM SIM entry points */
173#define ccb_trmsrb_ptr spriv_ptr0
174#define ccb_trmacb_ptr spriv_ptr1
175static void trm_action(struct cam_sim *psim, union ccb *pccb);
176static void trm_poll(struct cam_sim *psim);
177
178
179static void * trm_SCSI_phase0[] = {
180 trm_DataOutPhase0, /* phase:0 */
181 trm_DataInPhase0, /* phase:1 */
182 trm_CommandPhase0, /* phase:2 */
183 trm_StatusPhase0, /* phase:3 */
184 trm_Nop0, /* phase:4 */
185 trm_Nop1, /* phase:5 */
186 trm_MsgOutPhase0, /* phase:6 */
187 trm_MsgInPhase0, /* phase:7 */
188};
189
190/*
191 *
192 * stateV = (void *) trm_SCSI_phase1[phase]
193 *
194 */
195static void * trm_SCSI_phase1[] = {
196 trm_DataOutPhase1, /* phase:0 */
197 trm_DataInPhase1, /* phase:1 */
198 trm_CommandPhase1, /* phase:2 */
199 trm_StatusPhase1, /* phase:3 */
200 trm_Nop0, /* phase:4 */
201 trm_Nop1, /* phase:5 */
202 trm_MsgOutPhase1, /* phase:6 */
203 trm_MsgInPhase1, /* phase:7 */
204};
205
206
207NVRAMTYPE trm_eepromBuf[MAX_ADAPTER_NUM];
208/*
209 *Fast20: 000 50ns, 20.0 Mbytes/s
210 * 001 75ns, 13.3 Mbytes/s
211 * 010 100ns, 10.0 Mbytes/s
212 * 011 125ns, 8.0 Mbytes/s
213 * 100 150ns, 6.6 Mbytes/s
214 * 101 175ns, 5.7 Mbytes/s
215 * 110 200ns, 5.0 Mbytes/s
216 * 111 250ns, 4.0 Mbytes/s
217 *
218 *Fast40: 000 25ns, 40.0 Mbytes/s
219 * 001 50ns, 20.0 Mbytes/s
220 * 010 75ns, 13.3 Mbytes/s
221 * 011 100ns, 10.0 Mbytes/s
222 * 100 125ns, 8.0 Mbytes/s
223 * 101 150ns, 6.6 Mbytes/s
224 * 110 175ns, 5.7 Mbytes/s
225 * 111 200ns, 5.0 Mbytes/s
226 */
227 /* real period: */
228u_int8_t dc395x_trm_clock_period[] = {
229 12,/* 48 ns 20 MB/sec */
230 18,/* 72 ns 13.3 MB/sec */
231 25,/* 100 ns 10.0 MB/sec */
232 31,/* 124 ns 8.0 MB/sec */
233 37,/* 148 ns 6.6 MB/sec */
234 43,/* 172 ns 5.7 MB/sec */
235 50,/* 200 ns 5.0 MB/sec */
236 62 /* 248 ns 4.0 MB/sec */
237};
238
239u_int8_t dc395x_trm_tinfo_sync_period[] = {
240 12,/* 20.0 MB/sec */
241 18,/* 13.3 MB/sec */
242 25,/* 10.0 MB/sec */
243 31,/* 8.0 MB/sec */
244 37,/* 6.6 MB/sec */
245 43,/* 5.7 MB/sec */
246 50,/* 5.0 MB/sec */
247 62,/* 4.0 MB/sec */
248};
249
250static PSRB
251trm_GetSRB(PACB pACB)
252{
984263bc
MD
253 PSRB pSRB;
254
d9ed64be 255 crit_enter();
984263bc
MD
256 pSRB = pACB->pFreeSRB;
257 if (pSRB) {
258 pACB->pFreeSRB = pSRB->pNextSRB;
259 pSRB->pNextSRB = NULL;
260 }
d9ed64be 261 crit_exit();
984263bc
MD
262 return (pSRB);
263}
264
265static void
266trm_RewaitSRB0(PDCB pDCB, PSRB pSRB)
267{
268 PSRB psrb1;
984263bc 269
d9ed64be 270 crit_enter();
984263bc
MD
271 if ((psrb1 = pDCB->pWaitingSRB)) {
272 pSRB->pNextSRB = psrb1;
273 pDCB->pWaitingSRB = pSRB;
274 } else {
275 pSRB->pNextSRB = NULL;
276 pDCB->pWaitingSRB = pSRB;
277 pDCB->pWaitLastSRB = pSRB;
278 }
d9ed64be 279 crit_exit();
984263bc
MD
280}
281
282static void
283trm_RewaitSRB(PDCB pDCB, PSRB pSRB)
284{
285 PSRB psrb1;
984263bc
MD
286 u_int8_t bval;
287
d9ed64be 288 crit_enter();
984263bc
MD
289 pDCB->GoingSRBCnt--;
290 psrb1 = pDCB->pGoingSRB;
291 if (pSRB == psrb1)
292 pDCB->pGoingSRB = psrb1->pNextSRB;
293 else {
294 while (pSRB != psrb1->pNextSRB)
295 psrb1 = psrb1->pNextSRB;
296 psrb1->pNextSRB = pSRB->pNextSRB;
297 if (pSRB == pDCB->pGoingLastSRB)
298 pDCB->pGoingLastSRB = psrb1;
299 }
300 if ((psrb1 = pDCB->pWaitingSRB)) {
301 pSRB->pNextSRB = psrb1;
302 pDCB->pWaitingSRB = pSRB;
303 } else {
304 pSRB->pNextSRB = NULL;
305 pDCB->pWaitingSRB = pSRB;
306 pDCB->pWaitLastSRB = pSRB;
307 }
308 bval = pSRB->TagNumber;
309 pDCB->TagMask &= (~(1 << bval)); /* Free TAG number */
d9ed64be 310 crit_exit();
984263bc
MD
311}
312
313static void
314trm_DoWaitingSRB(PACB pACB)
315{
984263bc
MD
316 PDCB ptr, ptr1;
317 PSRB pSRB;
318
d9ed64be 319 crit_enter();
984263bc
MD
320 if (!(pACB->pActiveDCB) &&
321 !(pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV))) {
322 ptr = pACB->pDCBRunRobin;
323 if (!ptr) {
324 ptr = pACB->pLinkDCB;
325 pACB->pDCBRunRobin = ptr;
326 }
327 ptr1 = ptr;
328 for (;ptr1 ;) {
329 pACB->pDCBRunRobin = ptr1->pNextDCB;
330 if (!(ptr1->MaxCommand > ptr1->GoingSRBCnt)
331 || !(pSRB = ptr1->pWaitingSRB)) {
332 if (pACB->pDCBRunRobin == ptr)
333 break;
334 ptr1 = ptr1->pNextDCB;
335 } else {
336 if (!trm_StartSCSI(pACB, ptr1, pSRB)) {
337 /*
338 * If trm_StartSCSI return 0 :
339 * current interrupt status is interrupt enable
340 * It's said that SCSI processor is unoccupied
341 */
342 ptr1->GoingSRBCnt++;
343 if (ptr1->pWaitLastSRB == pSRB) {
344 ptr1->pWaitingSRB = NULL;
345 ptr1->pWaitLastSRB = NULL;
346 } else
347 ptr1->pWaitingSRB = pSRB->pNextSRB;
348 pSRB->pNextSRB = NULL;
349 if (ptr1->pGoingSRB)
350 ptr1->pGoingLastSRB->pNextSRB = pSRB;
351 else
352 ptr1->pGoingSRB = pSRB;
353 ptr1->pGoingLastSRB = pSRB;
354 }
355 break;
356 }
357 }
358 }
d9ed64be 359 crit_exit();
984263bc
MD
360 return;
361}
362
363static void
364trm_SRBwaiting(PDCB pDCB, PSRB pSRB)
365{
366
367 if (pDCB->pWaitingSRB) {
368 pDCB->pWaitLastSRB->pNextSRB = pSRB;
369 pDCB->pWaitLastSRB = pSRB;
370 pSRB->pNextSRB = NULL;
371 } else {
372 pDCB->pWaitingSRB = pSRB;
373 pDCB->pWaitLastSRB = pSRB;
374 }
375}
376
377static void
378trm_ExecuteSRB(void *arg, bus_dma_segment_t *dm_segs, int nseg, int vp)
379{
984263bc
MD
380 PACB pACB;
381 PSRB pSRB;
382 union ccb *ccb;
383 u_long totalxferlen=0;
384
385 pSRB = (PSRB)arg;
386 ccb = pSRB->pccb;
387 pACB = (PACB)ccb->ccb_h.ccb_trmacb_ptr;
388 TRM_DPRINTF("trm_ExecuteSRB..........\n");
389 if (nseg != 0) {
390 PSEG psg;
391 bus_dma_segment_t *end_seg;
392 bus_dmasync_op_t op;
393
394 /* Copy the segments into our SG list */
395 end_seg = dm_segs + nseg;
396 psg = (PSEG) &pSRB->SegmentX[0];
397 pSRB->SRBSGListPointer= psg;
398 while (dm_segs < end_seg) {
399 psg->address = vp?(u_long)vtophys(dm_segs->ds_addr)
400 :(u_long)dm_segs->ds_addr;
401 psg->length = (u_long)dm_segs->ds_len;
402 totalxferlen += dm_segs->ds_len;
403 psg++;
404 dm_segs++;
405 }
406 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
407 op = BUS_DMASYNC_PREREAD;
408 } else {
409 op = BUS_DMASYNC_PREWRITE;
410 }
411 bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op);
412 }
413 pSRB->RetryCnt = 0;
414 pSRB->SRBTotalXferLength=totalxferlen;
415 pSRB->SRBSGCount = nseg;
416 pSRB->SRBSGIndex = 0;
417 pSRB->AdaptStatus = 0;
418 pSRB->TargetStatus = 0;
419 pSRB->MsgCnt = 0;
420 pSRB->SRBStatus = 0;
421 pSRB->SRBFlag = 0;
422 pSRB->SRBState = 0;
423 pSRB->ScsiPhase = PH_BUS_FREE; /* SCSI bus free Phase */
424
d9ed64be 425 crit_enter();
984263bc
MD
426 if (ccb->ccb_h.status != CAM_REQ_INPROG) {
427 if (nseg != 0)
428 bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap);
429 pSRB->pNextSRB = pACB->pFreeSRB;
430 pACB->pFreeSRB = pSRB;
431 xpt_done(ccb);
d9ed64be 432 crit_exit();
984263bc
MD
433 return;
434 }
435 ccb->ccb_h.status |= CAM_SIM_QUEUED;
436#if 0
437 /* XXX Need a timeout handler */
ddcafce9
JS
438 callout_reset(&ccb->ccb_h.timeout_ch, (ccb->ccb_h.timeout * hz) / 1000,
439 trmtimeout, srb);
984263bc
MD
440#endif
441 trm_SendSRB(pACB, pSRB);
d9ed64be 442 crit_exit();
984263bc
MD
443 return;
444}
445
446static void
447trm_SendSRB(PACB pACB, PSRB pSRB)
448{
984263bc
MD
449 PDCB pDCB;
450
d9ed64be 451 crit_enter();
984263bc
MD
452 pDCB = pSRB->pSRBDCB;
453 if (!(pDCB->MaxCommand > pDCB->GoingSRBCnt) || (pACB->pActiveDCB)
454 || (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV))) {
455 TRM_DPRINTF("pDCB->MaxCommand=%d \n",pDCB->MaxCommand);
456 TRM_DPRINTF("pDCB->GoingSRBCnt=%d \n",pDCB->GoingSRBCnt);
457 TRM_DPRINTF("pACB->pActiveDCB=%8x \n",(u_int)pACB->pActiveDCB);
458 TRM_DPRINTF("pACB->ACBFlag=%x \n",pACB->ACBFlag);
459 trm_SRBwaiting(pDCB, pSRB);
460 goto SND_EXIT;
461 }
462
463 if (pDCB->pWaitingSRB) {
464 trm_SRBwaiting(pDCB, pSRB);
465 pSRB = pDCB->pWaitingSRB;
466 pDCB->pWaitingSRB = pSRB->pNextSRB;
467 pSRB->pNextSRB = NULL;
468 }
469
470 if (!trm_StartSCSI(pACB, pDCB, pSRB)) {
471 /*
472 * If trm_StartSCSI return 0 :
473 * current interrupt status is interrupt enable
474 * It's said that SCSI processor is unoccupied
475 */
476 pDCB->GoingSRBCnt++; /* stack waiting SRB*/
477 if (pDCB->pGoingSRB) {
478 pDCB->pGoingLastSRB->pNextSRB = pSRB;
479 pDCB->pGoingLastSRB = pSRB;
480 } else {
481 pDCB->pGoingSRB = pSRB;
482 pDCB->pGoingLastSRB = pSRB;
483 }
484 } else {
485 /*
486 * If trm_StartSCSI return 1 :
487 * current interrupt status is interrupt disreenable
488 * It's said that SCSI processor has more one SRB need to do
489 */
490 trm_RewaitSRB0(pDCB, pSRB);
491 }
492SND_EXIT:
d9ed64be 493 crit_exit();
984263bc
MD
494 /*
495 * enable interrupt
496 */
497 return;
498}
499
500
501static void
502trm_action(struct cam_sim *psim, union ccb *pccb)
503{
504 PACB pACB;
505 u_int target_id,target_lun;
506
507 CAM_DEBUG(pccb->ccb_h.path, CAM_DEBUG_TRACE, ("trm_action\n"));
508
509 pACB = (PACB) cam_sim_softc(psim);
510 target_id = pccb->ccb_h.target_id;
511 target_lun = pccb->ccb_h.target_lun;
512
513 switch (pccb->ccb_h.func_code) {
514 case XPT_NOOP:
515 TRM_DPRINTF(" XPT_NOOP \n");
516 pccb->ccb_h.status = CAM_REQ_INVALID;
517 xpt_done(pccb);
518 break;
519 /*
520 * Execute the requested I/O operation
521 */
522 case XPT_SCSI_IO: {
523 PDCB pDCB = NULL;
524 PSRB pSRB;
525 struct ccb_scsiio *pcsio;
526
527 pcsio = &pccb->csio;
528 TRM_DPRINTF(" XPT_SCSI_IO \n");
529 TRM_DPRINTF("trm: target_id= %d target_lun= %d \n"
530 ,target_id, target_lun);
531 TRM_DPRINTF(
532 "pACB->scan_devices[target_id][target_lun]= %d \n"
533 ,pACB->scan_devices[target_id][target_lun]);
534 pDCB = pACB->pDCB[target_id][target_lun];
535 /*
536 * Assign an SRB and connect it with this ccb.
537 */
538 pSRB = trm_GetSRB(pACB);
539 if (!pSRB) {
540 /* Freeze SIMQ */
541 pccb->ccb_h.status = CAM_RESRC_UNAVAIL;
542 xpt_done(pccb);
543 return;
544 }
545 pSRB->pSRBDCB = pDCB;
546 pccb->ccb_h.ccb_trmsrb_ptr = pSRB;
547 pccb->ccb_h.ccb_trmacb_ptr = pACB;
548 pSRB->pccb = pccb;
549 pSRB->ScsiCmdLen = pcsio->cdb_len;
550 /*
551 * move layer of CAM command block to layer of SCSI
552 * Request Block for SCSI processor command doing
553 */
554 bcopy(pcsio->cdb_io.cdb_bytes,pSRB->CmdBlock
555 ,pcsio->cdb_len);
556 if ((pccb->ccb_h.flags & CAM_DIR_MASK)
557 != CAM_DIR_NONE) {
558 if ((pccb->ccb_h.flags &
559 CAM_SCATTER_VALID) == 0) {
560 if ((pccb->ccb_h.flags
561 & CAM_DATA_PHYS) == 0) {
984263bc
MD
562 int error;
563
d9ed64be 564 crit_enter();
984263bc
MD
565 error = bus_dmamap_load(
566 pACB->buffer_dmat,
567 pSRB->dmamap,
568 pcsio->data_ptr,
569 pcsio->dxfer_len,
570 trm_ExecuteSRB,
571 pSRB,
572 0);
573 if (error == EINPROGRESS) {
574 xpt_freeze_simq(
575 pACB->psim,
576 1);
577 pccb->ccb_h.status |=
578 CAM_RELEASE_SIMQ;
579 }
d9ed64be 580 crit_exit();
984263bc
MD
581 } else {
582 struct bus_dma_segment seg;
583
584 /* Pointer to physical buffer */
585 seg.ds_addr =
586 (bus_addr_t)pcsio->data_ptr;
587 seg.ds_len = pcsio->dxfer_len;
588 trm_ExecuteSRB(pSRB, &seg, 1,
589 0);
590 }
591 } else {
592 /* CAM_SCATTER_VALID */
593 struct bus_dma_segment *segs;
594
595 if ((pccb->ccb_h.flags &
596 CAM_SG_LIST_PHYS) == 0 ||
597 (pccb->ccb_h.flags
598 & CAM_DATA_PHYS) != 0) {
599 pSRB->pNextSRB = pACB->pFreeSRB;
600 pACB->pFreeSRB = pSRB;
601 pccb->ccb_h.status =
602 CAM_PROVIDE_FAIL;
603 xpt_done(pccb);
604 return;
605 }
606
607 /* cam SG list is physical,
608 * cam data is virtual
609 */
610 segs = (struct bus_dma_segment *)
611 pcsio->data_ptr;
612 trm_ExecuteSRB(pSRB, segs,
613 pcsio->sglist_cnt, 1);
614 } /* CAM_SCATTER_VALID */
615 } else
616 trm_ExecuteSRB(pSRB, NULL, 0, 0);
617 }
618 break;
619 case XPT_GDEV_TYPE:
620 TRM_DPRINTF(" XPT_GDEV_TYPE \n");
621 pccb->ccb_h.status = CAM_REQ_INVALID;
622 xpt_done(pccb);
623 break;
624 case XPT_GDEVLIST:
625 TRM_DPRINTF(" XPT_GDEVLIST \n");
626 pccb->ccb_h.status = CAM_REQ_INVALID;
627 xpt_done(pccb);
628 break;
629 /*
630 * Path routing inquiry
631 * Path Inquiry CCB
632 */
633 case XPT_PATH_INQ: {
634 struct ccb_pathinq *cpi = &pccb->cpi;
635
636 TRM_DPRINTF(" XPT_PATH_INQ \n");
637 cpi->version_num = 1;
638 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
639 cpi->target_sprt = 0;
640 cpi->hba_misc = 0;
641 cpi->hba_eng_cnt = 0;
642 cpi->max_target = 15 ;
643 cpi->max_lun = pACB->max_lun; /* 7 or 0 */
644 cpi->initiator_id = pACB->AdaptSCSIID;
645 cpi->bus_id = cam_sim_bus(psim);
646 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
647 strncpy(cpi->hba_vid, "Tekram_TRM", HBA_IDLEN);
648 strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN);
649 cpi->unit_number = cam_sim_unit(psim);
650 cpi->ccb_h.status = CAM_REQ_CMP;
651 xpt_done(pccb);
652 }
653 break;
654 /*
655 * Release a frozen SIM queue
656 * Release SIM Queue
657 */
658 case XPT_REL_SIMQ:
659 TRM_DPRINTF(" XPT_REL_SIMQ \n");
660 pccb->ccb_h.status = CAM_REQ_INVALID;
661 xpt_done(pccb);
662 break;
663 /*
664 * Set Asynchronous Callback Parameters
665 * Set Asynchronous Callback CCB
666 */
667 case XPT_SASYNC_CB:
668 TRM_DPRINTF(" XPT_SASYNC_CB \n");
669 pccb->ccb_h.status = CAM_REQ_INVALID;
670 xpt_done(pccb);
671 break;
672 /*
673 * Set device type information
674 * Set Device Type CCB
675 */
676 case XPT_SDEV_TYPE:
677 TRM_DPRINTF(" XPT_SDEV_TYPE \n");
678 pccb->ccb_h.status = CAM_REQ_INVALID;
679 xpt_done(pccb);
680 break;
681 /*
682 * (Re)Scan the SCSI Bus
683 * Rescan the given bus, or bus/target/lun
684 */
685 case XPT_SCAN_BUS:
686 TRM_DPRINTF(" XPT_SCAN_BUS \n");
687 pccb->ccb_h.status = CAM_REQ_INVALID;
688 xpt_done(pccb);
689 break;
690 /*
691 * Get EDT entries matching the given pattern
692 */
693 case XPT_DEV_MATCH:
694 TRM_DPRINTF(" XPT_DEV_MATCH \n");
695 pccb->ccb_h.status = CAM_REQ_INVALID;
696 xpt_done(pccb);
697 break;
698 /*
699 * Turn on debugging for a bus, target or lun
700 */
701 case XPT_DEBUG:
702 TRM_DPRINTF(" XPT_DEBUG \n");
703 pccb->ccb_h.status = CAM_REQ_INVALID;
704 xpt_done(pccb);
705 break;
706 /*
707 * XPT_ABORT = 0x10, Abort the specified CCB
708 * Abort XPT request CCB
709 */
710 case XPT_ABORT:
711 TRM_DPRINTF(" XPT_ABORT \n");
712 pccb->ccb_h.status = CAM_REQ_INVALID;
713 xpt_done(pccb);
714 break;
715 /*
716 * Reset the specified SCSI bus
717 * Reset SCSI Bus CCB
718 */
719 case XPT_RESET_BUS: {
720 int i;
721
722 TRM_DPRINTF(" XPT_RESET_BUS \n");
723 trm_reset(pACB);
724 pACB->ACBFlag=0;
725 for (i=0; i<500; i++)
726 DELAY(1000);
727 pccb->ccb_h.status = CAM_REQ_CMP;
728 xpt_done(pccb);
729 }
730 break;
731 /*
732 * Bus Device Reset the specified SCSI device
733 * Reset SCSI Device CCB
734 */
735 case XPT_RESET_DEV:
736 /*
737 * Don't (yet?) support vendor
738 * specific commands.
739 */
740 TRM_DPRINTF(" XPT_RESET_DEV \n");
741 pccb->ccb_h.status = CAM_REQ_INVALID;
742 xpt_done(pccb);
743 break;
744 /*
745 * Terminate the I/O process
746 * Terminate I/O Process Request CCB
747 */
748 case XPT_TERM_IO:
749 TRM_DPRINTF(" XPT_TERM_IO \n");
750 pccb->ccb_h.status = CAM_REQ_INVALID;
751 xpt_done(pccb);
752 break;
753 /*
754 * Scan Logical Unit
755 */
756 case XPT_SCAN_LUN:
757 TRM_DPRINTF(" XPT_SCAN_LUN \n");
758 pccb->ccb_h.status = CAM_REQ_INVALID;
759 xpt_done(pccb);
760 break;
761
762 /*
763 * Get/Set transfer rate/width/disconnection/tag queueing
764 * settings
765 * (GET) default/user transfer settings for the target
766 */
767 case XPT_GET_TRAN_SETTINGS: {
768 struct ccb_trans_settings *cts;
984263bc
MD
769 struct trm_transinfo *tinfo;
770 PDCB pDCB;
771
772 TRM_DPRINTF(" XPT_GET_TRAN_SETTINGS \n");
773 cts = &pccb->cts;
774 pDCB = pACB->pDCB[target_id][target_lun];
d9ed64be 775 crit_enter();
984263bc
MD
776 /*
777 * disable interrupt
778 */
779 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
780 /* current transfer settings */
781 if (pDCB->tinfo.disc_tag & TRM_CUR_DISCENB)
782 cts->flags = CCB_TRANS_DISC_ENB;
783 else
784 cts->flags = 0;/* no tag & disconnect */
785 if (pDCB->tinfo.disc_tag & TRM_CUR_TAGENB)
786 cts->flags |= CCB_TRANS_TAG_ENB;
787 tinfo = &pDCB->tinfo.current;
788 TRM_DPRINTF("CURRENT: cts->flags= %2x \n",
789 cts->flags);
790 } else {
791 /* default(user) transfer settings */
792 if (pDCB->tinfo.disc_tag & TRM_USR_DISCENB)
793 cts->flags = CCB_TRANS_DISC_ENB;
794 else
795 cts->flags = 0;
796 if (pDCB->tinfo.disc_tag & TRM_USR_TAGENB)
797 cts->flags |= CCB_TRANS_TAG_ENB;
798 tinfo = &pDCB->tinfo.user;
799 TRM_DPRINTF("USER: cts->flags= %2x \n",
800 cts->flags);
801 }
802 cts->sync_period = tinfo->period;
803 cts->sync_offset = tinfo->offset;
804 cts->bus_width = tinfo->width;
805 TRM_DPRINTF("pDCB->SyncPeriod: %d \n",
806 pDCB->SyncPeriod);
807 TRM_DPRINTF("period: %d \n", tinfo->period);
808 TRM_DPRINTF("offset: %d \n", tinfo->offset);
809 TRM_DPRINTF("width: %d \n", tinfo->width);
810
d9ed64be 811 crit_exit();
984263bc
MD
812 cts->valid = CCB_TRANS_SYNC_RATE_VALID |
813 CCB_TRANS_SYNC_OFFSET_VALID |
814 CCB_TRANS_BUS_WIDTH_VALID |
815 CCB_TRANS_DISC_VALID |
816 CCB_TRANS_TQ_VALID;
817 pccb->ccb_h.status = CAM_REQ_CMP;
818 xpt_done(pccb);
819 }
820 break;
821 /*
822 * Get/Set transfer rate/width/disconnection/tag queueing
823 * settings
824 * (Set) transfer rate/width negotiation settings
825 */
826 case XPT_SET_TRAN_SETTINGS: {
827 struct ccb_trans_settings *cts;
828 u_int update_type;
984263bc
MD
829 PDCB pDCB;
830
831 TRM_DPRINTF(" XPT_SET_TRAN_SETTINGS \n");
832 cts = &pccb->cts;
833 update_type = 0;
834 if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
835 update_type |= TRM_TRANS_GOAL;
836 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
837 update_type |= TRM_TRANS_USER;
d9ed64be 838 crit_enter();
984263bc
MD
839 pDCB = pACB->pDCB[target_id][target_lun];
840
841 if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
842 /*ccb disc enables */
843 if (update_type & TRM_TRANS_GOAL) {
844 if ((cts->flags & CCB_TRANS_DISC_ENB)
845 != 0)
846 pDCB->tinfo.disc_tag
847 |= TRM_CUR_DISCENB;
848 else
849 pDCB->tinfo.disc_tag &=
850 ~TRM_CUR_DISCENB;
851 }
852 if (update_type & TRM_TRANS_USER) {
853 if ((cts->flags & CCB_TRANS_DISC_ENB)
854 != 0)
855 pDCB->tinfo.disc_tag
856 |= TRM_USR_DISCENB;
857 else
858 pDCB->tinfo.disc_tag &=
859 ~TRM_USR_DISCENB;
860 }
861 }
862 if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) {
863 /* if ccb tag q active */
864 if (update_type & TRM_TRANS_GOAL) {
865 if ((cts->flags & CCB_TRANS_TAG_ENB)
866 != 0)
867 pDCB->tinfo.disc_tag |=
868 TRM_CUR_TAGENB;
869 else
870 pDCB->tinfo.disc_tag &=
871 ~TRM_CUR_TAGENB;
872 }
873 if (update_type & TRM_TRANS_USER) {
874 if ((cts->flags & CCB_TRANS_TAG_ENB)
875 != 0)
876 pDCB->tinfo.disc_tag |=
877 TRM_USR_TAGENB;
878 else
879 pDCB->tinfo.disc_tag &=
880 ~TRM_USR_TAGENB;
881 }
882 }
883 /* Minimum sync period factor */
884
885 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0) {
886 /* if ccb sync active */
887 /* TRM-S1040 MinSyncPeriod = 4 clocks/byte */
888 if ((cts->sync_period != 0) &&
889 (cts->sync_period < 125))
890 cts->sync_period = 125;
891 /* 1/(125*4) minsync 2 MByte/sec */
892 if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID)
893 != 0) {
894 if (cts->sync_offset == 0)
895 cts->sync_period = 0;
896 /* TRM-S1040 MaxSyncOffset = 15 bytes*/
897 if (cts->sync_offset > 15)
898 cts->sync_offset = 15;
899 }
900 }
901 if ((update_type & TRM_TRANS_USER) != 0) {
902 pDCB->tinfo.user.period = cts->sync_period;
903 pDCB->tinfo.user.offset = cts->sync_offset;
904 pDCB->tinfo.user.width = cts->bus_width;
905 }
906 if ((update_type & TRM_TRANS_GOAL) != 0) {
907 pDCB->tinfo.goal.period = cts->sync_period;
908 pDCB->tinfo.goal.offset = cts->sync_offset;
909 pDCB->tinfo.goal.width = cts->bus_width;
910 }
d9ed64be 911 crit_exit();
984263bc
MD
912 pccb->ccb_h.status = CAM_REQ_CMP;
913 xpt_done(pccb);
914 break;
915 }
916 /*
917 * Calculate the geometry parameters for a device give
918 * the sector size and volume size.
919 */
920 case XPT_CALC_GEOMETRY: {
921 struct ccb_calc_geometry *ccg;
922 u_int32_t size_mb;
923 u_int32_t secs_per_cylinder;
924 int extended;
925
926 TRM_DPRINTF(" XPT_CALC_GEOMETRY \n");
927 ccg = &pccb->ccg;
928 size_mb = ccg->volume_size /
929 ((1024L * 1024L) / ccg->block_size);
930 extended = 1;
931 if (size_mb > 1024 && extended) {
932 ccg->heads = 255;
933 ccg->secs_per_track = 63;
934 } else {
935 ccg->heads = 64;
936 ccg->secs_per_track = 32;
937 }
938 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
939 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
940 pccb->ccb_h.status = CAM_REQ_CMP;
941 xpt_done(pccb);
942 }
943 break;
944 case XPT_ENG_INQ:
945 TRM_DPRINTF(" XPT_ENG_INQ \n");
946 pccb->ccb_h.status = CAM_REQ_INVALID;
947 xpt_done(pccb);
948 break;
949 /*
950 * HBA execute engine request
951 * This structure must match SCSIIO size
952 */
953 case XPT_ENG_EXEC:
954 TRM_DPRINTF(" XPT_ENG_EXEC \n");
955 pccb->ccb_h.status = CAM_REQ_INVALID;
956 xpt_done(pccb);
957 break;
958 /*
959 * XPT_EN_LUN = 0x30, Enable LUN as a target
960 * Target mode structures.
961 */
962 case XPT_EN_LUN:
963 /*
964 * Don't (yet?) support vendor
965 * specific commands.
966 */
967 TRM_DPRINTF(" XPT_EN_LUN \n");
968 pccb->ccb_h.status = CAM_REQ_INVALID;
969 xpt_done(pccb);
970 break;
971 /*
972 * Execute target I/O request
973 */
974 case XPT_TARGET_IO:
975 /*
976 * Don't (yet?) support vendor
977 * specific commands.
978 */
979 TRM_DPRINTF(" XPT_TARGET_IO \n");
980 pccb->ccb_h.status = CAM_REQ_INVALID;
981 xpt_done(pccb);
982 break;
983 /*
984 * Accept Host Target Mode CDB
985 */
986 case XPT_ACCEPT_TARGET_IO:
987 /*
988 * Don't (yet?) support vendor
989 * specific commands.
990 */
991 TRM_DPRINTF(" XPT_ACCEPT_TARGET_IO \n");
992 pccb->ccb_h.status = CAM_REQ_INVALID;
993 xpt_done(pccb);
994 break;
995 /*
996 * Continue Host Target I/O Connection
997 */
998 case XPT_CONT_TARGET_IO:
999 /*
1000 * Don't (yet?) support vendor
1001 * specific commands.
1002 */
1003 TRM_DPRINTF(" XPT_CONT_TARGET_IO \n");
1004 pccb->ccb_h.status = CAM_REQ_INVALID;
1005 xpt_done(pccb);
1006 break;
1007 /*
1008 * Notify Host Target driver of event
1009 */
1010 case XPT_IMMED_NOTIFY:
1011 TRM_DPRINTF(" XPT_IMMED_NOTIFY \n");
1012 pccb->ccb_h.status = CAM_REQ_INVALID;
1013 xpt_done(pccb);
1014 break;
1015 /*
1016 * Acknowledgement of event
1017 */
1018 case XPT_NOTIFY_ACK:
1019 TRM_DPRINTF(" XPT_NOTIFY_ACK \n");
1020 pccb->ccb_h.status = CAM_REQ_INVALID;
1021 xpt_done(pccb);
1022 break;
1023 /*
1024 * XPT_VUNIQUE = 0x80
1025 */
1026 case XPT_VUNIQUE:
1027 pccb->ccb_h.status = CAM_REQ_INVALID;
1028 xpt_done(pccb);
1029 break;
1030 default:
1031 pccb->ccb_h.status = CAM_REQ_INVALID;
1032 xpt_done(pccb);
1033 break;
1034 }
1035}
1036
1037static void
1038trm_poll(struct cam_sim *psim)
1039{
1040
1041}
1042
1043static void
1044trm_ResetDevParam(PACB pACB)
1045{
1046 PDCB pDCB, pdcb;
1047 PNVRAMTYPE pEEpromBuf;
1048 u_int8_t PeriodIndex;
1049
1050 pDCB = pACB->pLinkDCB;
1051 if (pDCB == NULL)
1052 return;
1053 pdcb = pDCB;
1054 do {
1055 pDCB->SyncMode &= ~(SYNC_NEGO_DONE+ WIDE_NEGO_DONE);
1056 pDCB->SyncPeriod = 0;
1057 pDCB->SyncOffset = 0;
1058 pEEpromBuf = &trm_eepromBuf[pACB->AdapterUnit];
1059 pDCB->DevMode =
1060 pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarCfg0;
1061 pDCB->AdpMode = pEEpromBuf->NvramChannelCfg;
1062 PeriodIndex =
1063 pEEpromBuf->NvramTarget[pDCB->TargetID].NvmTarPeriod & 0x07;
1064 pDCB->MaxNegoPeriod = dc395x_trm_clock_period[PeriodIndex];
1065 if ((pDCB->DevMode & NTC_DO_WIDE_NEGO) &&
1066 (pACB->Config & HCC_WIDE_CARD))
1067 pDCB->SyncMode |= WIDE_NEGO_ENABLE;
1068 pDCB = pDCB->pNextDCB;
1069 }
1070 while (pdcb != pDCB);
1071}
1072
1073static void
1074trm_RecoverSRB(PACB pACB)
1075{
1076 PDCB pDCB, pdcb;
1077 PSRB psrb, psrb2;
1078 u_int16_t cnt, i;
1079
1080 pDCB = pACB->pLinkDCB;
1081 if (pDCB == NULL)
1082 return;
1083 pdcb = pDCB;
1084 do {
1085 cnt = pdcb->GoingSRBCnt;
1086 psrb = pdcb->pGoingSRB;
1087 for (i = 0; i < cnt; i++) {
1088 psrb2 = psrb;
1089 psrb = psrb->pNextSRB;
1090 if (pdcb->pWaitingSRB) {
1091 psrb2->pNextSRB = pdcb->pWaitingSRB;
1092 pdcb->pWaitingSRB = psrb2;
1093 } else {
1094 pdcb->pWaitingSRB = psrb2;
1095 pdcb->pWaitLastSRB = psrb2;
1096 psrb2->pNextSRB = NULL;
1097 }
1098 }
1099 pdcb->GoingSRBCnt = 0;
1100 pdcb->pGoingSRB = NULL;
1101 pdcb->TagMask = 0;
1102 pdcb = pdcb->pNextDCB;
1103 }
1104 while (pdcb != pDCB);
1105}
1106
1107static void
1108trm_reset(PACB pACB)
1109{
984263bc
MD
1110 u_int16_t i;
1111
1112 TRM_DPRINTF("trm: RESET");
d9ed64be 1113 crit_enter();
984263bc
MD
1114 trm_reg_write8(0x00, TRMREG_DMA_INTEN);
1115 trm_reg_write8(0x00, TRMREG_SCSI_INTEN);
1116
1117 trm_ResetSCSIBus(pACB);
1118 for (i = 0; i < 500; i++)
1119 DELAY(1000);
1120 trm_reg_write8(0x7F, TRMREG_SCSI_INTEN);
1121 /* Enable DMA interrupt */
1122 trm_reg_write8(EN_SCSIINTR, TRMREG_DMA_INTEN);
1123 /* Clear DMA FIFO */
1124 trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL);
1125 /* Clear SCSI FIFO */
1126 trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL);
1127 trm_ResetDevParam(pACB);
1128 trm_DoingSRB_Done(pACB);
1129 pACB->pActiveDCB = NULL;
1130 pACB->ACBFlag = 0;/* RESET_DETECT, RESET_DONE ,RESET_DEV */
1131 trm_DoWaitingSRB(pACB);
1132 /* Tell the XPT layer that a bus reset occured */
1133 if (pACB->ppath != NULL)
1134 xpt_async(AC_BUS_RESET, pACB->ppath, NULL);
d9ed64be 1135 crit_exit();
984263bc
MD
1136 return;
1137}
1138
1139static u_int16_t
1140trm_StartSCSI(PACB pACB, PDCB pDCB, PSRB pSRB)
1141{
1142 u_int16_t return_code;
1143 u_int8_t tag_number, scsicommand, i,command,identify_message;
1144 u_int8_t * ptr;
1145 u_long tag_mask;
1146 union ccb *pccb;
1147 struct ccb_scsiio *pcsio;
1148
1149 pccb = pSRB->pccb;
1150 pcsio = &pccb->csio;
1151 pSRB->TagNumber = 31;
1152
1153 trm_reg_write8(pACB->AdaptSCSIID, TRMREG_SCSI_HOSTID);
1154 trm_reg_write8(pDCB->TargetID, TRMREG_SCSI_TARGETID);
1155 trm_reg_write8(pDCB->SyncPeriod, TRMREG_SCSI_SYNC);
1156 trm_reg_write8(pDCB->SyncOffset, TRMREG_SCSI_OFFSET);
1157 pSRB->ScsiPhase = PH_BUS_FREE;/* initial phase */
1158 /* Flush FIFO */
1159 trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
1160
1161 identify_message = pDCB->IdentifyMsg;
1162
1163 if ((pSRB->CmdBlock[0] == INQUIRY) ||
1164 (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
1165 (pSRB->SRBFlag & AUTO_REQSENSE)) {
1166 if (((pDCB->SyncMode & WIDE_NEGO_ENABLE) &&
1167 !(pDCB->SyncMode & WIDE_NEGO_DONE)) \
1168 || ((pDCB->SyncMode & SYNC_NEGO_ENABLE) &&
1169 !(pDCB->SyncMode & SYNC_NEGO_DONE))) {
1170 if (!(pDCB->IdentifyMsg & 7) ||
1171 (pSRB->CmdBlock[0] != INQUIRY)) {
1172 scsicommand = SCMD_SEL_ATNSTOP;
1173 pSRB->SRBState = SRB_MSGOUT;
1174 goto polling;
1175 }
1176 }
1177 /*
1178 * Send identify message
1179 */
1180 trm_reg_write8((identify_message & 0xBF) ,TRMREG_SCSI_FIFO);
1181 scsicommand = SCMD_SEL_ATN;
1182 pSRB->SRBState = SRB_START_;
1183 } else {
1184 /* not inquiry,request sense,auto request sense */
1185 /*
1186 * Send identify message
1187 */
1188 trm_reg_write8(identify_message,TRMREG_SCSI_FIFO);
1189 scsicommand = SCMD_SEL_ATN;
1190 pSRB->SRBState = SRB_START_;
1191 if (pDCB->SyncMode & EN_TAG_QUEUING) {
1192 /* Send Tag message */
1193 /*
1194 * Get tag id
1195 */
1196 tag_mask = 1;
1197 tag_number = 0;
1198 while (tag_mask & pDCB->TagMask) {
1199 tag_mask = tag_mask << 1;
1200 tag_number++;
1201 }
1202 /*
1203 * Send Tag id
1204 */
1205 trm_reg_write8(MSG_SIMPLE_QTAG, TRMREG_SCSI_FIFO);
1206 trm_reg_write8(tag_number, TRMREG_SCSI_FIFO);
1207 pDCB->TagMask |= tag_mask;
1208 pSRB->TagNumber = tag_number;
1209 scsicommand = SCMD_SEL_ATN3;
1210 pSRB->SRBState = SRB_START_;
1211 }
1212 }
1213polling:
1214 /*
1215 * Send CDB ..command block .........
1216 */
1217 if (pSRB->SRBFlag & AUTO_REQSENSE) {
1218 trm_reg_write8(REQUEST_SENSE, TRMREG_SCSI_FIFO);
1219 trm_reg_write8((pDCB->IdentifyMsg << 5), TRMREG_SCSI_FIFO);
1220 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1221 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1222 trm_reg_write8(pcsio->sense_len, TRMREG_SCSI_FIFO);
1223 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1224 } else {
1225 ptr = (u_int8_t *) pSRB->CmdBlock;
1226 for (i = 0; i < pSRB->ScsiCmdLen ; i++) {
1227 command = *ptr++;
1228 trm_reg_write8(command,TRMREG_SCSI_FIFO);
1229 }
1230 }
1231 if (trm_reg_read16(TRMREG_SCSI_STATUS) & SCSIINTERRUPT) {
1232 /*
1233 * If trm_StartSCSI return 1 :
1234 * current interrupt status is interrupt disreenable
1235 * It's said that SCSI processor has more one SRB need to do,
1236 * SCSI processor has been occupied by one SRB.
1237 */
1238 pSRB->SRBState = SRB_READY;
1239 pDCB->TagMask &= ~(1 << pSRB->TagNumber);
1240 return_code = 1;
1241 } else {
1242 /*
1243 * If trm_StartSCSI return 0 :
1244 * current interrupt status is interrupt enable
1245 * It's said that SCSI processor is unoccupied
1246 */
1247 pSRB->ScsiPhase = SCSI_NOP1; /* SCSI bus free Phase */
1248 pACB->pActiveDCB = pDCB;
1249 pDCB->pActiveSRB = pSRB;
1250 return_code = 0;
1251 trm_reg_write16(DO_DATALATCH | DO_HWRESELECT,
1252 TRMREG_SCSI_CONTROL);/* it's important for atn stop*/
1253 /*
1254 * SCSI cammand
1255 */
1256 trm_reg_write8(scsicommand,TRMREG_SCSI_COMMAND);
1257 }
1258 return (return_code);
1259}
1260
1261static void
c436375a 1262trm_Interrupt(void *vpACB)
984263bc
MD
1263{
1264 PACB pACB;
1265 PDCB pDCB;
1266 PSRB pSRB;
1267 u_int16_t phase;
1268 void (*stateV)(PACB, PSRB, u_int8_t *);
1269 u_int8_t scsi_status=0, scsi_intstatus;
1270
1271 pACB = vpACB;
1272
1273 if (pACB == NULL) {
1274 TRM_DPRINTF("trm_Interrupt: pACB NULL return......");
1275 return;
1276 }
1277
1278 scsi_status = trm_reg_read16(TRMREG_SCSI_STATUS);
1279 if (!(scsi_status & SCSIINTERRUPT)) {
1280 TRM_DPRINTF("trm_Interrupt: TRMREG_SCSI_STATUS scsi_status = NULL ,return......");
1281 return;
1282 }
1283 TRM_DPRINTF("scsi_status=%2x,",scsi_status);
1284
1285 scsi_intstatus = trm_reg_read8(TRMREG_SCSI_INTSTATUS);
1286
1287 TRM_DPRINTF("scsi_intstatus=%2x,",scsi_intstatus);
1288
1289 if (scsi_intstatus & (INT_SELTIMEOUT | INT_DISCONNECT)) {
1290 trm_Disconnect(pACB);
1291 return;
1292 }
1293
1294 if (scsi_intstatus & INT_RESELECTED) {
1295 trm_Reselect(pACB);
1296 return;
1297 }
1298 if (scsi_intstatus & INT_SCSIRESET) {
1299 trm_ScsiRstDetect(pACB);
1300 return;
1301 }
1302
1303 if (scsi_intstatus & (INT_BUSSERVICE | INT_CMDDONE)) {
1304 pDCB = pACB->pActiveDCB;
1305 pSRB = pDCB->pActiveSRB;
1306 if (pDCB) {
1307 if (pDCB->DCBFlag & ABORT_DEV_)
1308 trm_EnableMsgOutAbort1(pACB, pSRB);
1309 }
1310 phase = (u_int16_t) pSRB->ScsiPhase; /* phase: */
1311 stateV = (void *) trm_SCSI_phase0[phase];
1312 stateV(pACB, pSRB, &scsi_status);
1313 pSRB->ScsiPhase = scsi_status & PHASEMASK;
1314 /* phase:0,1,2,3,4,5,6,7 */
1315 phase = (u_int16_t) scsi_status & PHASEMASK;
1316 stateV = (void *) trm_SCSI_phase1[phase];
1317 stateV(pACB, pSRB, &scsi_status);
1318 }
1319}
1320
1321static void
1322trm_MsgOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1323{
1324
1325 if (pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT))
1326 *pscsi_status = PH_BUS_FREE;
1327 /*.. initial phase*/
1328}
1329
1330static void
1331trm_MsgOutPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1332{
1333 u_int8_t bval;
1334 u_int16_t i, cnt;
1335 u_int8_t * ptr;
1336 PDCB pDCB;
1337
1338 trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
1339 pDCB = pACB->pActiveDCB;
1340 if (!(pSRB->SRBState & SRB_MSGOUT)) {
1341 cnt = pSRB->MsgCnt;
1342 if (cnt) {
1343 ptr = (u_int8_t *) pSRB->MsgOutBuf;
1344 for (i = 0; i < cnt; i++) {
1345 trm_reg_write8(*ptr, TRMREG_SCSI_FIFO);
1346 ptr++;
1347 }
1348 pSRB->MsgCnt = 0;
1349 if ((pDCB->DCBFlag & ABORT_DEV_) &&
1350 (pSRB->MsgOutBuf[0] == MSG_ABORT)) {
1351 pSRB->SRBState = SRB_ABORT_SENT;
1352 }
1353 } else {
1354 bval = MSG_ABORT;
1355 if ((pSRB->CmdBlock[0] == INQUIRY) ||
1356 (pSRB->CmdBlock[0] == REQUEST_SENSE) ||
1357 (pSRB->SRBFlag & AUTO_REQSENSE)) {
1358 if (pDCB->SyncMode & SYNC_NEGO_ENABLE) {
1359 goto mop1;
1360 }
1361 }
1362 trm_reg_write8(bval, TRMREG_SCSI_FIFO);
1363 }
1364 } else {
1365mop1: /* message out phase */
1366 if (!(pSRB->SRBState & SRB_DO_WIDE_NEGO)
1367 && (pDCB->SyncMode & WIDE_NEGO_ENABLE)) {
1368 /*
1369 * WIDE DATA TRANSFER REQUEST code (03h)
1370 */
1371 pDCB->SyncMode &= ~(SYNC_NEGO_DONE | EN_ATN_STOP);
1372 trm_reg_write8((pDCB->IdentifyMsg & 0xBF),
1373 TRMREG_SCSI_FIFO);
1374 trm_reg_write8(MSG_EXTENDED,TRMREG_SCSI_FIFO);
1375 /* (01h) */
1376 trm_reg_write8(2,TRMREG_SCSI_FIFO);
1377 /* Message length (02h) */
1378 trm_reg_write8(3,TRMREG_SCSI_FIFO);
1379 /* wide data xfer (03h) */
1380 trm_reg_write8(1,TRMREG_SCSI_FIFO);
1381 /* width:0(8bit),1(16bit),2(32bit) */
1382 pSRB->SRBState |= SRB_DO_WIDE_NEGO;
1383 } else if (!(pSRB->SRBState & SRB_DO_SYNC_NEGO)
1384 && (pDCB->SyncMode & SYNC_NEGO_ENABLE)) {
1385 /*
1386 * SYNCHRONOUS DATA TRANSFER REQUEST code (01h)
1387 */
1388 if (!(pDCB->SyncMode & WIDE_NEGO_DONE))
1389 trm_reg_write8((pDCB->IdentifyMsg & 0xBF),
1390 TRMREG_SCSI_FIFO);
1391 trm_reg_write8(MSG_EXTENDED,TRMREG_SCSI_FIFO);
1392 /* (01h) */
1393 trm_reg_write8(3,TRMREG_SCSI_FIFO);
1394 /* Message length (03h) */
1395 trm_reg_write8(1,TRMREG_SCSI_FIFO);
1396 /* SYNCHRONOUS DATA TRANSFER REQUEST code (01h) */
1397 trm_reg_write8(pDCB->MaxNegoPeriod,TRMREG_SCSI_FIFO);
1398 /* Transfer peeriod factor */
1399 trm_reg_write8(SYNC_NEGO_OFFSET,TRMREG_SCSI_FIFO);
1400 /* REQ/ACK offset */
1401 pSRB->SRBState |= SRB_DO_SYNC_NEGO;
1402 }
1403 }
1404 trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1405 /* it's important for atn stop */
1406 /*
1407 * SCSI cammand
1408 */
1409 trm_reg_write8(SCMD_FIFO_OUT, TRMREG_SCSI_COMMAND);
1410}
1411
1412static void
1413trm_CommandPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1414{
1415
1416}
1417
1418static void
1419trm_CommandPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1420{
1421 PDCB pDCB;
1422 u_int8_t * ptr;
1423 u_int16_t i, cnt;
1424 union ccb *pccb;
1425 struct ccb_scsiio *pcsio;
1426
1427 pccb = pSRB->pccb;
1428 pcsio = &pccb->csio;
1429
1430 trm_reg_write16(DO_CLRATN | DO_CLRFIFO , TRMREG_SCSI_CONTROL);
1431 if (!(pSRB->SRBFlag & AUTO_REQSENSE)) {
1432 cnt = (u_int16_t) pSRB->ScsiCmdLen;
1433 ptr = (u_int8_t *) pSRB->CmdBlock;
1434 for (i = 0; i < cnt; i++) {
1435 trm_reg_write8(*ptr, TRMREG_SCSI_FIFO);
1436 ptr++;
1437 }
1438 } else {
1439 trm_reg_write8(REQUEST_SENSE, TRMREG_SCSI_FIFO);
1440 pDCB = pACB->pActiveDCB;
1441 /* target id */
1442 trm_reg_write8((pDCB->IdentifyMsg << 5), TRMREG_SCSI_FIFO);
1443 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1444 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1445 /* sizeof(struct scsi_sense_data) */
1446 trm_reg_write8(pcsio->sense_len, TRMREG_SCSI_FIFO);
1447 trm_reg_write8(0, TRMREG_SCSI_FIFO);
1448 }
1449 pSRB->SRBState = SRB_COMMAND;
1450 trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1451 /* it's important for atn stop*/
1452 /*
1453 * SCSI cammand
1454 */
1455 trm_reg_write8(SCMD_FIFO_OUT, TRMREG_SCSI_COMMAND);
1456}
1457
1458static void
1459trm_DataOutPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1460{
1461 PDCB pDCB;
1462 u_int8_t TempDMAstatus,SGIndexTemp;
1463 u_int16_t scsi_status;
1464 PSEG pseg;
1465 u_long TempSRBXferredLength,dLeftCounter=0;
1466
1467 pDCB = pSRB->pSRBDCB;
1468 scsi_status = *pscsi_status;
1469
1470 if (!(pSRB->SRBState & SRB_XFERPAD)) {
1471 if (scsi_status & PARITYERROR)
1472 pSRB->SRBStatus |= PARITY_ERROR;
1473 if (!(scsi_status & SCSIXFERDONE)) {
1474 /*
1475 * when data transfer from DMA FIFO to SCSI FIFO
1476 * if there was some data left in SCSI FIFO
1477 */
1478 dLeftCounter = (u_long)
1479 (trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x1F);
1480 if (pDCB->SyncPeriod & WIDE_SYNC) {
1481 /*
1482 * if WIDE scsi SCSI FIFOCNT unit is word
1483 * so need to * 2
1484 */
1485 dLeftCounter <<= 1;
1486 }
1487 }
1488 /*
1489 * caculate all the residue data that not yet tranfered
1490 * SCSI transfer counter + left in SCSI FIFO data
1491 *
1492 * .....TRM_SCSI_COUNTER (24bits)
1493 * The counter always decrement by one for every SCSI byte
1494 *transfer.
1495 * .....TRM_SCSI_FIFOCNT (5bits)
1496 * The counter is SCSI FIFO offset counter
1497 */
1498 dLeftCounter += trm_reg_read32(TRMREG_SCSI_COUNTER);
1499 if (dLeftCounter == 1) {
1500 dLeftCounter = 0;
1501 trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL);
1502 }
1503 if ((dLeftCounter == 0) ||
1504 (scsi_status & SCSIXFERCNT_2_ZERO)) {
1505 TempDMAstatus = trm_reg_read8(TRMREG_DMA_STATUS);
1506 while (!(TempDMAstatus & DMAXFERCOMP)) {
1507 TempDMAstatus =
1508 trm_reg_read8(TRMREG_DMA_STATUS);
1509 }
1510 pSRB->SRBTotalXferLength = 0;
1511 } else {
1512 /* Update SG list */
1513 /*
1514 * if transfer not yet complete
1515 * there were some data residue in SCSI FIFO or
1516 * SCSI transfer counter not empty
1517 */
1518 if (pSRB->SRBTotalXferLength != dLeftCounter) {
1519 /*
1520 * data that had transferred length
1521 */
1522 TempSRBXferredLength =
1523 pSRB->SRBTotalXferLength - dLeftCounter;
1524 /*
1525 * next time to be transferred length
1526 */
1527 pSRB->SRBTotalXferLength = dLeftCounter;
1528 /*
1529 * parsing from last time disconnect SRBSGIndex
1530 */
1531 pseg =
1532 pSRB->SRBSGListPointer + pSRB->SRBSGIndex;
1533 for (SGIndexTemp = pSRB->SRBSGIndex;
1534 SGIndexTemp < pSRB->SRBSGCount;
1535 SGIndexTemp++) {
1536 /*
1537 * find last time which SG transfer be
1538 * disconnect
1539 */
1540 if (TempSRBXferredLength >=
1541 pseg->length)
1542 TempSRBXferredLength -=
1543 pseg->length;
1544 else {
1545 /*
1546 * update last time disconnected SG
1547 * list
1548 */
1549 pseg->length -=
1550 TempSRBXferredLength;
1551 /* residue data length */
1552 pseg->address +=
1553 TempSRBXferredLength;
1554 /* residue data pointer */
1555 pSRB->SRBSGIndex = SGIndexTemp;
1556 break;
1557 }
1558 pseg++;
1559 }
1560 }
1561 }
1562 }
1563 trm_reg_write8(STOPDMAXFER ,TRMREG_DMA_CONTROL);
1564}
1565
1566
1567static void
1568trm_DataOutPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1569{
1570 u_int16_t ioDir;
1571 /*
1572 * do prepare befor transfer when data out phase
1573 */
1574
1575 ioDir = XFERDATAOUT;
1576 trm_DataIO_transfer(pACB, pSRB, ioDir);
1577}
1578
1579static void
1580trm_DataInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1581{
1582 u_int8_t bval,SGIndexTemp;
1583 u_int16_t scsi_status;
1584 PSEG pseg;
1585 u_long TempSRBXferredLength,dLeftCounter = 0;
1586
1587 scsi_status = *pscsi_status;
1588 if (!(pSRB->SRBState & SRB_XFERPAD)) {
1589 if (scsi_status & PARITYERROR)
1590 pSRB->SRBStatus |= PARITY_ERROR;
1591 dLeftCounter += trm_reg_read32(TRMREG_SCSI_COUNTER);
1592 if ((dLeftCounter == 0) || (scsi_status & SCSIXFERCNT_2_ZERO)) {
1593 bval = trm_reg_read8(TRMREG_DMA_STATUS);
1594 while (!(bval & DMAXFERCOMP))
1595 bval = trm_reg_read8(TRMREG_DMA_STATUS);
1596 pSRB->SRBTotalXferLength = 0;
1597 } else {
1598 /*
1599 * parsing the case:
1600 * when a transfer not yet complete
1601 * but be disconnected by uper layer
1602 * if transfer not yet complete
1603 * there were some data residue in SCSI FIFO or
1604 * SCSI transfer counter not empty
1605 */
1606 if (pSRB->SRBTotalXferLength != dLeftCounter) {
1607 /*
1608 * data that had transferred length
1609 */
1610 TempSRBXferredLength =
1611 pSRB->SRBTotalXferLength - dLeftCounter;
1612 /*
1613 * next time to be transferred length
1614 */
1615 pSRB->SRBTotalXferLength = dLeftCounter;
1616 /*
1617 * parsing from last time disconnect SRBSGIndex
1618 */
1619 pseg = pSRB->SRBSGListPointer + pSRB->SRBSGIndex;
1620 for (SGIndexTemp = pSRB->SRBSGIndex;
1621 SGIndexTemp < pSRB->SRBSGCount;
1622 SGIndexTemp++) {
1623 /*
1624 * find last time which SG transfer be disconnect
1625 */
1626 if (TempSRBXferredLength >= pseg->length)
1627 TempSRBXferredLength -= pseg->length;
1628 else {
1629 /*
1630 * update last time disconnected SG list
1631 */
1632 pseg->length -= TempSRBXferredLength;
1633 /* residue data length */
1634 pseg->address += TempSRBXferredLength;
1635 /* residue data pointer */
1636 pSRB->SRBSGIndex = SGIndexTemp;
1637 break;
1638 }
1639 pseg++;
1640 }
1641 }
1642 }
1643 }
1644}
1645
1646static void
1647trm_DataInPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1648{
1649 u_int16_t ioDir;
1650 /*
1651 * do prepare befor transfer when data in phase
1652 */
1653
1654 ioDir = XFERDATAIN;
1655 trm_DataIO_transfer(pACB, pSRB, ioDir);
1656}
1657
1658static void
1659trm_DataIO_transfer(PACB pACB, PSRB pSRB, u_int16_t ioDir)
1660{
1661 u_int8_t bval;
1662 PDCB pDCB;
1663
1664 pDCB = pSRB->pSRBDCB;
1665 if (pSRB->SRBSGIndex < pSRB->SRBSGCount) {
1666 if (pSRB->SRBTotalXferLength != 0) {
1667 pSRB->SRBSGPhyAddr = vtophys(pSRB->SRBSGListPointer);
1668 /*
1669 * load what physical address of Scatter/Gather list
1670 table want to be transfer
1671 */
1672 pSRB->SRBState = SRB_DATA_XFER;
1673 trm_reg_write32(0, TRMREG_DMA_XHIGHADDR);
1674 trm_reg_write32(
1675 (pSRB->SRBSGPhyAddr +
1676 ((u_long)pSRB->SRBSGIndex << 3)),
1677 TRMREG_DMA_XLOWADDR);
1678 /*
1679 * load how many bytes in the Scatter/Gather
1680 * list table
1681 */
1682 trm_reg_write32(
1683 ((u_long)(pSRB->SRBSGCount - pSRB->SRBSGIndex) << 3),
1684 TRMREG_DMA_XCNT);
1685 /*
1686 * load total transfer length (24bits) max value
1687 * 16Mbyte
1688 */
1689 trm_reg_write32(pSRB->SRBTotalXferLength,
1690 TRMREG_SCSI_COUNTER);
1691 /* Start DMA transfer */
1692 trm_reg_write16(ioDir, TRMREG_DMA_COMMAND);
1693 /* Start SCSI transfer */
1694 trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1695 /* it's important for atn stop */
1696 /*
1697 * SCSI cammand
1698 */
1699 bval = (ioDir == XFERDATAOUT) ?
1700 SCMD_DMA_OUT : SCMD_DMA_IN;
1701 trm_reg_write8(bval, TRMREG_SCSI_COMMAND);
1702 } else {
1703 /* xfer pad */
1704 if (pSRB->SRBSGCount) {
1705 pSRB->AdaptStatus = H_OVER_UNDER_RUN;
1706 pSRB->SRBStatus |= OVER_RUN;
1707 }
1708 if (pDCB->SyncPeriod & WIDE_SYNC)
1709 trm_reg_write32(2,TRMREG_SCSI_COUNTER);
1710 else
1711 trm_reg_write32(1,TRMREG_SCSI_COUNTER);
1712 if (ioDir == XFERDATAOUT)
1713 trm_reg_write16(0, TRMREG_SCSI_FIFO);
1714 else
1715 trm_reg_read16(TRMREG_SCSI_FIFO);
1716 pSRB->SRBState |= SRB_XFERPAD;
1717 trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1718 /* it's important for atn stop */
1719 /*
1720 * SCSI cammand
1721 */
1722 bval = (ioDir == XFERDATAOUT) ?
1723 SCMD_FIFO_OUT : SCMD_FIFO_IN;
1724 trm_reg_write8(bval, TRMREG_SCSI_COMMAND);
1725 }
1726 }
1727}
1728
1729static void
1730trm_StatusPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1731{
1732
1733 pSRB->TargetStatus = trm_reg_read8(TRMREG_SCSI_FIFO);
1734 pSRB->SRBState = SRB_COMPLETED;
1735 *pscsi_status = PH_BUS_FREE;
1736 /*.. initial phase*/
1737 trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1738 /* it's important for atn stop */
1739 /*
1740 * SCSI cammand
1741 */
1742 trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
1743}
1744
1745
1746
1747static void
1748trm_StatusPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1749{
1750
1751 if (trm_reg_read16(TRMREG_DMA_COMMAND) & 0x0001) {
1752 if (!(trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x40))
1753 trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
1754 if (!(trm_reg_read16(TRMREG_DMA_FIFOCNT) & 0x8000))
1755 trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL);
1756 } else {
1757 if (!(trm_reg_read16(TRMREG_DMA_FIFOCNT) & 0x8000))
1758 trm_reg_write8(CLRXFIFO, TRMREG_DMA_CONTROL);
1759 if (!(trm_reg_read8(TRMREG_SCSI_FIFOCNT) & 0x40))
1760 trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
1761 }
1762 pSRB->SRBState = SRB_STATUS;
1763 trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
1764 /* it's important for atn stop */
1765 /*
1766 * SCSI cammand
1767 */
1768 trm_reg_write8(SCMD_COMP, TRMREG_SCSI_COMMAND);
1769}
1770
1771/*
1772 *scsiiom
1773 * trm_MsgInPhase0: one of trm_SCSI_phase0[] vectors
1774 * stateV = (void *) trm_SCSI_phase0[phase]
1775 * if phase =7
1776 * extended message codes:
1777 *
1778 * code description
1779 *
1780 * 02h Reserved
1781 * 00h MODIFY DATA POINTER
1782 * 01h SYNCHRONOUS DATA TRANSFER REQUEST
1783 * 03h WIDE DATA TRANSFER REQUEST
1784 * 04h - 7Fh Reserved
1785 * 80h - FFh Vendor specific
1786 *
1787 */
1788
1789static void
1790trm_MsgInPhase0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
1791{
1792 u_int8_t message_in_code,bIndex,message_in_tag_id;
1793 PDCB pDCB;
1794 PSRB pSRBTemp;
1795
1796 pDCB = pACB->pActiveDCB;
1797
1798 message_in_code = trm_reg_read8(TRMREG_SCSI_FIFO);
1799 if (!(pSRB->SRBState & SRB_EXTEND_MSGIN)) {
1800 if (message_in_code == MSG_DISCONNECT) {
1801 pSRB->SRBState = SRB_DISCONNECT;
1802 goto min6;
1803 } else if (message_in_code == MSG_SAVE_PTR) {
1804 goto min6;
1805 } else if ((message_in_code == MSG_EXTENDED) ||
1806 ((message_in_code >= MSG_SIMPLE_QTAG) &&
1807 (message_in_code <= MSG_ORDER_QTAG))) {
1808 pSRB->SRBState |= SRB_EXTEND_MSGIN;
1809 pSRB->MsgInBuf[0] = message_in_code;
1810 /* extended message (01h) */
1811 pSRB->MsgCnt = 1;
1812 pSRB->pMsgPtr = &pSRB->MsgInBuf[1];
1813 /* extended message length (n) */
1814 goto min6;
1815 } else if (message_in_code == MSG_REJECT_) {
1816 /* Reject message */
1817 if (pDCB->SyncMode & WIDE_NEGO_ENABLE) {
1818 /* do wide nego reject */
1819 pDCB = pSRB->pSRBDCB;
1820 pDCB->SyncMode |= WIDE_NEGO_DONE;
1821 pDCB->SyncMode &= ~(SYNC_NEGO_DONE |
1822 EN_ATN_STOP | WIDE_NEGO_ENABLE);
1823 pSRB->SRBState &= ~(SRB_DO_WIDE_NEGO+SRB_MSGIN);
1824 if ((pDCB->SyncMode & SYNC_NEGO_ENABLE)
1825 && !(pDCB->SyncMode & SYNC_NEGO_DONE)) {
1826 /* Set ATN, in case ATN was clear */
1827 pSRB->SRBState |= SRB_MSGOUT;
1828 trm_reg_write16(
1829 DO_SETATN,
1830 TRMREG_SCSI_CONTROL);
1831 } else {
1832 /* Clear ATN */
1833 trm_reg_write16(
1834 DO_CLRATN,
1835 TRMREG_SCSI_CONTROL);
1836 }
1837 } else if (pDCB->SyncMode & SYNC_NEGO_ENABLE) {
1838 /* do sync nego reject */
1839 trm_reg_write16(DO_CLRATN,TRMREG_SCSI_CONTROL);
1840 if (pSRB->SRBState & SRB_DO_SYNC_NEGO) {
1841 pDCB = pSRB->pSRBDCB;
1842 pDCB->SyncMode &=
1843 ~(SYNC_NEGO_ENABLE+SYNC_NEGO_DONE);
1844 pDCB->SyncPeriod = 0;
1845 pDCB->SyncOffset = 0;
1846 goto re_prog;
1847 }
1848 }
1849 goto min6;
1850 } else if (message_in_code == MSG_IGNOREWIDE) {
1851 trm_reg_write32(1, TRMREG_SCSI_COUNTER);
1852 trm_reg_read8(TRMREG_SCSI_FIFO);
1853 goto min6;
1854 } else {
1855 /* Restore data pointer message */
1856 /* Save data pointer message */
1857 /* Completion message */
1858 /* NOP message */
1859 goto min6;
1860 }
1861 } else {
1862 /*
1863 * Parsing incomming extented messages
1864 */
1865 *pSRB->pMsgPtr = message_in_code;
1866 pSRB->MsgCnt++;
1867 pSRB->pMsgPtr++;
1868 TRM_DPRINTF("pSRB->MsgInBuf[0]=%2x \n ",pSRB->MsgInBuf[0]);
1869 TRM_DPRINTF("pSRB->MsgInBuf[1]=%2x \n ",pSRB->MsgInBuf[1]);
1870 TRM_DPRINTF("pSRB->MsgInBuf[2]=%2x \n ",pSRB->MsgInBuf[2]);
1871 TRM_DPRINTF("pSRB->MsgInBuf[3]=%2x \n ",pSRB->MsgInBuf[3]);
1872 TRM_DPRINTF("pSRB->MsgInBuf[4]=%2x \n ",pSRB->MsgInBuf[4]);
1873 if ((pSRB->MsgInBuf[0] >= MSG_SIMPLE_QTAG)
1874 && (pSRB->MsgInBuf[0] <= MSG_ORDER_QTAG)) {
1875 /*
1876 * is QUEUE tag message :
1877 *
1878 * byte 0:
1879 * HEAD QUEUE TAG (20h)
1880 * ORDERED QUEUE TAG (21h)
1881 * SIMPLE QUEUE TAG (22h)
1882 * byte 1:
1883 * Queue tag (00h - FFh)
1884 */
1885 if (pSRB->MsgCnt == 2) {
1886 pSRB->SRBState = 0;
1887 message_in_tag_id = pSRB->MsgInBuf[1];
1888 pSRB = pDCB->pGoingSRB;
1889 pSRBTemp = pDCB->pGoingLastSRB;
1890 if (pSRB) {
1891 for (;;) {
1892 if (pSRB->TagNumber !=
1893 message_in_tag_id) {
1894 if (pSRB == pSRBTemp) {
1895 goto mingx0;
1896 }
1897 pSRB = pSRB->pNextSRB;
1898 } else
1899 break;
1900 }
1901 if (pDCB->DCBFlag & ABORT_DEV_) {
1902 pSRB->SRBState = SRB_ABORT_SENT;
1903 trm_EnableMsgOutAbort1(
1904 pACB, pSRB);
1905 }
1906 if (!(pSRB->SRBState & SRB_DISCONNECT))
1907 goto mingx0;
1908 pDCB->pActiveSRB = pSRB;
1909 pSRB->SRBState = SRB_DATA_XFER;
1910 } else {
1911mingx0:
1912 pSRB = pACB->pTmpSRB;
1913 pSRB->SRBState = SRB_UNEXPECT_RESEL;
1914 pDCB->pActiveSRB = pSRB;
1915 pSRB->MsgOutBuf[0] = MSG_ABORT_TAG;
1916 trm_EnableMsgOutAbort2(
1917 pACB,
1918 pSRB);
1919 }
1920 }
1921 } else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) &&
1922 (pSRB->MsgInBuf[2] == 3) && (pSRB->MsgCnt == 4)) {
1923 /*
1924 * is Wide data xfer Extended message :
1925 * ======================================
1926 * WIDE DATA TRANSFER REQUEST
1927 * ======================================
1928 * byte 0 : Extended message (01h)
1929 * byte 1 : Extended message length (02h)
1930 * byte 2 : WIDE DATA TRANSFER code (03h)
1931 * byte 3 : Transfer width exponent
1932 */
1933 pDCB = pSRB->pSRBDCB;
1934 pSRB->SRBState &= ~(SRB_EXTEND_MSGIN+SRB_DO_WIDE_NEGO);
1935 if ((pSRB->MsgInBuf[1] != 2)) {
1936 /* Length is wrong, reject it */
1937 pDCB->SyncMode &=
1938 ~(WIDE_NEGO_ENABLE+WIDE_NEGO_DONE);
1939 pSRB->MsgCnt = 1;
1940 pSRB->MsgInBuf[0] = MSG_REJECT_;
1941 trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
1942 goto min6;
1943 }
1944 if (pDCB->SyncMode & WIDE_NEGO_ENABLE) {
1945 /* Do wide negoniation */
1946 if (pSRB->MsgInBuf[3] > 2) {
1947 /* > 32 bit */
1948 /* reject_msg: */
1949 pDCB->SyncMode &=
1950 ~(WIDE_NEGO_ENABLE+WIDE_NEGO_DONE);
1951 pSRB->MsgCnt = 1;
1952 pSRB->MsgInBuf[0] = MSG_REJECT_;
1953 trm_reg_write16(DO_SETATN,
1954 TRMREG_SCSI_CONTROL);
1955 goto min6;
1956 }
1957 if (pSRB->MsgInBuf[3] == 2) {
1958 pSRB->MsgInBuf[3] = 1;
1959 /* do 16 bits */
1960 } else {
1961 if (!(pDCB->SyncMode
1962 & WIDE_NEGO_DONE)) {
1963 pSRB->SRBState &=
1964 ~(SRB_DO_WIDE_NEGO+SRB_MSGIN);
1965 pDCB->SyncMode |=
1966 WIDE_NEGO_DONE;
1967 pDCB->SyncMode &=
1968 ~(SYNC_NEGO_DONE |
1969 EN_ATN_STOP |
1970 WIDE_NEGO_ENABLE);
1971 if (pSRB->MsgInBuf[3] != 0) {
1972 /* is Wide data xfer */
1973 pDCB->SyncPeriod |=
1974 WIDE_SYNC;
1975 pDCB->tinfo.current.width
1976 = MSG_EXT_WDTR_BUS_16_BIT;
1977 pDCB->tinfo.goal.width
1978 = MSG_EXT_WDTR_BUS_16_BIT;
1979 }
1980 }
1981 }
1982 } else
1983 pSRB->MsgInBuf[3] = 0;
1984 pSRB->SRBState |= SRB_MSGOUT;
1985 trm_reg_write16(DO_SETATN,TRMREG_SCSI_CONTROL);
1986 goto min6;
1987 } else if ((pSRB->MsgInBuf[0] == MSG_EXTENDED) &&
1988 (pSRB->MsgInBuf[2] == 1) && (pSRB->MsgCnt == 5)) {
1989 /*
1990 * is 8bit transfer Extended message :
1991 * =================================
1992 * SYNCHRONOUS DATA TRANSFER REQUEST
1993 * =================================
1994 * byte 0 : Extended message (01h)
1995 * byte 1 : Extended message length (03)
1996 * byte 2 : SYNCHRONOUS DATA TRANSFER code (01h)
1997 * byte 3 : Transfer period factor
1998 * byte 4 : REQ/ACK offset
1999 */
2000 pSRB->SRBState &= ~(SRB_EXTEND_MSGIN+SRB_DO_SYNC_NEGO);
2001 if ((pSRB->MsgInBuf[1] != 3) ||
2002 (pSRB->MsgInBuf[2] != 1)) {
2003 /* reject_msg: */
2004 pSRB->MsgCnt = 1;
2005 pSRB->MsgInBuf[0] = MSG_REJECT_;
2006 trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
2007 } else if (!(pSRB->MsgInBuf[3]) || !(pSRB->MsgInBuf[4])) {
2008 /* set async */
2009 pDCB = pSRB->pSRBDCB;
2010 /* disable sync & sync nego */
2011 pDCB->SyncMode &=
2012 ~(SYNC_NEGO_ENABLE+SYNC_NEGO_DONE);
2013 pDCB->SyncPeriod = 0;
2014 pDCB->SyncOffset = 0;
2015 pDCB->tinfo.goal.period = 0;
2016 pDCB->tinfo.goal.offset = 0;
2017 pDCB->tinfo.current.period = 0;
2018 pDCB->tinfo.current.offset = 0;
2019 pDCB->tinfo.current.width =
2020 MSG_EXT_WDTR_BUS_8_BIT;
2021 goto re_prog;
2022 } else {
2023 /* set sync */
2024 pDCB = pSRB->pSRBDCB;
2025 pDCB->SyncMode |=
2026 SYNC_NEGO_ENABLE+SYNC_NEGO_DONE;
2027 pDCB->MaxNegoPeriod = pSRB->MsgInBuf[3];
2028 /* Transfer period factor */
2029 pDCB->SyncOffset = pSRB->MsgInBuf[4];
2030 /* REQ/ACK offset */
2031 for (bIndex = 0; bIndex < 7; bIndex++) {
2032 if (pSRB->MsgInBuf[3] <=
2033 dc395x_trm_clock_period[bIndex]) {
2034 break;
2035 }
2036 }
2037 pDCB->tinfo.goal.period =
2038 dc395x_trm_tinfo_sync_period[bIndex];
2039 pDCB->tinfo.current.period =
2040 dc395x_trm_tinfo_sync_period[bIndex];
2041 pDCB->tinfo.goal.offset = pDCB->SyncOffset;
2042 pDCB->tinfo.current.offset = pDCB->SyncOffset;
2043 pDCB->SyncPeriod |= (bIndex | ALT_SYNC);
2044re_prog:
2045 /*
2046 *
2047 * program SCSI control register
2048 *
2049 */
2050 trm_reg_write8(pDCB->SyncPeriod,
2051 TRMREG_SCSI_SYNC);
2052 trm_reg_write8(pDCB->SyncOffset,
2053 TRMREG_SCSI_OFFSET);
2054 trm_SetXferRate(pACB,pSRB,pDCB);
2055 }
2056 }
2057 }
2058min6:
2059 *pscsi_status = PH_BUS_FREE;
2060 /* .. initial phase */
2061 trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
2062 /* it's important for atn stop */
2063 /*
2064 * SCSI cammand
2065 */
2066 trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
2067}
2068
2069static void
2070trm_MsgInPhase1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
2071{
2072
2073 trm_reg_write16(DO_CLRFIFO, TRMREG_SCSI_CONTROL);
2074 trm_reg_write32(1,TRMREG_SCSI_COUNTER);
2075 if (!(pSRB->SRBState & SRB_MSGIN)) {
2076 pSRB->SRBState &= SRB_DISCONNECT;
2077 pSRB->SRBState |= SRB_MSGIN;
2078 }
2079 trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
2080 /* it's important for atn stop*/
2081 /*
2082 * SCSI cammand
2083 */
2084 trm_reg_write8(SCMD_FIFO_IN, TRMREG_SCSI_COMMAND);
2085}
2086
2087static void
2088trm_Nop0(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
2089{
2090
2091}
2092
2093static void
2094trm_Nop1(PACB pACB, PSRB pSRB, u_int8_t *pscsi_status)
2095{
2096
2097}
2098
2099static void
2100trm_SetXferRate(PACB pACB,PSRB pSRB, PDCB pDCB)
2101{
2102 u_int16_t cnt, i;
2103 u_int8_t bval;
2104 PDCB pDCBTemp;
2105 u_int target_id,target_lun;
2106
2107 /*
2108 * set all lun device's period , offset
2109 */
2110 target_id = pSRB->pccb->ccb_h.target_id;
2111 target_lun = pSRB->pccb->ccb_h.target_lun;
2112 TRM_DPRINTF("trm_SetXferRate:target_id= %d ,target_lun= %d \n"
2113 ,target_id,target_lun);
2114 if (!(pDCB->IdentifyMsg & 0x07)) {
2115 if (!pACB->scan_devices[target_id][target_lun]) {
2116 pDCBTemp = pACB->pLinkDCB;
2117 cnt = pACB->DeviceCnt;
2118 bval = pDCB->TargetID;
2119 for (i = 0; i < cnt; i++) {
2120 if (pDCBTemp->TargetID == bval) {
2121 pDCBTemp->SyncPeriod = pDCB->SyncPeriod;
2122 pDCBTemp->SyncOffset = pDCB->SyncOffset;
2123 pDCBTemp->SyncMode = pDCB->SyncMode;
2124 }
2125 pDCBTemp = pDCBTemp->pNextDCB;
2126 }
2127 }
2128 }
2129 return;
2130}
2131
2132/*
2133 * scsiiom
2134 * trm_Interrupt
2135 *
2136 *
2137 * ---SCSI bus phase
2138 *
2139 * PH_DATA_OUT 0x00 Data out phase
2140 * PH_DATA_IN 0x01 Data in phase
2141 * PH_COMMAND 0x02 Command phase
2142 * PH_STATUS 0x03 Status phase
2143 * PH_BUS_FREE 0x04 Invalid phase used as bus free
2144 * PH_BUS_FREE 0x05 Invalid phase used as bus free
2145 * PH_MSG_OUT 0x06 Message out phase
2146 * PH_MSG_IN 0x07 Message in phase
2147 *
2148 */
2149static void
2150trm_Disconnect(PACB pACB)
2151{
2152 PDCB pDCB;
2153 PSRB pSRB, psrb;
984263bc
MD
2154 u_int16_t i,j, cnt;
2155 u_int8_t bval;
2156 u_int target_id,target_lun;
2157
2158 TRM_DPRINTF("trm_Disconnect...............\n ");
2159
d9ed64be 2160 crit_enter();
984263bc
MD
2161 pDCB = pACB->pActiveDCB;
2162 if (!pDCB) {
2163 TRM_DPRINTF(" Exception Disconnect DCB=NULL..............\n ");
2164 j = 400;
2165 while (--j)
2166 DELAY(1);
2167 /* 1 msec */
2168 trm_reg_write16((DO_CLRFIFO | DO_HWRESELECT),
2169 TRMREG_SCSI_CONTROL);
d9ed64be 2170 crit_exit();
984263bc
MD
2171 return;
2172 }
2173 pSRB = pDCB->pActiveSRB;
2174 /* bug pSRB=0 */
2175 target_id = pSRB->pccb->ccb_h.target_id;
2176 target_lun = pSRB->pccb->ccb_h.target_lun;
2177 TRM_DPRINTF(":pDCB->pActiveSRB= %8x \n ",(u_int) pDCB->pActiveSRB);
2178 pACB->pActiveDCB = 0;
2179 pSRB->ScsiPhase = PH_BUS_FREE;
2180 /* SCSI bus free Phase */
2181 trm_reg_write16((DO_CLRFIFO | DO_HWRESELECT), TRMREG_SCSI_CONTROL);
2182 if (pSRB->SRBState & SRB_UNEXPECT_RESEL) {
2183 pSRB->SRBState = 0;
2184 trm_DoWaitingSRB(pACB);
2185 } else if (pSRB->SRBState & SRB_ABORT_SENT) {
2186 pDCB->TagMask = 0;
2187 pDCB->DCBFlag = 0;
2188 cnt = pDCB->GoingSRBCnt;
2189 pDCB->GoingSRBCnt = 0;
2190 pSRB = pDCB->pGoingSRB;
2191 for (i = 0; i < cnt; i++) {
2192 psrb = pSRB->pNextSRB;
2193 pSRB->pNextSRB = pACB->pFreeSRB;
2194 pACB->pFreeSRB = pSRB;
2195 pSRB = psrb;
2196 }
2197 pDCB->pGoingSRB = 0;
2198 trm_DoWaitingSRB(pACB);
2199 } else {
2200 if ((pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||
2201 !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED))) {
2202 /* Selection time out */
2203 if (!(pACB->scan_devices[target_id][target_lun])) {
2204 pSRB->SRBState = SRB_READY;
2205 trm_RewaitSRB(pDCB, pSRB);
2206 } else {
2207 pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
2208 goto disc1;
2209 }
2210 } else if (pSRB->SRBState & SRB_DISCONNECT) {
2211 /*
2212 * SRB_DISCONNECT
2213 */
2214 trm_DoWaitingSRB(pACB);
2215 } else if (pSRB->SRBState & SRB_COMPLETED) {
2216disc1:
2217 /*
2218 * SRB_COMPLETED
2219 */
2220 if (pDCB->MaxCommand > 1) {
2221 bval = pSRB->TagNumber;
2222 pDCB->TagMask &= (~(1 << bval));
2223 /* free tag mask */
2224 }
2225 pDCB->pActiveSRB = 0;
2226 pSRB->SRBState = SRB_FREE;
2227 trm_SRBdone(pACB, pDCB, pSRB);
2228 }
2229 }
d9ed64be 2230 crit_exit();
984263bc
MD
2231 return;
2232}
2233
2234static void
2235trm_Reselect(PACB pACB)
2236{
2237 PDCB pDCB;
2238 PSRB pSRB;
2239 u_int16_t RselTarLunId;
2240
2241 TRM_DPRINTF("trm_Reselect................. \n");
2242 pDCB = pACB->pActiveDCB;
2243 if (pDCB) {
2244 /* Arbitration lost but Reselection win */
2245 pSRB = pDCB->pActiveSRB;
2246 pSRB->SRBState = SRB_READY;
2247 trm_RewaitSRB(pDCB, pSRB);
2248 }
2249 /* Read Reselected Target Id and LUN */
2250 RselTarLunId = trm_reg_read16(TRMREG_SCSI_TARGETID) & 0x1FFF;
2251 pDCB = pACB->pLinkDCB;
2252 while (RselTarLunId != *((u_int16_t *) &pDCB->TargetID)) {
2253 /* get pDCB of the reselect id */
2254 pDCB = pDCB->pNextDCB;
2255 }
2256
2257 pACB->pActiveDCB = pDCB;
2258 if (pDCB->SyncMode & EN_TAG_QUEUING) {
2259 pSRB = pACB->pTmpSRB;
2260 pDCB->pActiveSRB = pSRB;
2261 } else {
2262 pSRB = pDCB->pActiveSRB;
2263 if (!pSRB || !(pSRB->SRBState & SRB_DISCONNECT)) {
2264 /*
2265 * abort command
2266 */
2267 pSRB = pACB->pTmpSRB;
2268 pSRB->SRBState = SRB_UNEXPECT_RESEL;
2269 pDCB->pActiveSRB = pSRB;
2270 trm_EnableMsgOutAbort1(pACB, pSRB);
2271 } else {
2272 if (pDCB->DCBFlag & ABORT_DEV_) {
2273 pSRB->SRBState = SRB_ABORT_SENT;
2274 trm_EnableMsgOutAbort1(pACB, pSRB);
2275 } else
2276 pSRB->SRBState = SRB_DATA_XFER;
2277 }
2278 }
2279 pSRB->ScsiPhase = PH_BUS_FREE;
2280 /* SCSI bus free Phase */
2281 /*
2282 * Program HA ID, target ID, period and offset
2283 */
2284 trm_reg_write8((u_int8_t) RselTarLunId,TRMREG_SCSI_TARGETID);
2285 /* target ID */
2286 trm_reg_write8(pACB->AdaptSCSIID,TRMREG_SCSI_HOSTID);
2287 /* host ID */
2288 trm_reg_write8(pDCB->SyncPeriod,TRMREG_SCSI_SYNC);
2289 /* period */
2290 trm_reg_write8(pDCB->SyncOffset,TRMREG_SCSI_OFFSET);
2291 /* offset */
2292 trm_reg_write16(DO_DATALATCH, TRMREG_SCSI_CONTROL);
2293 /* it's important for atn stop*/
2294 /*
2295 * SCSI cammand
2296 */
2297 trm_reg_write8(SCMD_MSGACCEPT, TRMREG_SCSI_COMMAND);
2298 /* to rls the /ACK signal */
2299}
2300
2301static void
2302trm_SRBdone(PACB pACB, PDCB pDCB, PSRB pSRB)
2303{
2304 PSRB psrb;
2305 u_int8_t bval, bval1,status;
2306 union ccb *pccb;
2307 struct ccb_scsiio *pcsio;
2308 PSCSI_INQDATA ptr;
984263bc
MD
2309 u_int target_id,target_lun;
2310 PDCB pTempDCB;
2311
2312 pccb = pSRB->pccb;
2313 if (pccb == NULL)
2314 return;
2315 pcsio = &pccb->csio;
2316 target_id = pSRB->pccb->ccb_h.target_id;
2317 target_lun = pSRB->pccb->ccb_h.target_lun;
2318 if ((pccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
2319 bus_dmasync_op_t op;
2320 if ((pccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN)
2321 op = BUS_DMASYNC_POSTREAD;
2322 else
2323 op = BUS_DMASYNC_POSTWRITE;
2324 bus_dmamap_sync(pACB->buffer_dmat, pSRB->dmamap, op);
2325 bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap);
2326 }
2327 /*
2328 *
2329 * target status
2330 *
2331 */
2332 status = pSRB->TargetStatus;
2333 pcsio->scsi_status=SCSI_STAT_GOOD;
2334 pccb->ccb_h.status = CAM_REQ_CMP;
2335 if (pSRB->SRBFlag & AUTO_REQSENSE) {
2336 /*
2337 * status of auto request sense
2338 */
2339 pSRB->SRBFlag &= ~AUTO_REQSENSE;
2340 pSRB->AdaptStatus = 0;
2341 pSRB->TargetStatus = SCSI_STATUS_CHECK_COND;
2342
2343 if (status == SCSI_STATUS_CHECK_COND) {
2344 pccb->ccb_h.status = CAM_SEL_TIMEOUT;
2345 goto ckc_e;
2346 }
2347 *((u_long *) &(pSRB->CmdBlock[0])) = pSRB->Segment0[0];
2348 *((u_long *) &(pSRB->CmdBlock[4])) = pSRB->Segment0[1];
2349 pSRB->SRBTotalXferLength = pSRB->Segment1[1];
2350 pSRB->SegmentX[0].address = pSRB->SgSenseTemp.address;
2351 pSRB->SegmentX[0].length = pSRB->SgSenseTemp.length;
2352 pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
2353 pccb->ccb_h.status = CAM_AUTOSNS_VALID;
2354 goto ckc_e;
2355 }
2356 /*
2357 * target status
2358 */
2359 if (status) {
2360 if (status == SCSI_STATUS_CHECK_COND) {
2361 if ((pcsio->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0) {
2362 TRM_DPRINTF("trm_RequestSense..................\n");
2363 trm_RequestSense(pACB, pDCB, pSRB);
2364 return;
2365 }
2366 pcsio->scsi_status = SCSI_STATUS_CHECK_COND;
2367 pccb->ccb_h.status = CAM_AUTOSNS_VALID |
2368 CAM_SCSI_STATUS_ERROR;
2369 goto ckc_e;
2370 } else if (status == SCSI_STAT_QUEUEFULL) {
2371 bval = (u_int8_t) pDCB->GoingSRBCnt;
2372 bval--;
2373 pDCB->MaxCommand = bval;
2374 trm_RewaitSRB(pDCB, pSRB);
2375 pSRB->AdaptStatus = 0;
2376 pSRB->TargetStatus = 0;
2377 pcsio->scsi_status = SCSI_STAT_QUEUEFULL;
2378 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
2379 goto ckc_e;
2380 } else if (status == SCSI_STAT_SEL_TIMEOUT) {
2381 pSRB->AdaptStatus = H_SEL_TIMEOUT;
2382 pSRB->TargetStatus = 0;
2383 pcsio->scsi_status = SCSI_STAT_SEL_TIMEOUT;
2384 pccb->ccb_h.status = CAM_SEL_TIMEOUT;
2385 } else if (status == SCSI_STAT_BUSY) {
2386 TRM_DPRINTF("trm: target busy at %s %d\n",
2387 __FILE__, __LINE__);
2388 pcsio->scsi_status = SCSI_STAT_BUSY;
2389 pccb->ccb_h.status = CAM_SCSI_BUSY;
2390 /* The device busy, try again later? */
2391 } else if (status == SCSI_STAT_RESCONFLICT) {
2392 TRM_DPRINTF("trm: target reserved at %s %d\n",
2393 __FILE__, __LINE__);
2394 pcsio->scsi_status = SCSI_STAT_RESCONFLICT;
2395 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; /*XXX*/
2396 } else {
2397 pSRB->AdaptStatus = 0;
2398 if (pSRB->RetryCnt) {
2399 pSRB->RetryCnt--;
2400 pSRB->TargetStatus = 0;
2401 pSRB->SRBSGIndex = 0;
2402 pSRB->SRBSGListPointer = (PSEG)
2403 &pSRB->SegmentX[0];
2404 if (trm_StartSCSI(pACB, pDCB, pSRB)) {
2405 /*
2406 * If trm_StartSCSI return 1 :
2407 * current interrupt status is interrupt
2408 * disreenable
2409 * It's said that SCSI processor has more
2410 * one SRB need to do
2411 */
2412 trm_RewaitSRB(pDCB, pSRB);
2413 }
2414 return;
2415 } else {
2416 TRM_DPRINTF("trm: driver stuffup at %s %d\n",
2417 __FILE__, __LINE__);
2418 pccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
2419 }
2420 }
2421 } else {
2422 /*
2423 * process initiator status..........................
2424 * Adapter (initiator) status
2425 */
2426 status = pSRB->AdaptStatus;
2427 if (status & H_OVER_UNDER_RUN) {
2428 pSRB->TargetStatus = 0;
2429 pccb->ccb_h.status = CAM_DATA_RUN_ERR;
2430 /* Illegal length (over/under run) */
2431 } else if (pSRB->SRBStatus & PARITY_ERROR) {
2432 TRM_DPRINTF("trm: driver stuffup %s %d\n",
2433 __FILE__, __LINE__);
2434 pDCB->tinfo.goal.period = 0;
2435 pDCB->tinfo.goal.offset = 0;
2436 /* Driver failed to perform operation */
2437 pccb->ccb_h.status = CAM_UNCOR_PARITY;
2438 } else {
2439 /* no error */
2440 pSRB->AdaptStatus = 0;
2441 pSRB->TargetStatus = 0;
2442 pccb->ccb_h.status = CAM_REQ_CMP;
2443 /* there is no error, (sense is invalid) */
2444 }
2445 }
2446ckc_e:
2447 if (pACB->scan_devices[target_id][target_lun]) {
2448 /*
2449 * if SCSI command in "scan devices" duty
2450 */
2451 if (pSRB->CmdBlock[0] == TEST_UNIT_READY)
2452 pACB->scan_devices[target_id][target_lun] = 0;
2453 /* SCSI command phase :test unit ready */
2454 else if (pSRB->CmdBlock[0] == INQUIRY) {
2455 /*
2456 * SCSI command phase :inquiry scsi device data
2457 * (type,capacity,manufacture....
2458 */
2459 if (pccb->ccb_h.status == CAM_SEL_TIMEOUT)
2460 goto NO_DEV;
2461 ptr = (PSCSI_INQDATA) pcsio->data_ptr;
2462 /* page fault */
2463 TRM_DPRINTF("trm_SRBdone..PSCSI_INQDATA:%2x \n",
2464 ptr->DevType);
2465 bval1 = ptr->DevType & SCSI_DEVTYPE;
2466 if (bval1 == SCSI_NODEV) {
2467NO_DEV:
2468 TRM_DPRINTF("trm_SRBdone NO Device:target_id= %d ,target_lun= %d \n",
2469 target_id,
2470 target_lun);
d9ed64be 2471 crit_enter();
984263bc
MD
2472 pACB->scan_devices[target_id][target_lun] = 0;
2473 /* no device set scan device flag =0*/
2474 /* pDCB Q link */
2475 /* move the head of DCB to tempDCB*/
2476 pTempDCB=pACB->pLinkDCB;
2477 /* search current DCB for pass link */
2478 while (pTempDCB->pNextDCB != pDCB) {
2479 pTempDCB = pTempDCB->pNextDCB;
2480 }
2481 /*
2482 * when the current DCB found than connect
2483 * current DCB tail
2484 */
2485 /* to the DCB tail that before current DCB */
2486 pTempDCB->pNextDCB = pDCB->pNextDCB;
2487 /*
2488 * if there was only one DCB ,connect his tail
2489 * to his head
2490 */
2491 if (pACB->pLinkDCB == pDCB)
2492 pACB->pLinkDCB = pTempDCB->pNextDCB;
2493 if (pACB->pDCBRunRobin == pDCB)
2494 pACB->pDCBRunRobin = pTempDCB->pNextDCB;
2495 pACB->DeviceCnt--;
2496 if (pACB->DeviceCnt == 0) {
2497 pACB->pLinkDCB = NULL;
2498 pACB->pDCBRunRobin = NULL;
2499 }
d9ed64be 2500 crit_exit();
984263bc
MD
2501 } else {
2502#ifdef trm_DEBUG1
2503 int j;
2504 for (j = 0; j < 28; j++) {
2505 TRM_DPRINTF("ptr=%2x ",
2506 ((u_int8_t *)ptr)[j]);
2507 }
2508#endif
2509 pDCB->DevType = bval1;
2510 if (bval1 == SCSI_DASD ||
2511 bval1 == SCSI_OPTICAL) {
2512 if ((((ptr->Vers & 0x07) >= 2) ||
2513 ((ptr->RDF & 0x0F) == 2)) &&
2514 (ptr->Flags & SCSI_INQ_CMDQUEUE) &&
2515 (pDCB->DevMode & TAG_QUEUING_) &&
2516 (pDCB->DevMode & EN_DISCONNECT_)) {
2517 if (pDCB->DevMode &
2518 TAG_QUEUING_) {
2519 pDCB->MaxCommand =
2520 pACB->TagMaxNum;
2521 pDCB->SyncMode |=
2522 EN_TAG_QUEUING;
2523 pDCB->TagMask = 0;
2524 pDCB->tinfo.disc_tag |=
2525 TRM_CUR_TAGENB;
2526 } else {
2527 pDCB->SyncMode |=
2528 EN_ATN_STOP;
2529 pDCB->tinfo.disc_tag &=
2530 ~TRM_CUR_TAGENB;
2531 }
2532 }
2533 }
2534 }
2535 /* pSRB->CmdBlock[0] == INQUIRY */
2536 }
2537 /* pACB->scan_devices[target_id][target_lun] */
2538 }
d9ed64be 2539 crit_enter();
984263bc
MD
2540 /* ReleaseSRB(pDCB, pSRB); */
2541 if (pSRB == pDCB->pGoingSRB)
2542 pDCB->pGoingSRB = pSRB->pNextSRB;
2543 else {
2544 psrb = pDCB->pGoingSRB;
2545 while (psrb->pNextSRB != pSRB) {
2546 psrb = psrb->pNextSRB;
2547 }
2548 psrb->pNextSRB = pSRB->pNextSRB;
2549 if (pSRB == pDCB->pGoingLastSRB) {
2550 pDCB->pGoingLastSRB = psrb;
2551 }
2552 }
2553 pSRB->pNextSRB = pACB->pFreeSRB;
2554 pACB->pFreeSRB = pSRB;
2555 pDCB->GoingSRBCnt--;
2556 trm_DoWaitingSRB(pACB);
2557
d9ed64be 2558 crit_exit();
984263bc
MD
2559 /* Notify cmd done */
2560 xpt_done (pccb);
2561}
2562
2563static void
2564trm_DoingSRB_Done(PACB pACB)
2565{
2566 PDCB pDCB, pdcb;
2567 PSRB psrb, psrb2;
2568 u_int16_t cnt, i;
2569 union ccb *pccb;
2570
2571 pDCB = pACB->pLinkDCB;
2572 if (pDCB == NULL)
2573 return;
2574 pdcb = pDCB;
2575 do {
2576 cnt = pdcb->GoingSRBCnt;
2577 psrb = pdcb->pGoingSRB;
2578 for (i = 0; i < cnt; i++) {
2579 psrb2 = psrb->pNextSRB;
2580 pccb = psrb->pccb;
2581 pccb->ccb_h.status = CAM_SEL_TIMEOUT;
2582 /* ReleaseSRB(pDCB, pSRB); */
2583 psrb->pNextSRB = pACB->pFreeSRB;
2584 pACB->pFreeSRB = psrb;
2585 xpt_done(pccb);
2586 psrb = psrb2;
2587 }
fc6d0222 2588 pdcb->GoingSRBCnt = 0;
984263bc
MD
2589 pdcb->pGoingSRB = NULL;
2590 pdcb->TagMask = 0;
2591 pdcb = pdcb->pNextDCB;
2592 }
2593 while (pdcb != pDCB);
2594}
2595
2596static void
2597trm_ResetSCSIBus(PACB pACB)
2598{
d9ed64be 2599 crit_enter();
984263bc
MD
2600 pACB->ACBFlag |= RESET_DEV;
2601
2602 trm_reg_write16(DO_RSTSCSI,TRMREG_SCSI_CONTROL);
2603 while (!(trm_reg_read16(TRMREG_SCSI_INTSTATUS) & INT_SCSIRESET));
d9ed64be 2604 crit_exit();
984263bc
MD
2605 return;
2606}
2607
2608static void
2609trm_ScsiRstDetect(PACB pACB)
2610{
984263bc
MD
2611 u_long wlval;
2612
2613 TRM_DPRINTF("trm_ScsiRstDetect \n");
2614 wlval = 1000;
2615 while (--wlval)
2616 DELAY(1000);
d9ed64be 2617 crit_enter();
984263bc
MD
2618 trm_reg_write8(STOPDMAXFER,TRMREG_DMA_CONTROL);
2619
2620 trm_reg_write16(DO_CLRFIFO,TRMREG_SCSI_CONTROL);
2621
2622 if (pACB->ACBFlag & RESET_DEV)
2623 pACB->ACBFlag |= RESET_DONE;
2624 else {
2625 pACB->ACBFlag |= RESET_DETECT;
2626 trm_ResetDevParam(pACB);
2627 /* trm_DoingSRB_Done(pACB); ???? */
2628 trm_RecoverSRB(pACB);
2629 pACB->pActiveDCB = NULL;
2630 pACB->ACBFlag = 0;
2631 trm_DoWaitingSRB(pACB);
2632 }
d9ed64be 2633 crit_exit();
984263bc
MD
2634 return;
2635}
2636
2637static void
2638trm_RequestSense(PACB pACB, PDCB pDCB, PSRB pSRB)
2639{
2640 union ccb *pccb;
2641 struct ccb_scsiio *pcsio;
2642
2643 pccb = pSRB->pccb;
2644 pcsio = &pccb->csio;
2645
2646 pSRB->SRBFlag |= AUTO_REQSENSE;
2647 pSRB->Segment0[0] = *((u_long *) &(pSRB->CmdBlock[0]));
2648 pSRB->Segment0[1] = *((u_long *) &(pSRB->CmdBlock[4]));
2649 pSRB->Segment1[0] = (u_long) ((pSRB->ScsiCmdLen << 8) +
2650 pSRB->SRBSGCount);
2651 pSRB->Segment1[1] = pSRB->SRBTotalXferLength; /* ?????????? */
2652
2653 /* $$$$$$ Status of initiator/target $$$$$$$$ */
2654 pSRB->AdaptStatus = 0;
2655 pSRB->TargetStatus = 0;
2656 /* $$$$$$ Status of initiator/target $$$$$$$$ */
2657
2658 pSRB->SRBTotalXferLength = sizeof(pcsio->sense_data);
2659 pSRB->SgSenseTemp.address = pSRB->SegmentX[0].address;
2660 pSRB->SgSenseTemp.length = pSRB->SegmentX[0].length;
2661 pSRB->SegmentX[0].address = (u_long) vtophys(&pcsio->sense_data);
2662 pSRB->SegmentX[0].length = (u_long) pcsio->sense_len;
2663 pSRB->SRBSGListPointer = &pSRB->SegmentX[0];
2664 pSRB->SRBSGCount = 1;
2665 pSRB->SRBSGIndex = 0;
2666
2667 *((u_long *) &(pSRB->CmdBlock[0])) = 0x00000003;
2668 pSRB->CmdBlock[1] = pDCB->IdentifyMsg << 5;
2669 *((u_int16_t *) &(pSRB->CmdBlock[4])) = pcsio->sense_len;
2670 pSRB->ScsiCmdLen = 6;
2671
2672 if (trm_StartSCSI(pACB, pDCB, pSRB))
2673 /*
2674 * If trm_StartSCSI return 1 :
2675 * current interrupt status is interrupt disreenable
2676 * It's said that SCSI processor has more one SRB need to do
2677 */
2678 trm_RewaitSRB(pDCB, pSRB);
2679}
2680
2681static void
2682trm_EnableMsgOutAbort2(PACB pACB, PSRB pSRB)
2683{
2684
2685 pSRB->MsgCnt = 1;
2686 trm_reg_write16(DO_SETATN, TRMREG_SCSI_CONTROL);
2687}
2688
2689static void
2690trm_EnableMsgOutAbort1(PACB pACB, PSRB pSRB)
2691{
2692
2693 pSRB->MsgOutBuf[0] = MSG_ABORT;
2694 trm_EnableMsgOutAbort2(pACB, pSRB);
2695}
2696
2697static void
2698trm_initDCB(PACB pACB, PDCB pDCB, u_int16_t unit,u_int32_t i,u_int32_t j)
2699{
2700 PNVRAMTYPE pEEpromBuf;
2701 u_int8_t bval,PeriodIndex;
2702 u_int target_id,target_lun;
2703 PDCB pTempDCB;
984263bc
MD
2704
2705 target_id = i;
2706 target_lun = j;
2707
d9ed64be 2708 crit_enter();
984263bc
MD
2709 if (pACB->pLinkDCB == 0) {
2710 pACB->pLinkDCB = pDCB;
2711 /*
2712 * RunRobin impersonate the role
2713 * that let each device had good proportion
2714 * about SCSI command proceeding
2715 */
2716 pACB->pDCBRunRobin = pDCB;
2717 pDCB->pNextDCB = pDCB;
2718 } else {
2719 pTempDCB=pACB->pLinkDCB;
2720 /* search the last nod of DCB link */
2721 while (pTempDCB->pNextDCB != pACB->pLinkDCB)
2722 pTempDCB = pTempDCB->pNextDCB;
2723 /* connect current DCB with last DCB tail */
2724 pTempDCB->pNextDCB = pDCB;
2725 /* connect current DCB tail to this DCB Q head */
2726 pDCB->pNextDCB=pACB->pLinkDCB;
2727 }
d9ed64be 2728 crit_exit();
984263bc
MD
2729
2730 pACB->DeviceCnt++;
2731 pDCB->pDCBACB = pACB;
2732 pDCB->TargetID = target_id;
2733 pDCB->TargetLUN = target_lun;
2734 pDCB->pWaitingSRB = NULL;
2735 pDCB->pGoingSRB = NULL;
2736 pDCB->GoingSRBCnt = 0;
2737 pDCB->pActiveSRB = NULL;
2738 pDCB->TagMask = 0;
2739 pDCB->MaxCommand = 1;
2740 pDCB->DCBFlag = 0;
2741 /* $$$$$$$ */
2742 pEEpromBuf = &trm_eepromBuf[unit];
2743 pDCB->DevMode = pEEpromBuf->NvramTarget[target_id].NvmTarCfg0;
2744 pDCB->AdpMode = pEEpromBuf->NvramChannelCfg;
2745 /* $$$$$$$ */
2746 /*
2747 * disconnect enable ?
2748 */
2749 if (pDCB->DevMode & NTC_DO_DISCONNECT) {
2750 bval = 0xC0;
2751 pDCB->tinfo.disc_tag |= TRM_USR_DISCENB ;
2752 } else {
2753 bval = 0x80;
2754 pDCB->tinfo.disc_tag &= ~(TRM_USR_DISCENB);
2755 }
2756 bval |= target_lun;
2757 pDCB->IdentifyMsg = bval;
2758 /* $$$$$$$ */
2759 /*
2760 * tag Qing enable ?
2761 */
2762 if (pDCB->DevMode & TAG_QUEUING_) {
2763 pDCB->tinfo.disc_tag |= TRM_USR_TAGENB ;
2764 } else
2765 pDCB->tinfo.disc_tag &= ~(TRM_USR_TAGENB);
2766 /* $$$$$$$ */
2767 /*
2768 * wide nego ,sync nego enable ?
2769 */
2770 pDCB->SyncPeriod = 0;
2771 pDCB->SyncOffset = 0;
2772 PeriodIndex = pEEpromBuf->NvramTarget[target_id].NvmTarPeriod & 0x07;
2773 pDCB->MaxNegoPeriod = dc395x_trm_clock_period[ PeriodIndex ] ;
2774 pDCB->SyncMode = 0;
2775 if ((pDCB->DevMode & NTC_DO_WIDE_NEGO) &&
2776 (pACB->Config & HCC_WIDE_CARD))
2777 pDCB->SyncMode |= WIDE_NEGO_ENABLE;
2778 /* enable wide nego */
2779 if (pDCB->DevMode & NTC_DO_SYNC_NEGO)
2780 pDCB->SyncMode |= SYNC_NEGO_ENABLE;
2781 /* enable sync nego */
2782 /* $$$$$$$ */
2783 /*
2784 * Fill in tinfo structure.
2785 */
2786 pDCB->tinfo.user.period = pDCB->MaxNegoPeriod;
2787 pDCB->tinfo.user.offset = (pDCB->SyncMode & SYNC_NEGO_ENABLE) ? 15 : 0;
2788 pDCB->tinfo.user.width = (pDCB->SyncMode & WIDE_NEGO_ENABLE) ?
2789 MSG_EXT_WDTR_BUS_16_BIT : MSG_EXT_WDTR_BUS_8_BIT;
2790
2791 pDCB->tinfo.current.period = 0;
2792 pDCB->tinfo.current.offset = 0;
2793 pDCB->tinfo.current.width = MSG_EXT_WDTR_BUS_8_BIT;
2794}
2795
2796static void
2797trm_initSRB(PSRB psrb)
2798{
2799
2800 psrb->PhysSRB = vtophys(psrb);
2801}
2802
2803static void
2804trm_linkSRB(PACB pACB)
2805{
2806 u_int16_t i;
2807
2808 for (i = 0; i < MAX_SRB_CNT; i++) {
2809 if (i != MAX_SRB_CNT - 1)
2810 /*
2811 * link all SRB
2812 */
2813 pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
2814 else
2815 /*
2816 * load NULL to NextSRB of the last SRB
2817 */
2818 pACB->SRB_array[i].pNextSRB = NULL;
2819 /*
2820 * convert and save physical address of SRB to pSRB->PhysSRB
2821 */
2822 trm_initSRB((PSRB) &pACB->SRB_array[i]);
2823 }
2824}
2825
2826
2827static void
2828trm_initACB(PACB pACB, u_int16_t unit)
2829{
2830 PNVRAMTYPE pEEpromBuf;
2831 u_int16_t i,j;
2832
2833 pEEpromBuf = &trm_eepromBuf[unit];
2834 pACB->max_id = 15;
2835
2836 if (pEEpromBuf->NvramChannelCfg & NAC_SCANLUN)
2837 pACB->max_lun = 7;
2838 else
2839 pACB->max_lun = 0;
2840
2841 TRM_DPRINTF("trm: pACB->max_id= %d pACB->max_lun= %d \n",
2842 pACB->max_id, pACB->max_lun);
2843
2844 pACB->pLinkDCB = NULL;
2845 pACB->pDCBRunRobin = NULL;
2846 pACB->pActiveDCB = NULL;
2847 pACB->pFreeSRB = pACB->SRB_array;
2848 pACB->AdapterUnit = unit;
2849 pACB->AdaptSCSIID = pEEpromBuf->NvramScsiId;
2850 pACB->AdaptSCSILUN = 0;
2851 pACB->DeviceCnt = 0;
2852 pACB->TagMaxNum = 2 << pEEpromBuf->NvramMaxTag ;
2853 pACB->ACBFlag = 0;
2854 /*
2855 * link all device's SRB Q of this adapter
2856 */
2857 trm_linkSRB(pACB);
2858 /*
2859 * temp SRB for Q tag used or abord command used
2860 */
2861 pACB->pTmpSRB = &pACB->TmpSRB;
2862 /*
2863 * convert and save physical address of SRB to pSRB->PhysSRB
2864 */
2865 trm_initSRB(pACB->pTmpSRB);
2866 /* allocate DCB array for scan device */
2867 for (i = 0; i < (pACB->max_id +1); i++) {
2868 if (pACB->AdaptSCSIID != i) {
2869 for (j = 0; j < (pACB->max_lun +1); j++) {
2870 pACB->scan_devices[i][j] = 1;
77652cad 2871 pACB->pDCB[i][j]= (PDCB) kmalloc (
984263bc
MD
2872 sizeof (struct _DCB), M_DEVBUF, M_WAITOK);
2873 trm_initDCB(pACB,
2874 pACB->pDCB[i][j], unit, i, j);
2875 TRM_DPRINTF("pDCB= %8x \n",
2876 (u_int)pACB->pDCB[i][j]);
2877 }
2878 }
2879 }
2880 TRM_DPRINTF("sizeof(struct _DCB)= %8x \n",sizeof(struct _DCB));
2881 TRM_DPRINTF("sizeof(struct _ACB)= %8x \n",sizeof(struct _ACB));
2882 TRM_DPRINTF("sizeof(struct _SRB)= %8x \n",sizeof(struct _SRB));
2883}
2884
2885static void
2886TRM_write_all(PNVRAMTYPE pEEpromBuf,PACB pACB)
2887{
2888 u_int8_t *bpEeprom = (u_int8_t *) pEEpromBuf;
2889 u_int8_t bAddr;
2890
2891 /* Enable SEEPROM */
2892 trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) | EN_EEPROM),
2893 TRMREG_GEN_CONTROL);
2894 /*
2895 * Write enable
2896 */
2897 TRM_write_cmd(pACB, 0x04, 0xFF);
2898 trm_reg_write8(0, TRMREG_GEN_NVRAM);
2899 TRM_wait_30us(pACB);
2900 for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++) {
2901 TRM_set_data(pACB, bAddr, *bpEeprom);
2902 }
2903 /*
2904 * Write disable
2905 */
2906 TRM_write_cmd(pACB, 0x04, 0x00);
2907 trm_reg_write8(0 , TRMREG_GEN_NVRAM);
2908 TRM_wait_30us(pACB);
2909 /* Disable SEEPROM */
2910 trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) & ~EN_EEPROM),
2911 TRMREG_GEN_CONTROL);
2912 return;
2913}
2914
2915static void
2916TRM_set_data(PACB pACB, u_int8_t bAddr, u_int8_t bData)
2917{
2918 int i;
2919 u_int8_t bSendData;
2920 /*
2921 * Send write command & address
2922 */
2923
2924 TRM_write_cmd(pACB, 0x05, bAddr);
2925 /*
2926 * Write data
2927 */
2928 for (i = 0; i < 8; i++, bData <<= 1) {
2929 bSendData = NVR_SELECT;
2930 if (bData & 0x80)
2931 /* Start from bit 7 */
2932 bSendData |= NVR_BITOUT;
2933 trm_reg_write8(bSendData , TRMREG_GEN_NVRAM);
2934 TRM_wait_30us(pACB);
2935 trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
2936 TRM_wait_30us(pACB);
2937 }
2938 trm_reg_write8(NVR_SELECT , TRMREG_GEN_NVRAM);
2939 TRM_wait_30us(pACB);
2940 /*
2941 * Disable chip select
2942 */
2943 trm_reg_write8(0 , TRMREG_GEN_NVRAM);
2944 TRM_wait_30us(pACB);
2945 trm_reg_write8(NVR_SELECT ,TRMREG_GEN_NVRAM);
2946 TRM_wait_30us(pACB);
2947 /*
2948 * Wait for write ready
2949 */
2950 while (1) {
2951 trm_reg_write8((NVR_SELECT | NVR_CLOCK), TRMREG_GEN_NVRAM);
2952 TRM_wait_30us(pACB);
2953 trm_reg_write8(NVR_SELECT, TRMREG_GEN_NVRAM);
2954 TRM_wait_30us(pACB);
2955 if (trm_reg_read8(TRMREG_GEN_NVRAM) & NVR_BITIN) {
2956 break;
2957 }
2958 }
2959 /*
2960 * Disable chip select
2961 */
2962 trm_reg_write8(0, TRMREG_GEN_NVRAM);
2963 return;
2964}
2965
2966static void
2967TRM_read_all(PNVRAMTYPE pEEpromBuf, PACB pACB)
2968{
2969 u_int8_t *bpEeprom = (u_int8_t*) pEEpromBuf;
2970 u_int8_t bAddr;
2971
2972 /*
2973 * Enable SEEPROM
2974 */
2975 trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) | EN_EEPROM),
2976 TRMREG_GEN_CONTROL);
2977 for (bAddr = 0; bAddr < 128; bAddr++, bpEeprom++)
2978 *bpEeprom = TRM_get_data(pACB, bAddr);
2979 /*
2980 * Disable SEEPROM
2981 */
2982 trm_reg_write8((trm_reg_read8(TRMREG_GEN_CONTROL) & ~EN_EEPROM),
2983 TRMREG_GEN_CONTROL);
2984 return;
2985}
2986
2987static u_int8_t
2988TRM_get_data(PACB pACB, u_int8_t bAddr)
2989{
2990 int i;
2991 u_int8_t bReadData, bData = 0;
2992 /*
2993 * Send read command & address
2994 */
2995
2996 TRM_write_cmd(pACB, 0x06, bAddr);
2997
2998 for (i = 0; i < 8; i++) {
2999 /*
3000 * Read data
3001 */
3002 trm_reg_write8((NVR_SELECT | NVR_CLOCK) , TRMREG_GEN_NVRAM);
3003 TRM_wait_30us(pACB);
3004 trm_reg_write8(NVR_SELECT , TRMREG_GEN_NVRAM);
3005 /*
3006 * Get data bit while falling edge
3007 */
3008 bReadData = trm_reg_read8(TRMREG_GEN_NVRAM);
3009 bData <<= 1;
3010 if (bReadData & NVR_BITIN) {
3011 bData |= 1;
3012 }
3013 TRM_wait_30us(pACB);
3014 }
3015 /*
3016 * Disable chip select
3017 */
3018 trm_reg_write8(0, TRMREG_GEN_NVRAM);
3019 return (bData);
3020}
3021
3022static void
3023TRM_wait_30us(PACB pACB)
3024{
3025
3026 /* ScsiPortStallExecution(30); wait 30 us */
3027 trm_reg_write8(5, TRMREG_GEN_TIMER);
3028 while (!(trm_reg_read8(TRMREG_GEN_STATUS) & GTIMEOUT));
3029 return;
3030}
3031
3032static void
3033TRM_write_cmd(PACB pACB, u_int8_t bCmd, u_int8_t bAddr)
3034{
3035 int i;
3036 u_int8_t bSendData;
3037
3038 for (i = 0; i < 3; i++, bCmd <<= 1) {
3039 /*
3040 * Program SB+OP code
3041 */
3042 bSendData = NVR_SELECT;
3043 if (bCmd & 0x04)
3044 bSendData |= NVR_BITOUT;
3045 /* start from bit 2 */
3046 trm_reg_write8(bSendData, TRMREG_GEN_NVRAM);
3047 TRM_wait_30us(pACB);
3048 trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
3049 TRM_wait_30us(pACB);
3050 }
3051 for (i = 0; i < 7; i++, bAddr <<= 1) {
3052 /*
3053 * Program address
3054 */
3055 bSendData = NVR_SELECT;
3056 if (bAddr & 0x40)
3057 /* Start from bit 6 */
3058 bSendData |= NVR_BITOUT;
3059 trm_reg_write8(bSendData , TRMREG_GEN_NVRAM);
3060 TRM_wait_30us(pACB);
3061 trm_reg_write8((bSendData | NVR_CLOCK), TRMREG_GEN_NVRAM);
3062 TRM_wait_30us(pACB);
3063 }
3064 trm_reg_write8(NVR_SELECT, TRMREG_GEN_NVRAM);
3065 TRM_wait_30us(pACB);
3066}
3067
3068static void
3069trm_check_eeprom(PNVRAMTYPE pEEpromBuf, PACB pACB)
3070{
3071 u_int16_t *wpEeprom = (u_int16_t *) pEEpromBuf;
3072 u_int16_t wAddr, wCheckSum;
3073 u_long dAddr, *dpEeprom;
3074
3075 TRM_read_all(pEEpromBuf,pACB);
3076 wCheckSum = 0;
3077 for (wAddr = 0, wpEeprom = (u_int16_t *) pEEpromBuf;
3078 wAddr < 64; wAddr++, wpEeprom++) {
3079 wCheckSum += *wpEeprom;
3080 }
3081 if (wCheckSum != 0x1234) {
3082 /*
3083 * Checksum error, load default
3084 */
3085 pEEpromBuf->NvramSubVendorID[0] = (u_int8_t) PCI_Vendor_ID_TEKRAM;
3086 pEEpromBuf->NvramSubVendorID[1] =
3087 (u_int8_t) (PCI_Vendor_ID_TEKRAM >> 8);
3088 pEEpromBuf->NvramSubSysID[0] = (u_int8_t) PCI_Device_ID_TRM_S1040;
3089 pEEpromBuf->NvramSubSysID[1] =
3090 (u_int8_t) (PCI_Device_ID_TRM_S1040 >> 8);
3091 pEEpromBuf->NvramSubClass = 0x00;
3092 pEEpromBuf->NvramVendorID[0] = (u_int8_t) PCI_Vendor_ID_TEKRAM;
3093 pEEpromBuf->NvramVendorID[1] =
3094 (u_int8_t) (PCI_Vendor_ID_TEKRAM >> 8);
3095 pEEpromBuf->NvramDeviceID[0] = (u_int8_t) PCI_Device_ID_TRM_S1040;
3096 pEEpromBuf->NvramDeviceID[1] =
3097 (u_int8_t) (PCI_Device_ID_TRM_S1040 >> 8);
3098 pEEpromBuf->NvramReserved = 0x00;
3099
3100 for (dAddr = 0, dpEeprom = (u_long *) pEEpromBuf->NvramTarget;
3101 dAddr < 16; dAddr++, dpEeprom++) {
3102 *dpEeprom = 0x00000077;
3103 /* NvmTarCfg3,NvmTarCfg2,NvmTarPeriod,NvmTarCfg0 */
3104 }
3105
3106 *dpEeprom++ = 0x04000F07;
3107 /* NvramMaxTag,NvramDelayTime,NvramChannelCfg,NvramScsiId */
3108 *dpEeprom++ = 0x00000015;
3109 /* NvramReserved1,NvramBootLun,NvramBootTarget,NvramReserved0 */
3110 for (dAddr = 0; dAddr < 12; dAddr++, dpEeprom++)
3111 *dpEeprom = 0x00;
3112 pEEpromBuf->NvramCheckSum = 0x00;
3113 for (wAddr = 0, wCheckSum = 0, wpEeprom = (u_int16_t *) pEEpromBuf;
3114 wAddr < 63; wAddr++, wpEeprom++)
3115 wCheckSum += *wpEeprom;
3116 *wpEeprom = 0x1234 - wCheckSum;
3117 TRM_write_all(pEEpromBuf,pACB);
3118 }
3119 return;
3120}
3121static int
3122trm_initAdapter(PACB pACB, u_int16_t unit, device_t pci_config_id)
3123{
3124 PNVRAMTYPE pEEpromBuf;
3125 u_int16_t wval;
3126 u_int8_t bval;
3127
3128 pEEpromBuf = &trm_eepromBuf[unit];
3129
3130 /* 250ms selection timeout */
3131 trm_reg_write8(SEL_TIMEOUT, TRMREG_SCSI_TIMEOUT);
3132 /* Mask all the interrupt */
3133 trm_reg_write8(0x00, TRMREG_DMA_INTEN);
3134 trm_reg_write8(0x00, TRMREG_SCSI_INTEN);
3135 /* Reset SCSI module */
3136 trm_reg_write16(DO_RSTMODULE, TRMREG_SCSI_CONTROL);
3137 /* program configuration 0 */
3138 pACB->Config = HCC_AUTOTERM | HCC_PARITY;
3139 if (trm_reg_read8(TRMREG_GEN_STATUS) & WIDESCSI)
3140 pACB->Config |= HCC_WIDE_CARD;
3141 if (pEEpromBuf->NvramChannelCfg & NAC_POWERON_SCSI_RESET)
3142 pACB->Config |= HCC_SCSI_RESET;
3143 if (pACB->Config & HCC_PARITY)
3144 bval = PHASELATCH | INITIATOR | BLOCKRST | PARITYCHECK;
3145 else
3146 bval = PHASELATCH | INITIATOR | BLOCKRST ;
3147 trm_reg_write8(bval,TRMREG_SCSI_CONFIG0);
3148 /* program configuration 1 */
3149 trm_reg_write8(0x13, TRMREG_SCSI_CONFIG1);
3150 /* program Host ID */
3151 bval = pEEpromBuf->NvramScsiId;
3152 trm_reg_write8(bval, TRMREG_SCSI_HOSTID);
3153 /* set ansynchronous transfer */
3154 trm_reg_write8(0x00, TRMREG_SCSI_OFFSET);
3155 /* Trun LED control off*/
3156 wval = trm_reg_read16(TRMREG_GEN_CONTROL) & 0x7F;
3157 trm_reg_write16(wval, TRMREG_GEN_CONTROL);
3158 /* DMA config */
3159 wval = trm_reg_read16(TRMREG_DMA_CONFIG) | DMA_ENHANCE;
3160 trm_reg_write16(wval, TRMREG_DMA_CONFIG);
3161 /* Clear pending interrupt status */
3162 trm_reg_read8(TRMREG_SCSI_INTSTATUS);
3163 /* Enable SCSI interrupt */
3164 trm_reg_write8(0x7F, TRMREG_SCSI_INTEN);
3165 trm_reg_write8(EN_SCSIINTR, TRMREG_DMA_INTEN);
3166 return (0);
3167}
3168
3169static PACB
3170trm_init(u_int16_t unit, device_t pci_config_id)
3171{
3172 PACB pACB;
3173 int rid = PCIR_MAPS;
3174
3175 pACB = (PACB) device_get_softc(pci_config_id);
3176 if (!pACB) {
3177 printf("trm%d: cannot allocate ACB !\n", unit);
3178 return (NULL);
3179 }
3180 bzero (pACB, sizeof (struct _ACB));
3181 pACB->iores = bus_alloc_resource(pci_config_id, SYS_RES_IOPORT,
3182 &rid, 0, ~0, 1, RF_ACTIVE);
3183 if (pACB->iores == NULL) {
3184 printf("trm_init: bus_alloc_resource failed!\n");
3185 return (NULL);
3186 }
3187 pACB->tag = rman_get_bustag(pACB->iores);
3188 pACB->bsh = rman_get_bushandle(pACB->iores);
3189 if (bus_dma_tag_create(/*parent_dmat*/ NULL,
3190 /*alignment*/ 1,
3191 /*boundary*/ 0,
3192 /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
3193 /*highaddr*/ BUS_SPACE_MAXADDR,
3194 /*filter*/ NULL,
3195 /*filterarg*/ NULL,
3196 /*maxsize*/ MAXBSIZE,
3197 /*nsegments*/ TRM_NSEG,
3198 /*maxsegsz*/ TRM_MAXTRANSFER_SIZE,
3199 /*flags*/ BUS_DMA_ALLOCNOW,
3200 &pACB->buffer_dmat) != 0)
3201 goto bad;
3202 trm_check_eeprom(&trm_eepromBuf[unit],pACB);
3203 trm_initACB(pACB, unit);
3204 if (trm_initAdapter(pACB, unit, pci_config_id)) {
3205 printf("trm_initAdapter: initial ERROR\n");
3206 goto bad;
3207 }
3208 return (pACB);
3209bad:
3210 if (pACB->iores)
3211 bus_release_resource(pci_config_id, SYS_RES_IOPORT, PCIR_MAPS,
3212 pACB->iores);
3213 if (pACB->buffer_dmat)
3214 bus_dma_tag_destroy(pACB->buffer_dmat);
3215 return (NULL);
3216}
3217
3218static int
3219trm_attach(device_t pci_config_id)
3220{
3221 struct cam_devq *device_Q;
3222 u_long device_id;
3223 PACB pACB = 0;
3224 int rid = 0;
3225 int unit = device_get_unit(pci_config_id);
3226
3227 device_id = pci_get_devid(pci_config_id);
3228 /*
3229 * These cards do not allow memory mapped accesses
3230 */
3231 if (device_id == PCI_DEVICEID_TRMS1040) {
3232 if ((pACB=trm_init((u_int16_t) unit,
3233 pci_config_id)) == NULL) {
3234 printf("trm%d: trm_init error!\n",unit);
3235 return (ENXIO);
3236 }
3237 } else
3238 return (ENXIO);
3239 /* After setting up the adapter, map our interrupt */
3240 /*
3241 * Now let the CAM generic SCSI layer find the SCSI devices on the bus
3242 * start queue to reset to the idle loop.
3243 * Create device queue of SIM(s)
3244 * (MAX_START_JOB - 1) : max_sim_transactions
3245 */
3246 pACB->irq = bus_alloc_resource(pci_config_id, SYS_RES_IRQ, &rid, 0,
3247 ~0, 1, RF_SHAREABLE | RF_ACTIVE);
3248 if (pACB->irq == NULL ||
3249 bus_setup_intr(pci_config_id, pACB->irq,
ee61f228 3250 0, trm_Interrupt, pACB,
e9cb6d99 3251 &pACB->ih, NULL)) {
984263bc
MD
3252 printf("trm%d: register Interrupt handler error!\n", unit);
3253 goto bad;
3254 }
3255 device_Q = cam_simq_alloc(MAX_START_JOB);
3256 if (device_Q == NULL){
3257 printf("trm%d: device_Q == NULL !\n",unit);
3258 goto bad;
3259 }
3260 /*
3261 * Now tell the generic SCSI layer
3262 * about our bus.
3263 * If this is the xpt layer creating a sim, then it's OK
3264 * to wait for an allocation.
3265 * XXX Should we pass in a flag to indicate that wait is OK?
3266 *
3267 * SIM allocation
3268 *
3269 * SCSI Interface Modules
3270 * The sim driver creates a sim for each controller. The sim device
3271 * queue is separately created in order to allow resource sharing betwee
3272 * sims. For instance, a driver may create one sim for each channel of
3273 * a multi-channel controller and use the same queue for each channel.
3274 * In this way, the queue resources are shared across all the channels
3275 * of the multi-channel controller.
3276 * trm_action : sim_action_func
3277 * trm_poll : sim_poll_func
3278 * "trm" : sim_name ,if sim_name = "xpt" ..M_DEVBUF,M_WAITOK
3279 * pACB : *softc if sim_name <> "xpt" ..M_DEVBUF,M_NOWAIT
3280 * pACB->unit : unit
3281 * 1 : max_dev_transactions
3282 * MAX_TAGS : max_tagged_dev_transactions
3283 *
3284 * *******Construct our first channel SIM entry
3285 */
3286 pACB->psim = cam_sim_alloc(trm_action,
3287 trm_poll,
3288 "trm",
3289 pACB,
3290 unit,
3291 1,
3292 MAX_TAGS_CMD_QUEUE,
3293 device_Q);
3aed1355 3294 cam_simq_release(device_Q); /* SIM allocate fault*/
984263bc
MD
3295 if (pACB->psim == NULL) {
3296 printf("trm%d: SIM allocate fault !\n",unit);
984263bc
MD
3297 goto bad;
3298 }
3299 if (xpt_bus_register(pACB->psim, 0) != CAM_SUCCESS) {
3300 printf("trm%d: xpt_bus_register fault !\n",unit);
3301 goto bad;
3302 }
3303 if (xpt_create_path(&pACB->ppath,
3304 NULL,
3305 cam_sim_path(pACB->psim),
3306 CAM_TARGET_WILDCARD,
3307 CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
3308 printf("trm%d: xpt_create_path fault !\n",unit);
3309 xpt_bus_deregister(cam_sim_path(pACB->psim));
3310 goto bad;
3311 /*
3312 * cam_sim_free(pACB->psim, TRUE); free_devq
3313 * pACB->psim = NULL;
3314 */
3315 return (ENXIO);
3316 }
3317 return (0);
3318bad:
3319 if (pACB->iores)
3320 bus_release_resource(pci_config_id, SYS_RES_IOPORT, PCIR_MAPS,
3321 pACB->iores);
3322 if (pACB->buffer_dmat)
3323 bus_dma_tag_destroy(pACB->buffer_dmat);
3324 if (pACB->ih)
3325 bus_teardown_intr(pci_config_id, pACB->irq, pACB->ih);
3326 if (pACB->irq)
3327 bus_release_resource(pci_config_id, SYS_RES_IRQ, 0, pACB->irq);
3328 if (pACB->psim)
3aed1355 3329 cam_sim_free(pACB->psim);
984263bc
MD
3330
3331 return (ENXIO);
3332
3333}
3334
3335/*
3336* pci_device
3337* trm_probe (device_t tag, pcidi_t type)
3338*
3339*/
3340static int
3341trm_probe(device_t tag)
3342{
3343
3344 if (pci_get_devid(tag) == PCI_DEVICEID_TRMS1040) {
3345 device_set_desc(tag,
3346 "Tekram DC395U/UW/F DC315/U Fast20 Wide SCSI Adapter");
3347 return (0);
3348 } else
3349 return (ENXIO);
3350}
3351
3352static int
3353trm_detach(device_t dev)
3354{
3355 PACB pACB = device_get_softc(dev);
3356
3357 bus_release_resource(dev, SYS_RES_IOPORT, PCIR_MAPS, pACB->iores);
3358 bus_dma_tag_destroy(pACB->buffer_dmat);
3359 bus_teardown_intr(dev, pACB->irq, pACB->ih);
3360 bus_release_resource(dev, SYS_RES_IRQ, 0, pACB->irq);
3361 xpt_async(AC_LOST_DEVICE, pACB->ppath, NULL);
3362 xpt_free_path(pACB->ppath);
3363 xpt_bus_deregister(cam_sim_path(pACB->psim));
3aed1355 3364 cam_sim_free(pACB->psim);
984263bc
MD
3365 return (0);
3366}
3367static device_method_t trm_methods[] = {
3368 /* Device interface */
3369 DEVMETHOD(device_probe, trm_probe),
3370 DEVMETHOD(device_attach, trm_attach),
3371 DEVMETHOD(device_detach, trm_detach),
3372 { 0, 0 }
3373};
3374
3375static driver_t trm_driver = {
3376 "trm", trm_methods, sizeof(struct _ACB)
3377};
3378
3379static devclass_t trm_devclass;
3380DRIVER_MODULE(trm, pci, trm_driver, trm_devclass, 0, 0);