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#define NCR_700_VERSION "2.8"
116
117#include <linux/kernel.h>
118#include <linux/types.h>
119#include <linux/string.h>
120#include <linux/slab.h>
121#include <linux/ioport.h>
122#include <linux/delay.h>
123#include <linux/spinlock.h>
124#include <linux/completion.h>
125#include <linux/init.h>
126#include <linux/proc_fs.h>
127#include <linux/blkdev.h>
128#include <linux/module.h>
129#include <linux/interrupt.h>
130#include <linux/device.h>
131#include <asm/dma.h>
132#include <asm/io.h>
133#include <asm/pgtable.h>
134#include <asm/byteorder.h>
135
136#include <scsi/scsi.h>
137#include <scsi/scsi_cmnd.h>
138#include <scsi/scsi_dbg.h>
139#include <scsi/scsi_eh.h>
140#include <scsi/scsi_host.h>
141#include <scsi/scsi_tcq.h>
142#include <scsi/scsi_transport.h>
143#include <scsi/scsi_transport_spi.h>
144
145#include "53c700.h"
146
147
148
149
150
151
152
153#define to32bit(x) ((__u32)((unsigned long)(x)))
154
155#ifdef NCR_700_DEBUG
156#define STATIC
157#else
158#define STATIC static
159#endif
160
161MODULE_AUTHOR("James Bottomley");
162MODULE_DESCRIPTION("53c700 and 53c700-66 Driver");
163MODULE_LICENSE("GPL");
164
165
166#include "53c700_d.h"
167
168
169STATIC int NCR_700_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *);
170STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
171STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
172STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
173STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
174STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
175STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt);
176STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
177STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
178static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth);
179
180STATIC struct device_attribute *NCR_700_dev_attrs[];
181
182STATIC struct scsi_transport_template *NCR_700_transport_template = NULL;
183
184static char *NCR_700_phase[] = {
185 "",
186 "after selection",
187 "before command phase",
188 "after command phase",
189 "after status phase",
190 "after data in phase",
191 "after data out phase",
192 "during data phase",
193};
194
195static char *NCR_700_condition[] = {
196 "",
197 "NOT MSG_OUT",
198 "UNEXPECTED PHASE",
199 "NOT MSG_IN",
200 "UNEXPECTED MSG",
201 "MSG_IN",
202 "SDTR_MSG RECEIVED",
203 "REJECT_MSG RECEIVED",
204 "DISCONNECT_MSG RECEIVED",
205 "MSG_OUT",
206 "DATA_IN",
207
208};
209
210static char *NCR_700_fatal_messages[] = {
211 "unexpected message after reselection",
212 "still MSG_OUT after message injection",
213 "not MSG_IN after selection",
214 "Illegal message length received",
215};
216
217static char *NCR_700_SBCL_bits[] = {
218 "IO ",
219 "CD ",
220 "MSG ",
221 "ATN ",
222 "SEL ",
223 "BSY ",
224 "ACK ",
225 "REQ ",
226};
227
228static char *NCR_700_SBCL_to_phase[] = {
229 "DATA_OUT",
230 "DATA_IN",
231 "CMD_OUT",
232 "STATE",
233 "ILLEGAL PHASE",
234 "ILLEGAL PHASE",
235 "MSG OUT",
236 "MSG IN",
237};
238
239
240
241
242
243
244static inline __u8
245NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
246 __u8 offset, __u8 period)
247{
248 int XFERP;
249
250 __u8 min_xferp = (hostdata->chip710
251 ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP);
252 __u8 max_offset = (hostdata->chip710
253 ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET);
254
255 if(offset == 0)
256 return 0;
257
258 if(period < hostdata->min_period) {
259 printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_MIN_PERIOD*4);
260 period = hostdata->min_period;
261 }
262 XFERP = (period*4 * hostdata->sync_clock)/1000 - 4;
263 if(offset > max_offset) {
264 printk(KERN_WARNING "53c700: Offset %d exceeds chip maximum, setting to %d\n",
265 offset, max_offset);
266 offset = max_offset;
267 }
268 if(XFERP < min_xferp) {
269 XFERP = min_xferp;
270 }
271 return (offset & 0x0f) | (XFERP & 0x07)<<4;
272}
273
274static inline __u8
275NCR_700_get_SXFER(struct scsi_device *SDp)
276{
277 struct NCR_700_Host_Parameters *hostdata =
278 (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
279
280 return NCR_700_offset_period_to_sxfer(hostdata,
281 spi_offset(SDp->sdev_target),
282 spi_period(SDp->sdev_target));
283}
284
285struct Scsi_Host *
286NCR_700_detect(struct scsi_host_template *tpnt,
287 struct NCR_700_Host_Parameters *hostdata, struct device *dev)
288{
289 dma_addr_t pScript, pSlots;
290 __u8 *memory;
291 __u32 *script;
292 struct Scsi_Host *host;
293 static int banner = 0;
294 int j;
295
296 if(tpnt->sdev_attrs == NULL)
297 tpnt->sdev_attrs = NCR_700_dev_attrs;
298
299 memory = dma_alloc_noncoherent(hostdata->dev, TOTAL_MEM_SIZE,
300 &pScript, GFP_KERNEL);
301 if(memory == NULL) {
302 printk(KERN_ERR "53c700: Failed to allocate memory for driver, detaching\n");
303 return NULL;
304 }
305
306 script = (__u32 *)memory;
307 hostdata->msgin = memory + MSGIN_OFFSET;
308 hostdata->msgout = memory + MSGOUT_OFFSET;
309 hostdata->status = memory + STATUS_OFFSET;
310 hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET);
311 hostdata->dev = dev;
312
313 pSlots = pScript + SLOTS_OFFSET;
314
315
316 tpnt->queuecommand = NCR_700_queuecommand;
317 tpnt->eh_abort_handler = NCR_700_abort;
318 tpnt->eh_bus_reset_handler = NCR_700_bus_reset;
319 tpnt->eh_host_reset_handler = NCR_700_host_reset;
320 tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST;
321 tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
322 tpnt->cmd_per_lun = NCR_700_CMD_PER_LUN;
323 tpnt->use_clustering = ENABLE_CLUSTERING;
324 tpnt->slave_configure = NCR_700_slave_configure;
325 tpnt->slave_destroy = NCR_700_slave_destroy;
326 tpnt->slave_alloc = NCR_700_slave_alloc;
327 tpnt->change_queue_depth = NCR_700_change_queue_depth;
328
329 if(tpnt->name == NULL)
330 tpnt->name = "53c700";
331 if(tpnt->proc_name == NULL)
332 tpnt->proc_name = "53c700";
333
334 host = scsi_host_alloc(tpnt, 4);
335 if (!host)
336 return NULL;
337 memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot)
338 * NCR_700_COMMAND_SLOTS_PER_HOST);
339 for (j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
340 dma_addr_t offset = (dma_addr_t)((unsigned long)&hostdata->slots[j].SG[0]
341 - (unsigned long)&hostdata->slots[0].SG[0]);
342 hostdata->slots[j].pSG = (struct NCR_700_SG_List *)((unsigned long)(pSlots + offset));
343 if(j == 0)
344 hostdata->free_list = &hostdata->slots[j];
345 else
346 hostdata->slots[j-1].ITL_forw = &hostdata->slots[j];
347 hostdata->slots[j].state = NCR_700_SLOT_FREE;
348 }
349
350 for (j = 0; j < ARRAY_SIZE(SCRIPT); j++)
351 script[j] = bS_to_host(SCRIPT[j]);
352
353
354 for (j = 0; j < PATCHES; j++)
355 script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
356
357 script_patch_32(hostdata->dev, script, MessageLocation,
358 pScript + MSGOUT_OFFSET);
359 script_patch_32(hostdata->dev, script, StatusAddress,
360 pScript + STATUS_OFFSET);
361 script_patch_32(hostdata->dev, script, ReceiveMsgAddress,
362 pScript + MSGIN_OFFSET);
363
364 hostdata->script = script;
365 hostdata->pScript = pScript;
366 dma_sync_single_for_device(hostdata->dev, pScript, sizeof(SCRIPT), DMA_TO_DEVICE);
367 hostdata->state = NCR_700_HOST_FREE;
368 hostdata->cmd = NULL;
369 host->max_id = 8;
370 host->max_lun = NCR_700_MAX_LUNS;
371 BUG_ON(NCR_700_transport_template == NULL);
372 host->transportt = NCR_700_transport_template;
373 host->unique_id = (unsigned long)hostdata->base;
374 hostdata->eh_complete = NULL;
375 host->hostdata[0] = (unsigned long)hostdata;
376
377 NCR_700_writeb(0xff, host, CTEST9_REG);
378 if (hostdata->chip710)
379 hostdata->rev = (NCR_700_readb(host, CTEST8_REG)>>4) & 0x0f;
380 else
381 hostdata->rev = (NCR_700_readb(host, CTEST7_REG)>>4) & 0x0f;
382 hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0);
383 if (banner == 0) {
384 printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n");
385 banner = 1;
386 }
387 printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no,
388 hostdata->chip710 ? "53c710" :
389 (hostdata->fast ? "53c700-66" : "53c700"),
390 hostdata->rev, hostdata->differential ?
391 "(Differential)" : "");
392
393 NCR_700_chip_reset(host);
394
395 if (scsi_add_host(host, dev)) {
396 dev_printk(KERN_ERR, dev, "53c700: scsi_add_host failed\n");
397 scsi_host_put(host);
398 return NULL;
399 }
400
401 spi_signalling(host) = hostdata->differential ? SPI_SIGNAL_HVD :
402 SPI_SIGNAL_SE;
403
404 return host;
405}
406
407int
408NCR_700_release(struct Scsi_Host *host)
409{
410 struct NCR_700_Host_Parameters *hostdata =
411 (struct NCR_700_Host_Parameters *)host->hostdata[0];
412
413 dma_free_noncoherent(hostdata->dev, TOTAL_MEM_SIZE,
414 hostdata->script, hostdata->pScript);
415 return 1;
416}
417
418static inline __u8
419NCR_700_identify(int can_disconnect, __u8 lun)
420{
421 return IDENTIFY_BASE |
422 ((can_disconnect) ? 0x40 : 0) |
423 (lun & NCR_700_LUN_MASK);
424}
425
426
427
428
429
430
431
432
433
434
435
436static inline int
437NCR_700_data_residual (struct Scsi_Host *host) {
438 struct NCR_700_Host_Parameters *hostdata =
439 (struct NCR_700_Host_Parameters *)host->hostdata[0];
440 int count, synchronous = 0;
441 unsigned int ddir;
442
443 if(hostdata->chip710) {
444 count = ((NCR_700_readb(host, DFIFO_REG) & 0x7f) -
445 (NCR_700_readl(host, DBC_REG) & 0x7f)) & 0x7f;
446 } else {
447 count = ((NCR_700_readb(host, DFIFO_REG) & 0x3f) -
448 (NCR_700_readl(host, DBC_REG) & 0x3f)) & 0x3f;
449 }
450
451 if(hostdata->fast)
452 synchronous = NCR_700_readb(host, SXFER_REG) & 0x0f;
453
454
455 ddir = NCR_700_readb(host, CTEST0_REG) & 0x01;
456
457 if (ddir) {
458
459 if (synchronous)
460 count += (NCR_700_readb(host, SSTAT2_REG) & 0xf0) >> 4;
461 else
462 if (NCR_700_readb(host, SSTAT1_REG) & SIDL_REG_FULL)
463 ++count;
464 } else {
465
466 __u8 sstat = NCR_700_readb(host, SSTAT1_REG);
467 if (sstat & SODL_REG_FULL)
468 ++count;
469 if (synchronous && (sstat & SODR_REG_FULL))
470 ++count;
471 }
472#ifdef NCR_700_DEBUG
473 if(count)
474 printk("RESIDUAL IS %d (ddir %d)\n", count, ddir);
475#endif
476 return count;
477}
478
479
480
481static inline char *
482sbcl_to_string(__u8 sbcl)
483{
484 int i;
485 static char ret[256];
486
487 ret[0]='\0';
488 for(i=0; i<8; i++) {
489 if((1<<i) & sbcl)
490 strcat(ret, NCR_700_SBCL_bits[i]);
491 }
492 strcat(ret, NCR_700_SBCL_to_phase[sbcl & 0x07]);
493 return ret;
494}
495
496static inline __u8
497bitmap_to_number(__u8 bitmap)
498{
499 __u8 i;
500
501 for(i=0; i<8 && !(bitmap &(1<<i)); i++)
502 ;
503 return i;
504}
505
506
507STATIC struct NCR_700_command_slot *
508find_empty_slot(struct NCR_700_Host_Parameters *hostdata)
509{
510 struct NCR_700_command_slot *slot = hostdata->free_list;
511
512 if(slot == NULL) {
513
514 if(hostdata->command_slot_count != NCR_700_COMMAND_SLOTS_PER_HOST)
515 printk(KERN_ERR "SLOTS FULL, but count is %d, should be %d\n", hostdata->command_slot_count, NCR_700_COMMAND_SLOTS_PER_HOST);
516 return NULL;
517 }
518
519 if(slot->state != NCR_700_SLOT_FREE)
520
521 printk(KERN_ERR "BUSY SLOT ON FREE LIST!!!\n");
522
523
524 hostdata->free_list = slot->ITL_forw;
525 slot->ITL_forw = NULL;
526
527
528
529
530
531
532 slot->state = NCR_700_SLOT_BUSY;
533 slot->flags = 0;
534 hostdata->command_slot_count++;
535
536 return slot;
537}
538
539STATIC void
540free_slot(struct NCR_700_command_slot *slot,
541 struct NCR_700_Host_Parameters *hostdata)
542{
543 if((slot->state & NCR_700_SLOT_MASK) != NCR_700_SLOT_MAGIC) {
544 printk(KERN_ERR "53c700: SLOT %p is not MAGIC!!!\n", slot);
545 }
546 if(slot->state == NCR_700_SLOT_FREE) {
547 printk(KERN_ERR "53c700: SLOT %p is FREE!!!\n", slot);
548 }
549
550 slot->resume_offset = 0;
551 slot->cmnd = NULL;
552 slot->state = NCR_700_SLOT_FREE;
553 slot->ITL_forw = hostdata->free_list;
554 hostdata->free_list = slot;
555 hostdata->command_slot_count--;
556}
557
558
559
560
561STATIC void
562save_for_reselection(struct NCR_700_Host_Parameters *hostdata,
563 struct scsi_cmnd *SCp, __u32 dsp)
564{
565
566 if(SCp != NULL) {
567 struct NCR_700_command_slot *slot =
568 (struct NCR_700_command_slot *)SCp->host_scribble;
569
570 slot->resume_offset = dsp;
571 }
572 hostdata->state = NCR_700_HOST_FREE;
573 hostdata->cmd = NULL;
574}
575
576STATIC inline void
577NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp,
578 struct NCR_700_command_slot *slot)
579{
580 if(SCp->sc_data_direction != DMA_NONE &&
581 SCp->sc_data_direction != DMA_BIDIRECTIONAL)
582 scsi_dma_unmap(SCp);
583}
584
585STATIC inline void
586NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
587 struct scsi_cmnd *SCp, int result)
588{
589 hostdata->state = NCR_700_HOST_FREE;
590 hostdata->cmd = NULL;
591
592 if(SCp != NULL) {
593 struct NCR_700_command_slot *slot =
594 (struct NCR_700_command_slot *)SCp->host_scribble;
595
596 dma_unmap_single(hostdata->dev, slot->pCmd,
597 MAX_COMMAND_SIZE, DMA_TO_DEVICE);
598 if (slot->flags == NCR_700_FLAG_AUTOSENSE) {
599 char *cmnd = NCR_700_get_sense_cmnd(SCp->device);
600
601 dma_unmap_single(hostdata->dev, slot->dma_handle,
602 SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
603
604
605 if (result == 0)
606 result = cmnd[7];
607
608 SCp->cmd_len = cmnd[8];
609 } else
610 NCR_700_unmap(hostdata, SCp, slot);
611
612 free_slot(slot, hostdata);
613#ifdef NCR_700_DEBUG
614 if(NCR_700_get_depth(SCp->device) == 0 ||
615 NCR_700_get_depth(SCp->device) > SCp->device->queue_depth)
616 printk(KERN_ERR "Invalid depth in NCR_700_scsi_done(): %d\n",
617 NCR_700_get_depth(SCp->device));
618#endif
619 NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) - 1);
620
621 SCp->host_scribble = NULL;
622 SCp->result = result;
623 SCp->scsi_done(SCp);
624 } else {
625 printk(KERN_ERR "53c700: SCSI DONE HAS NULL SCp\n");
626 }
627}
628
629
630STATIC void
631NCR_700_internal_bus_reset(struct Scsi_Host *host)
632{
633
634 NCR_700_writeb(ASSERT_RST, host, SCNTL1_REG);
635 udelay(50);
636 NCR_700_writeb(0, host, SCNTL1_REG);
637
638}
639
640STATIC void
641NCR_700_chip_setup(struct Scsi_Host *host)
642{
643 struct NCR_700_Host_Parameters *hostdata =
644 (struct NCR_700_Host_Parameters *)host->hostdata[0];
645 __u8 min_period;
646 __u8 min_xferp = (hostdata->chip710 ? NCR_710_MIN_XFERP : NCR_700_MIN_XFERP);
647
648 if(hostdata->chip710) {
649 __u8 burst_disable = 0;
650 __u8 burst_length = 0;
651
652 switch (hostdata->burst_length) {
653 case 1:
654 burst_length = BURST_LENGTH_1;
655 break;
656 case 2:
657 burst_length = BURST_LENGTH_2;
658 break;
659 case 4:
660 burst_length = BURST_LENGTH_4;
661 break;
662 case 8:
663 burst_length = BURST_LENGTH_8;
664 break;
665 default:
666 burst_disable = BURST_DISABLE;
667 break;
668 }
669 hostdata->dcntl_extra |= COMPAT_700_MODE;
670
671 NCR_700_writeb(hostdata->dcntl_extra, host, DCNTL_REG);
672 NCR_700_writeb(burst_length | hostdata->dmode_extra,
673 host, DMODE_710_REG);
674 NCR_700_writeb(burst_disable | hostdata->ctest7_extra |
675 (hostdata->differential ? DIFF : 0),
676 host, CTEST7_REG);
677 NCR_700_writeb(BTB_TIMER_DISABLE, host, CTEST0_REG);
678 NCR_700_writeb(FULL_ARBITRATION | ENABLE_PARITY | PARITY
679 | AUTO_ATN, host, SCNTL0_REG);
680 } else {
681 NCR_700_writeb(BURST_LENGTH_8 | hostdata->dmode_extra,
682 host, DMODE_700_REG);
683 NCR_700_writeb(hostdata->differential ?
684 DIFF : 0, host, CTEST7_REG);
685 if(hostdata->fast) {
686
687 NCR_700_writeb(LAST_DIS_ENBL | ENABLE_ACTIVE_NEGATION
688 | GENERATE_RECEIVE_PARITY, host,
689 CTEST8_REG);
690 } else {
691 NCR_700_writeb(FULL_ARBITRATION | ENABLE_PARITY
692 | PARITY | AUTO_ATN, host, SCNTL0_REG);
693 }
694 }
695
696 NCR_700_writeb(1 << host->this_id, host, SCID_REG);
697 NCR_700_writeb(0, host, SBCL_REG);
698 NCR_700_writeb(ASYNC_OPERATION, host, SXFER_REG);
699
700 NCR_700_writeb(PHASE_MM_INT | SEL_TIMEOUT_INT | GROSS_ERR_INT | UX_DISC_INT
701 | RST_INT | PAR_ERR_INT | SELECT_INT, host, SIEN_REG);
702
703 NCR_700_writeb(ABORT_INT | INT_INST_INT | ILGL_INST_INT, host, DIEN_REG);
704 NCR_700_writeb(ENABLE_SELECT, host, SCNTL1_REG);
705 if(hostdata->clock > 75) {
706 printk(KERN_ERR "53c700: Clock speed %dMHz is too high: 75Mhz is the maximum this chip can be driven at\n", hostdata->clock);
707
708
709 DEBUG(("53c700: sync 2 async 3\n"));
710 NCR_700_writeb(SYNC_DIV_2_0, host, SBCL_REG);
711 NCR_700_writeb(ASYNC_DIV_3_0 | hostdata->dcntl_extra, host, DCNTL_REG);
712 hostdata->sync_clock = hostdata->clock/2;
713 } else if(hostdata->clock > 50 && hostdata->clock <= 75) {
714
715 DEBUG(("53c700: sync 1.5 async 3\n"));
716 NCR_700_writeb(SYNC_DIV_1_5, host, SBCL_REG);
717 NCR_700_writeb(ASYNC_DIV_3_0 | hostdata->dcntl_extra, host, DCNTL_REG);
718 hostdata->sync_clock = hostdata->clock*2;
719 hostdata->sync_clock /= 3;
720
721 } else if(hostdata->clock > 37 && hostdata->clock <= 50) {
722
723 DEBUG(("53c700: sync 1 async 2\n"));
724 NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
725 NCR_700_writeb(ASYNC_DIV_2_0 | hostdata->dcntl_extra, host, DCNTL_REG);
726 hostdata->sync_clock = hostdata->clock;
727 } else if(hostdata->clock > 25 && hostdata->clock <=37) {
728
729 DEBUG(("53c700: sync 1 async 1.5\n"));
730 NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
731 NCR_700_writeb(ASYNC_DIV_1_5 | hostdata->dcntl_extra, host, DCNTL_REG);
732 hostdata->sync_clock = hostdata->clock;
733 } else {
734 DEBUG(("53c700: sync 1 async 1\n"));
735 NCR_700_writeb(SYNC_DIV_1_0, host, SBCL_REG);
736 NCR_700_writeb(ASYNC_DIV_1_0 | hostdata->dcntl_extra, host, DCNTL_REG);
737
738 hostdata->sync_clock = hostdata->clock;
739 }
740
741
742
743
744 min_period = 1000*(4+min_xferp)/(4*hostdata->sync_clock);
745 hostdata->min_period = NCR_700_MIN_PERIOD;
746 if(min_period > NCR_700_MIN_PERIOD)
747 hostdata->min_period = min_period;
748}
749
750STATIC void
751NCR_700_chip_reset(struct Scsi_Host *host)
752{
753 struct NCR_700_Host_Parameters *hostdata =
754 (struct NCR_700_Host_Parameters *)host->hostdata[0];
755 if(hostdata->chip710) {
756 NCR_700_writeb(SOFTWARE_RESET_710, host, ISTAT_REG);
757 udelay(100);
758
759 NCR_700_writeb(0, host, ISTAT_REG);
760 } else {
761 NCR_700_writeb(SOFTWARE_RESET, host, DCNTL_REG);
762 udelay(100);
763
764 NCR_700_writeb(0, host, DCNTL_REG);
765 }
766
767 mdelay(1000);
768
769 NCR_700_chip_setup(host);
770}
771
772
773
774
775
776
777
778STATIC __u32
779process_extended_message(struct Scsi_Host *host,
780 struct NCR_700_Host_Parameters *hostdata,
781 struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps)
782{
783 __u32 resume_offset = dsp, temp = dsp + 8;
784 __u8 pun = 0xff, lun = 0xff;
785
786 if(SCp != NULL) {
787 pun = SCp->device->id;
788 lun = SCp->device->lun;
789 }
790
791 switch(hostdata->msgin[2]) {
792 case A_SDTR_MSG:
793 if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
794 struct scsi_target *starget = SCp->device->sdev_target;
795 __u8 period = hostdata->msgin[3];
796 __u8 offset = hostdata->msgin[4];
797
798 if(offset == 0 || period == 0) {
799 offset = 0;
800 period = 0;
801 }
802
803 spi_offset(starget) = offset;
804 spi_period(starget) = period;
805
806 if(NCR_700_is_flag_set(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION)) {
807 spi_display_xfer_agreement(starget);
808 NCR_700_clear_flag(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION);
809 }
810
811 NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
812 NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
813
814 NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
815 host, SXFER_REG);
816
817 } else {
818
819 shost_printk(KERN_WARNING, host,
820 "Unexpected SDTR msg\n");
821 hostdata->msgout[0] = A_REJECT_MSG;
822 dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
823 script_patch_16(hostdata->dev, hostdata->script,
824 MessageCount, 1);
825
826
827 resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
828 }
829 break;
830
831 case A_WDTR_MSG:
832 printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
833 host->host_no, pun, lun);
834 hostdata->msgout[0] = A_REJECT_MSG;
835 dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
836 script_patch_16(hostdata->dev, hostdata->script, MessageCount,
837 1);
838 resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
839
840 break;
841
842 default:
843 printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
844 host->host_no, pun, lun,
845 NCR_700_phase[(dsps & 0xf00) >> 8]);
846 spi_print_msg(hostdata->msgin);
847 printk("\n");
848
849 hostdata->msgout[0] = A_REJECT_MSG;
850 dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
851 script_patch_16(hostdata->dev, hostdata->script, MessageCount,
852 1);
853
854
855 resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
856 }
857 NCR_700_writel(temp, host, TEMP_REG);
858 return resume_offset;
859}
860
861STATIC __u32
862process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata,
863 struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps)
864{
865
866 __u32 temp = dsp + 8, resume_offset = dsp;
867 __u8 pun = 0xff, lun = 0xff;
868
869 if(SCp != NULL) {
870 pun = SCp->device->id;
871 lun = SCp->device->lun;
872 }
873
874#ifdef NCR_700_DEBUG
875 printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,
876 NCR_700_phase[(dsps & 0xf00) >> 8]);
877 spi_print_msg(hostdata->msgin);
878 printk("\n");
879#endif
880
881 switch(hostdata->msgin[0]) {
882
883 case A_EXTENDED_MSG:
884 resume_offset = process_extended_message(host, hostdata, SCp,
885 dsp, dsps);
886 break;
887
888 case A_REJECT_MSG:
889 if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
890
891 spi_period(SCp->device->sdev_target) =
892 spi_offset(SCp->device->sdev_target) = 0;
893 NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
894 NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
895 } else if(SCp != NULL && NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION) {
896
897 scmd_printk(KERN_WARNING, SCp,
898 "Rejected first tag queue attempt, turning off tag queueing\n");
899
900 NCR_700_set_tag_neg_state(SCp->device, NCR_700_FINISHED_TAG_NEGOTIATION);
901 hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
902
903 SCp->device->tagged_supported = 0;
904 SCp->device->simple_tags = 0;
905 scsi_change_queue_depth(SCp->device, host->cmd_per_lun);
906 } else {
907 shost_printk(KERN_WARNING, host,
908 "(%d:%d) Unexpected REJECT Message %s\n",
909 pun, lun,
910 NCR_700_phase[(dsps & 0xf00) >> 8]);
911
912 }
913 break;
914
915 case A_PARITY_ERROR_MSG:
916 printk(KERN_ERR "scsi%d (%d:%d) Parity Error!\n", host->host_no,
917 pun, lun);
918 NCR_700_internal_bus_reset(host);
919 break;
920 case A_SIMPLE_TAG_MSG:
921 printk(KERN_INFO "scsi%d (%d:%d) SIMPLE TAG %d %s\n", host->host_no,
922 pun, lun, hostdata->msgin[1],
923 NCR_700_phase[(dsps & 0xf00) >> 8]);
924
925 break;
926 default:
927 printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
928 host->host_no, pun, lun,
929 NCR_700_phase[(dsps & 0xf00) >> 8]);
930
931 spi_print_msg(hostdata->msgin);
932 printk("\n");
933
934 hostdata->msgout[0] = A_REJECT_MSG;
935 dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
936 script_patch_16(hostdata->dev, hostdata->script, MessageCount,
937 1);
938
939
940 resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
941
942 break;
943 }
944 NCR_700_writel(temp, host, TEMP_REG);
945
946 dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
947 return resume_offset;
948}
949
950STATIC __u32
951process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
952 struct Scsi_Host *host,
953 struct NCR_700_Host_Parameters *hostdata)
954{
955 __u32 resume_offset = 0;
956 __u8 pun = 0xff, lun=0xff;
957
958 if(SCp != NULL) {
959 pun = SCp->device->id;
960 lun = SCp->device->lun;
961 }
962
963 if(dsps == A_GOOD_STATUS_AFTER_STATUS) {
964 DEBUG((" COMMAND COMPLETE, status=%02x\n",
965 hostdata->status[0]));
966
967 if (NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION)
968 NCR_700_set_tag_neg_state(SCp->device,
969 NCR_700_FINISHED_TAG_NEGOTIATION);
970
971
972 if(status_byte(hostdata->status[0]) == CHECK_CONDITION ||
973 status_byte(hostdata->status[0]) == COMMAND_TERMINATED) {
974 struct NCR_700_command_slot *slot =
975 (struct NCR_700_command_slot *)SCp->host_scribble;
976 if(slot->flags == NCR_700_FLAG_AUTOSENSE) {
977
978
979 scmd_printk(KERN_ERR, SCp,
980 "broken device is looping in contingent allegiance: ignoring\n");
981 NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
982 } else {
983 char *cmnd =
984 NCR_700_get_sense_cmnd(SCp->device);
985#ifdef NCR_DEBUG
986 scsi_print_command(SCp);
987 printk(" cmd %p has status %d, requesting sense\n",
988 SCp, hostdata->status[0]);
989#endif
990
991
992
993
994
995
996
997 NCR_700_unmap(hostdata, SCp, slot);
998 dma_unmap_single(hostdata->dev, slot->pCmd,
999 MAX_COMMAND_SIZE,
1000 DMA_TO_DEVICE);
1001
1002 cmnd[0] = REQUEST_SENSE;
1003 cmnd[1] = (lun & 0x7) << 5;
1004 cmnd[2] = 0;
1005 cmnd[3] = 0;
1006 cmnd[4] = SCSI_SENSE_BUFFERSIZE;
1007 cmnd[5] = 0;
1008
1009
1010
1011
1012
1013
1014 cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
1015 cmnd[7] = hostdata->status[0];
1016 cmnd[8] = SCp->cmd_len;
1017 SCp->cmd_len = 6;
1018
1019 slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE);
1020 slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
1021 slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | SCSI_SENSE_BUFFERSIZE);
1022 slot->SG[0].pAddr = bS_to_host(slot->dma_handle);
1023 slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
1024 slot->SG[1].pAddr = 0;
1025 slot->resume_offset = hostdata->pScript;
1026 dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE);
1027 dma_cache_sync(hostdata->dev, SCp->sense_buffer, SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
1028
1029
1030 slot->state = NCR_700_SLOT_QUEUED;
1031 slot->flags = NCR_700_FLAG_AUTOSENSE;
1032 hostdata->state = NCR_700_HOST_FREE;
1033 hostdata->cmd = NULL;
1034 }
1035 } else {
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057 NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
1058 }
1059 } else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) {
1060 __u8 i = (dsps & 0xf00) >> 8;
1061
1062 scmd_printk(KERN_ERR, SCp, "UNEXPECTED PHASE %s (%s)\n",
1063 NCR_700_phase[i],
1064 sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
1065 scmd_printk(KERN_ERR, SCp, " len = %d, cmd =",
1066 SCp->cmd_len);
1067 scsi_print_command(SCp);
1068
1069 NCR_700_internal_bus_reset(host);
1070 } else if((dsps & 0xfffff000) == A_FATAL) {
1071 int i = (dsps & 0xfff);
1072
1073 printk(KERN_ERR "scsi%d: (%d:%d) FATAL ERROR: %s\n",
1074 host->host_no, pun, lun, NCR_700_fatal_messages[i]);
1075 if(dsps == A_FATAL_ILLEGAL_MSG_LENGTH) {
1076 printk(KERN_ERR " msg begins %02x %02x\n",
1077 hostdata->msgin[0], hostdata->msgin[1]);
1078 }
1079 NCR_700_internal_bus_reset(host);
1080 } else if((dsps & 0xfffff0f0) == A_DISCONNECT) {
1081#ifdef NCR_700_DEBUG
1082 __u8 i = (dsps & 0xf00) >> 8;
1083
1084 printk("scsi%d: (%d:%d), DISCONNECTED (%d) %s\n",
1085 host->host_no, pun, lun,
1086 i, NCR_700_phase[i]);
1087#endif
1088 save_for_reselection(hostdata, SCp, dsp);
1089
1090 } else if(dsps == A_RESELECTION_IDENTIFIED) {
1091 __u8 lun;
1092 struct NCR_700_command_slot *slot;
1093 __u8 reselection_id = hostdata->reselection_id;
1094 struct scsi_device *SDp;
1095
1096 lun = hostdata->msgin[0] & 0x1f;
1097
1098 hostdata->reselection_id = 0xff;
1099 DEBUG(("scsi%d: (%d:%d) RESELECTED!\n",
1100 host->host_no, reselection_id, lun));
1101
1102 SDp = __scsi_device_lookup(host, 0, reselection_id, lun);
1103 if(unlikely(SDp == NULL)) {
1104 printk(KERN_ERR "scsi%d: (%d:%d) HAS NO device\n",
1105 host->host_no, reselection_id, lun);
1106 BUG();
1107 }
1108 if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) {
1109 struct scsi_cmnd *SCp;
1110
1111 SCp = scsi_host_find_tag(SDp->host, hostdata->msgin[2]);
1112 if(unlikely(SCp == NULL)) {
1113 printk(KERN_ERR "scsi%d: (%d:%d) no saved request for tag %d\n",
1114 host->host_no, reselection_id, lun, hostdata->msgin[2]);
1115 BUG();
1116 }
1117
1118 slot = (struct NCR_700_command_slot *)SCp->host_scribble;
1119 DDEBUG(KERN_DEBUG, SDp,
1120 "reselection is tag %d, slot %p(%d)\n",
1121 hostdata->msgin[2], slot, slot->tag);
1122 } else {
1123 struct NCR_700_Device_Parameters *p = SDp->hostdata;
1124 struct scsi_cmnd *SCp = p->current_cmnd;
1125
1126 if(unlikely(SCp == NULL)) {
1127 sdev_printk(KERN_ERR, SDp,
1128 "no saved request for untagged cmd\n");
1129 BUG();
1130 }
1131 slot = (struct NCR_700_command_slot *)SCp->host_scribble;
1132 }
1133
1134 if(slot == NULL) {
1135 printk(KERN_ERR "scsi%d: (%d:%d) RESELECTED but no saved command (MSG = %02x %02x %02x)!!\n",
1136 host->host_no, reselection_id, lun,
1137 hostdata->msgin[0], hostdata->msgin[1],
1138 hostdata->msgin[2]);
1139 } else {
1140 if(hostdata->state != NCR_700_HOST_BUSY)
1141 printk(KERN_ERR "scsi%d: FATAL, host not busy during valid reselection!\n",
1142 host->host_no);
1143 resume_offset = slot->resume_offset;
1144 hostdata->cmd = slot->cmnd;
1145
1146
1147 script_patch_32_abs(hostdata->dev, hostdata->script,
1148 CommandAddress, slot->pCmd);
1149 script_patch_16(hostdata->dev, hostdata->script,
1150 CommandCount, slot->cmnd->cmd_len);
1151 script_patch_32_abs(hostdata->dev, hostdata->script,
1152 SGScriptStartAddress,
1153 to32bit(&slot->pSG[0].ins));
1154
1155
1156
1157
1158
1159
1160 NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
1161 host, SXFER_REG);
1162 dma_cache_sync(hostdata->dev, hostdata->msgin,
1163 MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
1164 dma_cache_sync(hostdata->dev, hostdata->msgout,
1165 MSG_ARRAY_SIZE, DMA_TO_DEVICE);
1166
1167
1168 dma_cache_sync(hostdata->dev, slot->cmnd->cmnd,
1169 slot->cmnd->cmd_len, DMA_TO_DEVICE);
1170
1171
1172
1173 }
1174 } else if(dsps == A_RESELECTED_DURING_SELECTION) {
1175
1176
1177
1178
1179
1180
1181
1182
1183 __u8 reselection_id = NCR_700_readb(host, SFBR_REG);
1184 struct NCR_700_command_slot *slot;
1185
1186
1187 reselection_id &= ~(1<<host->this_id);
1188
1189
1190
1191 printk(KERN_INFO "scsi%d: (%d:%d) RESELECTION DURING SELECTION, dsp=%08x[%04x] state=%d, count=%d\n",
1192 host->host_no, reselection_id, lun, dsp, dsp - hostdata->pScript, hostdata->state, hostdata->command_slot_count);
1193
1194 {
1195
1196 __u32 SG = (__u32)bS_to_cpu(hostdata->script[A_SGScriptStartAddress_used[0]]);
1197 int i;
1198
1199 for(i=0; i< NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
1200 if(SG >= to32bit(&hostdata->slots[i].pSG[0])
1201 && SG <= to32bit(&hostdata->slots[i].pSG[NCR_700_SG_SEGMENTS]))
1202 break;
1203 }
1204 printk(KERN_INFO "IDENTIFIED SG segment as being %08x in slot %p, cmd %p, slot->resume_offset=%08x\n", SG, &hostdata->slots[i], hostdata->slots[i].cmnd, hostdata->slots[i].resume_offset);
1205 SCp = hostdata->slots[i].cmnd;
1206 }
1207
1208 if(SCp != NULL) {
1209 slot = (struct NCR_700_command_slot *)SCp->host_scribble;
1210
1211 slot->state = NCR_700_SLOT_QUEUED;
1212 }
1213 hostdata->cmd = NULL;
1214
1215 if(reselection_id == 0) {
1216 if(hostdata->reselection_id == 0xff) {
1217 printk(KERN_ERR "scsi%d: Invalid reselection during selection!!\n", host->host_no);
1218 return 0;
1219 } else {
1220 printk(KERN_ERR "scsi%d: script reselected and we took a selection interrupt\n",
1221 host->host_no);
1222 reselection_id = hostdata->reselection_id;
1223 }
1224 } else {
1225
1226
1227 reselection_id = bitmap_to_number(reselection_id);
1228 }
1229 hostdata->reselection_id = reselection_id;
1230
1231 hostdata->msgin[1] = 0;
1232 dma_cache_sync(hostdata->dev, hostdata->msgin,
1233 MSG_ARRAY_SIZE, DMA_BIDIRECTIONAL);
1234 if(hostdata->tag_negotiated & (1<<reselection_id)) {
1235 resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
1236 } else {
1237 resume_offset = hostdata->pScript + Ent_GetReselectionData;
1238 }
1239 } else if(dsps == A_COMPLETED_SELECTION_AS_TARGET) {
1240
1241
1242
1243 DEBUG((" SELECTION COMPLETED\n"));
1244 } else if((dsps & 0xfffff0f0) == A_MSG_IN) {
1245 resume_offset = process_message(host, hostdata, SCp,
1246 dsp, dsps);
1247 } else if((dsps & 0xfffff000) == 0) {
1248 __u8 i = (dsps & 0xf0) >> 4, j = (dsps & 0xf00) >> 8;
1249 printk(KERN_ERR "scsi%d: (%d:%d), unhandled script condition %s %s at %04x\n",
1250 host->host_no, pun, lun, NCR_700_condition[i],
1251 NCR_700_phase[j], dsp - hostdata->pScript);
1252 if(SCp != NULL) {
1253 struct scatterlist *sg;
1254
1255 scsi_print_command(SCp);
1256 scsi_for_each_sg(SCp, sg, scsi_sg_count(SCp) + 1, i) {
1257 printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, sg->length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
1258 }
1259 }
1260 NCR_700_internal_bus_reset(host);
1261 } else if((dsps & 0xfffff000) == A_DEBUG_INTERRUPT) {
1262 printk(KERN_NOTICE "scsi%d (%d:%d) DEBUG INTERRUPT %d AT %08x[%04x], continuing\n",
1263 host->host_no, pun, lun, dsps & 0xfff, dsp, dsp - hostdata->pScript);
1264 resume_offset = dsp;
1265 } else {
1266 printk(KERN_ERR "scsi%d: (%d:%d), unidentified script interrupt 0x%x at %04x\n",
1267 host->host_no, pun, lun, dsps, dsp - hostdata->pScript);
1268 NCR_700_internal_bus_reset(host);
1269 }
1270 return resume_offset;
1271}
1272
1273
1274
1275
1276
1277
1278
1279
1280STATIC inline __u32
1281process_selection(struct Scsi_Host *host, __u32 dsp)
1282{
1283 __u8 id = 0;
1284 int count = 0;
1285 __u32 resume_offset = 0;
1286 struct NCR_700_Host_Parameters *hostdata =
1287 (struct NCR_700_Host_Parameters *)host->hostdata[0];
1288 struct scsi_cmnd *SCp = hostdata->cmd;
1289 __u8 sbcl;
1290
1291 for(count = 0; count < 5; count++) {
1292 id = NCR_700_readb(host, hostdata->chip710 ?
1293 CTEST9_REG : SFBR_REG);
1294
1295
1296 id &= ~(1<<host->this_id);
1297 if(id != 0)
1298 break;
1299 udelay(5);
1300 }
1301 sbcl = NCR_700_readb(host, SBCL_REG);
1302 if((sbcl & SBCL_IO) == 0) {
1303
1304 id = 0xff;
1305 } else {
1306
1307 hostdata->reselection_id = id = bitmap_to_number(id);
1308 DEBUG(("scsi%d: Reselected by %d\n",
1309 host->host_no, id));
1310 }
1311 if(hostdata->state == NCR_700_HOST_BUSY && SCp != NULL) {
1312 struct NCR_700_command_slot *slot =
1313 (struct NCR_700_command_slot *)SCp->host_scribble;
1314 DEBUG((" ID %d WARNING: RESELECTION OF BUSY HOST, saving cmd %p, slot %p, addr %x [%04x], resume %x!\n", id, hostdata->cmd, slot, dsp, dsp - hostdata->pScript, resume_offset));
1315
1316 switch(dsp - hostdata->pScript) {
1317 case Ent_Disconnect1:
1318 case Ent_Disconnect2:
1319 save_for_reselection(hostdata, SCp, Ent_Disconnect2 + hostdata->pScript);
1320 break;
1321 case Ent_Disconnect3:
1322 case Ent_Disconnect4:
1323 save_for_reselection(hostdata, SCp, Ent_Disconnect4 + hostdata->pScript);
1324 break;
1325 case Ent_Disconnect5:
1326 case Ent_Disconnect6:
1327 save_for_reselection(hostdata, SCp, Ent_Disconnect6 + hostdata->pScript);
1328 break;
1329 case Ent_Disconnect7:
1330 case Ent_Disconnect8:
1331 save_for_reselection(hostdata, SCp, Ent_Disconnect8 + hostdata->pScript);
1332 break;
1333 case Ent_Finish1:
1334 case Ent_Finish2:
1335 process_script_interrupt(A_GOOD_STATUS_AFTER_STATUS, dsp, SCp, host, hostdata);
1336 break;
1337
1338 default:
1339 slot->state = NCR_700_SLOT_QUEUED;
1340 break;
1341 }
1342 }
1343 hostdata->state = NCR_700_HOST_BUSY;
1344 hostdata->cmd = NULL;
1345
1346 hostdata->msgin[1] = 0;
1347 dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE,
1348 DMA_BIDIRECTIONAL);
1349
1350 if(id == 0xff) {
1351
1352 resume_offset = hostdata->pScript + Ent_SelectedAsTarget;
1353 } else if(hostdata->tag_negotiated & (1<<id)) {
1354 resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
1355 } else {
1356 resume_offset = hostdata->pScript + Ent_GetReselectionData;
1357 }
1358 return resume_offset;
1359}
1360
1361static inline void
1362NCR_700_clear_fifo(struct Scsi_Host *host) {
1363 const struct NCR_700_Host_Parameters *hostdata
1364 = (struct NCR_700_Host_Parameters *)host->hostdata[0];
1365 if(hostdata->chip710) {
1366 NCR_700_writeb(CLR_FIFO_710, host, CTEST8_REG);
1367 } else {
1368 NCR_700_writeb(CLR_FIFO, host, DFIFO_REG);
1369 }
1370}
1371
1372static inline void
1373NCR_700_flush_fifo(struct Scsi_Host *host) {
1374 const struct NCR_700_Host_Parameters *hostdata
1375 = (struct NCR_700_Host_Parameters *)host->hostdata[0];
1376 if(hostdata->chip710) {
1377 NCR_700_writeb(FLUSH_DMA_FIFO_710, host, CTEST8_REG);
1378 udelay(10);
1379 NCR_700_writeb(0, host, CTEST8_REG);
1380 } else {
1381 NCR_700_writeb(FLUSH_DMA_FIFO, host, DFIFO_REG);
1382 udelay(10);
1383 NCR_700_writeb(0, host, DFIFO_REG);
1384 }
1385}
1386
1387
1388
1389
1390STATIC int
1391NCR_700_start_command(struct scsi_cmnd *SCp)
1392{
1393 struct NCR_700_command_slot *slot =
1394 (struct NCR_700_command_slot *)SCp->host_scribble;
1395 struct NCR_700_Host_Parameters *hostdata =
1396 (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
1397 __u16 count = 1;
1398 u8 lun = SCp->device->lun;
1399
1400 if(hostdata->state != NCR_700_HOST_FREE) {
1401
1402
1403
1404 slot->state = NCR_700_SLOT_QUEUED;
1405
1406 DEBUG(("scsi%d: host busy, queueing command %p, slot %p\n",
1407 SCp->device->host->host_no, slot->cmnd, slot));
1408 return 0;
1409 }
1410 hostdata->state = NCR_700_HOST_BUSY;
1411 hostdata->cmd = SCp;
1412 slot->state = NCR_700_SLOT_BUSY;
1413
1414
1415
1416 hostdata->msgout[0] = NCR_700_identify((SCp->cmnd[0] != REQUEST_SENSE &&
1417 slot->flags != NCR_700_FLAG_AUTOSENSE),
1418 lun);
1419
1420
1421
1422 if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE ||
1423 slot->flags == NCR_700_FLAG_AUTOSENSE) {
1424 NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
1425 }
1426
1427
1428
1429
1430
1431 if((hostdata->tag_negotiated & (1<<scmd_id(SCp)))
1432 && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE &&
1433 slot->flags != NCR_700_FLAG_AUTOSENSE)) {
1434 count += spi_populate_tag_msg(&hostdata->msgout[count], SCp);
1435 }
1436
1437 if(hostdata->fast &&
1438 NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) {
1439 count += spi_populate_sync_msg(&hostdata->msgout[count],
1440 spi_period(SCp->device->sdev_target),
1441 spi_offset(SCp->device->sdev_target));
1442 NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
1443 }
1444
1445 script_patch_16(hostdata->dev, hostdata->script, MessageCount, count);
1446
1447
1448 script_patch_ID(hostdata->dev, hostdata->script,
1449 Device_ID, 1<<scmd_id(SCp));
1450
1451 script_patch_32_abs(hostdata->dev, hostdata->script, CommandAddress,
1452 slot->pCmd);
1453 script_patch_16(hostdata->dev, hostdata->script, CommandCount,
1454 SCp->cmd_len);
1455
1456
1457 script_patch_32_abs(hostdata->dev, hostdata->script,
1458 SGScriptStartAddress, to32bit(&slot->pSG[0].ins));
1459 NCR_700_clear_fifo(SCp->device->host);
1460
1461 if(slot->resume_offset == 0)
1462 slot->resume_offset = hostdata->pScript;
1463
1464 dma_cache_sync(hostdata->dev, hostdata->msgout, count, DMA_TO_DEVICE);
1465 dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE,
1466 DMA_FROM_DEVICE);
1467 dma_cache_sync(hostdata->dev, SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE);
1468 dma_cache_sync(hostdata->dev, hostdata->status, 1, DMA_FROM_DEVICE);
1469
1470
1471 NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
1472 SCp->device->host, SXFER_REG);
1473 NCR_700_writel(slot->temp, SCp->device->host, TEMP_REG);
1474 NCR_700_writel(slot->resume_offset, SCp->device->host, DSP_REG);
1475
1476 return 1;
1477}
1478
1479irqreturn_t
1480NCR_700_intr(int irq, void *dev_id)
1481{
1482 struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
1483 struct NCR_700_Host_Parameters *hostdata =
1484 (struct NCR_700_Host_Parameters *)host->hostdata[0];
1485 __u8 istat;
1486 __u32 resume_offset = 0;
1487 __u8 pun = 0xff, lun = 0xff;
1488 unsigned long flags;
1489 int handled = 0;
1490
1491
1492
1493
1494
1495
1496 spin_lock_irqsave(host->host_lock, flags);
1497 if((istat = NCR_700_readb(host, ISTAT_REG))
1498 & (SCSI_INT_PENDING | DMA_INT_PENDING)) {
1499 __u32 dsps;
1500 __u8 sstat0 = 0, dstat = 0;
1501 __u32 dsp;
1502 struct scsi_cmnd *SCp = hostdata->cmd;
1503 enum NCR_700_Host_State state;
1504
1505 handled = 1;
1506 state = hostdata->state;
1507 SCp = hostdata->cmd;
1508
1509 if(istat & SCSI_INT_PENDING) {
1510 udelay(10);
1511
1512 sstat0 = NCR_700_readb(host, SSTAT0_REG);
1513 }
1514
1515 if(istat & DMA_INT_PENDING) {
1516 udelay(10);
1517
1518 dstat = NCR_700_readb(host, DSTAT_REG);
1519 }
1520
1521 dsps = NCR_700_readl(host, DSPS_REG);
1522 dsp = NCR_700_readl(host, DSP_REG);
1523
1524 DEBUG(("scsi%d: istat %02x sstat0 %02x dstat %02x dsp %04x[%08x] dsps 0x%x\n",
1525 host->host_no, istat, sstat0, dstat,
1526 (dsp - (__u32)(hostdata->pScript))/4,
1527 dsp, dsps));
1528
1529 if(SCp != NULL) {
1530 pun = SCp->device->id;
1531 lun = SCp->device->lun;
1532 }
1533
1534 if(sstat0 & SCSI_RESET_DETECTED) {
1535 struct scsi_device *SDp;
1536 int i;
1537
1538 hostdata->state = NCR_700_HOST_BUSY;
1539
1540 printk(KERN_ERR "scsi%d: Bus Reset detected, executing command %p, slot %p, dsp %08x[%04x]\n",
1541 host->host_no, SCp, SCp == NULL ? NULL : SCp->host_scribble, dsp, dsp - hostdata->pScript);
1542
1543 scsi_report_bus_reset(host, 0);
1544
1545
1546 __shost_for_each_device(SDp, host)
1547 NCR_700_clear_flag(SDp, ~0);
1548
1549
1550 for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
1551 struct scsi_cmnd *SCp;
1552 struct NCR_700_command_slot *slot =
1553 &hostdata->slots[i];
1554
1555 if(slot->state == NCR_700_SLOT_FREE)
1556 continue;
1557
1558 SCp = slot->cmnd;
1559 printk(KERN_ERR " failing command because of reset, slot %p, cmnd %p\n",
1560 slot, SCp);
1561 free_slot(slot, hostdata);
1562 SCp->host_scribble = NULL;
1563 NCR_700_set_depth(SCp->device, 0);
1564
1565
1566
1567
1568
1569
1570 SCp->result = DID_RESET << 16;
1571 SCp->scsi_done(SCp);
1572 }
1573 mdelay(25);
1574 NCR_700_chip_setup(host);
1575
1576 hostdata->state = NCR_700_HOST_FREE;
1577 hostdata->cmd = NULL;
1578
1579 if(hostdata->eh_complete != NULL)
1580 complete(hostdata->eh_complete);
1581 goto out_unlock;
1582 } else if(sstat0 & SELECTION_TIMEOUT) {
1583 DEBUG(("scsi%d: (%d:%d) selection timeout\n",
1584 host->host_no, pun, lun));
1585 NCR_700_scsi_done(hostdata, SCp, DID_NO_CONNECT<<16);
1586 } else if(sstat0 & PHASE_MISMATCH) {
1587 struct NCR_700_command_slot *slot = (SCp == NULL) ? NULL :
1588 (struct NCR_700_command_slot *)SCp->host_scribble;
1589
1590 if(dsp == Ent_SendMessage + 8 + hostdata->pScript) {
1591
1592
1593#ifdef NCR_700_DEBUG
1594 __u32 temp = NCR_700_readl(host, TEMP_REG);
1595 int count = (hostdata->script[Ent_SendMessage/4] & 0xffffff) - ((NCR_700_readl(host, DBC_REG) & 0xffffff) + NCR_700_data_residual(host));
1596 printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
1597#endif
1598 resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch;
1599 } else if(dsp >= to32bit(&slot->pSG[0].ins) &&
1600 dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) {
1601 int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff;
1602 int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List);
1603 int residual = NCR_700_data_residual(host);
1604 int i;
1605#ifdef NCR_700_DEBUG
1606 __u32 naddr = NCR_700_readl(host, DNAD_REG);
1607
1608 printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n",
1609 host->host_no, pun, lun,
1610 SGcount, data_transfer);
1611 scsi_print_command(SCp);
1612 if(residual) {
1613 printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x, residual %d\n",
1614 host->host_no, pun, lun,
1615 SGcount, data_transfer, residual);
1616 }
1617#endif
1618 data_transfer += residual;
1619
1620 if(data_transfer != 0) {
1621 int count;
1622 __u32 pAddr;
1623
1624 SGcount--;
1625
1626 count = (bS_to_cpu(slot->SG[SGcount].ins) & 0x00ffffff);
1627 DEBUG(("DATA TRANSFER MISMATCH, count = %d, transferred %d\n", count, count-data_transfer));
1628 slot->SG[SGcount].ins &= bS_to_host(0xff000000);
1629 slot->SG[SGcount].ins |= bS_to_host(data_transfer);
1630 pAddr = bS_to_cpu(slot->SG[SGcount].pAddr);
1631 pAddr += (count - data_transfer);
1632#ifdef NCR_700_DEBUG
1633 if(pAddr != naddr) {
1634 printk("scsi%d (%d:%d) transfer mismatch pAddr=%lx, naddr=%lx, data_transfer=%d, residual=%d\n", host->host_no, pun, lun, (unsigned long)pAddr, (unsigned long)naddr, data_transfer, residual);
1635 }
1636#endif
1637 slot->SG[SGcount].pAddr = bS_to_host(pAddr);
1638 }
1639
1640 for(i=0; i<SGcount; i++) {
1641 slot->SG[i].ins = bS_to_host(SCRIPT_NOP);
1642 slot->SG[i].pAddr = 0;
1643 }
1644 dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
1645
1646
1647 resume_offset = hostdata->pScript + Ent_MsgInDuringData;
1648
1649 NCR_700_flush_fifo(host);
1650 } else {
1651 __u8 sbcl = NCR_700_readb(host, SBCL_REG);
1652 printk(KERN_ERR "scsi%d: (%d:%d) phase mismatch at %04x, phase %s\n",
1653 host->host_no, pun, lun, dsp - hostdata->pScript, sbcl_to_string(sbcl));
1654 NCR_700_internal_bus_reset(host);
1655 }
1656
1657 } else if(sstat0 & SCSI_GROSS_ERROR) {
1658 printk(KERN_ERR "scsi%d: (%d:%d) GROSS ERROR\n",
1659 host->host_no, pun, lun);
1660 NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
1661 } else if(sstat0 & PARITY_ERROR) {
1662 printk(KERN_ERR "scsi%d: (%d:%d) PARITY ERROR\n",
1663 host->host_no, pun, lun);
1664 NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
1665 } else if(dstat & SCRIPT_INT_RECEIVED) {
1666 DEBUG(("scsi%d: (%d:%d) ====>SCRIPT INTERRUPT<====\n",
1667 host->host_no, pun, lun));
1668 resume_offset = process_script_interrupt(dsps, dsp, SCp, host, hostdata);
1669 } else if(dstat & (ILGL_INST_DETECTED)) {
1670 printk(KERN_ERR "scsi%d: (%d:%d) Illegal Instruction detected at 0x%08x[0x%x]!!!\n"
1671 " Please email James.Bottomley@HansenPartnership.com with the details\n",
1672 host->host_no, pun, lun,
1673 dsp, dsp - hostdata->pScript);
1674 NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
1675 } else if(dstat & (WATCH_DOG_INTERRUPT|ABORTED)) {
1676 printk(KERN_ERR "scsi%d: (%d:%d) serious DMA problem, dstat=%02x\n",
1677 host->host_no, pun, lun, dstat);
1678 NCR_700_scsi_done(hostdata, SCp, DID_ERROR<<16);
1679 }
1680
1681
1682
1683
1684
1685
1686
1687 if(sstat0 & SELECTED) {
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703 resume_offset = process_selection(host, dsp);
1704
1705 }
1706
1707 }
1708
1709 if(resume_offset) {
1710 if(hostdata->state != NCR_700_HOST_BUSY) {
1711 printk(KERN_ERR "scsi%d: Driver error: resume at 0x%08x [0x%04x] with non busy host!\n",
1712 host->host_no, resume_offset, resume_offset - hostdata->pScript);
1713 hostdata->state = NCR_700_HOST_BUSY;
1714 }
1715
1716 DEBUG(("Attempting to resume at %x\n", resume_offset));
1717 NCR_700_clear_fifo(host);
1718 NCR_700_writel(resume_offset, host, DSP_REG);
1719 }
1720
1721
1722
1723
1724
1725 if(hostdata->state == NCR_700_HOST_FREE) {
1726 int i;
1727
1728 for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
1729
1730
1731 int j = (i + hostdata->saved_slot_position)
1732 % NCR_700_COMMAND_SLOTS_PER_HOST;
1733
1734 if(hostdata->slots[j].state != NCR_700_SLOT_QUEUED)
1735 continue;
1736 if(NCR_700_start_command(hostdata->slots[j].cmnd)) {
1737 DEBUG(("scsi%d: Issuing saved command slot %p, cmd %p\t\n",
1738 host->host_no, &hostdata->slots[j],
1739 hostdata->slots[j].cmnd));
1740 hostdata->saved_slot_position = j + 1;
1741 }
1742
1743 break;
1744 }
1745 }
1746 out_unlock:
1747 spin_unlock_irqrestore(host->host_lock, flags);
1748 return IRQ_RETVAL(handled);
1749}
1750
1751static int
1752NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
1753{
1754 struct NCR_700_Host_Parameters *hostdata =
1755 (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
1756 __u32 move_ins;
1757 enum dma_data_direction direction;
1758 struct NCR_700_command_slot *slot;
1759
1760 if(hostdata->command_slot_count >= NCR_700_COMMAND_SLOTS_PER_HOST) {
1761
1762
1763 printk(KERN_WARNING "scsi%d: Command depth has gone over queue depth\n", SCp->device->host->host_no);
1764 return 1;
1765 }
1766
1767
1768
1769
1770
1771
1772 if(NCR_700_get_depth(SCp->device) != 0
1773 && (!(hostdata->tag_negotiated & (1<<scmd_id(SCp)))
1774 || !(SCp->flags & SCMD_TAGGED))) {
1775 CDEBUG(KERN_ERR, SCp, "has non zero depth %d\n",
1776 NCR_700_get_depth(SCp->device));
1777 return SCSI_MLQUEUE_DEVICE_BUSY;
1778 }
1779 if(NCR_700_get_depth(SCp->device) >= SCp->device->queue_depth) {
1780 CDEBUG(KERN_ERR, SCp, "has max tag depth %d\n",
1781 NCR_700_get_depth(SCp->device));
1782 return SCSI_MLQUEUE_DEVICE_BUSY;
1783 }
1784 NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1);
1785
1786
1787
1788
1789 slot = find_empty_slot(hostdata);
1790
1791 slot->cmnd = SCp;
1792
1793 SCp->scsi_done = done;
1794 SCp->host_scribble = (unsigned char *)slot;
1795 SCp->SCp.ptr = NULL;
1796 SCp->SCp.buffer = NULL;
1797
1798#ifdef NCR_700_DEBUG
1799 printk("53c700: scsi%d, command ", SCp->device->host->host_no);
1800 scsi_print_command(SCp);
1801#endif
1802 if ((SCp->flags & SCMD_TAGGED)
1803 && (hostdata->tag_negotiated &(1<<scmd_id(SCp))) == 0
1804 && NCR_700_get_tag_neg_state(SCp->device) == NCR_700_START_TAG_NEGOTIATION) {
1805 scmd_printk(KERN_ERR, SCp, "Enabling Tag Command Queuing\n");
1806 hostdata->tag_negotiated |= (1<<scmd_id(SCp));
1807 NCR_700_set_tag_neg_state(SCp->device, NCR_700_DURING_TAG_NEGOTIATION);
1808 }
1809
1810
1811
1812
1813
1814
1815
1816 if (!(SCp->flags & SCMD_TAGGED)
1817 && (hostdata->tag_negotiated &(1<<scmd_id(SCp)))) {
1818 scmd_printk(KERN_INFO, SCp, "Disabling Tag Command Queuing\n");
1819 hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
1820 }
1821
1822 if ((hostdata->tag_negotiated & (1<<scmd_id(SCp))) &&
1823 SCp->device->simple_tags) {
1824 slot->tag = SCp->request->tag;
1825 CDEBUG(KERN_DEBUG, SCp, "sending out tag %d, slot %p\n",
1826 slot->tag, slot);
1827 } else {
1828 struct NCR_700_Device_Parameters *p = SCp->device->hostdata;
1829
1830 slot->tag = SCSI_NO_TAG;
1831
1832 p->current_cmnd = SCp;
1833 }
1834
1835
1836 if(!scsi_sg_count(SCp) && !scsi_bufflen(SCp) &&
1837 SCp->sc_data_direction != DMA_NONE) {
1838#ifdef NCR_700_DEBUG
1839 printk("53c700: Command");
1840 scsi_print_command(SCp);
1841 printk("Has wrong data direction %d\n", SCp->sc_data_direction);
1842#endif
1843 SCp->sc_data_direction = DMA_NONE;
1844 }
1845
1846 switch (SCp->cmnd[0]) {
1847 case REQUEST_SENSE:
1848
1849 SCp->cmnd[6] = 0;
1850
1851 default:
1852
1853 switch(SCp->sc_data_direction) {
1854 case DMA_BIDIRECTIONAL:
1855 default:
1856 printk(KERN_ERR "53c700: Unknown command for data direction ");
1857 scsi_print_command(SCp);
1858
1859 move_ins = 0;
1860 break;
1861 case DMA_NONE:
1862 move_ins = 0;
1863 break;
1864 case DMA_FROM_DEVICE:
1865 move_ins = SCRIPT_MOVE_DATA_IN;
1866 break;
1867 case DMA_TO_DEVICE:
1868 move_ins = SCRIPT_MOVE_DATA_OUT;
1869 break;
1870 }
1871 }
1872
1873
1874 direction = SCp->sc_data_direction;
1875 if(move_ins != 0) {
1876 int i;
1877 int sg_count;
1878 dma_addr_t vPtr = 0;
1879 struct scatterlist *sg;
1880 __u32 count = 0;
1881
1882 sg_count = scsi_dma_map(SCp);
1883 BUG_ON(sg_count < 0);
1884
1885 scsi_for_each_sg(SCp, sg, sg_count, i) {
1886 vPtr = sg_dma_address(sg);
1887 count = sg_dma_len(sg);
1888
1889 slot->SG[i].ins = bS_to_host(move_ins | count);
1890 DEBUG((" scatter block %d: move %d[%08x] from 0x%lx\n",
1891 i, count, slot->SG[i].ins, (unsigned long)vPtr));
1892 slot->SG[i].pAddr = bS_to_host(vPtr);
1893 }
1894 slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
1895 slot->SG[i].pAddr = 0;
1896 dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
1897 DEBUG((" SETTING %p to %x\n",
1898 (&slot->pSG[i].ins),
1899 slot->SG[i].ins));
1900 }
1901 slot->resume_offset = 0;
1902 slot->pCmd = dma_map_single(hostdata->dev, SCp->cmnd,
1903 MAX_COMMAND_SIZE, DMA_TO_DEVICE);
1904 NCR_700_start_command(SCp);
1905 return 0;
1906}
1907
1908STATIC DEF_SCSI_QCMD(NCR_700_queuecommand)
1909
1910STATIC int
1911NCR_700_abort(struct scsi_cmnd * SCp)
1912{
1913 struct NCR_700_command_slot *slot;
1914
1915 scmd_printk(KERN_INFO, SCp, "abort command\n");
1916
1917 slot = (struct NCR_700_command_slot *)SCp->host_scribble;
1918
1919 if(slot == NULL)
1920
1921 return SUCCESS;
1922 if(SCp->cmnd[0] == TEST_UNIT_READY) {
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933 NCR_700_internal_bus_reset(SCp->device->host);
1934
1935 }
1936 return FAILED;
1937
1938}
1939
1940STATIC int
1941NCR_700_bus_reset(struct scsi_cmnd * SCp)
1942{
1943 DECLARE_COMPLETION_ONSTACK(complete);
1944 struct NCR_700_Host_Parameters *hostdata =
1945 (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
1946
1947 scmd_printk(KERN_INFO, SCp,
1948 "New error handler wants BUS reset, cmd %p\n\t", SCp);
1949 scsi_print_command(SCp);
1950
1951
1952
1953
1954 spin_lock_irq(SCp->device->host->host_lock);
1955 while (hostdata->eh_complete != NULL) {
1956 spin_unlock_irq(SCp->device->host->host_lock);
1957 msleep_interruptible(100);
1958 spin_lock_irq(SCp->device->host->host_lock);
1959 }
1960
1961 hostdata->eh_complete = &complete;
1962 NCR_700_internal_bus_reset(SCp->device->host);
1963
1964 spin_unlock_irq(SCp->device->host->host_lock);
1965 wait_for_completion(&complete);
1966 spin_lock_irq(SCp->device->host->host_lock);
1967
1968 hostdata->eh_complete = NULL;
1969
1970 if(hostdata->fast)
1971 spi_schedule_dv_device(SCp->device);
1972
1973 spin_unlock_irq(SCp->device->host->host_lock);
1974 return SUCCESS;
1975}
1976
1977STATIC int
1978NCR_700_host_reset(struct scsi_cmnd * SCp)
1979{
1980 scmd_printk(KERN_INFO, SCp, "New error handler wants HOST reset\n\t");
1981 scsi_print_command(SCp);
1982
1983 spin_lock_irq(SCp->device->host->host_lock);
1984
1985 NCR_700_internal_bus_reset(SCp->device->host);
1986 NCR_700_chip_reset(SCp->device->host);
1987
1988 spin_unlock_irq(SCp->device->host->host_lock);
1989
1990 return SUCCESS;
1991}
1992
1993STATIC void
1994NCR_700_set_period(struct scsi_target *STp, int period)
1995{
1996 struct Scsi_Host *SHp = dev_to_shost(STp->dev.parent);
1997 struct NCR_700_Host_Parameters *hostdata =
1998 (struct NCR_700_Host_Parameters *)SHp->hostdata[0];
1999
2000 if(!hostdata->fast)
2001 return;
2002
2003 if(period < hostdata->min_period)
2004 period = hostdata->min_period;
2005
2006 spi_period(STp) = period;
2007 spi_flags(STp) &= ~(NCR_700_DEV_NEGOTIATED_SYNC |
2008 NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
2009 spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION;
2010}
2011
2012STATIC void
2013NCR_700_set_offset(struct scsi_target *STp, int offset)
2014{
2015 struct Scsi_Host *SHp = dev_to_shost(STp->dev.parent);
2016 struct NCR_700_Host_Parameters *hostdata =
2017 (struct NCR_700_Host_Parameters *)SHp->hostdata[0];
2018 int max_offset = hostdata->chip710
2019 ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET;
2020
2021 if(!hostdata->fast)
2022 return;
2023
2024 if(offset > max_offset)
2025 offset = max_offset;
2026
2027
2028 if(spi_offset(STp) == 0 && (spi_period(STp) < hostdata->min_period ||
2029 spi_period(STp) > 0xff))
2030 spi_period(STp) = hostdata->min_period;
2031
2032 spi_offset(STp) = offset;
2033 spi_flags(STp) &= ~(NCR_700_DEV_NEGOTIATED_SYNC |
2034 NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
2035 spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION;
2036}
2037
2038STATIC int
2039NCR_700_slave_alloc(struct scsi_device *SDp)
2040{
2041 SDp->hostdata = kzalloc(sizeof(struct NCR_700_Device_Parameters),
2042 GFP_KERNEL);
2043
2044 if (!SDp->hostdata)
2045 return -ENOMEM;
2046
2047 return 0;
2048}
2049
2050STATIC int
2051NCR_700_slave_configure(struct scsi_device *SDp)
2052{
2053 struct NCR_700_Host_Parameters *hostdata =
2054 (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
2055
2056
2057 if(SDp->tagged_supported) {
2058 scsi_change_queue_depth(SDp, NCR_700_DEFAULT_TAGS);
2059 NCR_700_set_tag_neg_state(SDp, NCR_700_START_TAG_NEGOTIATION);
2060 }
2061
2062 if(hostdata->fast) {
2063
2064 if (!spi_initial_dv(SDp->sdev_target))
2065 spi_dv_device(SDp);
2066 } else {
2067 spi_offset(SDp->sdev_target) = 0;
2068 spi_period(SDp->sdev_target) = 0;
2069 }
2070 return 0;
2071}
2072
2073STATIC void
2074NCR_700_slave_destroy(struct scsi_device *SDp)
2075{
2076 kfree(SDp->hostdata);
2077 SDp->hostdata = NULL;
2078}
2079
2080static int
2081NCR_700_change_queue_depth(struct scsi_device *SDp, int depth)
2082{
2083 if (depth > NCR_700_MAX_TAGS)
2084 depth = NCR_700_MAX_TAGS;
2085 return scsi_change_queue_depth(SDp, depth);
2086}
2087
2088static ssize_t
2089NCR_700_show_active_tags(struct device *dev, struct device_attribute *attr, char *buf)
2090{
2091 struct scsi_device *SDp = to_scsi_device(dev);
2092
2093 return snprintf(buf, 20, "%d\n", NCR_700_get_depth(SDp));
2094}
2095
2096static struct device_attribute NCR_700_active_tags_attr = {
2097 .attr = {
2098 .name = "active_tags",
2099 .mode = S_IRUGO,
2100 },
2101 .show = NCR_700_show_active_tags,
2102};
2103
2104STATIC struct device_attribute *NCR_700_dev_attrs[] = {
2105 &NCR_700_active_tags_attr,
2106 NULL,
2107};
2108
2109EXPORT_SYMBOL(NCR_700_detect);
2110EXPORT_SYMBOL(NCR_700_release);
2111EXPORT_SYMBOL(NCR_700_intr);
2112
2113static struct spi_function_template NCR_700_transport_functions = {
2114 .set_period = NCR_700_set_period,
2115 .show_period = 1,
2116 .set_offset = NCR_700_set_offset,
2117 .show_offset = 1,
2118};
2119
2120static int __init NCR_700_init(void)
2121{
2122 NCR_700_transport_template = spi_attach_transport(&NCR_700_transport_functions);
2123 if(!NCR_700_transport_template)
2124 return -ENODEV;
2125 return 0;
2126}
2127
2128static void __exit NCR_700_exit(void)
2129{
2130 spi_release_transport(NCR_700_transport_template);
2131}
2132
2133module_init(NCR_700_init);
2134module_exit(NCR_700_exit);
2135
2136