1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191#define C_NOP
192
193
194#ifdef DC390_DEBUG0
195# define DEBUG0(x) x
196#else
197# define DEBUG0(x) C_NOP
198#endif
199#ifdef DC390_DEBUG1
200# define DEBUG1(x) x
201#else
202# define DEBUG1(x) C_NOP
203#endif
204#ifdef DC390_DCBDEBUG
205# define DCBDEBUG(x) x
206#else
207# define DCBDEBUG(x) C_NOP
208#endif
209#ifdef DC390_PARSEDEBUG
210# define PARSEDEBUG(x) x
211#else
212# define PARSEDEBUG(x) C_NOP
213#endif
214#ifdef DC390_REMOVABLEDEBUG
215# define REMOVABLEDEBUG(x) x
216#else
217# define REMOVABLEDEBUG(x) C_NOP
218#endif
219#define DCBDEBUG1(x) C_NOP
220
221#include <linux/module.h>
222#include <linux/delay.h>
223#include <linux/signal.h>
224#include <linux/sched.h>
225#include <linux/errno.h>
226#include <linux/kernel.h>
227#include <linux/ioport.h>
228#include <linux/pci.h>
229#include <linux/proc_fs.h>
230#include <linux/string.h>
231#include <linux/mm.h>
232#include <linux/blkdev.h>
233#include <linux/timer.h>
234#include <linux/interrupt.h>
235#include <linux/init.h>
236#include <linux/spinlock.h>
237#include <asm/io.h>
238
239#include <scsi/scsi.h>
240#include <scsi/scsi_cmnd.h>
241#include <scsi/scsi_device.h>
242#include <scsi/scsi_host.h>
243#include <scsi/scsicam.h>
244#include <scsi/scsi_tcq.h>
245
246
247#define DC390_BANNER "Tekram DC390/AM53C974"
248#define DC390_VERSION "2.1d 2004-05-27"
249
250#define PCI_DEVICE_ID_AMD53C974 PCI_DEVICE_ID_AMD_SCSI
251
252#include "tmscsim.h"
253
254
255static void dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
256static void dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
257static void dc390_Command_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
258static void dc390_Status_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
259static void dc390_MsgOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
260static void dc390_MsgIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
261static void dc390_DataOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
262static void dc390_DataInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
263static void dc390_CommandPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
264static void dc390_StatusPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
265static void dc390_MsgOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
266static void dc390_MsgInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
267static void dc390_Nop_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
268static void dc390_Nop_1( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus);
269
270static void dc390_SetXferRate( struct dc390_acb* pACB, struct dc390_dcb* pDCB );
271static void dc390_Disconnect( struct dc390_acb* pACB );
272static void dc390_Reselect( struct dc390_acb* pACB );
273static void dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB );
274static void dc390_ScsiRstDetect( struct dc390_acb* pACB );
275static void dc390_EnableMsgOut_Abort(struct dc390_acb*, struct dc390_srb*);
276static void dc390_dumpinfo(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB);
277static void dc390_ResetDevParam(struct dc390_acb* pACB);
278
279static u32 dc390_laststatus = 0;
280static u8 dc390_adapterCnt = 0;
281
282static int disable_clustering;
283module_param(disable_clustering, int, S_IRUGO);
284MODULE_PARM_DESC(disable_clustering, "If you experience problems with your devices, try setting to 1");
285
286
287static int tmscsim[] = {-2, -2, -2, -2, -2, -2};
288
289module_param_array(tmscsim, int, NULL, 0);
290MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)");
291MODULE_AUTHOR("C.L. Huang / Kurt Garloff");
292MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");
293MODULE_LICENSE("GPL");
294MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
295
296static void *dc390_phase0[]={
297 dc390_DataOut_0,
298 dc390_DataIn_0,
299 dc390_Command_0,
300 dc390_Status_0,
301 dc390_Nop_0,
302 dc390_Nop_0,
303 dc390_MsgOut_0,
304 dc390_MsgIn_0,
305 dc390_Nop_1
306 };
307
308static void *dc390_phase1[]={
309 dc390_DataOutPhase,
310 dc390_DataInPhase,
311 dc390_CommandPhase,
312 dc390_StatusPhase,
313 dc390_Nop_0,
314 dc390_Nop_0,
315 dc390_MsgOutPhase,
316 dc390_MsgInPhase,
317 dc390_Nop_1
318 };
319
320#ifdef DC390_DEBUG1
321static char* dc390_p0_str[] = {
322 "dc390_DataOut_0",
323 "dc390_DataIn_0",
324 "dc390_Command_0",
325 "dc390_Status_0",
326 "dc390_Nop_0",
327 "dc390_Nop_0",
328 "dc390_MsgOut_0",
329 "dc390_MsgIn_0",
330 "dc390_Nop_1"
331 };
332
333static char* dc390_p1_str[] = {
334 "dc390_DataOutPhase",
335 "dc390_DataInPhase",
336 "dc390_CommandPhase",
337 "dc390_StatusPhase",
338 "dc390_Nop_0",
339 "dc390_Nop_0",
340 "dc390_MsgOutPhase",
341 "dc390_MsgInPhase",
342 "dc390_Nop_1"
343 };
344#endif
345
346static u8 dc390_eepromBuf[MAX_ADAPTER_NUM][EE_LEN];
347static u8 dc390_clock_period1[] = {4, 5, 6, 7, 8, 10, 13, 20};
348static u8 dc390_clock_speed[] = {100,80,67,57,50, 40, 31, 20};
349
350
351
352
353
354
355static struct dc390_dcb __inline__ *dc390_findDCB ( struct dc390_acb* pACB, u8 id, u8 lun)
356{
357 struct dc390_dcb* pDCB = pACB->pLinkDCB; if (!pDCB) return NULL;
358 while (pDCB->TargetID != id || pDCB->TargetLUN != lun)
359 {
360 pDCB = pDCB->pNextDCB;
361 if (pDCB == pACB->pLinkDCB)
362 return NULL;
363 }
364 DCBDEBUG1( printk (KERN_DEBUG "DCB %p (%02x,%02x) found.\n", \
365 pDCB, pDCB->TargetID, pDCB->TargetLUN));
366 return pDCB;
367}
368
369
370static __inline__ void dc390_Free_insert (struct dc390_acb* pACB, struct dc390_srb* pSRB)
371{
372 DEBUG0(printk ("DC390: Free SRB %p\n", pSRB));
373 pSRB->pNextSRB = pACB->pFreeSRB;
374 pACB->pFreeSRB = pSRB;
375}
376
377static __inline__ void dc390_Going_append (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
378{
379 pDCB->GoingSRBCnt++;
380 DEBUG0(printk("DC390: Append SRB %p to Going\n", pSRB));
381
382 if( pDCB->pGoingSRB )
383 pDCB->pGoingLast->pNextSRB = pSRB;
384 else
385 pDCB->pGoingSRB = pSRB;
386
387 pDCB->pGoingLast = pSRB;
388
389 pSRB->pNextSRB = NULL;
390}
391
392static __inline__ void dc390_Going_remove (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
393{
394 DEBUG0(printk("DC390: Remove SRB %p from Going\n", pSRB));
395 if (pSRB == pDCB->pGoingSRB)
396 pDCB->pGoingSRB = pSRB->pNextSRB;
397 else
398 {
399 struct dc390_srb* psrb = pDCB->pGoingSRB;
400 while (psrb && psrb->pNextSRB != pSRB)
401 psrb = psrb->pNextSRB;
402 if (!psrb)
403 { printk (KERN_ERR "DC390: Remove non-ex. SRB %p from Going!\n", pSRB); return; }
404 psrb->pNextSRB = pSRB->pNextSRB;
405 if (pSRB == pDCB->pGoingLast)
406 pDCB->pGoingLast = psrb;
407 }
408 pDCB->GoingSRBCnt--;
409}
410
411static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
412{
413 memset(sg, 0, sizeof(struct scatterlist));
414 sg->page = virt_to_page(addr);
415 sg->length = length;
416 sg->offset = (unsigned long)addr & ~PAGE_MASK;
417 return sg;
418}
419
420
421static int dc390_pci_map (struct dc390_srb* pSRB)
422{
423 int error = 0;
424 struct scsi_cmnd *pcmd = pSRB->pcmd;
425 struct pci_dev *pdev = pSRB->pSRBDCB->pDCBACB->pdev;
426 dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp));
427
428
429 if (pSRB->SRBFlag & AUTO_REQSENSE) {
430 pSRB->pSegmentList = dc390_sg_build_single(&pSRB->Segmentx, pcmd->sense_buffer, sizeof(pcmd->sense_buffer));
431 pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, 1,
432 DMA_FROM_DEVICE);
433 cmdp->saved_dma_handle = sg_dma_address(pSRB->pSegmentList);
434
435
436 if (pSRB->SGcount != 1)
437 error = 1;
438 DEBUG1(printk("%s(): Mapped sense buffer %p at %x\n", __FUNCTION__, pcmd->sense_buffer, cmdp->saved_dma_handle));
439
440 } else if (pcmd->use_sg) {
441 pSRB->pSegmentList = (struct scatterlist *) pcmd->request_buffer;
442 pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, pcmd->use_sg,
443 pcmd->sc_data_direction);
444
445 if (!pSRB->SGcount)
446 error = 1;
447 DEBUG1(printk("%s(): Mapped SG %p with %d (%d) elements\n",\
448 __FUNCTION__, pcmd->request_buffer, pSRB->SGcount, pcmd->use_sg));
449
450 } else if (pcmd->request_buffer && pcmd->request_bufflen) {
451 pSRB->pSegmentList = dc390_sg_build_single(&pSRB->Segmentx, pcmd->request_buffer, pcmd->request_bufflen);
452 pSRB->SGcount = pci_map_sg(pdev, pSRB->pSegmentList, 1,
453 pcmd->sc_data_direction);
454 cmdp->saved_dma_handle = sg_dma_address(pSRB->pSegmentList);
455
456
457 if (pSRB->SGcount != 1)
458 error = 1;
459 DEBUG1(printk("%s(): Mapped request buffer %p at %x\n", __FUNCTION__, pcmd->request_buffer, cmdp->saved_dma_handle));
460
461 } else
462 pSRB->SGcount = 0;
463
464 return error;
465}
466
467
468static void dc390_pci_unmap (struct dc390_srb* pSRB)
469{
470 struct scsi_cmnd *pcmd = pSRB->pcmd;
471 struct pci_dev *pdev = pSRB->pSRBDCB->pDCBACB->pdev;
472 DEBUG1(dc390_cmd_scp_t* cmdp = ((dc390_cmd_scp_t*)(&pcmd->SCp)));
473
474 if (pSRB->SRBFlag) {
475 pci_unmap_sg(pdev, &pSRB->Segmentx, 1, DMA_FROM_DEVICE);
476 DEBUG1(printk("%s(): Unmapped sense buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle));
477 } else if (pcmd->use_sg) {
478 pci_unmap_sg(pdev, pcmd->request_buffer, pcmd->use_sg, pcmd->sc_data_direction);
479 DEBUG1(printk("%s(): Unmapped SG at %p with %d elements\n", __FUNCTION__, pcmd->request_buffer, pcmd->use_sg));
480 } else if (pcmd->request_buffer && pcmd->request_bufflen) {
481 pci_unmap_sg(pdev, &pSRB->Segmentx, 1, pcmd->sc_data_direction);
482 DEBUG1(printk("%s(): Unmapped request buffer at %x\n", __FUNCTION__, cmdp->saved_dma_handle));
483 }
484}
485
486static void __inline__
487dc390_freetag (struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
488{
489 if (pSRB->TagNumber != SCSI_NO_TAG) {
490 pDCB->TagMask &= ~(1 << pSRB->TagNumber);
491 pSRB->TagNumber = SCSI_NO_TAG;
492 }
493}
494
495
496static int
497dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB )
498{
499 struct scsi_cmnd *scmd = pSRB->pcmd;
500 struct scsi_device *sdev = scmd->device;
501 u8 cmd, disc_allowed, try_sync_nego;
502 char tag[2];
503
504 pSRB->ScsiPhase = SCSI_NOP0;
505
506 if (pACB->Connected)
507 {
508
509 printk (KERN_WARNING "DC390: Can't select when connected! (%08x,%02x)\n",
510 pSRB->SRBState, pSRB->SRBFlag);
511 pSRB->SRBState = SRB_READY;
512 pACB->SelConn++;
513 return 1;
514 }
515 if (time_before (jiffies, pACB->pScsiHost->last_reset))
516 {
517 DEBUG0(printk ("DC390: We were just reset and don't accept commands yet!\n"));
518 return 1;
519 }
520
521 dc390_pci_map(pSRB);
522
523 DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
524 DC390_write8 (Sync_Period, pDCB->SyncPeriod);
525 DC390_write8 (Sync_Offset, pDCB->SyncOffset);
526 DC390_write8 (CtrlReg1, pDCB->CtrlR1);
527 DC390_write8 (CtrlReg3, pDCB->CtrlR3);
528 DC390_write8 (CtrlReg4, pDCB->CtrlR4);
529 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
530 DEBUG1(printk (KERN_INFO "DC390: Start SCSI command: %02x (Sync:%02x)\n",\
531 scmd->cmnd[0], pDCB->SyncMode));
532
533
534
535
536
537
538 if (! (pSRB->SRBFlag & AUTO_REQSENSE))
539 disc_allowed = pDCB->DevMode & EN_DISCONNECT_;
540 else
541 disc_allowed = 0;
542
543 if ((pDCB->SyncMode & SYNC_ENABLE) && pDCB->TargetLUN == 0 && sdev->sdtr &&
544 (((scmd->cmnd[0] == REQUEST_SENSE || (pSRB->SRBFlag & AUTO_REQSENSE)) &&
545 !(pDCB->SyncMode & SYNC_NEGO_DONE)) || scmd->cmnd[0] == INQUIRY))
546 try_sync_nego = 1;
547 else
548 try_sync_nego = 0;
549
550 pSRB->MsgCnt = 0;
551 cmd = SEL_W_ATN;
552 DC390_write8 (ScsiFifo, IDENTIFY(disc_allowed, pDCB->TargetLUN));
553
554 if ((pDCB->SyncMode & EN_TAG_QUEUEING) && disc_allowed && scsi_populate_tag_msg(scmd, tag)) {
555 DC390_write8(ScsiFifo, tag[0]);
556 pDCB->TagMask |= 1 << tag[1];
557 pSRB->TagNumber = tag[1];
558 DC390_write8(ScsiFifo, tag[1]);
559 DEBUG1(printk(KERN_INFO "DC390: Select w/DisCn for Cmd %li (SRB %p), block tag %02x\n", scmd->pid, pSRB, tag[1]));
560 cmd = SEL_W_ATN3;
561 } else {
562
563
564 DEBUG1(printk(KERN_INFO "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", disc_allowed ? "" : "o", scmd->pid, pSRB));
565 }
566
567 pSRB->SRBState = SRB_START_;
568
569 if (try_sync_nego)
570 {
571 u8 Sync_Off = pDCB->SyncOffset;
572 DEBUG0(printk (KERN_INFO "DC390: NEW Sync Nego code triggered (%i %i)\n", pDCB->TargetID, pDCB->TargetLUN));
573 pSRB->MsgOutBuf[0] = EXTENDED_MESSAGE;
574 pSRB->MsgOutBuf[1] = 3;
575 pSRB->MsgOutBuf[2] = EXTENDED_SDTR;
576 pSRB->MsgOutBuf[3] = pDCB->NegoPeriod;
577 if (!(Sync_Off & 0x0f)) Sync_Off = SYNC_NEGO_OFFSET;
578 pSRB->MsgOutBuf[4] = Sync_Off;
579 pSRB->MsgCnt = 5;
580
581 pSRB->SRBState |= DO_SYNC_NEGO;
582 cmd = SEL_W_ATN_STOP;
583 }
584
585
586 if (cmd != SEL_W_ATN_STOP)
587 {
588 if( pSRB->SRBFlag & AUTO_REQSENSE )
589 {
590 DC390_write8 (ScsiFifo, REQUEST_SENSE);
591 DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
592 DC390_write8 (ScsiFifo, 0);
593 DC390_write8 (ScsiFifo, 0);
594 DC390_write8 (ScsiFifo, sizeof(scmd->sense_buffer));
595 DC390_write8 (ScsiFifo, 0);
596 DEBUG1(printk (KERN_DEBUG "DC390: AutoReqSense !\n"));
597 }
598 else
599 {
600 u8 *ptr; u8 i;
601 ptr = (u8 *)scmd->cmnd;
602 for (i = 0; i < scmd->cmd_len; i++)
603 DC390_write8 (ScsiFifo, *(ptr++));
604 }
605 }
606 DEBUG0(if (pACB->pActiveDCB) \
607 printk (KERN_WARNING "DC390: ActiveDCB != 0\n"));
608 DEBUG0(if (pDCB->pActiveSRB) \
609 printk (KERN_WARNING "DC390: ActiveSRB != 0\n"));
610
611 if (DC390_read8 (Scsi_Status) & INTERRUPT)
612 {
613 dc390_freetag (pDCB, pSRB);
614 DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)\n",
615 scmd->pid, scmd->device->id, scmd->device->lun));
616 pSRB->SRBState = SRB_READY;
617
618 pACB->SelLost++;
619 return 1;
620 }
621 DC390_write8 (ScsiCmd, cmd);
622 pACB->pActiveDCB = pDCB;
623 pDCB->pActiveSRB = pSRB;
624 pACB->Connected = 1;
625 pSRB->ScsiPhase = SCSI_NOP1;
626 return 0;
627}
628
629
630#define DMA_INT 0
631
632#if DMA_INT
633
634static u8
635dc390_dma_intr (struct dc390_acb* pACB)
636{
637 struct dc390_srb* pSRB;
638 u8 dstate;
639 DEBUG0(u16 pstate; struct pci_dev *pdev = pACB->pdev);
640
641 DEBUG0(pci_read_config_word(pdev, PCI_STATUS, &pstate));
642 DEBUG0(if (pstate & (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY))\
643 { printk(KERN_WARNING "DC390: PCI state = %04x!\n", pstate); \
644 pci_write_config_word(pdev, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));});
645
646 dstate = DC390_read8 (DMA_Status);
647
648 if (! pACB->pActiveDCB || ! pACB->pActiveDCB->pActiveSRB) return dstate;
649 else pSRB = pACB->pActiveDCB->pActiveSRB;
650
651 if (dstate & (DMA_XFER_ABORT | DMA_XFER_ERROR | POWER_DOWN | PCI_MS_ABORT))
652 {
653 printk (KERN_ERR "DC390: DMA error (%02x)!\n", dstate);
654 return dstate;
655 }
656 if (dstate & DMA_XFER_DONE)
657 {
658 u32 residual, xferCnt; int ctr = 6000000;
659 if (! (DC390_read8 (DMA_Cmd) & READ_DIRECTION))
660 {
661 do
662 {
663 DEBUG1(printk (KERN_DEBUG "DC390: read residual bytes ... \n"));
664 dstate = DC390_read8 (DMA_Status);
665 residual = DC390_read8 (CtcReg_Low) | DC390_read8 (CtcReg_Mid) << 8 |
666 DC390_read8 (CtcReg_High) << 16;
667 residual += DC390_read8 (Current_Fifo) & 0x1f;
668 } while (residual && ! (dstate & SCSI_INTERRUPT) && --ctr);
669 if (!ctr) printk (KERN_CRIT "DC390: dma_intr: DMA aborted unfinished: %06x bytes remain!!\n", DC390_read32 (DMA_Wk_ByteCntr));
670
671 }
672 else
673 residual = 0;
674
675
676
677 xferCnt = pSRB->SGToBeXferLen - residual;
678 pSRB->SGBusAddr += xferCnt;
679 pSRB->TotalXferredLen += xferCnt;
680 pSRB->SGToBeXferLen = residual;
681# ifdef DC390_DEBUG0
682 printk (KERN_INFO "DC390: DMA: residual = %i, xfer = %i\n",
683 (unsigned int)residual, (unsigned int)xferCnt);
684# endif
685
686 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
687 }
688 dc390_laststatus &= ~0xff000000; dc390_laststatus |= dstate << 24;
689 return dstate;
690}
691#endif
692
693
694static void __inline__
695dc390_InvalidCmd(struct dc390_acb* pACB)
696{
697 if (pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_ | SRB_MSGOUT))
698 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
699}
700
701
702static irqreturn_t __inline__
703DC390_Interrupt(void *dev_id)
704{
705 struct dc390_acb *pACB = dev_id;
706 struct dc390_dcb *pDCB;
707 struct dc390_srb *pSRB;
708 u8 sstatus=0;
709 u8 phase;
710 void (*stateV)( struct dc390_acb*, struct dc390_srb*, u8 *);
711 u8 istate, istatus;
712#if DMA_INT
713 u8 dstatus;
714#endif
715
716 sstatus = DC390_read8 (Scsi_Status);
717 if( !(sstatus & INTERRUPT) )
718 return IRQ_NONE;
719
720 DEBUG1(printk (KERN_DEBUG "sstatus=%02x,", sstatus));
721
722#if DMA_INT
723 spin_lock_irq(pACB->pScsiHost->host_lock);
724 dstatus = dc390_dma_intr (pACB);
725 spin_unlock_irq(pACB->pScsiHost->host_lock);
726
727 DEBUG1(printk (KERN_DEBUG "dstatus=%02x,", dstatus));
728 if (! (dstatus & SCSI_INTERRUPT))
729 {
730 DEBUG0(printk (KERN_WARNING "DC390 Int w/o SCSI actions (only DMA?)\n"));
731 return IRQ_NONE;
732 }
733#else
734
735
736
737#endif
738
739 spin_lock_irq(pACB->pScsiHost->host_lock);
740
741 istate = DC390_read8 (Intern_State);
742 istatus = DC390_read8 (INT_Status);
743
744 DEBUG1(printk (KERN_INFO "Istatus(Res,Inv,Dis,Serv,Succ,ReS,SelA,Sel)=%02x,",istatus));
745 dc390_laststatus &= ~0x00ffffff;
746 dc390_laststatus |= sstatus<<16 | istate<<8 | istatus;
747
748 if (sstatus & ILLEGAL_OP_ERR)
749 {
750 printk ("DC390: Illegal Operation detected (%08x)!\n", dc390_laststatus);
751 dc390_dumpinfo (pACB, pACB->pActiveDCB, pACB->pActiveDCB->pActiveSRB);
752 }
753
754 else if (istatus & INVALID_CMD)
755 {
756 printk ("DC390: Invalid Command detected (%08x)!\n", dc390_laststatus);
757 dc390_InvalidCmd( pACB );
758 goto unlock;
759 }
760
761 if (istatus & SCSI_RESET)
762 {
763 dc390_ScsiRstDetect( pACB );
764 goto unlock;
765 }
766
767 if (istatus & DISCONNECTED)
768 {
769 dc390_Disconnect( pACB );
770 goto unlock;
771 }
772
773 if (istatus & RESELECTED)
774 {
775 dc390_Reselect( pACB );
776 goto unlock;
777 }
778
779 else if (istatus & (SELECTED | SEL_ATTENTION))
780 {
781 printk (KERN_ERR "DC390: Target mode not supported!\n");
782 goto unlock;
783 }
784
785 if (istatus & (SUCCESSFUL_OP|SERVICE_REQUEST) )
786 {
787 pDCB = pACB->pActiveDCB;
788 if (!pDCB)
789 {
790 printk (KERN_ERR "DC390: Suc. op/ Serv. req: pActiveDCB = 0!\n");
791 goto unlock;
792 }
793 pSRB = pDCB->pActiveSRB;
794 if( pDCB->DCBFlag & ABORT_DEV_ )
795 dc390_EnableMsgOut_Abort (pACB, pSRB);
796
797 phase = pSRB->ScsiPhase;
798 DEBUG1(printk (KERN_INFO "DC390: [%i]%s(0) (%02x)\n", phase, dc390_p0_str[phase], sstatus));
799 stateV = (void *) dc390_phase0[phase];
800 ( *stateV )( pACB, pSRB, &sstatus );
801
802 pSRB->ScsiPhase = sstatus & 7;
803 phase = (u8) sstatus & 7;
804 DEBUG1(printk (KERN_INFO "DC390: [%i]%s(1) (%02x)\n", phase, dc390_p1_str[phase], sstatus));
805 stateV = (void *) dc390_phase1[phase];
806 ( *stateV )( pACB, pSRB, &sstatus );
807 }
808
809 unlock:
810 spin_unlock_irq(pACB->pScsiHost->host_lock);
811 return IRQ_HANDLED;
812}
813
814static irqreturn_t do_DC390_Interrupt(int irq, void *dev_id)
815{
816 irqreturn_t ret;
817 DEBUG1(printk (KERN_INFO "DC390: Irq (%i) caught: ", irq));
818
819 ret = DC390_Interrupt(dev_id);
820 DEBUG1(printk (".. IRQ returned\n"));
821 return ret;
822}
823
824static void
825dc390_DataOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
826{
827 u8 sstatus;
828 struct scatterlist *psgl;
829 u32 ResidCnt, xferCnt;
830 u8 dstate = 0;
831
832 sstatus = *psstatus;
833
834 if( !(pSRB->SRBState & SRB_XFERPAD) )
835 {
836 if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR) )
837 pSRB->SRBStatus |= PARITY_ERROR;
838
839 if( sstatus & COUNT_2_ZERO )
840 {
841 unsigned long timeout = jiffies + HZ;
842
843
844 if (pSRB->SGToBeXferLen)
845 while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE)) {
846 spin_unlock_irq(pACB->pScsiHost->host_lock);
847 udelay(50);
848 spin_lock_irq(pACB->pScsiHost->host_lock);
849 }
850 if (!time_before(jiffies, timeout))
851 printk (KERN_CRIT "DC390: Deadlock in DataOut_0: DMA aborted unfinished: %06x bytes remain!!\n",
852 DC390_read32 (DMA_Wk_ByteCntr));
853 dc390_laststatus &= ~0xff000000;
854 dc390_laststatus |= dstate << 24;
855 pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
856 pSRB->SGIndex++;
857 if( pSRB->SGIndex < pSRB->SGcount )
858 {
859 pSRB->pSegmentList++;
860 psgl = pSRB->pSegmentList;
861
862 pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
863 pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
864 }
865 else
866 pSRB->SGToBeXferLen = 0;
867 }
868 else
869 {
870 ResidCnt = (u32) DC390_read8 (Current_Fifo) & 0x1f;
871 ResidCnt |= (u32) DC390_read8 (CtcReg_High) << 16;
872 ResidCnt |= (u32) DC390_read8 (CtcReg_Mid) << 8;
873 ResidCnt += (u32) DC390_read8 (CtcReg_Low);
874
875 xferCnt = pSRB->SGToBeXferLen - ResidCnt;
876 pSRB->SGBusAddr += xferCnt;
877 pSRB->TotalXferredLen += xferCnt;
878 pSRB->SGToBeXferLen = ResidCnt;
879 }
880 }
881 if ((*psstatus & 7) != SCSI_DATA_OUT)
882 {
883 DC390_write8 (DMA_Cmd, WRITE_DIRECTION+DMA_IDLE_CMD);
884 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
885 }
886}
887
888static void
889dc390_DataIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
890{
891 u8 sstatus, residual, bval;
892 struct scatterlist *psgl;
893 u32 ResidCnt, i;
894 unsigned long xferCnt;
895 u8 *ptr;
896
897 sstatus = *psstatus;
898
899 if( !(pSRB->SRBState & SRB_XFERPAD) )
900 {
901 if( sstatus & (PARITY_ERR | ILLEGAL_OP_ERR))
902 pSRB->SRBStatus |= PARITY_ERROR;
903
904 if( sstatus & COUNT_2_ZERO )
905 {
906 int dstate = 0;
907 unsigned long timeout = jiffies + HZ;
908
909
910 if (pSRB->SGToBeXferLen)
911 while (time_before(jiffies, timeout) && !((dstate = DC390_read8 (DMA_Status)) & DMA_XFER_DONE)) {
912 spin_unlock_irq(pACB->pScsiHost->host_lock);
913 udelay(50);
914 spin_lock_irq(pACB->pScsiHost->host_lock);
915 }
916 if (!time_before(jiffies, timeout)) {
917 printk (KERN_CRIT "DC390: Deadlock in DataIn_0: DMA aborted unfinished: %06x bytes remain!!\n",
918 DC390_read32 (DMA_Wk_ByteCntr));
919 printk (KERN_CRIT "DC390: DataIn_0: DMA State: %i\n", dstate);
920 }
921 dc390_laststatus &= ~0xff000000;
922 dc390_laststatus |= dstate << 24;
923 DEBUG1(ResidCnt = ((unsigned long) DC390_read8 (CtcReg_High) << 16) \
924 + ((unsigned long) DC390_read8 (CtcReg_Mid) << 8) \
925 + ((unsigned long) DC390_read8 (CtcReg_Low)));
926 DEBUG1(printk (KERN_DEBUG "Count_2_Zero (ResidCnt=%i,ToBeXfer=%li),", ResidCnt, pSRB->SGToBeXferLen));
927
928 DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD);
929
930 pSRB->TotalXferredLen += pSRB->SGToBeXferLen;
931 pSRB->SGIndex++;
932 if( pSRB->SGIndex < pSRB->SGcount )
933 {
934 pSRB->pSegmentList++;
935 psgl = pSRB->pSegmentList;
936
937 pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
938 pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
939 }
940 else
941 pSRB->SGToBeXferLen = 0;
942 }
943 else
944 {
945 residual = 0;
946 bval = DC390_read8 (Current_Fifo);
947 while( bval & 0x1f )
948 {
949 DEBUG1(printk (KERN_DEBUG "Check for residuals,"));
950 if( (bval & 0x1f) == 1 )
951 {
952 for(i=0; i < 0x100; i++)
953 {
954 bval = DC390_read8 (Current_Fifo);
955 if( !(bval & 0x1f) )
956 goto din_1;
957 else if( i == 0x0ff )
958 {
959 residual = 1;
960 goto din_1;
961 }
962 }
963 }
964 else
965 bval = DC390_read8 (Current_Fifo);
966 }
967din_1:
968 DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_BLAST_CMD);
969 for (i = 0xa000; i; i--)
970 {
971 bval = DC390_read8 (DMA_Status);
972 if (bval & BLAST_COMPLETE)
973 break;
974 }
975
976 if (!i) printk (KERN_ERR "DC390: DMA Blast aborted unfinished!\n");
977
978 dc390_laststatus &= ~0xff000000; dc390_laststatus |= bval << 24;
979
980 DEBUG1(printk (KERN_DEBUG "Blast: Read %i times DMA_Status %02x", 0xa000-i, bval));
981 ResidCnt = (u32) DC390_read8 (CtcReg_High);
982 ResidCnt <<= 8;
983 ResidCnt |= (u32) DC390_read8 (CtcReg_Mid);
984 ResidCnt <<= 8;
985 ResidCnt |= (u32) DC390_read8 (CtcReg_Low);
986
987 xferCnt = pSRB->SGToBeXferLen - ResidCnt;
988 pSRB->SGBusAddr += xferCnt;
989 pSRB->TotalXferredLen += xferCnt;
990 pSRB->SGToBeXferLen = ResidCnt;
991
992 if( residual )
993 {
994 static int feedback_requested;
995 bval = DC390_read8 (ScsiFifo);
996
997 if (!feedback_requested) {
998 feedback_requested = 1;
999 printk(KERN_WARNING "%s: Please, contact <linux-scsi@vger.kernel.org> "
1000 "to help improve support for your system.\n", __FILE__);
1001 }
1002
1003 ptr = (u8 *) bus_to_virt( pSRB->SGBusAddr );
1004 *ptr = bval;
1005 pSRB->SGBusAddr++; xferCnt++;
1006 pSRB->TotalXferredLen++;
1007 pSRB->SGToBeXferLen--;
1008 }
1009 DEBUG1(printk (KERN_DEBUG "Xfered: %li, Total: %li, Remaining: %li\n", xferCnt,\
1010 pSRB->TotalXferredLen, pSRB->SGToBeXferLen));
1011
1012 }
1013 }
1014 if ((*psstatus & 7) != SCSI_DATA_IN)
1015 {
1016 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1017 DC390_write8 (DMA_Cmd, READ_DIRECTION+DMA_IDLE_CMD);
1018 }
1019}
1020
1021static void
1022dc390_Command_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1023{
1024}
1025
1026static void
1027dc390_Status_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1028{
1029
1030 pSRB->TargetStatus = DC390_read8 (ScsiFifo);
1031
1032 pSRB->EndMessage = DC390_read8 (ScsiFifo);
1033
1034 *psstatus = SCSI_NOP0;
1035 pSRB->SRBState = SRB_COMPLETED;
1036 DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
1037}
1038
1039static void
1040dc390_MsgOut_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1041{
1042 if( pSRB->SRBState & (SRB_UNEXPECT_RESEL+SRB_ABORT_SENT) )
1043 *psstatus = SCSI_NOP0;
1044
1045}
1046
1047
1048static void __inline__
1049dc390_reprog (struct dc390_acb* pACB, struct dc390_dcb* pDCB)
1050{
1051 DC390_write8 (Sync_Period, pDCB->SyncPeriod);
1052 DC390_write8 (Sync_Offset, pDCB->SyncOffset);
1053 DC390_write8 (CtrlReg3, pDCB->CtrlR3);
1054 DC390_write8 (CtrlReg4, pDCB->CtrlR4);
1055 dc390_SetXferRate (pACB, pDCB);
1056}
1057
1058
1059#ifdef DC390_DEBUG0
1060static void
1061dc390_printMsg (u8 *MsgBuf, u8 len)
1062{
1063 int i;
1064 printk (" %02x", MsgBuf[0]);
1065 for (i = 1; i < len; i++)
1066 printk (" %02x", MsgBuf[i]);
1067 printk ("\n");
1068}
1069#endif
1070
1071#define DC390_ENABLE_MSGOUT DC390_write8 (ScsiCmd, SET_ATN_CMD)
1072
1073
1074static void __inline__
1075dc390_MsgIn_reject (struct dc390_acb* pACB, struct dc390_srb* pSRB)
1076{
1077 pSRB->MsgOutBuf[0] = MESSAGE_REJECT;
1078 pSRB->MsgCnt = 1;
1079 DC390_ENABLE_MSGOUT;
1080 DEBUG0 (printk (KERN_INFO "DC390: Reject message\n"));
1081}
1082
1083
1084static void
1085dc390_EnableMsgOut_Abort ( struct dc390_acb* pACB, struct dc390_srb* pSRB )
1086{
1087 pSRB->MsgOutBuf[0] = ABORT;
1088 pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
1089 pSRB->pSRBDCB->DCBFlag &= ~ABORT_DEV_;
1090}
1091
1092static struct dc390_srb*
1093dc390_MsgIn_QTag (struct dc390_acb* pACB, struct dc390_dcb* pDCB, s8 tag)
1094{
1095 struct dc390_srb* pSRB = pDCB->pGoingSRB;
1096
1097 if (pSRB)
1098 {
1099 struct scsi_cmnd *scmd = scsi_find_tag(pSRB->pcmd->device, tag);
1100 pSRB = (struct dc390_srb *)scmd->host_scribble;
1101
1102 if (pDCB->DCBFlag & ABORT_DEV_)
1103 {
1104 pSRB->SRBState = SRB_ABORT_SENT;
1105 dc390_EnableMsgOut_Abort( pACB, pSRB );
1106 }
1107
1108 if (!(pSRB->SRBState & SRB_DISCONNECT))
1109 goto mingx0;
1110
1111 pDCB->pActiveSRB = pSRB;
1112 pSRB->SRBState = SRB_DATA_XFER;
1113 }
1114 else
1115 {
1116 mingx0:
1117 pSRB = pACB->pTmpSRB;
1118 pSRB->SRBState = SRB_UNEXPECT_RESEL;
1119 pDCB->pActiveSRB = pSRB;
1120 pSRB->MsgOutBuf[0] = ABORT_TAG;
1121 pSRB->MsgCnt = 1; DC390_ENABLE_MSGOUT;
1122 }
1123 return pSRB;
1124}
1125
1126
1127
1128static void
1129dc390_MsgIn_set_async (struct dc390_acb* pACB, struct dc390_srb* pSRB)
1130{
1131 struct dc390_dcb* pDCB = pSRB->pSRBDCB;
1132 if (!(pSRB->SRBState & DO_SYNC_NEGO))
1133 printk (KERN_INFO "DC390: Target %i initiates Non-Sync?\n", pDCB->TargetID);
1134 pSRB->SRBState &= ~DO_SYNC_NEGO;
1135 pDCB->SyncMode &= ~(SYNC_ENABLE+SYNC_NEGO_DONE);
1136 pDCB->SyncPeriod = 0;
1137 pDCB->SyncOffset = 0;
1138
1139 pDCB->CtrlR3 = FAST_CLK;
1140 pDCB->CtrlR4 &= 0x3f;
1141 pDCB->CtrlR4 |= pACB->glitch_cfg;
1142 dc390_reprog (pACB, pDCB);
1143}
1144
1145
1146static void
1147dc390_MsgIn_set_sync (struct dc390_acb* pACB, struct dc390_srb* pSRB)
1148{
1149 u8 bval;
1150 u16 wval, wval1;
1151 struct dc390_dcb* pDCB = pSRB->pSRBDCB;
1152 u8 oldsyncperiod = pDCB->SyncPeriod;
1153 u8 oldsyncoffset = pDCB->SyncOffset;
1154
1155 if (!(pSRB->SRBState & DO_SYNC_NEGO))
1156 {
1157 printk (KERN_INFO "DC390: Target %i initiates Sync: %ins %i ... answer ...\n",
1158 pDCB->TargetID, pSRB->MsgInBuf[3]<<2, pSRB->MsgInBuf[4]);
1159
1160
1161
1162
1163
1164
1165 if (pSRB->MsgInBuf[4] > 15)
1166 {
1167 printk (KERN_INFO "DC390: Lower Sync Offset to 15\n");
1168 pSRB->MsgInBuf[4] = 15;
1169 }
1170 if (pSRB->MsgInBuf[3] < pDCB->NegoPeriod)
1171 {
1172 printk (KERN_INFO "DC390: Set sync nego period to %ins\n", pDCB->NegoPeriod << 2);
1173 pSRB->MsgInBuf[3] = pDCB->NegoPeriod;
1174 }
1175 memcpy (pSRB->MsgOutBuf, pSRB->MsgInBuf, 5);
1176 pSRB->MsgCnt = 5;
1177 DC390_ENABLE_MSGOUT;
1178 }
1179
1180 pSRB->SRBState &= ~DO_SYNC_NEGO;
1181 pDCB->SyncMode |= SYNC_ENABLE+SYNC_NEGO_DONE;
1182 pDCB->SyncOffset &= 0x0f0;
1183 pDCB->SyncOffset |= pSRB->MsgInBuf[4];
1184 pDCB->NegoPeriod = pSRB->MsgInBuf[3];
1185
1186 wval = (u16) pSRB->MsgInBuf[3];
1187 wval = wval << 2; wval -= 3; wval1 = wval / 25;
1188 if( (wval1 * 25) != wval) wval1++;
1189 bval = FAST_CLK+FAST_SCSI;
1190
1191 pDCB->CtrlR4 &= 0x3f;
1192 if (pACB->glitch_cfg != NS_TO_GLITCH(0))
1193 pDCB->CtrlR4 |= NS_TO_GLITCH(((GLITCH_TO_NS(pACB->glitch_cfg)) - 1));
1194 else
1195 pDCB->CtrlR4 |= NS_TO_GLITCH(0);
1196 if (wval1 < 4) pDCB->CtrlR4 |= NS_TO_GLITCH(0);
1197
1198 if (wval1 >= 8)
1199 {
1200 wval1--;
1201 bval = FAST_CLK;
1202 pDCB->CtrlR4 |= pACB->glitch_cfg;
1203 }
1204
1205 pDCB->CtrlR3 = bval;
1206 pDCB->SyncPeriod = (u8)wval1;
1207
1208 if ((oldsyncperiod != wval1 || oldsyncoffset != pDCB->SyncOffset) && pDCB->TargetLUN == 0)
1209 {
1210 if (! (bval & FAST_SCSI)) wval1++;
1211 printk (KERN_INFO "DC390: Target %i: Sync transfer %i.%1i MHz, Offset %i\n", pDCB->TargetID,
1212 40/wval1, ((40%wval1)*10+wval1/2)/wval1, pDCB->SyncOffset & 0x0f);
1213 }
1214
1215 dc390_reprog (pACB, pDCB);
1216}
1217
1218
1219
1220
1221static void
1222dc390_restore_ptr (struct dc390_acb* pACB, struct dc390_srb* pSRB)
1223{
1224 struct scsi_cmnd *pcmd = pSRB->pcmd;
1225 struct scatterlist *psgl;
1226 pSRB->TotalXferredLen = 0;
1227 pSRB->SGIndex = 0;
1228 if (pcmd->use_sg) {
1229 pSRB->pSegmentList = (struct scatterlist *)pcmd->request_buffer;
1230 psgl = pSRB->pSegmentList;
1231
1232
1233 while (pSRB->TotalXferredLen + (unsigned long) sg_dma_len(psgl) < pSRB->Saved_Ptr)
1234 {
1235 pSRB->TotalXferredLen += (unsigned long) sg_dma_len(psgl);
1236 pSRB->SGIndex++;
1237 if( pSRB->SGIndex < pSRB->SGcount )
1238 {
1239 pSRB->pSegmentList++;
1240 psgl = pSRB->pSegmentList;
1241 pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
1242 pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
1243 }
1244 else
1245 pSRB->SGToBeXferLen = 0;
1246 }
1247 pSRB->SGToBeXferLen -= (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
1248 pSRB->SGBusAddr += (pSRB->Saved_Ptr - pSRB->TotalXferredLen);
1249 printk (KERN_INFO "DC390: Pointer restored. Segment %i, Total %li, Bus %08lx\n",
1250 pSRB->SGIndex, pSRB->Saved_Ptr, pSRB->SGBusAddr);
1251
1252 } else if(pcmd->request_buffer) {
1253
1254
1255 sg_dma_len(&pSRB->Segmentx) = pcmd->request_bufflen - pSRB->Saved_Ptr;
1256 pSRB->SGcount = 1;
1257 pSRB->pSegmentList = (struct scatterlist *) &pSRB->Segmentx;
1258 } else {
1259 pSRB->SGcount = 0;
1260 printk (KERN_INFO "DC390: RESTORE_PTR message for Transfer without Scatter-Gather ??\n");
1261 }
1262
1263 pSRB->TotalXferredLen = pSRB->Saved_Ptr;
1264}
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276static u8 __inline__
1277dc390_MsgIn_complete (u8 *msgbuf, u32 len)
1278{
1279 if (*msgbuf == EXTENDED_MESSAGE)
1280 {
1281 if (len < 2) return 0;
1282 if (len < msgbuf[1] + 2) return 0;
1283 }
1284 else if (*msgbuf >= 0x20 && *msgbuf <= 0x2f)
1285 if (len < 2) return 0;
1286 return 1;
1287}
1288
1289
1290
1291
1292static void
1293dc390_MsgIn_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1294{
1295 struct dc390_dcb* pDCB = pACB->pActiveDCB;
1296
1297
1298
1299 pSRB->MsgInBuf[pACB->MsgLen++] = DC390_read8 (ScsiFifo);
1300
1301
1302
1303 if (dc390_MsgIn_complete (pSRB->MsgInBuf, pACB->MsgLen))
1304 {
1305 DEBUG0 (printk (KERN_INFO "DC390: MsgIn:"); dc390_printMsg (pSRB->MsgInBuf, pACB->MsgLen));
1306
1307 switch (pSRB->MsgInBuf[0])
1308 {
1309 case DISCONNECT:
1310 pSRB->SRBState = SRB_DISCONNECT; break;
1311
1312 case SIMPLE_QUEUE_TAG:
1313 case HEAD_OF_QUEUE_TAG:
1314 case ORDERED_QUEUE_TAG:
1315 pSRB = dc390_MsgIn_QTag (pACB, pDCB, pSRB->MsgInBuf[1]);
1316 break;
1317
1318 case MESSAGE_REJECT:
1319 DC390_write8 (ScsiCmd, RESET_ATN_CMD);
1320 pDCB->NegoPeriod = 50;
1321 if( pSRB->SRBState & DO_SYNC_NEGO)
1322 dc390_MsgIn_set_async (pACB, pSRB);
1323 break;
1324
1325 case EXTENDED_MESSAGE:
1326
1327 if (pSRB->MsgInBuf[1] != 3 || pSRB->MsgInBuf[2] != EXTENDED_SDTR)
1328 dc390_MsgIn_reject (pACB, pSRB);
1329 else
1330 {
1331 if (pSRB->MsgInBuf[3] == 0 || pSRB->MsgInBuf[4] == 0)
1332 dc390_MsgIn_set_async (pACB, pSRB);
1333 else
1334 dc390_MsgIn_set_sync (pACB, pSRB);
1335 }
1336
1337
1338 case COMMAND_COMPLETE: break;
1339
1340
1341
1342 case SAVE_POINTERS:
1343 pSRB->Saved_Ptr = pSRB->TotalXferredLen;
1344 break;
1345
1346 case RESTORE_POINTERS:
1347 DEBUG0(printk ("DC390: RESTORE POINTER message received ... try to handle\n"));
1348 dc390_restore_ptr (pACB, pSRB);
1349 break;
1350
1351
1352 default: dc390_MsgIn_reject (pACB, pSRB);
1353 }
1354
1355
1356 pSRB->SRBState &= ~SRB_MSGIN;
1357 pACB->MsgLen = 0;
1358 }
1359
1360 *psstatus = SCSI_NOP0;
1361 DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
1362
1363}
1364
1365
1366static void
1367dc390_DataIO_Comm( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 ioDir)
1368{
1369 struct scatterlist *psgl;
1370 unsigned long lval;
1371 struct dc390_dcb* pDCB = pACB->pActiveDCB;
1372
1373 if (pSRB == pACB->pTmpSRB)
1374 {
1375 if (pDCB)
1376 printk(KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (%02i-%i)\n", pDCB->TargetID, pDCB->TargetLUN);
1377 else
1378 printk(KERN_ERR "DC390: pSRB == pTmpSRB! (TagQ Error?) (DCB 0!)\n");
1379
1380
1381 if (pDCB && pACB->scan_devices && pDCB->GoingSRBCnt == 1) {
1382 pSRB = pDCB->pGoingSRB;
1383 pDCB->pActiveSRB = pSRB;
1384 } else {
1385 pSRB->pSRBDCB = pDCB;
1386 dc390_EnableMsgOut_Abort(pACB, pSRB);
1387 if (pDCB)
1388 pDCB->DCBFlag |= ABORT_DEV;
1389 return;
1390 }
1391 }
1392
1393 if( pSRB->SGIndex < pSRB->SGcount )
1394 {
1395 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD | ioDir );
1396 if( !pSRB->SGToBeXferLen )
1397 {
1398 psgl = pSRB->pSegmentList;
1399 pSRB->SGBusAddr = cpu_to_le32(pci_dma_lo32(sg_dma_address(psgl)));
1400 pSRB->SGToBeXferLen = cpu_to_le32(sg_dma_len(psgl));
1401 DEBUG1(printk (KERN_DEBUG " DC390: Next SG segment."));
1402 }
1403 lval = pSRB->SGToBeXferLen;
1404 DEBUG1(printk (KERN_DEBUG " DC390: Start transfer: %li bytes (address %08lx)\n", lval, pSRB->SGBusAddr));
1405 DC390_write8 (CtcReg_Low, (u8) lval);
1406 lval >>= 8;
1407 DC390_write8 (CtcReg_Mid, (u8) lval);
1408 lval >>= 8;
1409 DC390_write8 (CtcReg_High, (u8) lval);
1410
1411 DC390_write32 (DMA_XferCnt, pSRB->SGToBeXferLen);
1412 DC390_write32 (DMA_XferAddr, pSRB->SGBusAddr);
1413
1414
1415 pSRB->SRBState = SRB_DATA_XFER;
1416
1417 DC390_write8 (ScsiCmd, DMA_COMMAND+INFO_XFER_CMD);
1418
1419 DC390_write8 (DMA_Cmd, DMA_START_CMD | ioDir | DMA_INT);
1420
1421
1422
1423 }
1424 else
1425 {
1426 if( pSRB->SGcount )
1427 {
1428 pSRB->AdaptStatus = H_OVER_UNDER_RUN;
1429 pSRB->SRBStatus |= OVER_RUN;
1430 DEBUG0(printk (KERN_WARNING " DC390: Overrun -"));
1431 }
1432 DEBUG0(printk (KERN_WARNING " Clear transfer pad \n"));
1433 DC390_write8 (CtcReg_Low, 0);
1434 DC390_write8 (CtcReg_Mid, 0);
1435 DC390_write8 (CtcReg_High, 0);
1436
1437 pSRB->SRBState |= SRB_XFERPAD;
1438 DC390_write8 (ScsiCmd, DMA_COMMAND+XFER_PAD_BYTE);
1439
1440
1441
1442
1443 }
1444}
1445
1446
1447static void
1448dc390_DataOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1449{
1450 dc390_DataIO_Comm (pACB, pSRB, WRITE_DIRECTION);
1451}
1452
1453static void
1454dc390_DataInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1455{
1456 dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
1457}
1458
1459static void
1460dc390_CommandPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1461{
1462 struct dc390_dcb* pDCB;
1463 u8 i, cnt;
1464 u8 *ptr;
1465
1466 DC390_write8 (ScsiCmd, RESET_ATN_CMD);
1467 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1468 if( !(pSRB->SRBFlag & AUTO_REQSENSE) )
1469 {
1470 cnt = (u8) pSRB->pcmd->cmd_len;
1471 ptr = (u8 *) pSRB->pcmd->cmnd;
1472 for(i=0; i < cnt; i++)
1473 DC390_write8 (ScsiFifo, *(ptr++));
1474 }
1475 else
1476 {
1477 DC390_write8 (ScsiFifo, REQUEST_SENSE);
1478 pDCB = pACB->pActiveDCB;
1479 DC390_write8 (ScsiFifo, pDCB->TargetLUN << 5);
1480 DC390_write8 (ScsiFifo, 0);
1481 DC390_write8 (ScsiFifo, 0);
1482 DC390_write8 (ScsiFifo, sizeof(pSRB->pcmd->sense_buffer));
1483 DC390_write8 (ScsiFifo, 0);
1484 DEBUG0(printk(KERN_DEBUG "DC390: AutoReqSense (CmndPhase)!\n"));
1485 }
1486 pSRB->SRBState = SRB_COMMAND;
1487 DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1488}
1489
1490static void
1491dc390_StatusPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1492{
1493 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1494 pSRB->SRBState = SRB_STATUS;
1495 DC390_write8 (ScsiCmd, INITIATOR_CMD_CMPLTE);
1496
1497}
1498
1499static void
1500dc390_MsgOutPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1501{
1502 u8 bval, i, cnt;
1503 u8 *ptr;
1504 struct dc390_dcb* pDCB;
1505
1506 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1507 pDCB = pACB->pActiveDCB;
1508 if( !(pSRB->SRBState & SRB_MSGOUT) )
1509 {
1510 cnt = pSRB->MsgCnt;
1511 if( cnt )
1512 {
1513 ptr = (u8 *) pSRB->MsgOutBuf;
1514 for(i=0; i < cnt; i++)
1515 DC390_write8 (ScsiFifo, *(ptr++));
1516 pSRB->MsgCnt = 0;
1517 if( (pDCB->DCBFlag & ABORT_DEV_) &&
1518 (pSRB->MsgOutBuf[0] == ABORT) )
1519 pSRB->SRBState = SRB_ABORT_SENT;
1520 }
1521 else
1522 {
1523 bval = ABORT;
1524 if( (pSRB->pcmd->cmnd[0] == INQUIRY ) ||
1525 (pSRB->pcmd->cmnd[0] == REQUEST_SENSE) ||
1526 (pSRB->SRBFlag & AUTO_REQSENSE) )
1527 {
1528 if( pDCB->SyncMode & SYNC_ENABLE )
1529 goto mop1;
1530 }
1531 DC390_write8 (ScsiFifo, bval);
1532 }
1533 DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1534 }
1535 else
1536 {
1537mop1:
1538 printk (KERN_ERR "DC390: OLD Sync Nego code triggered! (%i %i)\n", pDCB->TargetID, pDCB->TargetLUN);
1539 DC390_write8 (ScsiFifo, EXTENDED_MESSAGE);
1540 DC390_write8 (ScsiFifo, 3);
1541 DC390_write8 (ScsiFifo, EXTENDED_SDTR);
1542 DC390_write8 (ScsiFifo, pDCB->NegoPeriod);
1543 if (pDCB->SyncOffset & 0x0f)
1544 DC390_write8 (ScsiFifo, pDCB->SyncOffset);
1545 else
1546 DC390_write8 (ScsiFifo, SYNC_NEGO_OFFSET);
1547 pSRB->SRBState |= DO_SYNC_NEGO;
1548 DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1549 }
1550}
1551
1552static void
1553dc390_MsgInPhase( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1554{
1555 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1556 if( !(pSRB->SRBState & SRB_MSGIN) )
1557 {
1558 pSRB->SRBState &= ~SRB_DISCONNECT;
1559 pSRB->SRBState |= SRB_MSGIN;
1560 }
1561 DC390_write8 (ScsiCmd, INFO_XFER_CMD);
1562
1563}
1564
1565static void
1566dc390_Nop_0( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1567{
1568}
1569
1570static void
1571dc390_Nop_1( struct dc390_acb* pACB, struct dc390_srb* pSRB, u8 *psstatus)
1572{
1573}
1574
1575
1576static void
1577dc390_SetXferRate( struct dc390_acb* pACB, struct dc390_dcb* pDCB )
1578{
1579 u8 bval, i, cnt;
1580 struct dc390_dcb* ptr;
1581
1582 if( !(pDCB->TargetLUN) )
1583 {
1584 if( !pACB->scan_devices )
1585 {
1586 ptr = pACB->pLinkDCB;
1587 cnt = pACB->DCBCnt;
1588 bval = pDCB->TargetID;
1589 for(i=0; i<cnt; i++)
1590 {
1591 if( ptr->TargetID == bval )
1592 {
1593 ptr->SyncPeriod = pDCB->SyncPeriod;
1594 ptr->SyncOffset = pDCB->SyncOffset;
1595 ptr->CtrlR3 = pDCB->CtrlR3;
1596 ptr->CtrlR4 = pDCB->CtrlR4;
1597 ptr->SyncMode = pDCB->SyncMode;
1598 }
1599 ptr = ptr->pNextDCB;
1600 }
1601 }
1602 }
1603 return;
1604}
1605
1606
1607static void
1608dc390_Disconnect( struct dc390_acb* pACB )
1609{
1610 struct dc390_dcb *pDCB;
1611 struct dc390_srb *pSRB, *psrb;
1612 u8 i, cnt;
1613
1614 DEBUG0(printk(KERN_INFO "DISC,"));
1615
1616 if (!pACB->Connected) printk(KERN_ERR "DC390: Disconnect not-connected bus?\n");
1617 pACB->Connected = 0;
1618 pDCB = pACB->pActiveDCB;
1619 if (!pDCB)
1620 {
1621 DEBUG0(printk(KERN_ERR "ACB:%p->ActiveDCB:%p IOPort:%04x IRQ:%02x !\n",\
1622 pACB, pDCB, pACB->IOPortBase, pACB->IRQLevel));
1623 mdelay(400);
1624 DC390_read8 (INT_Status);
1625 DC390_write8 (ScsiCmd, EN_SEL_RESEL);
1626 return;
1627 }
1628 DC390_write8 (ScsiCmd, EN_SEL_RESEL);
1629 pSRB = pDCB->pActiveSRB;
1630 pACB->pActiveDCB = NULL;
1631 pSRB->ScsiPhase = SCSI_NOP0;
1632 if( pSRB->SRBState & SRB_UNEXPECT_RESEL )
1633 pSRB->SRBState = 0;
1634 else if( pSRB->SRBState & SRB_ABORT_SENT )
1635 {
1636 pDCB->TagMask = 0;
1637 pDCB->DCBFlag = 0;
1638 cnt = pDCB->GoingSRBCnt;
1639 pDCB->GoingSRBCnt = 0;
1640 pSRB = pDCB->pGoingSRB;
1641 for( i=0; i < cnt; i++)
1642 {
1643 psrb = pSRB->pNextSRB;
1644 dc390_Free_insert (pACB, pSRB);
1645 pSRB = psrb;
1646 }
1647 pDCB->pGoingSRB = NULL;
1648 }
1649 else
1650 {
1651 if( (pSRB->SRBState & (SRB_START_+SRB_MSGOUT)) ||
1652 !(pSRB->SRBState & (SRB_DISCONNECT+SRB_COMPLETED)) )
1653 {
1654 pSRB->TargetStatus = SCSI_STAT_SEL_TIMEOUT;
1655 goto disc1;
1656 }
1657 else if (!(pSRB->SRBState & SRB_DISCONNECT) && (pSRB->SRBState & SRB_COMPLETED))
1658 {
1659disc1:
1660 dc390_freetag (pDCB, pSRB);
1661 pDCB->pActiveSRB = NULL;
1662 pSRB->SRBState = SRB_FREE;
1663 dc390_SRBdone( pACB, pDCB, pSRB);
1664 }
1665 }
1666 pACB->MsgLen = 0;
1667}
1668
1669
1670static void
1671dc390_Reselect( struct dc390_acb* pACB )
1672{
1673 struct dc390_dcb* pDCB;
1674 struct dc390_srb* pSRB;
1675 u8 id, lun;
1676
1677 DEBUG0(printk(KERN_INFO "RSEL,"));
1678 pACB->Connected = 1;
1679 pDCB = pACB->pActiveDCB;
1680 if( pDCB )
1681 {
1682 DEBUG0(printk ("DC390: (ActiveDCB != 0: Arb. lost but resel. won)!\n"));
1683 pSRB = pDCB->pActiveSRB;
1684 if( !( pACB->scan_devices ) )
1685 {
1686 struct scsi_cmnd *pcmd = pSRB->pcmd;
1687 pcmd->resid = pcmd->request_bufflen;
1688 SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
1689 dc390_Going_remove(pDCB, pSRB);
1690 dc390_Free_insert(pACB, pSRB);
1691 pcmd->scsi_done (pcmd);
1692 DEBUG0(printk(KERN_DEBUG"DC390: Return SRB %p to free\n", pSRB));
1693 }
1694 }
1695
1696 lun = DC390_read8 (ScsiFifo);
1697 DEBUG0(printk ("Dev %02x,", lun));
1698 if (!(lun & (1 << pACB->pScsiHost->this_id)))
1699 printk (KERN_ERR "DC390: Reselection must select host adapter: %02x!\n", lun);
1700 else
1701 lun ^= 1 << pACB->pScsiHost->this_id;
1702 id = 0; while (lun >>= 1) id++;
1703
1704 lun = DC390_read8 (ScsiFifo);
1705 if (!(lun & IDENTIFY_BASE)) printk (KERN_ERR "DC390: Resel: Expect identify message!\n");
1706 lun &= 7;
1707 DEBUG0(printk ("(%02i-%i),", id, lun));
1708 pDCB = dc390_findDCB (pACB, id, lun);
1709 if (!pDCB)
1710 {
1711 printk (KERN_ERR "DC390: Reselect from non existing device (%02i-%i)\n",
1712 id, lun);
1713 return;
1714 }
1715 pACB->pActiveDCB = pDCB;
1716
1717 if( pDCB->SyncMode & EN_TAG_QUEUEING )
1718 {
1719 pSRB = pACB->pTmpSRB;
1720 pDCB->pActiveSRB = pSRB;
1721 }
1722 else
1723 {
1724 pSRB = pDCB->pActiveSRB;
1725 if( !pSRB || !(pSRB->SRBState & SRB_DISCONNECT) )
1726 {
1727 pSRB= pACB->pTmpSRB;
1728 pSRB->SRBState = SRB_UNEXPECT_RESEL;
1729 printk (KERN_ERR "DC390: Reselect without outstanding cmnd (%02i-%i)\n",
1730 id, lun);
1731 pDCB->pActiveSRB = pSRB;
1732 dc390_EnableMsgOut_Abort ( pACB, pSRB );
1733 }
1734 else
1735 {
1736 if( pDCB->DCBFlag & ABORT_DEV_ )
1737 {
1738 pSRB->SRBState = SRB_ABORT_SENT;
1739 printk (KERN_INFO "DC390: Reselect: Abort (%02i-%i)\n",
1740 id, lun);
1741 dc390_EnableMsgOut_Abort( pACB, pSRB );
1742 }
1743 else
1744 pSRB->SRBState = SRB_DATA_XFER;
1745 }
1746 }
1747
1748 DEBUG1(printk (KERN_DEBUG "Resel SRB(%p): TagNum (%02x)\n", pSRB, pSRB->TagNumber));
1749 pSRB->ScsiPhase = SCSI_NOP0;
1750 DC390_write8 (Scsi_Dest_ID, pDCB->TargetID);
1751 DC390_write8 (Sync_Period, pDCB->SyncPeriod);
1752 DC390_write8 (Sync_Offset, pDCB->SyncOffset);
1753 DC390_write8 (CtrlReg1, pDCB->CtrlR1);
1754 DC390_write8 (CtrlReg3, pDCB->CtrlR3);
1755 DC390_write8 (CtrlReg4, pDCB->CtrlR4);
1756 DC390_write8 (ScsiCmd, MSG_ACCEPTED_CMD);
1757}
1758
1759static int __inline__
1760dc390_RequestSense(struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
1761{
1762 struct scsi_cmnd *pcmd;
1763
1764 pcmd = pSRB->pcmd;
1765
1766 REMOVABLEDEBUG(printk(KERN_INFO "DC390: RequestSense(Cmd %02x, Id %02x, LUN %02x)\n",\
1767 pcmd->cmnd[0], pDCB->TargetID, pDCB->TargetLUN));
1768
1769 pSRB->SRBFlag |= AUTO_REQSENSE;
1770 pSRB->SavedSGCount = pcmd->use_sg;
1771 pSRB->SavedTotXLen = pSRB->TotalXferredLen;
1772 pSRB->AdaptStatus = 0;
1773 pSRB->TargetStatus = 0;
1774
1775
1776
1777 pSRB->SGIndex = 0;
1778
1779 pSRB->TotalXferredLen = 0;
1780 pSRB->SGToBeXferLen = 0;
1781 return dc390_StartSCSI(pACB, pDCB, pSRB);
1782}
1783
1784
1785static void
1786dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB )
1787{
1788 u8 status;
1789 struct scsi_cmnd *pcmd;
1790
1791 pcmd = pSRB->pcmd;
1792
1793 dc390_pci_unmap(pSRB);
1794
1795 status = pSRB->TargetStatus;
1796
1797 DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\
1798 pSRB, pcmd->pid));
1799 if(pSRB->SRBFlag & AUTO_REQSENSE)
1800 {
1801 pSRB->SRBFlag &= ~AUTO_REQSENSE;
1802 pSRB->AdaptStatus = 0;
1803 pSRB->TargetStatus = CHECK_CONDITION << 1;
1804
1805
1806 if (status == (CHECK_CONDITION << 1))
1807 pcmd->result = MK_RES_LNX(0, DID_BAD_TARGET, 0, 0);
1808 else
1809 {
1810 if( pSRB->pcmd->cmnd[0] == TEST_UNIT_READY )
1811 {
1812
1813 pcmd->result = MK_RES_LNX(DRIVER_SENSE,DID_OK,0,CHECK_CONDITION);
1814 REMOVABLEDEBUG(printk(KERN_INFO "Cmd=%02x, Result=%08x, XferL=%08x\n",pSRB->pcmd->cmnd[0],\
1815 (u32) pcmd->result, (u32) pSRB->TotalXferredLen));
1816 } else {
1817 SET_RES_DRV(pcmd->result, DRIVER_SENSE);
1818 pcmd->use_sg = pSRB->SavedSGCount;
1819
1820 DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
1821 pSRB->TotalXferredLen = 0;
1822 SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
1823 }
1824 }
1825 goto cmd_done;
1826 }
1827 if( status )
1828 {
1829 if( status_byte(status) == CHECK_CONDITION )
1830 {
1831 if (dc390_RequestSense(pACB, pDCB, pSRB)) {
1832 SET_RES_DID(pcmd->result, DID_ERROR);
1833 goto cmd_done;
1834 }
1835 return;
1836 }
1837 else if( status_byte(status) == QUEUE_FULL )
1838 {
1839 scsi_track_queue_full(pcmd->device, pDCB->GoingSRBCnt - 1);
1840 pcmd->use_sg = pSRB->SavedSGCount;
1841 DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
1842 pSRB->TotalXferredLen = 0;
1843 SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
1844 }
1845 else if(status == SCSI_STAT_SEL_TIMEOUT)
1846 {
1847 pSRB->AdaptStatus = H_SEL_TIMEOUT;
1848 pSRB->TargetStatus = 0;
1849 pcmd->result = MK_RES(0,DID_NO_CONNECT,0,0);
1850
1851 }
1852 else if (status_byte(status) == BUSY &&
1853 (pcmd->cmnd[0] == TEST_UNIT_READY || pcmd->cmnd[0] == INQUIRY) &&
1854 pACB->scan_devices)
1855 {
1856 pSRB->AdaptStatus = 0;
1857 pSRB->TargetStatus = status;
1858 pcmd->result = MK_RES(0,0,pSRB->EndMessage,0);
1859 }
1860 else
1861 {
1862 pSRB->TotalXferredLen = 0;
1863 SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
1864 goto cmd_done;
1865 }
1866 }
1867 else
1868 {
1869 status = pSRB->AdaptStatus;
1870 if(status & H_OVER_UNDER_RUN)
1871 {
1872 pSRB->TargetStatus = 0;
1873 SET_RES_DID(pcmd->result,DID_OK);
1874 SET_RES_MSG(pcmd->result,pSRB->EndMessage);
1875 }
1876 else if( pSRB->SRBStatus & PARITY_ERROR)
1877 {
1878
1879 SET_RES_DID(pcmd->result,DID_PARITY);
1880 SET_RES_MSG(pcmd->result,pSRB->EndMessage);
1881 }
1882 else
1883 {
1884 pSRB->AdaptStatus = 0;
1885 pSRB->TargetStatus = 0;
1886 SET_RES_DID(pcmd->result,DID_OK);
1887 }
1888 }
1889
1890cmd_done:
1891 pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
1892
1893 dc390_Going_remove (pDCB, pSRB);
1894
1895 dc390_Free_insert (pACB, pSRB);
1896
1897 DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->pid));
1898 pcmd->scsi_done (pcmd);
1899
1900 return;
1901}
1902
1903
1904
1905static void
1906dc390_DoingSRB_Done(struct dc390_acb* pACB, struct scsi_cmnd *cmd)
1907{
1908 struct dc390_dcb *pDCB, *pdcb;
1909 struct dc390_srb *psrb, *psrb2;
1910 int i;
1911 struct scsi_cmnd *pcmd;
1912
1913 pDCB = pACB->pLinkDCB;
1914 pdcb = pDCB;
1915 if (! pdcb) return;
1916 do
1917 {
1918 psrb = pdcb->pGoingSRB;
1919 for (i = 0; i < pdcb->GoingSRBCnt; i++)
1920 {
1921 psrb2 = psrb->pNextSRB;
1922 pcmd = psrb->pcmd;
1923 dc390_Free_insert (pACB, psrb);
1924 psrb = psrb2;
1925 }
1926 pdcb->GoingSRBCnt = 0;
1927 pdcb->pGoingSRB = NULL;
1928 pdcb->TagMask = 0;
1929 pdcb = pdcb->pNextDCB;
1930 } while( pdcb != pDCB );
1931}
1932
1933
1934static void
1935dc390_ResetSCSIBus( struct dc390_acb* pACB )
1936{
1937
1938
1939
1940
1941 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1942 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1943 DC390_write8 (ScsiCmd, RST_SCSI_BUS_CMD);
1944 pACB->Connected = 0;
1945
1946 return;
1947}
1948
1949static void
1950dc390_ScsiRstDetect( struct dc390_acb* pACB )
1951{
1952 printk ("DC390: Rst_Detect: laststat = %08x\n", dc390_laststatus);
1953
1954
1955 DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
1956
1957
1958 udelay (1000);
1959 DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
1960 pACB->pScsiHost->last_reset = jiffies + 5*HZ/2
1961 + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
1962 pACB->Connected = 0;
1963
1964 if( pACB->ACBFlag & RESET_DEV )
1965 pACB->ACBFlag |= RESET_DONE;
1966 else
1967 {
1968 pACB->ACBFlag |= RESET_DETECT;
1969
1970 dc390_ResetDevParam( pACB );
1971 dc390_DoingSRB_Done( pACB, NULL);
1972
1973 pACB->pActiveDCB = NULL;
1974 pACB->ACBFlag = 0;
1975 }
1976 return;
1977}
1978
1979static int DC390_queuecommand(struct scsi_cmnd *cmd,
1980 void (*done)(struct scsi_cmnd *))
1981{
1982 struct scsi_device *sdev = cmd->device;
1983 struct dc390_acb *acb = (struct dc390_acb *)sdev->host->hostdata;
1984 struct dc390_dcb *dcb = sdev->hostdata;
1985 struct dc390_srb *srb;
1986
1987 if (sdev->queue_depth <= dcb->GoingSRBCnt)
1988 goto device_busy;
1989 if (acb->pActiveDCB)
1990 goto host_busy;
1991 if (acb->ACBFlag & (RESET_DETECT|RESET_DONE|RESET_DEV))
1992 goto host_busy;
1993
1994 srb = acb->pFreeSRB;
1995 if (unlikely(srb == NULL))
1996 goto host_busy;
1997
1998 cmd->scsi_done = done;
1999 cmd->result = 0;
2000 acb->Cmds++;
2001
2002 acb->pFreeSRB = srb->pNextSRB;
2003 srb->pNextSRB = NULL;
2004
2005 srb->pSRBDCB = dcb;
2006 srb->pcmd = cmd;
2007 cmd->host_scribble = (char *)srb;
2008
2009 srb->SGIndex = 0;
2010 srb->AdaptStatus = 0;
2011 srb->TargetStatus = 0;
2012 srb->MsgCnt = 0;
2013
2014 srb->SRBStatus = 0;
2015 srb->SRBFlag = 0;
2016 srb->SRBState = 0;
2017 srb->TotalXferredLen = 0;
2018 srb->SGBusAddr = 0;
2019 srb->SGToBeXferLen = 0;
2020 srb->ScsiPhase = 0;
2021 srb->EndMessage = 0;
2022 srb->TagNumber = SCSI_NO_TAG;
2023
2024 if (dc390_StartSCSI(acb, dcb, srb)) {
2025 dc390_Free_insert(acb, srb);
2026 goto host_busy;
2027 }
2028
2029 dc390_Going_append(dcb, srb);
2030
2031 return 0;
2032
2033 host_busy:
2034 return SCSI_MLQUEUE_HOST_BUSY;
2035
2036 device_busy:
2037 return SCSI_MLQUEUE_DEVICE_BUSY;
2038}
2039
2040static void dc390_dumpinfo (struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB)
2041{
2042 struct pci_dev *pdev;
2043 u16 pstat;
2044
2045 if (!pDCB) pDCB = pACB->pActiveDCB;
2046 if (!pSRB && pDCB) pSRB = pDCB->pActiveSRB;
2047
2048 if (pSRB)
2049 {
2050 printk ("DC390: SRB: Xferred %08lx, Remain %08lx, State %08x, Phase %02x\n",
2051 pSRB->TotalXferredLen, pSRB->SGToBeXferLen, pSRB->SRBState,
2052 pSRB->ScsiPhase);
2053 printk ("DC390: AdpaterStatus: %02x, SRB Status %02x\n", pSRB->AdaptStatus, pSRB->SRBStatus);
2054 }
2055 printk ("DC390: Status of last IRQ (DMA/SC/Int/IRQ): %08x\n", dc390_laststatus);
2056 printk ("DC390: Register dump: SCSI block:\n");
2057 printk ("DC390: XferCnt Cmd Stat IntS IRQS FFIS Ctl1 Ctl2 Ctl3 Ctl4\n");
2058 printk ("DC390: %06x %02x %02x %02x",
2059 DC390_read8(CtcReg_Low) + (DC390_read8(CtcReg_Mid) << 8) + (DC390_read8(CtcReg_High) << 16),
2060 DC390_read8(ScsiCmd), DC390_read8(Scsi_Status), DC390_read8(Intern_State));
2061 printk (" %02x %02x %02x %02x %02x %02x\n",
2062 DC390_read8(INT_Status), DC390_read8(Current_Fifo), DC390_read8(CtrlReg1),
2063 DC390_read8(CtrlReg2), DC390_read8(CtrlReg3), DC390_read8(CtrlReg4));
2064 DC390_write32 (DMA_ScsiBusCtrl, WRT_ERASE_DMA_STAT | EN_INT_ON_PCI_ABORT);
2065 if (DC390_read8(Current_Fifo) & 0x1f)
2066 {
2067 printk ("DC390: FIFO:");
2068 while (DC390_read8(Current_Fifo) & 0x1f) printk (" %02x", DC390_read8(ScsiFifo));
2069 printk ("\n");
2070 }
2071 printk ("DC390: Register dump: DMA engine:\n");
2072 printk ("DC390: Cmd STrCnt SBusA WrkBC WrkAC Stat SBusCtrl\n");
2073 printk ("DC390: %02x %08x %08x %08x %08x %02x %08x\n",
2074 DC390_read8(DMA_Cmd), DC390_read32(DMA_XferCnt), DC390_read32(DMA_XferAddr),
2075 DC390_read32(DMA_Wk_ByteCntr), DC390_read32(DMA_Wk_AddrCntr),
2076 DC390_read8(DMA_Status), DC390_read32(DMA_ScsiBusCtrl));
2077 DC390_write32 (DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
2078
2079 pdev = pACB->pdev;
2080 pci_read_config_word(pdev, PCI_STATUS, &pstat);
2081 printk ("DC390: Register dump: PCI Status: %04x\n", pstat);
2082 printk ("DC390: In case of driver trouble read Documentation/scsi/tmscsim.txt\n");
2083}
2084
2085
2086static int DC390_abort(struct scsi_cmnd *cmd)
2087{
2088 struct dc390_acb *pACB = (struct dc390_acb*) cmd->device->host->hostdata;
2089 struct dc390_dcb *pDCB = (struct dc390_dcb*) cmd->device->hostdata;
2090
2091 scmd_printk(KERN_WARNING, cmd,
2092 "DC390: Abort command (pid %li)\n", cmd->pid);
2093
2094
2095
2096
2097 dc390_dumpinfo(pACB, pDCB, NULL);
2098
2099 pDCB->DCBFlag |= ABORT_DEV_;
2100 printk(KERN_INFO "DC390: Aborted pid %li\n", cmd->pid);
2101
2102 return FAILED;
2103}
2104
2105
2106static void dc390_ResetDevParam( struct dc390_acb* pACB )
2107{
2108 struct dc390_dcb *pDCB, *pdcb;
2109
2110 pDCB = pACB->pLinkDCB;
2111 if (! pDCB) return;
2112 pdcb = pDCB;
2113 do
2114 {
2115 pDCB->SyncMode &= ~SYNC_NEGO_DONE;
2116 pDCB->SyncPeriod = 0;
2117 pDCB->SyncOffset = 0;
2118 pDCB->TagMask = 0;
2119 pDCB->CtrlR3 = FAST_CLK;
2120 pDCB->CtrlR4 &= NEGATE_REQACKDATA | CTRL4_RESERVED | NEGATE_REQACK;
2121 pDCB->CtrlR4 |= pACB->glitch_cfg;
2122 pDCB = pDCB->pNextDCB;
2123 }
2124 while( pdcb != pDCB );
2125 pACB->ACBFlag &= ~(RESET_DEV | RESET_DONE | RESET_DETECT);
2126
2127}
2128
2129static int DC390_bus_reset (struct scsi_cmnd *cmd)
2130{
2131 struct dc390_acb* pACB = (struct dc390_acb*) cmd->device->host->hostdata;
2132 u8 bval;
2133
2134 spin_lock_irq(cmd->device->host->host_lock);
2135
2136 bval = DC390_read8(CtrlReg1) | DIS_INT_ON_SCSI_RST;
2137 DC390_write8(CtrlReg1, bval);
2138
2139 pACB->ACBFlag |= RESET_DEV;
2140 dc390_ResetSCSIBus(pACB);
2141
2142 dc390_ResetDevParam(pACB);
2143 mdelay(1);
2144 pACB->pScsiHost->last_reset = jiffies + 3*HZ/2
2145 + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
2146
2147 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
2148 DC390_read8(INT_Status);
2149
2150 dc390_DoingSRB_Done(pACB, cmd);
2151
2152 pACB->pActiveDCB = NULL;
2153 pACB->ACBFlag = 0;
2154
2155 bval = DC390_read8(CtrlReg1) & ~DIS_INT_ON_SCSI_RST;
2156 DC390_write8(CtrlReg1, bval);
2157
2158 spin_unlock_irq(cmd->device->host->host_lock);
2159
2160 return SUCCESS;
2161}
2162
2163
2164
2165
2166
2167
2168
2169static int dc390_slave_alloc(struct scsi_device *scsi_device)
2170{
2171 struct dc390_acb *pACB = (struct dc390_acb*) scsi_device->host->hostdata;
2172 struct dc390_dcb *pDCB, *pDCB2 = NULL;
2173 uint id = scsi_device->id;
2174 uint lun = scsi_device->lun;
2175
2176 pDCB = kmalloc(sizeof(struct dc390_dcb), GFP_KERNEL);
2177 if (!pDCB)
2178 return -ENOMEM;
2179 memset(pDCB, 0, sizeof(struct dc390_dcb));
2180
2181 if (!pACB->DCBCnt++) {
2182 pACB->pLinkDCB = pDCB;
2183 pACB->pDCBRunRobin = pDCB;
2184 } else {
2185 pACB->pLastDCB->pNextDCB = pDCB;
2186 }
2187
2188 pDCB->pNextDCB = pACB->pLinkDCB;
2189 pACB->pLastDCB = pDCB;
2190
2191 pDCB->pDCBACB = pACB;
2192 pDCB->TargetID = id;
2193 pDCB->TargetLUN = lun;
2194
2195
2196
2197
2198
2199 if (lun && (pDCB2 = dc390_findDCB(pACB, id, 0))) {
2200 pDCB->DevMode = pDCB2->DevMode;
2201 pDCB->SyncMode = pDCB2->SyncMode & SYNC_NEGO_DONE;
2202 pDCB->SyncPeriod = pDCB2->SyncPeriod;
2203 pDCB->SyncOffset = pDCB2->SyncOffset;
2204 pDCB->NegoPeriod = pDCB2->NegoPeriod;
2205
2206 pDCB->CtrlR3 = pDCB2->CtrlR3;
2207 pDCB->CtrlR4 = pDCB2->CtrlR4;
2208 } else {
2209 u8 index = pACB->AdapterIndex;
2210 PEEprom prom = (PEEprom) &dc390_eepromBuf[index][id << 2];
2211
2212 pDCB->DevMode = prom->EE_MODE1;
2213 pDCB->NegoPeriod =
2214 (dc390_clock_period1[prom->EE_SPEED] * 25) >> 2;
2215 pDCB->CtrlR3 = FAST_CLK;
2216 pDCB->CtrlR4 = pACB->glitch_cfg | CTRL4_RESERVED;
2217 if (dc390_eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION)
2218 pDCB->CtrlR4 |= NEGATE_REQACKDATA | NEGATE_REQACK;
2219 }
2220
2221 if (pDCB->DevMode & SYNC_NEGO_)
2222 pDCB->SyncMode |= SYNC_ENABLE;
2223 else {
2224 pDCB->SyncMode = 0;
2225 pDCB->SyncOffset &= ~0x0f;
2226 }
2227
2228 pDCB->CtrlR1 = pACB->pScsiHost->this_id;
2229 if (pDCB->DevMode & PARITY_CHK_)
2230 pDCB->CtrlR1 |= PARITY_ERR_REPO;
2231
2232 pACB->scan_devices = 1;
2233 scsi_device->hostdata = pDCB;
2234 return 0;
2235}
2236
2237
2238
2239
2240
2241
2242
2243static void dc390_slave_destroy(struct scsi_device *scsi_device)
2244{
2245 struct dc390_acb* pACB = (struct dc390_acb*) scsi_device->host->hostdata;
2246 struct dc390_dcb* pDCB = (struct dc390_dcb*) scsi_device->hostdata;
2247 struct dc390_dcb* pPrevDCB = pACB->pLinkDCB;
2248
2249 pACB->scan_devices = 0;
2250
2251 BUG_ON(pDCB->GoingSRBCnt > 1);
2252
2253 if (pDCB == pACB->pLinkDCB) {
2254 if (pACB->pLastDCB == pDCB) {
2255 pDCB->pNextDCB = NULL;
2256 pACB->pLastDCB = NULL;
2257 }
2258 pACB->pLinkDCB = pDCB->pNextDCB;
2259 } else {
2260 while (pPrevDCB->pNextDCB != pDCB)
2261 pPrevDCB = pPrevDCB->pNextDCB;
2262 pPrevDCB->pNextDCB = pDCB->pNextDCB;
2263 if (pDCB == pACB->pLastDCB)
2264 pACB->pLastDCB = pPrevDCB;
2265 }
2266
2267 if (pDCB == pACB->pActiveDCB)
2268 pACB->pActiveDCB = NULL;
2269 if (pDCB == pACB->pLinkDCB)
2270 pACB->pLinkDCB = pDCB->pNextDCB;
2271 if (pDCB == pACB->pDCBRunRobin)
2272 pACB->pDCBRunRobin = pDCB->pNextDCB;
2273 kfree(pDCB);
2274
2275 pACB->DCBCnt--;
2276}
2277
2278static int dc390_slave_configure(struct scsi_device *sdev)
2279{
2280 struct dc390_acb *acb = (struct dc390_acb *)sdev->host->hostdata;
2281 struct dc390_dcb *dcb = (struct dc390_dcb *)sdev->hostdata;
2282
2283 acb->scan_devices = 0;
2284 if (sdev->tagged_supported && (dcb->DevMode & TAG_QUEUEING_)) {
2285 dcb->SyncMode |= EN_TAG_QUEUEING;
2286 scsi_activate_tcq(sdev, acb->TagMaxNum);
2287 }
2288
2289 return 0;
2290}
2291
2292static struct scsi_host_template driver_template = {
2293 .module = THIS_MODULE,
2294 .proc_name = "tmscsim",
2295 .name = DC390_BANNER " V" DC390_VERSION,
2296 .slave_alloc = dc390_slave_alloc,
2297 .slave_configure = dc390_slave_configure,
2298 .slave_destroy = dc390_slave_destroy,
2299 .queuecommand = DC390_queuecommand,
2300 .eh_abort_handler = DC390_abort,
2301 .eh_bus_reset_handler = DC390_bus_reset,
2302 .can_queue = 1,
2303 .this_id = 7,
2304 .sg_tablesize = SG_ALL,
2305 .cmd_per_lun = 1,
2306 .use_clustering = ENABLE_CLUSTERING,
2307 .max_sectors = 0x4000,
2308};
2309
2310
2311
2312
2313
2314
2315
2316static void __devinit dc390_eeprom_prepare_read(struct pci_dev *pdev, u8 cmd)
2317{
2318 u8 carryFlag = 1, j = 0x80, bval;
2319 int i;
2320
2321 for (i = 0; i < 9; i++) {
2322 if (carryFlag) {
2323 pci_write_config_byte(pdev, 0x80, 0x40);
2324 bval = 0xc0;
2325 } else
2326 bval = 0x80;
2327
2328 udelay(160);
2329 pci_write_config_byte(pdev, 0x80, bval);
2330 udelay(160);
2331 pci_write_config_byte(pdev, 0x80, 0);
2332 udelay(160);
2333
2334 carryFlag = (cmd & j) ? 1 : 0;
2335 j >>= 1;
2336 }
2337}
2338
2339static u16 __devinit dc390_eeprom_get_data(struct pci_dev *pdev)
2340{
2341 int i;
2342 u16 wval = 0;
2343 u8 bval;
2344
2345 for (i = 0; i < 16; i++) {
2346 wval <<= 1;
2347
2348 pci_write_config_byte(pdev, 0x80, 0x80);
2349 udelay(160);
2350 pci_write_config_byte(pdev, 0x80, 0x40);
2351 udelay(160);
2352 pci_read_config_byte(pdev, 0x00, &bval);
2353
2354 if (bval == 0x22)
2355 wval |= 1;
2356 }
2357
2358 return wval;
2359}
2360
2361static void __devinit dc390_read_eeprom(struct pci_dev *pdev, u16 *ptr)
2362{
2363 u8 cmd = EEPROM_READ, i;
2364
2365 for (i = 0; i < 0x40; i++) {
2366 pci_write_config_byte(pdev, 0xc0, 0);
2367 udelay(160);
2368
2369 dc390_eeprom_prepare_read(pdev, cmd++);
2370 *ptr++ = dc390_eeprom_get_data(pdev);
2371
2372 pci_write_config_byte(pdev, 0x80, 0);
2373 pci_write_config_byte(pdev, 0x80, 0);
2374 udelay(160);
2375 }
2376}
2377
2378
2379static void __devinit dc390_eeprom_override(u8 index)
2380{
2381 u8 *ptr = (u8 *) dc390_eepromBuf[index], id;
2382
2383
2384 if (tmscsim[0] != -2)
2385 ptr[EE_ADAPT_SCSI_ID] = (u8)tmscsim[0];
2386 if (tmscsim[3] != -2)
2387 ptr[EE_MODE2] = (u8)tmscsim[3];
2388 if (tmscsim[5] != -2)
2389 ptr[EE_DELAY] = tmscsim[5];
2390 if (tmscsim[4] != -2)
2391 ptr[EE_TAG_CMD_NUM] = (u8)tmscsim[4];
2392
2393
2394 for (id = 0; id < MAX_SCSI_ID; id++) {
2395 if (tmscsim[2] != -2)
2396 ptr[id << 2] = (u8)tmscsim[2];
2397 if (tmscsim[1] != -2)
2398 ptr[(id << 2) + 1] = (u8)tmscsim[1];
2399 }
2400}
2401
2402static int __devinitdata tmscsim_def[] = {
2403 7,
2404 0 ,
2405 PARITY_CHK_ | SEND_START_ | EN_DISCONNECT_ | SYNC_NEGO_ | TAG_QUEUEING_,
2406 MORE2_DRV | GREATER_1G | RST_SCSI_BUS | ACTIVE_NEGATION | LUN_CHECK,
2407 3 ,
2408 1 ,
2409};
2410
2411
2412static void __devinit dc390_fill_with_defaults (void)
2413{
2414 int i;
2415
2416 for (i = 0; i < 6; i++) {
2417 if (tmscsim[i] < 0 || tmscsim[i] > 255)
2418 tmscsim[i] = tmscsim_def[i];
2419 }
2420
2421
2422 if (tmscsim[0] > 7)
2423 tmscsim[0] = 7;
2424 if (tmscsim[1] > 7)
2425 tmscsim[1] = 4;
2426 if (tmscsim[4] > 5)
2427 tmscsim[4] = 4;
2428 if (tmscsim[5] > 180)
2429 tmscsim[5] = 180;
2430}
2431
2432static void __devinit dc390_check_eeprom(struct pci_dev *pdev, u8 index)
2433{
2434 u8 interpd[] = {1, 3, 5, 10, 16, 30, 60, 120};
2435 u8 EEbuf[128];
2436 u16 *ptr = (u16 *)EEbuf, wval = 0;
2437 int i;
2438
2439 dc390_read_eeprom(pdev, ptr);
2440 memcpy(dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID);
2441 memcpy(&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID],
2442 &EEbuf[REAL_EE_ADAPT_SCSI_ID], EE_LEN - EE_ADAPT_SCSI_ID);
2443
2444 dc390_eepromBuf[index][EE_DELAY] = interpd[dc390_eepromBuf[index][EE_DELAY]];
2445
2446 for (i = 0; i < 0x40; i++, ptr++)
2447 wval += *ptr;
2448
2449
2450 if (wval != 0x1234) {
2451 int speed;
2452
2453 printk(KERN_INFO "DC390_init: No EEPROM found! Trying default settings ...\n");
2454
2455
2456
2457
2458
2459 dc390_fill_with_defaults();
2460
2461 speed = dc390_clock_speed[tmscsim[1]];
2462 printk(KERN_INFO "DC390: Used defaults: AdaptID=%i, SpeedIdx=%i (%i.%i MHz), "
2463 "DevMode=0x%02x, AdaptMode=0x%02x, TaggedCmnds=%i (%i), DelayReset=%is\n",
2464 tmscsim[0], tmscsim[1], speed / 10, speed % 10,
2465 (u8)tmscsim[2], (u8)tmscsim[3], tmscsim[4], 2 << (tmscsim[4]), tmscsim[5]);
2466 }
2467}
2468
2469static void __devinit dc390_init_hw(struct dc390_acb *pACB, u8 index)
2470{
2471 struct Scsi_Host *shost = pACB->pScsiHost;
2472 u8 dstate;
2473
2474
2475 DC390_write8(CtrlReg1, DIS_INT_ON_SCSI_RST | shost->this_id);
2476
2477 if (pACB->Gmode2 & RST_SCSI_BUS) {
2478 dc390_ResetSCSIBus(pACB);
2479 udelay(1000);
2480 shost->last_reset = jiffies + HZ/2 +
2481 HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
2482 }
2483
2484 pACB->ACBFlag = 0;
2485
2486
2487 DC390_read8(INT_Status);
2488
2489
2490 DC390_write8(Scsi_TimeOut, SEL_TIMEOUT);
2491
2492
2493 DC390_write8(Clk_Factor, CLK_FREQ_40MHZ);
2494
2495
2496 DC390_write8(ScsiCmd, NOP_CMD);
2497
2498
2499 DC390_write8(CtrlReg2, EN_FEATURE+EN_SCSI2_CMD);
2500
2501
2502 DC390_write8(CtrlReg3, FAST_CLK);
2503
2504
2505 DC390_write8(CtrlReg4, pACB->glitch_cfg |
2506 (dc390_eepromBuf[index][EE_MODE2] & ACTIVE_NEGATION) ?
2507 NEGATE_REQACKDATA : 0);
2508
2509
2510 DC390_write8(CtcReg_High, 0);
2511 DC390_write8(DMA_Cmd, DMA_IDLE_CMD);
2512 DC390_write8(ScsiCmd, CLEAR_FIFO_CMD);
2513 DC390_write32(DMA_ScsiBusCtrl, EN_INT_ON_PCI_ABORT);
2514
2515 dstate = DC390_read8(DMA_Status);
2516 DC390_write8(DMA_Status, dstate);
2517}
2518
2519static int __devinit dc390_probe_one(struct pci_dev *pdev,
2520 const struct pci_device_id *id)
2521{
2522 struct dc390_acb *pACB;
2523 struct Scsi_Host *shost;
2524 unsigned long io_port;
2525 int error = -ENODEV, i;
2526
2527 if (pci_enable_device(pdev))
2528 goto out;
2529
2530 pci_set_master(pdev);
2531
2532 error = -ENOMEM;
2533 if (disable_clustering)
2534 driver_template.use_clustering = DISABLE_CLUSTERING;
2535 shost = scsi_host_alloc(&driver_template, sizeof(struct dc390_acb));
2536 if (!shost)
2537 goto out_disable_device;
2538
2539 pACB = (struct dc390_acb *)shost->hostdata;
2540 memset(pACB, 0, sizeof(struct dc390_acb));
2541
2542 dc390_check_eeprom(pdev, dc390_adapterCnt);
2543 dc390_eeprom_override(dc390_adapterCnt);
2544
2545 io_port = pci_resource_start(pdev, 0);
2546
2547 shost->this_id = dc390_eepromBuf[dc390_adapterCnt][EE_ADAPT_SCSI_ID];
2548 shost->io_port = io_port;
2549 shost->n_io_port = 0x80;
2550 shost->irq = pdev->irq;
2551 shost->base = io_port;
2552 shost->unique_id = io_port;
2553 shost->last_reset = jiffies;
2554
2555 pACB->pScsiHost = shost;
2556 pACB->IOPortBase = (u16) io_port;
2557 pACB->IRQLevel = pdev->irq;
2558
2559 shost->max_id = 8;
2560
2561 if (shost->max_id - 1 ==
2562 dc390_eepromBuf[dc390_adapterCnt][EE_ADAPT_SCSI_ID])
2563 shost->max_id--;
2564
2565 if (dc390_eepromBuf[dc390_adapterCnt][EE_MODE2] & LUN_CHECK)
2566 shost->max_lun = 8;
2567 else
2568 shost->max_lun = 1;
2569
2570 pACB->pFreeSRB = pACB->SRB_array;
2571 pACB->SRBCount = MAX_SRB_CNT;
2572 pACB->AdapterIndex = dc390_adapterCnt;
2573 pACB->TagMaxNum =
2574 2 << dc390_eepromBuf[dc390_adapterCnt][EE_TAG_CMD_NUM];
2575 pACB->Gmode2 = dc390_eepromBuf[dc390_adapterCnt][EE_MODE2];
2576
2577 for (i = 0; i < pACB->SRBCount-1; i++)
2578 pACB->SRB_array[i].pNextSRB = &pACB->SRB_array[i+1];
2579 pACB->SRB_array[pACB->SRBCount-1].pNextSRB = NULL;
2580 pACB->pTmpSRB = &pACB->TmpSRB;
2581
2582 pACB->sel_timeout = SEL_TIMEOUT;
2583 pACB->glitch_cfg = EATER_25NS;
2584 pACB->pdev = pdev;
2585
2586 if (!request_region(io_port, shost->n_io_port, "tmscsim")) {
2587 printk(KERN_ERR "DC390: register IO ports error!\n");
2588 goto out_host_put;
2589 }
2590
2591
2592 DC390_read8_(INT_Status, io_port);
2593
2594 if (request_irq(pdev->irq, do_DC390_Interrupt, IRQF_SHARED,
2595 "tmscsim", pACB)) {
2596 printk(KERN_ERR "DC390: register IRQ error!\n");
2597 goto out_release_region;
2598 }
2599
2600 dc390_init_hw(pACB, dc390_adapterCnt);
2601
2602 dc390_adapterCnt++;
2603
2604 pci_set_drvdata(pdev, shost);
2605
2606 error = scsi_add_host(shost, &pdev->dev);
2607 if (error)
2608 goto out_free_irq;
2609 scsi_scan_host(shost);
2610 return 0;
2611
2612 out_free_irq:
2613 free_irq(pdev->irq, pACB);
2614 out_release_region:
2615 release_region(io_port, shost->n_io_port);
2616 out_host_put:
2617 scsi_host_put(shost);
2618 out_disable_device:
2619 pci_disable_device(pdev);
2620 out:
2621 return error;
2622}
2623
2624
2625
2626
2627
2628
2629static void __devexit dc390_remove_one(struct pci_dev *dev)
2630{
2631 struct Scsi_Host *scsi_host = pci_get_drvdata(dev);
2632 unsigned long iflags;
2633 struct dc390_acb* pACB = (struct dc390_acb*) scsi_host->hostdata;
2634 u8 bval;
2635
2636 scsi_remove_host(scsi_host);
2637
2638 spin_lock_irqsave(scsi_host->host_lock, iflags);
2639 pACB->ACBFlag = RESET_DEV;
2640 bval = DC390_read8(CtrlReg1) | DIS_INT_ON_SCSI_RST;
2641 DC390_write8 (CtrlReg1, bval);
2642 if (pACB->Gmode2 & RST_SCSI_BUS)
2643 dc390_ResetSCSIBus(pACB);
2644 spin_unlock_irqrestore(scsi_host->host_lock, iflags);
2645
2646 free_irq(scsi_host->irq, pACB);
2647 release_region(scsi_host->io_port, scsi_host->n_io_port);
2648
2649 pci_disable_device(dev);
2650 scsi_host_put(scsi_host);
2651 pci_set_drvdata(dev, NULL);
2652}
2653
2654static struct pci_device_id tmscsim_pci_tbl[] = {
2655 { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD53C974,
2656 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
2657 { }
2658};
2659MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl);
2660
2661static struct pci_driver dc390_driver = {
2662 .name = "tmscsim",
2663 .id_table = tmscsim_pci_tbl,
2664 .probe = dc390_probe_one,
2665 .remove = __devexit_p(dc390_remove_one),
2666};
2667
2668static int __init dc390_module_init(void)
2669{
2670 if (!disable_clustering)
2671 printk(KERN_INFO "DC390: clustering now enabled by default. If you get problems load\n"
2672 "\twith \"disable_clustering=1\" and report to maintainers\n");
2673
2674 if (tmscsim[0] == -1 || tmscsim[0] > 15) {
2675 tmscsim[0] = 7;
2676 tmscsim[1] = 4;
2677 tmscsim[2] = PARITY_CHK_ | TAG_QUEUEING_;
2678 tmscsim[3] = MORE2_DRV | GREATER_1G | RST_SCSI_BUS | ACTIVE_NEGATION;
2679 tmscsim[4] = 2;
2680 tmscsim[5] = 10;
2681 printk (KERN_INFO "DC390: Using safe settings.\n");
2682 }
2683
2684 return pci_module_init(&dc390_driver);
2685}
2686
2687static void __exit dc390_module_exit(void)
2688{
2689 pci_unregister_driver(&dc390_driver);
2690}
2691
2692module_init(dc390_module_init);
2693module_exit(dc390_module_exit);
2694
2695#ifndef MODULE
2696static int __init dc390_setup (char *str)
2697{
2698 int ints[8],i, im;
2699
2700 get_options(str, ARRAY_SIZE(ints), ints);
2701 im = ints[0];
2702
2703 if (im > 6) {
2704 printk (KERN_NOTICE "DC390: ignore extra params!\n");
2705 im = 6;
2706 }
2707
2708 for (i = 0; i < im; i++)
2709 tmscsim[i] = ints[i+1];
2710
2711 return 1;
2712}
2713
2714__setup("tmscsim=", dc390_setup);
2715#endif
2716