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#include "aic79xx_osm.h"
46#include "aic79xx_inline.h"
47#include <scsi/scsicam.h>
48
49static struct scsi_transport_template *ahd_linux_transport_template = NULL;
50
51#include <linux/init.h>
52#include <linux/mm.h>
53#include <linux/blkdev.h>
54#include <linux/delay.h>
55#include <linux/device.h>
56#include <linux/slab.h>
57
58
59
60
61#define AHD_LINUX_ERR_THRESH 1000
62
63
64
65
66
67
68
69#ifdef CONFIG_AIC79XX_RESET_DELAY_MS
70#define AIC79XX_RESET_DELAY CONFIG_AIC79XX_RESET_DELAY_MS
71#else
72#define AIC79XX_RESET_DELAY 5000
73#endif
74
75
76
77
78
79
80
81
82
83
84
85
86typedef struct {
87 uint16_t tag_commands[16];
88} adapter_tag_info_t;
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#ifdef CONFIG_AIC79XX_CMDS_PER_DEVICE
134#define AIC79XX_CMDS_PER_DEVICE CONFIG_AIC79XX_CMDS_PER_DEVICE
135#else
136#define AIC79XX_CMDS_PER_DEVICE AHD_MAX_QUEUE
137#endif
138
139#define AIC79XX_CONFIGED_TAG_COMMANDS { \
140 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
141 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
142 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
143 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
144 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
145 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
146 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
147 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE \
148}
149
150
151
152
153
154static adapter_tag_info_t aic79xx_tag_info[] =
155{
156 {AIC79XX_CONFIGED_TAG_COMMANDS},
157 {AIC79XX_CONFIGED_TAG_COMMANDS},
158 {AIC79XX_CONFIGED_TAG_COMMANDS},
159 {AIC79XX_CONFIGED_TAG_COMMANDS},
160 {AIC79XX_CONFIGED_TAG_COMMANDS},
161 {AIC79XX_CONFIGED_TAG_COMMANDS},
162 {AIC79XX_CONFIGED_TAG_COMMANDS},
163 {AIC79XX_CONFIGED_TAG_COMMANDS},
164 {AIC79XX_CONFIGED_TAG_COMMANDS},
165 {AIC79XX_CONFIGED_TAG_COMMANDS},
166 {AIC79XX_CONFIGED_TAG_COMMANDS},
167 {AIC79XX_CONFIGED_TAG_COMMANDS},
168 {AIC79XX_CONFIGED_TAG_COMMANDS},
169 {AIC79XX_CONFIGED_TAG_COMMANDS},
170 {AIC79XX_CONFIGED_TAG_COMMANDS},
171 {AIC79XX_CONFIGED_TAG_COMMANDS}
172};
173
174
175
176
177
178
179struct ahd_linux_iocell_opts
180{
181 uint8_t precomp;
182 uint8_t slewrate;
183 uint8_t amplitude;
184};
185#define AIC79XX_DEFAULT_PRECOMP 0xFF
186#define AIC79XX_DEFAULT_SLEWRATE 0xFF
187#define AIC79XX_DEFAULT_AMPLITUDE 0xFF
188#define AIC79XX_DEFAULT_IOOPTS \
189{ \
190 AIC79XX_DEFAULT_PRECOMP, \
191 AIC79XX_DEFAULT_SLEWRATE, \
192 AIC79XX_DEFAULT_AMPLITUDE \
193}
194#define AIC79XX_PRECOMP_INDEX 0
195#define AIC79XX_SLEWRATE_INDEX 1
196#define AIC79XX_AMPLITUDE_INDEX 2
197static const struct ahd_linux_iocell_opts aic79xx_iocell_info[] =
198{
199 AIC79XX_DEFAULT_IOOPTS,
200 AIC79XX_DEFAULT_IOOPTS,
201 AIC79XX_DEFAULT_IOOPTS,
202 AIC79XX_DEFAULT_IOOPTS,
203 AIC79XX_DEFAULT_IOOPTS,
204 AIC79XX_DEFAULT_IOOPTS,
205 AIC79XX_DEFAULT_IOOPTS,
206 AIC79XX_DEFAULT_IOOPTS,
207 AIC79XX_DEFAULT_IOOPTS,
208 AIC79XX_DEFAULT_IOOPTS,
209 AIC79XX_DEFAULT_IOOPTS,
210 AIC79XX_DEFAULT_IOOPTS,
211 AIC79XX_DEFAULT_IOOPTS,
212 AIC79XX_DEFAULT_IOOPTS,
213 AIC79XX_DEFAULT_IOOPTS,
214 AIC79XX_DEFAULT_IOOPTS
215};
216
217
218
219
220
221#define DID_UNDERFLOW DID_ERROR
222
223void
224ahd_print_path(struct ahd_softc *ahd, struct scb *scb)
225{
226 printk("(scsi%d:%c:%d:%d): ",
227 ahd->platform_data->host->host_no,
228 scb != NULL ? SCB_GET_CHANNEL(ahd, scb) : 'X',
229 scb != NULL ? SCB_GET_TARGET(ahd, scb) : -1,
230 scb != NULL ? SCB_GET_LUN(scb) : -1);
231}
232
233
234
235
236
237
238
239
240
241
242
243
244static uint32_t aic79xx_no_reset;
245
246
247
248
249
250
251static uint32_t aic79xx_extended;
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267static uint32_t aic79xx_pci_parity = ~0;
268
269
270
271
272
273
274
275uint32_t aic79xx_allow_memio = ~0;
276
277
278
279
280
281
282
283
284
285
286
287static uint32_t aic79xx_seltime;
288
289
290
291
292
293
294
295
296
297static uint32_t aic79xx_periodic_otag;
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312uint32_t aic79xx_slowcrc;
313
314
315
316
317static char *aic79xx = NULL;
318
319MODULE_AUTHOR("Maintainer: Hannes Reinecke <hare@suse.de>");
320MODULE_DESCRIPTION("Adaptec AIC790X U320 SCSI Host Bus Adapter driver");
321MODULE_LICENSE("Dual BSD/GPL");
322MODULE_VERSION(AIC79XX_DRIVER_VERSION);
323module_param(aic79xx, charp, 0444);
324MODULE_PARM_DESC(aic79xx,
325"period-delimited options string:\n"
326" verbose Enable verbose/diagnostic logging\n"
327" allow_memio Allow device registers to be memory mapped\n"
328" debug Bitmask of debug values to enable\n"
329" no_reset Suppress initial bus resets\n"
330" extended Enable extended geometry on all controllers\n"
331" periodic_otag Send an ordered tagged transaction\n"
332" periodically to prevent tag starvation.\n"
333" This may be required by some older disk\n"
334" or drives/RAID arrays.\n"
335" tag_info:<tag_str> Set per-target tag depth\n"
336" global_tag_depth:<int> Global tag depth for all targets on all buses\n"
337" slewrate:<slewrate_list>Set the signal slew rate (0-15).\n"
338" precomp:<pcomp_list> Set the signal precompensation (0-7).\n"
339" amplitude:<int> Set the signal amplitude (0-7).\n"
340" seltime:<int> Selection Timeout:\n"
341" (0/256ms,1/128ms,2/64ms,3/32ms)\n"
342" slowcrc Turn on the SLOWCRC bit (Rev B only)\n"
343"\n"
344" Sample modprobe configuration file:\n"
345" # Enable verbose logging\n"
346" # Set tag depth on Controller 2/Target 2 to 10 tags\n"
347" # Shorten the selection timeout to 128ms\n"
348"\n"
349" options aic79xx 'aic79xx=verbose.tag_info:{{}.{}.{..10}}.seltime:1'\n"
350);
351
352static void ahd_linux_handle_scsi_status(struct ahd_softc *,
353 struct scsi_device *,
354 struct scb *);
355static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd,
356 struct scsi_cmnd *cmd);
357static int ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd);
358static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd);
359static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd,
360 struct ahd_devinfo *devinfo);
361static void ahd_linux_device_queue_depth(struct scsi_device *);
362static int ahd_linux_run_command(struct ahd_softc*,
363 struct ahd_linux_device *,
364 struct scsi_cmnd *);
365static void ahd_linux_setup_tag_info_global(char *p);
366static int aic79xx_setup(char *c);
367static void ahd_freeze_simq(struct ahd_softc *ahd);
368static void ahd_release_simq(struct ahd_softc *ahd);
369
370static int ahd_linux_unit;
371
372
373
374void ahd_delay(long);
375void
376ahd_delay(long usec)
377{
378
379
380
381
382
383 while (usec > 0) {
384 udelay(usec % 1024);
385 usec -= 1024;
386 }
387}
388
389
390
391uint8_t ahd_inb(struct ahd_softc * ahd, long port);
392void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
393void ahd_outw_atomic(struct ahd_softc * ahd,
394 long port, uint16_t val);
395void ahd_outsb(struct ahd_softc * ahd, long port,
396 uint8_t *, int count);
397void ahd_insb(struct ahd_softc * ahd, long port,
398 uint8_t *, int count);
399
400uint8_t
401ahd_inb(struct ahd_softc * ahd, long port)
402{
403 uint8_t x;
404
405 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
406 x = readb(ahd->bshs[0].maddr + port);
407 } else {
408 x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
409 }
410 mb();
411 return (x);
412}
413
414#if 0
415static uint16_t
416ahd_inw_atomic(struct ahd_softc * ahd, long port)
417{
418 uint8_t x;
419
420 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
421 x = readw(ahd->bshs[0].maddr + port);
422 } else {
423 x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
424 }
425 mb();
426 return (x);
427}
428#endif
429
430void
431ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
432{
433 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
434 writeb(val, ahd->bshs[0].maddr + port);
435 } else {
436 outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
437 }
438 mb();
439}
440
441void
442ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
443{
444 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
445 writew(val, ahd->bshs[0].maddr + port);
446 } else {
447 outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
448 }
449 mb();
450}
451
452void
453ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
454{
455 int i;
456
457
458
459
460
461
462 for (i = 0; i < count; i++)
463 ahd_outb(ahd, port, *array++);
464}
465
466void
467ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
468{
469 int i;
470
471
472
473
474
475
476 for (i = 0; i < count; i++)
477 *array++ = ahd_inb(ahd, port);
478}
479
480
481uint32_t
482ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width)
483{
484 switch (width) {
485 case 1:
486 {
487 uint8_t retval;
488
489 pci_read_config_byte(pci, reg, &retval);
490 return (retval);
491 }
492 case 2:
493 {
494 uint16_t retval;
495 pci_read_config_word(pci, reg, &retval);
496 return (retval);
497 }
498 case 4:
499 {
500 uint32_t retval;
501 pci_read_config_dword(pci, reg, &retval);
502 return (retval);
503 }
504 default:
505 panic("ahd_pci_read_config: Read size too big");
506
507 return (0);
508 }
509}
510
511void
512ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width)
513{
514 switch (width) {
515 case 1:
516 pci_write_config_byte(pci, reg, value);
517 break;
518 case 2:
519 pci_write_config_word(pci, reg, value);
520 break;
521 case 4:
522 pci_write_config_dword(pci, reg, value);
523 break;
524 default:
525 panic("ahd_pci_write_config: Write size too big");
526
527 }
528}
529
530
531static void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
532
533static void
534ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
535{
536 struct scsi_cmnd *cmd;
537
538 cmd = scb->io_ctx;
539 ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
540 scsi_dma_unmap(cmd);
541}
542
543
544#define BUILD_SCSIID(ahd, cmd) \
545 (((scmd_id(cmd) << TID_SHIFT) & TID) | (ahd)->our_id)
546
547
548
549
550static const char *
551ahd_linux_info(struct Scsi_Host *host)
552{
553 static char buffer[512];
554 char ahd_info[256];
555 char *bp;
556 struct ahd_softc *ahd;
557
558 bp = &buffer[0];
559 ahd = *(struct ahd_softc **)host->hostdata;
560 memset(bp, 0, sizeof(buffer));
561 strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev " AIC79XX_DRIVER_VERSION "\n"
562 " <");
563 strcat(bp, ahd->description);
564 strcat(bp, ">\n"
565 " ");
566 ahd_controller_info(ahd, ahd_info);
567 strcat(bp, ahd_info);
568
569 return (bp);
570}
571
572
573
574
575static int
576ahd_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
577{
578 struct ahd_softc *ahd;
579 struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
580 int rtn = SCSI_MLQUEUE_HOST_BUSY;
581
582 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
583
584 cmd->scsi_done = scsi_done;
585 cmd->result = CAM_REQ_INPROG << 16;
586 rtn = ahd_linux_run_command(ahd, dev, cmd);
587
588 return rtn;
589}
590
591static DEF_SCSI_QCMD(ahd_linux_queue)
592
593static struct scsi_target **
594ahd_linux_target_in_softc(struct scsi_target *starget)
595{
596 struct ahd_softc *ahd =
597 *((struct ahd_softc **)dev_to_shost(&starget->dev)->hostdata);
598 unsigned int target_offset;
599
600 target_offset = starget->id;
601 if (starget->channel != 0)
602 target_offset += 8;
603
604 return &ahd->platform_data->starget[target_offset];
605}
606
607static int
608ahd_linux_target_alloc(struct scsi_target *starget)
609{
610 struct ahd_softc *ahd =
611 *((struct ahd_softc **)dev_to_shost(&starget->dev)->hostdata);
612 struct seeprom_config *sc = ahd->seep_config;
613 unsigned long flags;
614 struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
615 struct ahd_devinfo devinfo;
616 struct ahd_initiator_tinfo *tinfo;
617 struct ahd_tmode_tstate *tstate;
618 char channel = starget->channel + 'A';
619
620 ahd_lock(ahd, &flags);
621
622 BUG_ON(*ahd_targp != NULL);
623
624 *ahd_targp = starget;
625
626 if (sc) {
627 int flags = sc->device_flags[starget->id];
628
629 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
630 starget->id, &tstate);
631
632 if ((flags & CFPACKETIZED) == 0) {
633
634 spi_max_iu(starget) = 0;
635 } else {
636 if ((ahd->features & AHD_RTI) == 0)
637 spi_rti(starget) = 0;
638 }
639
640 if ((flags & CFQAS) == 0)
641 spi_max_qas(starget) = 0;
642
643
644 spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0;
645 spi_min_period(starget) = tinfo->user.period;
646 spi_max_offset(starget) = tinfo->user.offset;
647 }
648
649 tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
650 starget->id, &tstate);
651 ahd_compile_devinfo(&devinfo, ahd->our_id, starget->id,
652 CAM_LUN_WILDCARD, channel,
653 ROLE_INITIATOR);
654 ahd_set_syncrate(ahd, &devinfo, 0, 0, 0,
655 AHD_TRANS_GOAL, FALSE);
656 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
657 AHD_TRANS_GOAL, FALSE);
658 ahd_unlock(ahd, &flags);
659
660 return 0;
661}
662
663static void
664ahd_linux_target_destroy(struct scsi_target *starget)
665{
666 struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
667
668 *ahd_targp = NULL;
669}
670
671static int
672ahd_linux_slave_alloc(struct scsi_device *sdev)
673{
674 struct ahd_softc *ahd =
675 *((struct ahd_softc **)sdev->host->hostdata);
676 struct ahd_linux_device *dev;
677
678 if (bootverbose)
679 printk("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id);
680
681 dev = scsi_transport_device_data(sdev);
682 memset(dev, 0, sizeof(*dev));
683
684
685
686
687
688 dev->openings = 1;
689
690
691
692
693
694
695 dev->maxtags = 0;
696
697 return (0);
698}
699
700static int
701ahd_linux_slave_configure(struct scsi_device *sdev)
702{
703 struct ahd_softc *ahd;
704
705 ahd = *((struct ahd_softc **)sdev->host->hostdata);
706 if (bootverbose)
707 sdev_printk(KERN_INFO, sdev, "Slave Configure\n");
708
709 ahd_linux_device_queue_depth(sdev);
710
711
712 if (!spi_initial_dv(sdev->sdev_target))
713 spi_dv_device(sdev);
714
715 return 0;
716}
717
718#if defined(__i386__)
719
720
721
722static int
723ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
724 sector_t capacity, int geom[])
725{
726 uint8_t *bh;
727 int heads;
728 int sectors;
729 int cylinders;
730 int ret;
731 int extended;
732 struct ahd_softc *ahd;
733
734 ahd = *((struct ahd_softc **)sdev->host->hostdata);
735
736 bh = scsi_bios_ptable(bdev);
737 if (bh) {
738 ret = scsi_partsize(bh, capacity,
739 &geom[2], &geom[0], &geom[1]);
740 kfree(bh);
741 if (ret != -1)
742 return (ret);
743 }
744 heads = 64;
745 sectors = 32;
746 cylinders = aic_sector_div(capacity, heads, sectors);
747
748 if (aic79xx_extended != 0)
749 extended = 1;
750 else
751 extended = (ahd->flags & AHD_EXTENDED_TRANS_A) != 0;
752 if (extended && cylinders >= 1024) {
753 heads = 255;
754 sectors = 63;
755 cylinders = aic_sector_div(capacity, heads, sectors);
756 }
757 geom[0] = heads;
758 geom[1] = sectors;
759 geom[2] = cylinders;
760 return (0);
761}
762#endif
763
764
765
766
767static int
768ahd_linux_abort(struct scsi_cmnd *cmd)
769{
770 int error;
771
772 error = ahd_linux_queue_abort_cmd(cmd);
773
774 return error;
775}
776
777
778
779
780static int
781ahd_linux_dev_reset(struct scsi_cmnd *cmd)
782{
783 struct ahd_softc *ahd;
784 struct ahd_linux_device *dev;
785 struct scb *reset_scb;
786 u_int cdb_byte;
787 int retval = SUCCESS;
788 int paused;
789 int wait;
790 struct ahd_initiator_tinfo *tinfo;
791 struct ahd_tmode_tstate *tstate;
792 unsigned long flags;
793 DECLARE_COMPLETION_ONSTACK(done);
794
795 reset_scb = NULL;
796 paused = FALSE;
797 wait = FALSE;
798 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
799
800 scmd_printk(KERN_INFO, cmd,
801 "Attempting to queue a TARGET RESET message:");
802
803 printk("CDB:");
804 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
805 printk(" 0x%x", cmd->cmnd[cdb_byte]);
806 printk("\n");
807
808
809
810
811 dev = scsi_transport_device_data(cmd->device);
812
813 if (dev == NULL) {
814
815
816
817
818 scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
819 return SUCCESS;
820 }
821
822
823
824
825 reset_scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX);
826 if (!reset_scb) {
827 scmd_printk(KERN_INFO, cmd, "No SCB available\n");
828 return FAILED;
829 }
830
831 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
832 cmd->device->id, &tstate);
833 reset_scb->io_ctx = cmd;
834 reset_scb->platform_data->dev = dev;
835 reset_scb->sg_count = 0;
836 ahd_set_residual(reset_scb, 0);
837 ahd_set_sense_residual(reset_scb, 0);
838 reset_scb->platform_data->xfer_len = 0;
839 reset_scb->hscb->control = 0;
840 reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd);
841 reset_scb->hscb->lun = cmd->device->lun;
842 reset_scb->hscb->cdb_len = 0;
843 reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET;
844 reset_scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE;
845 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
846 reset_scb->flags |= SCB_PACKETIZED;
847 } else {
848 reset_scb->hscb->control |= MK_MESSAGE;
849 }
850 dev->openings--;
851 dev->active++;
852 dev->commands_issued++;
853
854 ahd_lock(ahd, &flags);
855
856 LIST_INSERT_HEAD(&ahd->pending_scbs, reset_scb, pending_links);
857 ahd_queue_scb(ahd, reset_scb);
858
859 ahd->platform_data->eh_done = &done;
860 ahd_unlock(ahd, &flags);
861
862 printk("%s: Device reset code sleeping\n", ahd_name(ahd));
863 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
864 ahd_lock(ahd, &flags);
865 ahd->platform_data->eh_done = NULL;
866 ahd_unlock(ahd, &flags);
867 printk("%s: Device reset timer expired (active %d)\n",
868 ahd_name(ahd), dev->active);
869 retval = FAILED;
870 }
871 printk("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
872
873 return (retval);
874}
875
876
877
878
879static int
880ahd_linux_bus_reset(struct scsi_cmnd *cmd)
881{
882 struct ahd_softc *ahd;
883 int found;
884 unsigned long flags;
885
886 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
887#ifdef AHD_DEBUG
888 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
889 printk("%s: Bus reset called for cmd %p\n",
890 ahd_name(ahd), cmd);
891#endif
892 ahd_lock(ahd, &flags);
893
894 found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A',
895 TRUE);
896 ahd_unlock(ahd, &flags);
897
898 if (bootverbose)
899 printk("%s: SCSI bus reset delivered. "
900 "%d SCBs aborted.\n", ahd_name(ahd), found);
901
902 return (SUCCESS);
903}
904
905struct scsi_host_template aic79xx_driver_template = {
906 .module = THIS_MODULE,
907 .name = "aic79xx",
908 .proc_name = "aic79xx",
909 .show_info = ahd_linux_show_info,
910 .write_info = ahd_proc_write_seeprom,
911 .info = ahd_linux_info,
912 .queuecommand = ahd_linux_queue,
913 .eh_abort_handler = ahd_linux_abort,
914 .eh_device_reset_handler = ahd_linux_dev_reset,
915 .eh_bus_reset_handler = ahd_linux_bus_reset,
916#if defined(__i386__)
917 .bios_param = ahd_linux_biosparam,
918#endif
919 .can_queue = AHD_MAX_QUEUE,
920 .this_id = -1,
921 .max_sectors = 8192,
922 .cmd_per_lun = 2,
923 .use_clustering = ENABLE_CLUSTERING,
924 .slave_alloc = ahd_linux_slave_alloc,
925 .slave_configure = ahd_linux_slave_configure,
926 .target_alloc = ahd_linux_target_alloc,
927 .target_destroy = ahd_linux_target_destroy,
928};
929
930
931int
932ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent,
933 bus_size_t alignment, bus_size_t boundary,
934 dma_addr_t lowaddr, dma_addr_t highaddr,
935 bus_dma_filter_t *filter, void *filterarg,
936 bus_size_t maxsize, int nsegments,
937 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
938{
939 bus_dma_tag_t dmat;
940
941 dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC);
942 if (dmat == NULL)
943 return (ENOMEM);
944
945
946
947
948
949
950
951
952 dmat->alignment = alignment;
953 dmat->boundary = boundary;
954 dmat->maxsize = maxsize;
955 *ret_tag = dmat;
956 return (0);
957}
958
959void
960ahd_dma_tag_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat)
961{
962 kfree(dmat);
963}
964
965int
966ahd_dmamem_alloc(struct ahd_softc *ahd, bus_dma_tag_t dmat, void** vaddr,
967 int flags, bus_dmamap_t *mapp)
968{
969 *vaddr = pci_alloc_consistent(ahd->dev_softc,
970 dmat->maxsize, mapp);
971 if (*vaddr == NULL)
972 return (ENOMEM);
973 return(0);
974}
975
976void
977ahd_dmamem_free(struct ahd_softc *ahd, bus_dma_tag_t dmat,
978 void* vaddr, bus_dmamap_t map)
979{
980 pci_free_consistent(ahd->dev_softc, dmat->maxsize,
981 vaddr, map);
982}
983
984int
985ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map,
986 void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
987 void *cb_arg, int flags)
988{
989
990
991
992
993 bus_dma_segment_t stack_sg;
994
995 stack_sg.ds_addr = map;
996 stack_sg.ds_len = dmat->maxsize;
997 cb(cb_arg, &stack_sg, 1, 0);
998 return (0);
999}
1000
1001void
1002ahd_dmamap_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
1003{
1004}
1005
1006int
1007ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
1008{
1009
1010 return (0);
1011}
1012
1013
1014static void
1015ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value)
1016{
1017
1018 if ((instance >= 0)
1019 && (instance < ARRAY_SIZE(aic79xx_iocell_info))) {
1020 uint8_t *iocell_info;
1021
1022 iocell_info = (uint8_t*)&aic79xx_iocell_info[instance];
1023 iocell_info[index] = value & 0xFFFF;
1024 if (bootverbose)
1025 printk("iocell[%d:%ld] = %d\n", instance, index, value);
1026 }
1027}
1028
1029static void
1030ahd_linux_setup_tag_info_global(char *p)
1031{
1032 int tags, i, j;
1033
1034 tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
1035 printk("Setting Global Tags= %d\n", tags);
1036
1037 for (i = 0; i < ARRAY_SIZE(aic79xx_tag_info); i++) {
1038 for (j = 0; j < AHD_NUM_TARGETS; j++) {
1039 aic79xx_tag_info[i].tag_commands[j] = tags;
1040 }
1041 }
1042}
1043
1044static void
1045ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
1046{
1047
1048 if ((instance >= 0) && (targ >= 0)
1049 && (instance < ARRAY_SIZE(aic79xx_tag_info))
1050 && (targ < AHD_NUM_TARGETS)) {
1051 aic79xx_tag_info[instance].tag_commands[targ] = value & 0x1FF;
1052 if (bootverbose)
1053 printk("tag_info[%d:%d] = %d\n", instance, targ, value);
1054 }
1055}
1056
1057static char *
1058ahd_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
1059 void (*callback)(u_long, int, int, int32_t),
1060 u_long callback_arg)
1061{
1062 char *tok_end;
1063 char *tok_end2;
1064 int i;
1065 int instance;
1066 int targ;
1067 int done;
1068 char tok_list[] = {'.', ',', '{', '}', '\0'};
1069
1070
1071 if (*opt_arg != ':')
1072 return (opt_arg);
1073 opt_arg++;
1074 instance = -1;
1075 targ = -1;
1076 done = FALSE;
1077
1078
1079
1080
1081 tok_end = strchr(opt_arg, '\0');
1082 if (tok_end < end)
1083 *tok_end = ',';
1084 while (!done) {
1085 switch (*opt_arg) {
1086 case '{':
1087 if (instance == -1) {
1088 instance = 0;
1089 } else {
1090 if (depth > 1) {
1091 if (targ == -1)
1092 targ = 0;
1093 } else {
1094 printk("Malformed Option %s\n",
1095 opt_name);
1096 done = TRUE;
1097 }
1098 }
1099 opt_arg++;
1100 break;
1101 case '}':
1102 if (targ != -1)
1103 targ = -1;
1104 else if (instance != -1)
1105 instance = -1;
1106 opt_arg++;
1107 break;
1108 case ',':
1109 case '.':
1110 if (instance == -1)
1111 done = TRUE;
1112 else if (targ >= 0)
1113 targ++;
1114 else if (instance >= 0)
1115 instance++;
1116 opt_arg++;
1117 break;
1118 case '\0':
1119 done = TRUE;
1120 break;
1121 default:
1122 tok_end = end;
1123 for (i = 0; tok_list[i]; i++) {
1124 tok_end2 = strchr(opt_arg, tok_list[i]);
1125 if ((tok_end2) && (tok_end2 < tok_end))
1126 tok_end = tok_end2;
1127 }
1128 callback(callback_arg, instance, targ,
1129 simple_strtol(opt_arg, NULL, 0));
1130 opt_arg = tok_end;
1131 break;
1132 }
1133 }
1134 return (opt_arg);
1135}
1136
1137
1138
1139
1140
1141
1142static int
1143aic79xx_setup(char *s)
1144{
1145 int i, n;
1146 char *p;
1147 char *end;
1148
1149 static const struct {
1150 const char *name;
1151 uint32_t *flag;
1152 } options[] = {
1153 { "extended", &aic79xx_extended },
1154 { "no_reset", &aic79xx_no_reset },
1155 { "verbose", &aic79xx_verbose },
1156 { "allow_memio", &aic79xx_allow_memio},
1157#ifdef AHD_DEBUG
1158 { "debug", &ahd_debug },
1159#endif
1160 { "periodic_otag", &aic79xx_periodic_otag },
1161 { "pci_parity", &aic79xx_pci_parity },
1162 { "seltime", &aic79xx_seltime },
1163 { "tag_info", NULL },
1164 { "global_tag_depth", NULL},
1165 { "slewrate", NULL },
1166 { "precomp", NULL },
1167 { "amplitude", NULL },
1168 { "slowcrc", &aic79xx_slowcrc },
1169 };
1170
1171 end = strchr(s, '\0');
1172
1173
1174
1175
1176
1177 n = 0;
1178
1179 while ((p = strsep(&s, ",.")) != NULL) {
1180 if (*p == '\0')
1181 continue;
1182 for (i = 0; i < ARRAY_SIZE(options); i++) {
1183
1184 n = strlen(options[i].name);
1185 if (strncmp(options[i].name, p, n) == 0)
1186 break;
1187 }
1188 if (i == ARRAY_SIZE(options))
1189 continue;
1190
1191 if (strncmp(p, "global_tag_depth", n) == 0) {
1192 ahd_linux_setup_tag_info_global(p + n);
1193 } else if (strncmp(p, "tag_info", n) == 0) {
1194 s = ahd_parse_brace_option("tag_info", p + n, end,
1195 2, ahd_linux_setup_tag_info, 0);
1196 } else if (strncmp(p, "slewrate", n) == 0) {
1197 s = ahd_parse_brace_option("slewrate",
1198 p + n, end, 1, ahd_linux_setup_iocell_info,
1199 AIC79XX_SLEWRATE_INDEX);
1200 } else if (strncmp(p, "precomp", n) == 0) {
1201 s = ahd_parse_brace_option("precomp",
1202 p + n, end, 1, ahd_linux_setup_iocell_info,
1203 AIC79XX_PRECOMP_INDEX);
1204 } else if (strncmp(p, "amplitude", n) == 0) {
1205 s = ahd_parse_brace_option("amplitude",
1206 p + n, end, 1, ahd_linux_setup_iocell_info,
1207 AIC79XX_AMPLITUDE_INDEX);
1208 } else if (p[n] == ':') {
1209 *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
1210 } else if (!strncmp(p, "verbose", n)) {
1211 *(options[i].flag) = 1;
1212 } else {
1213 *(options[i].flag) ^= 0xFFFFFFFF;
1214 }
1215 }
1216 return 1;
1217}
1218
1219__setup("aic79xx=", aic79xx_setup);
1220
1221uint32_t aic79xx_verbose;
1222
1223int
1224ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *template)
1225{
1226 char buf[80];
1227 struct Scsi_Host *host;
1228 char *new_name;
1229 u_long s;
1230 int retval;
1231
1232 template->name = ahd->description;
1233 host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
1234 if (host == NULL)
1235 return (ENOMEM);
1236
1237 *((struct ahd_softc **)host->hostdata) = ahd;
1238 ahd->platform_data->host = host;
1239 host->can_queue = AHD_MAX_QUEUE;
1240 host->cmd_per_lun = 2;
1241 host->sg_tablesize = AHD_NSEG;
1242 host->this_id = ahd->our_id;
1243 host->irq = ahd->platform_data->irq;
1244 host->max_id = (ahd->features & AHD_WIDE) ? 16 : 8;
1245 host->max_lun = AHD_NUM_LUNS;
1246 host->max_channel = 0;
1247 host->sg_tablesize = AHD_NSEG;
1248 ahd_lock(ahd, &s);
1249 ahd_set_unit(ahd, ahd_linux_unit++);
1250 ahd_unlock(ahd, &s);
1251 sprintf(buf, "scsi%d", host->host_no);
1252 new_name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
1253 if (new_name != NULL) {
1254 strcpy(new_name, buf);
1255 ahd_set_name(ahd, new_name);
1256 }
1257 host->unique_id = ahd->unit;
1258 ahd_linux_initialize_scsi_bus(ahd);
1259 ahd_intr_enable(ahd, TRUE);
1260
1261 host->transportt = ahd_linux_transport_template;
1262
1263 retval = scsi_add_host(host, &ahd->dev_softc->dev);
1264 if (retval) {
1265 printk(KERN_WARNING "aic79xx: scsi_add_host failed\n");
1266 scsi_host_put(host);
1267 return retval;
1268 }
1269
1270 scsi_scan_host(host);
1271 return 0;
1272}
1273
1274
1275
1276
1277
1278
1279static void
1280ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd)
1281{
1282 u_int target_id;
1283 u_int numtarg;
1284 unsigned long s;
1285
1286 target_id = 0;
1287 numtarg = 0;
1288
1289 if (aic79xx_no_reset != 0)
1290 ahd->flags &= ~AHD_RESET_BUS_A;
1291
1292 if ((ahd->flags & AHD_RESET_BUS_A) != 0)
1293 ahd_reset_channel(ahd, 'A', TRUE);
1294 else
1295 numtarg = (ahd->features & AHD_WIDE) ? 16 : 8;
1296
1297 ahd_lock(ahd, &s);
1298
1299
1300
1301
1302
1303 for (; target_id < numtarg; target_id++) {
1304 struct ahd_devinfo devinfo;
1305 struct ahd_initiator_tinfo *tinfo;
1306 struct ahd_tmode_tstate *tstate;
1307
1308 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
1309 target_id, &tstate);
1310 ahd_compile_devinfo(&devinfo, ahd->our_id, target_id,
1311 CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR);
1312 ahd_update_neg_request(ahd, &devinfo, tstate,
1313 tinfo, AHD_NEG_ALWAYS);
1314 }
1315 ahd_unlock(ahd, &s);
1316
1317 if ((ahd->flags & AHD_RESET_BUS_A) != 0) {
1318 ahd_freeze_simq(ahd);
1319 msleep(AIC79XX_RESET_DELAY);
1320 ahd_release_simq(ahd);
1321 }
1322}
1323
1324int
1325ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg)
1326{
1327 ahd->platform_data =
1328 kzalloc(sizeof(struct ahd_platform_data), GFP_ATOMIC);
1329 if (ahd->platform_data == NULL)
1330 return (ENOMEM);
1331 ahd->platform_data->irq = AHD_LINUX_NOIRQ;
1332 ahd_lockinit(ahd);
1333 ahd->seltime = (aic79xx_seltime & 0x3) << 4;
1334 return (0);
1335}
1336
1337void
1338ahd_platform_free(struct ahd_softc *ahd)
1339{
1340 struct scsi_target *starget;
1341 int i;
1342
1343 if (ahd->platform_data != NULL) {
1344
1345 for (i = 0; i < AHD_NUM_TARGETS; i++) {
1346 starget = ahd->platform_data->starget[i];
1347 if (starget != NULL) {
1348 ahd->platform_data->starget[i] = NULL;
1349 }
1350 }
1351
1352 if (ahd->platform_data->irq != AHD_LINUX_NOIRQ)
1353 free_irq(ahd->platform_data->irq, ahd);
1354 if (ahd->tags[0] == BUS_SPACE_PIO
1355 && ahd->bshs[0].ioport != 0)
1356 release_region(ahd->bshs[0].ioport, 256);
1357 if (ahd->tags[1] == BUS_SPACE_PIO
1358 && ahd->bshs[1].ioport != 0)
1359 release_region(ahd->bshs[1].ioport, 256);
1360 if (ahd->tags[0] == BUS_SPACE_MEMIO
1361 && ahd->bshs[0].maddr != NULL) {
1362 iounmap(ahd->bshs[0].maddr);
1363 release_mem_region(ahd->platform_data->mem_busaddr,
1364 0x1000);
1365 }
1366 if (ahd->platform_data->host)
1367 scsi_host_put(ahd->platform_data->host);
1368
1369 kfree(ahd->platform_data);
1370 }
1371}
1372
1373void
1374ahd_platform_init(struct ahd_softc *ahd)
1375{
1376
1377
1378
1379 if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
1380 const struct ahd_linux_iocell_opts *iocell_opts;
1381
1382 iocell_opts = &aic79xx_iocell_info[ahd->unit];
1383 if (iocell_opts->precomp != AIC79XX_DEFAULT_PRECOMP)
1384 AHD_SET_PRECOMP(ahd, iocell_opts->precomp);
1385 if (iocell_opts->slewrate != AIC79XX_DEFAULT_SLEWRATE)
1386 AHD_SET_SLEWRATE(ahd, iocell_opts->slewrate);
1387 if (iocell_opts->amplitude != AIC79XX_DEFAULT_AMPLITUDE)
1388 AHD_SET_AMPLITUDE(ahd, iocell_opts->amplitude);
1389 }
1390
1391}
1392
1393void
1394ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
1395{
1396 ahd_platform_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
1397 SCB_GET_CHANNEL(ahd, scb),
1398 SCB_GET_LUN(scb), SCB_LIST_NULL,
1399 ROLE_UNKNOWN, CAM_REQUEUE_REQ);
1400}
1401
1402void
1403ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
1404 struct ahd_devinfo *devinfo, ahd_queue_alg alg)
1405{
1406 struct ahd_linux_device *dev;
1407 int was_queuing;
1408 int now_queuing;
1409
1410 if (sdev == NULL)
1411 return;
1412
1413 dev = scsi_transport_device_data(sdev);
1414
1415 if (dev == NULL)
1416 return;
1417 was_queuing = dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED);
1418 switch (alg) {
1419 default:
1420 case AHD_QUEUE_NONE:
1421 now_queuing = 0;
1422 break;
1423 case AHD_QUEUE_BASIC:
1424 now_queuing = AHD_DEV_Q_BASIC;
1425 break;
1426 case AHD_QUEUE_TAGGED:
1427 now_queuing = AHD_DEV_Q_TAGGED;
1428 break;
1429 }
1430 if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) == 0
1431 && (was_queuing != now_queuing)
1432 && (dev->active != 0)) {
1433 dev->flags |= AHD_DEV_FREEZE_TIL_EMPTY;
1434 dev->qfrozen++;
1435 }
1436
1437 dev->flags &= ~(AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED|AHD_DEV_PERIODIC_OTAG);
1438 if (now_queuing) {
1439 u_int usertags;
1440
1441 usertags = ahd_linux_user_tagdepth(ahd, devinfo);
1442 if (!was_queuing) {
1443
1444
1445
1446
1447
1448 dev->maxtags = usertags;
1449 dev->openings = dev->maxtags - dev->active;
1450 }
1451 if (dev->maxtags == 0) {
1452
1453
1454
1455 dev->openings = 1;
1456 } else if (alg == AHD_QUEUE_TAGGED) {
1457 dev->flags |= AHD_DEV_Q_TAGGED;
1458 if (aic79xx_periodic_otag != 0)
1459 dev->flags |= AHD_DEV_PERIODIC_OTAG;
1460 } else
1461 dev->flags |= AHD_DEV_Q_BASIC;
1462 } else {
1463
1464 dev->maxtags = 0;
1465 dev->openings = 1 - dev->active;
1466 }
1467
1468 switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) {
1469 case AHD_DEV_Q_BASIC:
1470 case AHD_DEV_Q_TAGGED:
1471 scsi_change_queue_depth(sdev,
1472 dev->openings + dev->active);
1473 break;
1474 default:
1475
1476
1477
1478
1479
1480
1481 scsi_change_queue_depth(sdev, 1);
1482 break;
1483 }
1484}
1485
1486int
1487ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel,
1488 int lun, u_int tag, role_t role, uint32_t status)
1489{
1490 return 0;
1491}
1492
1493static u_int
1494ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
1495{
1496 static int warned_user;
1497 u_int tags;
1498
1499 tags = 0;
1500 if ((ahd->user_discenable & devinfo->target_mask) != 0) {
1501 if (ahd->unit >= ARRAY_SIZE(aic79xx_tag_info)) {
1502
1503 if (warned_user == 0) {
1504 printk(KERN_WARNING
1505"aic79xx: WARNING: Insufficient tag_info instances\n"
1506"aic79xx: for installed controllers. Using defaults\n"
1507"aic79xx: Please update the aic79xx_tag_info array in\n"
1508"aic79xx: the aic79xx_osm.c source file.\n");
1509 warned_user++;
1510 }
1511 tags = AHD_MAX_QUEUE;
1512 } else {
1513 adapter_tag_info_t *tag_info;
1514
1515 tag_info = &aic79xx_tag_info[ahd->unit];
1516 tags = tag_info->tag_commands[devinfo->target_offset];
1517 if (tags > AHD_MAX_QUEUE)
1518 tags = AHD_MAX_QUEUE;
1519 }
1520 }
1521 return (tags);
1522}
1523
1524
1525
1526
1527static void
1528ahd_linux_device_queue_depth(struct scsi_device *sdev)
1529{
1530 struct ahd_devinfo devinfo;
1531 u_int tags;
1532 struct ahd_softc *ahd = *((struct ahd_softc **)sdev->host->hostdata);
1533
1534 ahd_compile_devinfo(&devinfo,
1535 ahd->our_id,
1536 sdev->sdev_target->id, sdev->lun,
1537 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1538 ROLE_INITIATOR);
1539 tags = ahd_linux_user_tagdepth(ahd, &devinfo);
1540 if (tags != 0 && sdev->tagged_supported != 0) {
1541
1542 ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_TAGGED);
1543 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1544 devinfo.lun, AC_TRANSFER_NEG);
1545 ahd_print_devinfo(ahd, &devinfo);
1546 printk("Tagged Queuing enabled. Depth %d\n", tags);
1547 } else {
1548 ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE);
1549 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1550 devinfo.lun, AC_TRANSFER_NEG);
1551 }
1552}
1553
1554static int
1555ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
1556 struct scsi_cmnd *cmd)
1557{
1558 struct scb *scb;
1559 struct hardware_scb *hscb;
1560 struct ahd_initiator_tinfo *tinfo;
1561 struct ahd_tmode_tstate *tstate;
1562 u_int col_idx;
1563 uint16_t mask;
1564 unsigned long flags;
1565 int nseg;
1566
1567 nseg = scsi_dma_map(cmd);
1568 if (nseg < 0)
1569 return SCSI_MLQUEUE_HOST_BUSY;
1570
1571 ahd_lock(ahd, &flags);
1572
1573
1574
1575
1576 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
1577 cmd->device->id, &tstate);
1578 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0
1579 || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
1580 col_idx = AHD_NEVER_COL_IDX;
1581 } else {
1582 col_idx = AHD_BUILD_COL_IDX(cmd->device->id,
1583 cmd->device->lun);
1584 }
1585 if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
1586 ahd->flags |= AHD_RESOURCE_SHORTAGE;
1587 ahd_unlock(ahd, &flags);
1588 scsi_dma_unmap(cmd);
1589 return SCSI_MLQUEUE_HOST_BUSY;
1590 }
1591
1592 scb->io_ctx = cmd;
1593 scb->platform_data->dev = dev;
1594 hscb = scb->hscb;
1595 cmd->host_scribble = (char *)scb;
1596
1597
1598
1599
1600 hscb->control = 0;
1601 hscb->scsiid = BUILD_SCSIID(ahd, cmd);
1602 hscb->lun = cmd->device->lun;
1603 scb->hscb->task_management = 0;
1604 mask = SCB_GET_TARGET_MASK(ahd, scb);
1605
1606 if ((ahd->user_discenable & mask) != 0)
1607 hscb->control |= DISCENB;
1608
1609 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0)
1610 scb->flags |= SCB_PACKETIZED;
1611
1612 if ((tstate->auto_negotiate & mask) != 0) {
1613 scb->flags |= SCB_AUTO_NEGOTIATE;
1614 scb->hscb->control |= MK_MESSAGE;
1615 }
1616
1617 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
1618 if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH
1619 && (dev->flags & AHD_DEV_Q_TAGGED) != 0) {
1620 hscb->control |= MSG_ORDERED_TASK;
1621 dev->commands_since_idle_or_otag = 0;
1622 } else {
1623 hscb->control |= MSG_SIMPLE_TASK;
1624 }
1625 }
1626
1627 hscb->cdb_len = cmd->cmd_len;
1628 memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len);
1629
1630 scb->platform_data->xfer_len = 0;
1631 ahd_set_residual(scb, 0);
1632 ahd_set_sense_residual(scb, 0);
1633 scb->sg_count = 0;
1634
1635 if (nseg > 0) {
1636 void *sg = scb->sg_list;
1637 struct scatterlist *cur_seg;
1638 int i;
1639
1640 scb->platform_data->xfer_len = 0;
1641
1642 scsi_for_each_sg(cmd, cur_seg, nseg, i) {
1643 dma_addr_t addr;
1644 bus_size_t len;
1645
1646 addr = sg_dma_address(cur_seg);
1647 len = sg_dma_len(cur_seg);
1648 scb->platform_data->xfer_len += len;
1649 sg = ahd_sg_setup(ahd, scb, sg, addr, len,
1650 i == (nseg - 1));
1651 }
1652 }
1653
1654 LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
1655 dev->openings--;
1656 dev->active++;
1657 dev->commands_issued++;
1658
1659 if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0)
1660 dev->commands_since_idle_or_otag++;
1661 scb->flags |= SCB_ACTIVE;
1662 ahd_queue_scb(ahd, scb);
1663
1664 ahd_unlock(ahd, &flags);
1665
1666 return 0;
1667}
1668
1669
1670
1671
1672irqreturn_t
1673ahd_linux_isr(int irq, void *dev_id)
1674{
1675 struct ahd_softc *ahd;
1676 u_long flags;
1677 int ours;
1678
1679 ahd = (struct ahd_softc *) dev_id;
1680 ahd_lock(ahd, &flags);
1681 ours = ahd_intr(ahd);
1682 ahd_unlock(ahd, &flags);
1683 return IRQ_RETVAL(ours);
1684}
1685
1686void
1687ahd_send_async(struct ahd_softc *ahd, char channel,
1688 u_int target, u_int lun, ac_code code)
1689{
1690 switch (code) {
1691 case AC_TRANSFER_NEG:
1692 {
1693 struct scsi_target *starget;
1694 struct ahd_initiator_tinfo *tinfo;
1695 struct ahd_tmode_tstate *tstate;
1696 unsigned int target_ppr_options;
1697
1698 BUG_ON(target == CAM_TARGET_WILDCARD);
1699
1700 tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
1701 target, &tstate);
1702
1703
1704
1705
1706
1707 if (tinfo->curr.period != tinfo->goal.period
1708 || tinfo->curr.width != tinfo->goal.width
1709 || tinfo->curr.offset != tinfo->goal.offset
1710 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
1711 if (bootverbose == 0)
1712 break;
1713
1714
1715
1716
1717
1718 starget = ahd->platform_data->starget[target];
1719 if (starget == NULL)
1720 break;
1721
1722 target_ppr_options =
1723 (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
1724 + (spi_qas(starget) ? MSG_EXT_PPR_QAS_REQ : 0)
1725 + (spi_iu(starget) ? MSG_EXT_PPR_IU_REQ : 0)
1726 + (spi_rd_strm(starget) ? MSG_EXT_PPR_RD_STRM : 0)
1727 + (spi_pcomp_en(starget) ? MSG_EXT_PPR_PCOMP_EN : 0)
1728 + (spi_rti(starget) ? MSG_EXT_PPR_RTI : 0)
1729 + (spi_wr_flow(starget) ? MSG_EXT_PPR_WR_FLOW : 0)
1730 + (spi_hold_mcs(starget) ? MSG_EXT_PPR_HOLD_MCS : 0);
1731
1732 if (tinfo->curr.period == spi_period(starget)
1733 && tinfo->curr.width == spi_width(starget)
1734 && tinfo->curr.offset == spi_offset(starget)
1735 && tinfo->curr.ppr_options == target_ppr_options)
1736 if (bootverbose == 0)
1737 break;
1738
1739 spi_period(starget) = tinfo->curr.period;
1740 spi_width(starget) = tinfo->curr.width;
1741 spi_offset(starget) = tinfo->curr.offset;
1742 spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
1743 spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
1744 spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
1745 spi_rd_strm(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_RD_STRM ? 1 : 0;
1746 spi_pcomp_en(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_PCOMP_EN ? 1 : 0;
1747 spi_rti(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_RTI ? 1 : 0;
1748 spi_wr_flow(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_WR_FLOW ? 1 : 0;
1749 spi_hold_mcs(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_HOLD_MCS ? 1 : 0;
1750 spi_display_xfer_agreement(starget);
1751 break;
1752 }
1753 case AC_SENT_BDR:
1754 {
1755 WARN_ON(lun != CAM_LUN_WILDCARD);
1756 scsi_report_device_reset(ahd->platform_data->host,
1757 channel - 'A', target);
1758 break;
1759 }
1760 case AC_BUS_RESET:
1761 if (ahd->platform_data->host != NULL) {
1762 scsi_report_bus_reset(ahd->platform_data->host,
1763 channel - 'A');
1764 }
1765 break;
1766 default:
1767 panic("ahd_send_async: Unexpected async event");
1768 }
1769}
1770
1771
1772
1773
1774void
1775ahd_done(struct ahd_softc *ahd, struct scb *scb)
1776{
1777 struct scsi_cmnd *cmd;
1778 struct ahd_linux_device *dev;
1779
1780 if ((scb->flags & SCB_ACTIVE) == 0) {
1781 printk("SCB %d done'd twice\n", SCB_GET_TAG(scb));
1782 ahd_dump_card_state(ahd);
1783 panic("Stopping for safety");
1784 }
1785 LIST_REMOVE(scb, pending_links);
1786 cmd = scb->io_ctx;
1787 dev = scb->platform_data->dev;
1788 dev->active--;
1789 dev->openings++;
1790 if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
1791 cmd->result &= ~(CAM_DEV_QFRZN << 16);
1792 dev->qfrozen--;
1793 }
1794 ahd_linux_unmap_scb(ahd, scb);
1795
1796
1797
1798
1799
1800
1801
1802 cmd->sense_buffer[0] = 0;
1803 if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) {
1804 uint32_t amount_xferred;
1805
1806 amount_xferred =
1807 ahd_get_transfer_length(scb) - ahd_get_residual(scb);
1808 if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
1809#ifdef AHD_DEBUG
1810 if ((ahd_debug & AHD_SHOW_MISC) != 0) {
1811 ahd_print_path(ahd, scb);
1812 printk("Set CAM_UNCOR_PARITY\n");
1813 }
1814#endif
1815 ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
1816#ifdef AHD_REPORT_UNDERFLOWS
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826 } else if (amount_xferred < scb->io_ctx->underflow) {
1827 u_int i;
1828
1829 ahd_print_path(ahd, scb);
1830 printk("CDB:");
1831 for (i = 0; i < scb->io_ctx->cmd_len; i++)
1832 printk(" 0x%x", scb->io_ctx->cmnd[i]);
1833 printk("\n");
1834 ahd_print_path(ahd, scb);
1835 printk("Saw underflow (%ld of %ld bytes). "
1836 "Treated as error\n",
1837 ahd_get_residual(scb),
1838 ahd_get_transfer_length(scb));
1839 ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1840#endif
1841 } else {
1842 ahd_set_transaction_status(scb, CAM_REQ_CMP);
1843 }
1844 } else if (ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
1845 ahd_linux_handle_scsi_status(ahd, cmd->device, scb);
1846 }
1847
1848 if (dev->openings == 1
1849 && ahd_get_transaction_status(scb) == CAM_REQ_CMP
1850 && ahd_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
1851 dev->tag_success_count++;
1852
1853
1854
1855
1856
1857
1858 if ((dev->openings + dev->active) < dev->maxtags
1859 && dev->tag_success_count > AHD_TAG_SUCCESS_INTERVAL) {
1860 dev->tag_success_count = 0;
1861 dev->openings++;
1862 }
1863
1864 if (dev->active == 0)
1865 dev->commands_since_idle_or_otag = 0;
1866
1867 if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
1868 printk("Recovery SCB completes\n");
1869 if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
1870 || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
1871 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
1872
1873 if (ahd->platform_data->eh_done)
1874 complete(ahd->platform_data->eh_done);
1875 }
1876
1877 ahd_free_scb(ahd, scb);
1878 ahd_linux_queue_cmd_complete(ahd, cmd);
1879}
1880
1881static void
1882ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
1883 struct scsi_device *sdev, struct scb *scb)
1884{
1885 struct ahd_devinfo devinfo;
1886 struct ahd_linux_device *dev = scsi_transport_device_data(sdev);
1887
1888 ahd_compile_devinfo(&devinfo,
1889 ahd->our_id,
1890 sdev->sdev_target->id, sdev->lun,
1891 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1892 ROLE_INITIATOR);
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904 switch (ahd_get_scsi_status(scb)) {
1905 default:
1906 break;
1907 case SCSI_STATUS_CHECK_COND:
1908 case SCSI_STATUS_CMD_TERMINATED:
1909 {
1910 struct scsi_cmnd *cmd;
1911
1912
1913
1914
1915
1916 cmd = scb->io_ctx;
1917 if ((scb->flags & (SCB_SENSE|SCB_PKT_SENSE)) != 0) {
1918 struct scsi_status_iu_header *siu;
1919 u_int sense_size;
1920 u_int sense_offset;
1921
1922 if (scb->flags & SCB_SENSE) {
1923 sense_size = min(sizeof(struct scsi_sense_data)
1924 - ahd_get_sense_residual(scb),
1925 (u_long)SCSI_SENSE_BUFFERSIZE);
1926 sense_offset = 0;
1927 } else {
1928
1929
1930
1931
1932 siu = (struct scsi_status_iu_header *)
1933 scb->sense_data;
1934 sense_size = min_t(size_t,
1935 scsi_4btoul(siu->sense_length),
1936 SCSI_SENSE_BUFFERSIZE);
1937 sense_offset = SIU_SENSE_OFFSET(siu);
1938 }
1939
1940 memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
1941 memcpy(cmd->sense_buffer,
1942 ahd_get_sense_buf(ahd, scb)
1943 + sense_offset, sense_size);
1944 cmd->result |= (DRIVER_SENSE << 24);
1945
1946#ifdef AHD_DEBUG
1947 if (ahd_debug & AHD_SHOW_SENSE) {
1948 int i;
1949
1950 printk("Copied %d bytes of sense data at %d:",
1951 sense_size, sense_offset);
1952 for (i = 0; i < sense_size; i++) {
1953 if ((i & 0xF) == 0)
1954 printk("\n");
1955 printk("0x%x ", cmd->sense_buffer[i]);
1956 }
1957 printk("\n");
1958 }
1959#endif
1960 }
1961 break;
1962 }
1963 case SCSI_STATUS_QUEUE_FULL:
1964
1965
1966
1967
1968
1969
1970
1971
1972 dev->tag_success_count = 0;
1973 if (dev->active != 0) {
1974
1975
1976
1977
1978 dev->openings = 0;
1979#ifdef AHD_DEBUG
1980 if ((ahd_debug & AHD_SHOW_QFULL) != 0) {
1981 ahd_print_path(ahd, scb);
1982 printk("Dropping tag count to %d\n",
1983 dev->active);
1984 }
1985#endif
1986 if (dev->active == dev->tags_on_last_queuefull) {
1987
1988 dev->last_queuefull_same_count++;
1989
1990
1991
1992
1993
1994
1995
1996
1997 if (dev->last_queuefull_same_count
1998 == AHD_LOCK_TAGS_COUNT) {
1999 dev->maxtags = dev->active;
2000 ahd_print_path(ahd, scb);
2001 printk("Locking max tag count at %d\n",
2002 dev->active);
2003 }
2004 } else {
2005 dev->tags_on_last_queuefull = dev->active;
2006 dev->last_queuefull_same_count = 0;
2007 }
2008 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
2009 ahd_set_scsi_status(scb, SCSI_STATUS_OK);
2010 ahd_platform_set_tags(ahd, sdev, &devinfo,
2011 (dev->flags & AHD_DEV_Q_BASIC)
2012 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
2013 break;
2014 }
2015
2016
2017
2018
2019 dev->openings = 1;
2020 ahd_platform_set_tags(ahd, sdev, &devinfo,
2021 (dev->flags & AHD_DEV_Q_BASIC)
2022 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
2023 ahd_set_scsi_status(scb, SCSI_STATUS_BUSY);
2024 }
2025}
2026
2027static void
2028ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
2029{
2030 int status;
2031 int new_status = DID_OK;
2032 int do_fallback = 0;
2033 int scsi_status;
2034
2035
2036
2037
2038
2039
2040
2041
2042 status = ahd_cmd_get_transaction_status(cmd);
2043 switch (status) {
2044 case CAM_REQ_INPROG:
2045 case CAM_REQ_CMP:
2046 new_status = DID_OK;
2047 break;
2048 case CAM_AUTOSENSE_FAIL:
2049 new_status = DID_ERROR;
2050
2051 case CAM_SCSI_STATUS_ERROR:
2052 scsi_status = ahd_cmd_get_scsi_status(cmd);
2053
2054 switch(scsi_status) {
2055 case SCSI_STATUS_CMD_TERMINATED:
2056 case SCSI_STATUS_CHECK_COND:
2057 if ((cmd->result >> 24) != DRIVER_SENSE) {
2058 do_fallback = 1;
2059 } else {
2060 struct scsi_sense_data *sense;
2061
2062 sense = (struct scsi_sense_data *)
2063 cmd->sense_buffer;
2064 if (sense->extra_len >= 5 &&
2065 (sense->add_sense_code == 0x47
2066 || sense->add_sense_code == 0x48))
2067 do_fallback = 1;
2068 }
2069 break;
2070 default:
2071 break;
2072 }
2073 break;
2074 case CAM_REQ_ABORTED:
2075 new_status = DID_ABORT;
2076 break;
2077 case CAM_BUSY:
2078 new_status = DID_BUS_BUSY;
2079 break;
2080 case CAM_REQ_INVALID:
2081 case CAM_PATH_INVALID:
2082 new_status = DID_BAD_TARGET;
2083 break;
2084 case CAM_SEL_TIMEOUT:
2085 new_status = DID_NO_CONNECT;
2086 break;
2087 case CAM_SCSI_BUS_RESET:
2088 case CAM_BDR_SENT:
2089 new_status = DID_RESET;
2090 break;
2091 case CAM_UNCOR_PARITY:
2092 new_status = DID_PARITY;
2093 do_fallback = 1;
2094 break;
2095 case CAM_CMD_TIMEOUT:
2096 new_status = DID_TIME_OUT;
2097 do_fallback = 1;
2098 break;
2099 case CAM_REQ_CMP_ERR:
2100 case CAM_UNEXP_BUSFREE:
2101 case CAM_DATA_RUN_ERR:
2102 new_status = DID_ERROR;
2103 do_fallback = 1;
2104 break;
2105 case CAM_UA_ABORT:
2106 case CAM_NO_HBA:
2107 case CAM_SEQUENCE_FAIL:
2108 case CAM_CCB_LEN_ERR:
2109 case CAM_PROVIDE_FAIL:
2110 case CAM_REQ_TERMIO:
2111 case CAM_UNREC_HBA_ERROR:
2112 case CAM_REQ_TOO_BIG:
2113 new_status = DID_ERROR;
2114 break;
2115 case CAM_REQUEUE_REQ:
2116 new_status = DID_REQUEUE;
2117 break;
2118 default:
2119
2120 new_status = DID_ERROR;
2121 break;
2122 }
2123
2124 if (do_fallback) {
2125 printk("%s: device overrun (status %x) on %d:%d:%d\n",
2126 ahd_name(ahd), status, cmd->device->channel,
2127 cmd->device->id, (u8)cmd->device->lun);
2128 }
2129
2130 ahd_cmd_set_transaction_status(cmd, new_status);
2131
2132 cmd->scsi_done(cmd);
2133}
2134
2135static void
2136ahd_freeze_simq(struct ahd_softc *ahd)
2137{
2138 scsi_block_requests(ahd->platform_data->host);
2139}
2140
2141static void
2142ahd_release_simq(struct ahd_softc *ahd)
2143{
2144 scsi_unblock_requests(ahd->platform_data->host);
2145}
2146
2147static int
2148ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
2149{
2150 struct ahd_softc *ahd;
2151 struct ahd_linux_device *dev;
2152 struct scb *pending_scb;
2153 u_int saved_scbptr;
2154 u_int active_scbptr;
2155 u_int last_phase;
2156 u_int saved_scsiid;
2157 u_int cdb_byte;
2158 int retval;
2159 int was_paused;
2160 int paused;
2161 int wait;
2162 int disconnected;
2163 ahd_mode_state saved_modes;
2164 unsigned long flags;
2165
2166 pending_scb = NULL;
2167 paused = FALSE;
2168 wait = FALSE;
2169 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
2170
2171 scmd_printk(KERN_INFO, cmd,
2172 "Attempting to queue an ABORT message:");
2173
2174 printk("CDB:");
2175 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
2176 printk(" 0x%x", cmd->cmnd[cdb_byte]);
2177 printk("\n");
2178
2179 ahd_lock(ahd, &flags);
2180
2181
2182
2183
2184
2185
2186
2187
2188 dev = scsi_transport_device_data(cmd->device);
2189
2190 if (dev == NULL) {
2191
2192
2193
2194
2195 scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
2196 retval = SUCCESS;
2197 goto no_cmd;
2198 }
2199
2200
2201
2202
2203 LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
2204 if (pending_scb->io_ctx == cmd)
2205 break;
2206 }
2207
2208 if (pending_scb == NULL) {
2209 scmd_printk(KERN_INFO, cmd, "Command not found\n");
2210 goto no_cmd;
2211 }
2212
2213 if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
2214
2215
2216
2217 retval = FAILED;
2218 goto done;
2219 }
2220
2221
2222
2223
2224
2225
2226
2227 was_paused = ahd_is_paused(ahd);
2228 ahd_pause_and_flushwork(ahd);
2229 paused = TRUE;
2230
2231 if ((pending_scb->flags & SCB_ACTIVE) == 0) {
2232 scmd_printk(KERN_INFO, cmd, "Command already completed\n");
2233 goto no_cmd;
2234 }
2235
2236 printk("%s: At time of recovery, card was %spaused\n",
2237 ahd_name(ahd), was_paused ? "" : "not ");
2238 ahd_dump_card_state(ahd);
2239
2240 disconnected = TRUE;
2241 if (ahd_search_qinfifo(ahd, cmd->device->id,
2242 cmd->device->channel + 'A',
2243 cmd->device->lun,
2244 pending_scb->hscb->tag,
2245 ROLE_INITIATOR, CAM_REQ_ABORTED,
2246 SEARCH_COMPLETE) > 0) {
2247 printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
2248 ahd_name(ahd), cmd->device->channel,
2249 cmd->device->id, (u8)cmd->device->lun);
2250 retval = SUCCESS;
2251 goto done;
2252 }
2253
2254 saved_modes = ahd_save_modes(ahd);
2255 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2256 last_phase = ahd_inb(ahd, LASTPHASE);
2257 saved_scbptr = ahd_get_scbptr(ahd);
2258 active_scbptr = saved_scbptr;
2259 if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
2260 struct scb *bus_scb;
2261
2262 bus_scb = ahd_lookup_scb(ahd, active_scbptr);
2263 if (bus_scb == pending_scb)
2264 disconnected = FALSE;
2265 }
2266
2267
2268
2269
2270
2271
2272 saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
2273 if (last_phase != P_BUSFREE
2274 && SCB_GET_TAG(pending_scb) == active_scbptr) {
2275
2276
2277
2278
2279
2280 pending_scb = ahd_lookup_scb(ahd, active_scbptr);
2281 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
2282 ahd_outb(ahd, MSG_OUT, HOST_MSG);
2283 ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
2284 scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
2285 wait = TRUE;
2286 } else if (disconnected) {
2287
2288
2289
2290
2291
2292 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
2293 ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));
2294 pending_scb->hscb->cdb_len = 0;
2295 pending_scb->hscb->task_attribute = 0;
2296 pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK;
2297
2298 if ((pending_scb->flags & SCB_PACKETIZED) != 0) {
2299
2300
2301
2302
2303
2304
2305
2306 ahd_outb(ahd, SCB_TASK_MANAGEMENT,
2307 pending_scb->hscb->task_management);
2308 } else {
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318 pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
2319
2320
2321
2322
2323
2324
2325
2326 ahd_outb(ahd, SCB_CONTROL,
2327 ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE);
2328 }
2329
2330
2331
2332
2333
2334
2335 ahd_search_qinfifo(ahd, cmd->device->id,
2336 cmd->device->channel + 'A', cmd->device->lun,
2337 SCB_LIST_NULL, ROLE_INITIATOR,
2338 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
2339 ahd_qinfifo_requeue_tail(ahd, pending_scb);
2340 ahd_set_scbptr(ahd, saved_scbptr);
2341 ahd_print_path(ahd, pending_scb);
2342 printk("Device is disconnected, re-queuing SCB\n");
2343 wait = TRUE;
2344 } else {
2345 scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
2346 retval = FAILED;
2347 goto done;
2348 }
2349
2350no_cmd:
2351
2352
2353
2354
2355
2356
2357 retval = SUCCESS;
2358done:
2359 if (paused)
2360 ahd_unpause(ahd);
2361 if (wait) {
2362 DECLARE_COMPLETION_ONSTACK(done);
2363
2364 ahd->platform_data->eh_done = &done;
2365 ahd_unlock(ahd, &flags);
2366
2367 printk("%s: Recovery code sleeping\n", ahd_name(ahd));
2368 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
2369 ahd_lock(ahd, &flags);
2370 ahd->platform_data->eh_done = NULL;
2371 ahd_unlock(ahd, &flags);
2372 printk("%s: Timer Expired (active %d)\n",
2373 ahd_name(ahd), dev->active);
2374 retval = FAILED;
2375 }
2376 printk("Recovery code awake\n");
2377 } else
2378 ahd_unlock(ahd, &flags);
2379
2380 if (retval != SUCCESS)
2381 printk("%s: Command abort returning 0x%x\n",
2382 ahd_name(ahd), retval);
2383
2384 return retval;
2385}
2386
2387static void ahd_linux_set_width(struct scsi_target *starget, int width)
2388{
2389 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2390 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2391 struct ahd_devinfo devinfo;
2392 unsigned long flags;
2393
2394 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2395 starget->channel + 'A', ROLE_INITIATOR);
2396 ahd_lock(ahd, &flags);
2397 ahd_set_width(ahd, &devinfo, width, AHD_TRANS_GOAL, FALSE);
2398 ahd_unlock(ahd, &flags);
2399}
2400
2401static void ahd_linux_set_period(struct scsi_target *starget, int period)
2402{
2403 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2404 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2405 struct ahd_tmode_tstate *tstate;
2406 struct ahd_initiator_tinfo *tinfo
2407 = ahd_fetch_transinfo(ahd,
2408 starget->channel + 'A',
2409 shost->this_id, starget->id, &tstate);
2410 struct ahd_devinfo devinfo;
2411 unsigned int ppr_options = tinfo->goal.ppr_options;
2412 unsigned int dt;
2413 unsigned long flags;
2414 unsigned long offset = tinfo->goal.offset;
2415
2416#ifdef AHD_DEBUG
2417 if ((ahd_debug & AHD_SHOW_DV) != 0)
2418 printk("%s: set period to %d\n", ahd_name(ahd), period);
2419#endif
2420 if (offset == 0)
2421 offset = MAX_OFFSET;
2422
2423 if (period < 8)
2424 period = 8;
2425 if (period < 10) {
2426 if (spi_max_width(starget)) {
2427 ppr_options |= MSG_EXT_PPR_DT_REQ;
2428 if (period == 8)
2429 ppr_options |= MSG_EXT_PPR_IU_REQ;
2430 } else
2431 period = 10;
2432 }
2433
2434 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2435
2436 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2437 starget->channel + 'A', ROLE_INITIATOR);
2438
2439
2440 if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) {
2441 if (spi_width(starget) == 0)
2442 ppr_options &= MSG_EXT_PPR_QAS_REQ;
2443 }
2444
2445 ahd_find_syncrate(ahd, &period, &ppr_options,
2446 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2447
2448 ahd_lock(ahd, &flags);
2449 ahd_set_syncrate(ahd, &devinfo, period, offset,
2450 ppr_options, AHD_TRANS_GOAL, FALSE);
2451 ahd_unlock(ahd, &flags);
2452}
2453
2454static void ahd_linux_set_offset(struct scsi_target *starget, int offset)
2455{
2456 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2457 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2458 struct ahd_tmode_tstate *tstate;
2459 struct ahd_initiator_tinfo *tinfo
2460 = ahd_fetch_transinfo(ahd,
2461 starget->channel + 'A',
2462 shost->this_id, starget->id, &tstate);
2463 struct ahd_devinfo devinfo;
2464 unsigned int ppr_options = 0;
2465 unsigned int period = 0;
2466 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2467 unsigned long flags;
2468
2469#ifdef AHD_DEBUG
2470 if ((ahd_debug & AHD_SHOW_DV) != 0)
2471 printk("%s: set offset to %d\n", ahd_name(ahd), offset);
2472#endif
2473
2474 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2475 starget->channel + 'A', ROLE_INITIATOR);
2476 if (offset != 0) {
2477 period = tinfo->goal.period;
2478 ppr_options = tinfo->goal.ppr_options;
2479 ahd_find_syncrate(ahd, &period, &ppr_options,
2480 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2481 }
2482
2483 ahd_lock(ahd, &flags);
2484 ahd_set_syncrate(ahd, &devinfo, period, offset, ppr_options,
2485 AHD_TRANS_GOAL, FALSE);
2486 ahd_unlock(ahd, &flags);
2487}
2488
2489static void ahd_linux_set_dt(struct scsi_target *starget, int dt)
2490{
2491 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2492 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2493 struct ahd_tmode_tstate *tstate;
2494 struct ahd_initiator_tinfo *tinfo
2495 = ahd_fetch_transinfo(ahd,
2496 starget->channel + 'A',
2497 shost->this_id, starget->id, &tstate);
2498 struct ahd_devinfo devinfo;
2499 unsigned int ppr_options = tinfo->goal.ppr_options
2500 & ~MSG_EXT_PPR_DT_REQ;
2501 unsigned int period = tinfo->goal.period;
2502 unsigned int width = tinfo->goal.width;
2503 unsigned long flags;
2504
2505#ifdef AHD_DEBUG
2506 if ((ahd_debug & AHD_SHOW_DV) != 0)
2507 printk("%s: %s DT\n", ahd_name(ahd),
2508 dt ? "enabling" : "disabling");
2509#endif
2510 if (dt && spi_max_width(starget)) {
2511 ppr_options |= MSG_EXT_PPR_DT_REQ;
2512 if (!width)
2513 ahd_linux_set_width(starget, 1);
2514 } else {
2515 if (period <= 9)
2516 period = 10;
2517
2518 ppr_options &= ~MSG_EXT_PPR_IU_REQ;
2519 }
2520 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2521 starget->channel + 'A', ROLE_INITIATOR);
2522 ahd_find_syncrate(ahd, &period, &ppr_options,
2523 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2524
2525 ahd_lock(ahd, &flags);
2526 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2527 ppr_options, AHD_TRANS_GOAL, FALSE);
2528 ahd_unlock(ahd, &flags);
2529}
2530
2531static void ahd_linux_set_qas(struct scsi_target *starget, int qas)
2532{
2533 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2534 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2535 struct ahd_tmode_tstate *tstate;
2536 struct ahd_initiator_tinfo *tinfo
2537 = ahd_fetch_transinfo(ahd,
2538 starget->channel + 'A',
2539 shost->this_id, starget->id, &tstate);
2540 struct ahd_devinfo devinfo;
2541 unsigned int ppr_options = tinfo->goal.ppr_options
2542 & ~MSG_EXT_PPR_QAS_REQ;
2543 unsigned int period = tinfo->goal.period;
2544 unsigned int dt;
2545 unsigned long flags;
2546
2547#ifdef AHD_DEBUG
2548 if ((ahd_debug & AHD_SHOW_DV) != 0)
2549 printk("%s: %s QAS\n", ahd_name(ahd),
2550 qas ? "enabling" : "disabling");
2551#endif
2552
2553 if (qas) {
2554 ppr_options |= MSG_EXT_PPR_QAS_REQ;
2555 }
2556
2557 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2558
2559 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2560 starget->channel + 'A', ROLE_INITIATOR);
2561 ahd_find_syncrate(ahd, &period, &ppr_options,
2562 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2563
2564 ahd_lock(ahd, &flags);
2565 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2566 ppr_options, AHD_TRANS_GOAL, FALSE);
2567 ahd_unlock(ahd, &flags);
2568}
2569
2570static void ahd_linux_set_iu(struct scsi_target *starget, int iu)
2571{
2572 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2573 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2574 struct ahd_tmode_tstate *tstate;
2575 struct ahd_initiator_tinfo *tinfo
2576 = ahd_fetch_transinfo(ahd,
2577 starget->channel + 'A',
2578 shost->this_id, starget->id, &tstate);
2579 struct ahd_devinfo devinfo;
2580 unsigned int ppr_options = tinfo->goal.ppr_options
2581 & ~MSG_EXT_PPR_IU_REQ;
2582 unsigned int period = tinfo->goal.period;
2583 unsigned int dt;
2584 unsigned long flags;
2585
2586#ifdef AHD_DEBUG
2587 if ((ahd_debug & AHD_SHOW_DV) != 0)
2588 printk("%s: %s IU\n", ahd_name(ahd),
2589 iu ? "enabling" : "disabling");
2590#endif
2591
2592 if (iu && spi_max_width(starget)) {
2593 ppr_options |= MSG_EXT_PPR_IU_REQ;
2594 ppr_options |= MSG_EXT_PPR_DT_REQ;
2595 }
2596
2597 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2598
2599 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2600 starget->channel + 'A', ROLE_INITIATOR);
2601 ahd_find_syncrate(ahd, &period, &ppr_options,
2602 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2603
2604 ahd_lock(ahd, &flags);
2605 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2606 ppr_options, AHD_TRANS_GOAL, FALSE);
2607 ahd_unlock(ahd, &flags);
2608}
2609
2610static void ahd_linux_set_rd_strm(struct scsi_target *starget, int rdstrm)
2611{
2612 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2613 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2614 struct ahd_tmode_tstate *tstate;
2615 struct ahd_initiator_tinfo *tinfo
2616 = ahd_fetch_transinfo(ahd,
2617 starget->channel + 'A',
2618 shost->this_id, starget->id, &tstate);
2619 struct ahd_devinfo devinfo;
2620 unsigned int ppr_options = tinfo->goal.ppr_options
2621 & ~MSG_EXT_PPR_RD_STRM;
2622 unsigned int period = tinfo->goal.period;
2623 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2624 unsigned long flags;
2625
2626#ifdef AHD_DEBUG
2627 if ((ahd_debug & AHD_SHOW_DV) != 0)
2628 printk("%s: %s Read Streaming\n", ahd_name(ahd),
2629 rdstrm ? "enabling" : "disabling");
2630#endif
2631
2632 if (rdstrm && spi_max_width(starget))
2633 ppr_options |= MSG_EXT_PPR_RD_STRM;
2634
2635 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2636 starget->channel + 'A', ROLE_INITIATOR);
2637 ahd_find_syncrate(ahd, &period, &ppr_options,
2638 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2639
2640 ahd_lock(ahd, &flags);
2641 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2642 ppr_options, AHD_TRANS_GOAL, FALSE);
2643 ahd_unlock(ahd, &flags);
2644}
2645
2646static void ahd_linux_set_wr_flow(struct scsi_target *starget, int wrflow)
2647{
2648 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2649 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2650 struct ahd_tmode_tstate *tstate;
2651 struct ahd_initiator_tinfo *tinfo
2652 = ahd_fetch_transinfo(ahd,
2653 starget->channel + 'A',
2654 shost->this_id, starget->id, &tstate);
2655 struct ahd_devinfo devinfo;
2656 unsigned int ppr_options = tinfo->goal.ppr_options
2657 & ~MSG_EXT_PPR_WR_FLOW;
2658 unsigned int period = tinfo->goal.period;
2659 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2660 unsigned long flags;
2661
2662#ifdef AHD_DEBUG
2663 if ((ahd_debug & AHD_SHOW_DV) != 0)
2664 printk("%s: %s Write Flow Control\n", ahd_name(ahd),
2665 wrflow ? "enabling" : "disabling");
2666#endif
2667
2668 if (wrflow && spi_max_width(starget))
2669 ppr_options |= MSG_EXT_PPR_WR_FLOW;
2670
2671 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2672 starget->channel + 'A', ROLE_INITIATOR);
2673 ahd_find_syncrate(ahd, &period, &ppr_options,
2674 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2675
2676 ahd_lock(ahd, &flags);
2677 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2678 ppr_options, AHD_TRANS_GOAL, FALSE);
2679 ahd_unlock(ahd, &flags);
2680}
2681
2682static void ahd_linux_set_rti(struct scsi_target *starget, int rti)
2683{
2684 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2685 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2686 struct ahd_tmode_tstate *tstate;
2687 struct ahd_initiator_tinfo *tinfo
2688 = ahd_fetch_transinfo(ahd,
2689 starget->channel + 'A',
2690 shost->this_id, starget->id, &tstate);
2691 struct ahd_devinfo devinfo;
2692 unsigned int ppr_options = tinfo->goal.ppr_options
2693 & ~MSG_EXT_PPR_RTI;
2694 unsigned int period = tinfo->goal.period;
2695 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2696 unsigned long flags;
2697
2698 if ((ahd->features & AHD_RTI) == 0) {
2699#ifdef AHD_DEBUG
2700 if ((ahd_debug & AHD_SHOW_DV) != 0)
2701 printk("%s: RTI not available\n", ahd_name(ahd));
2702#endif
2703 return;
2704 }
2705
2706#ifdef AHD_DEBUG
2707 if ((ahd_debug & AHD_SHOW_DV) != 0)
2708 printk("%s: %s RTI\n", ahd_name(ahd),
2709 rti ? "enabling" : "disabling");
2710#endif
2711
2712 if (rti && spi_max_width(starget))
2713 ppr_options |= MSG_EXT_PPR_RTI;
2714
2715 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2716 starget->channel + 'A', ROLE_INITIATOR);
2717 ahd_find_syncrate(ahd, &period, &ppr_options,
2718 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2719
2720 ahd_lock(ahd, &flags);
2721 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2722 ppr_options, AHD_TRANS_GOAL, FALSE);
2723 ahd_unlock(ahd, &flags);
2724}
2725
2726static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp)
2727{
2728 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2729 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2730 struct ahd_tmode_tstate *tstate;
2731 struct ahd_initiator_tinfo *tinfo
2732 = ahd_fetch_transinfo(ahd,
2733 starget->channel + 'A',
2734 shost->this_id, starget->id, &tstate);
2735 struct ahd_devinfo devinfo;
2736 unsigned int ppr_options = tinfo->goal.ppr_options
2737 & ~MSG_EXT_PPR_PCOMP_EN;
2738 unsigned int period = tinfo->goal.period;
2739 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2740 unsigned long flags;
2741
2742#ifdef AHD_DEBUG
2743 if ((ahd_debug & AHD_SHOW_DV) != 0)
2744 printk("%s: %s Precompensation\n", ahd_name(ahd),
2745 pcomp ? "Enable" : "Disable");
2746#endif
2747
2748 if (pcomp && spi_max_width(starget)) {
2749 uint8_t precomp;
2750
2751 if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
2752 const struct ahd_linux_iocell_opts *iocell_opts;
2753
2754 iocell_opts = &aic79xx_iocell_info[ahd->unit];
2755 precomp = iocell_opts->precomp;
2756 } else {
2757 precomp = AIC79XX_DEFAULT_PRECOMP;
2758 }
2759 ppr_options |= MSG_EXT_PPR_PCOMP_EN;
2760 AHD_SET_PRECOMP(ahd, precomp);
2761 } else {
2762 AHD_SET_PRECOMP(ahd, 0);
2763 }
2764
2765 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2766 starget->channel + 'A', ROLE_INITIATOR);
2767 ahd_find_syncrate(ahd, &period, &ppr_options,
2768 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2769
2770 ahd_lock(ahd, &flags);
2771 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2772 ppr_options, AHD_TRANS_GOAL, FALSE);
2773 ahd_unlock(ahd, &flags);
2774}
2775
2776static void ahd_linux_set_hold_mcs(struct scsi_target *starget, int hold)
2777{
2778 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2779 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2780 struct ahd_tmode_tstate *tstate;
2781 struct ahd_initiator_tinfo *tinfo
2782 = ahd_fetch_transinfo(ahd,
2783 starget->channel + 'A',
2784 shost->this_id, starget->id, &tstate);
2785 struct ahd_devinfo devinfo;
2786 unsigned int ppr_options = tinfo->goal.ppr_options
2787 & ~MSG_EXT_PPR_HOLD_MCS;
2788 unsigned int period = tinfo->goal.period;
2789 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2790 unsigned long flags;
2791
2792 if (hold && spi_max_width(starget))
2793 ppr_options |= MSG_EXT_PPR_HOLD_MCS;
2794
2795 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2796 starget->channel + 'A', ROLE_INITIATOR);
2797 ahd_find_syncrate(ahd, &period, &ppr_options,
2798 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2799
2800 ahd_lock(ahd, &flags);
2801 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2802 ppr_options, AHD_TRANS_GOAL, FALSE);
2803 ahd_unlock(ahd, &flags);
2804}
2805
2806static void ahd_linux_get_signalling(struct Scsi_Host *shost)
2807{
2808 struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata;
2809 unsigned long flags;
2810 u8 mode;
2811
2812 ahd_lock(ahd, &flags);
2813 ahd_pause(ahd);
2814 mode = ahd_inb(ahd, SBLKCTL);
2815 ahd_unpause(ahd);
2816 ahd_unlock(ahd, &flags);
2817
2818 if (mode & ENAB40)
2819 spi_signalling(shost) = SPI_SIGNAL_LVD;
2820 else if (mode & ENAB20)
2821 spi_signalling(shost) = SPI_SIGNAL_SE;
2822 else
2823 spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
2824}
2825
2826static struct spi_function_template ahd_linux_transport_functions = {
2827 .set_offset = ahd_linux_set_offset,
2828 .show_offset = 1,
2829 .set_period = ahd_linux_set_period,
2830 .show_period = 1,
2831 .set_width = ahd_linux_set_width,
2832 .show_width = 1,
2833 .set_dt = ahd_linux_set_dt,
2834 .show_dt = 1,
2835 .set_iu = ahd_linux_set_iu,
2836 .show_iu = 1,
2837 .set_qas = ahd_linux_set_qas,
2838 .show_qas = 1,
2839 .set_rd_strm = ahd_linux_set_rd_strm,
2840 .show_rd_strm = 1,
2841 .set_wr_flow = ahd_linux_set_wr_flow,
2842 .show_wr_flow = 1,
2843 .set_rti = ahd_linux_set_rti,
2844 .show_rti = 1,
2845 .set_pcomp_en = ahd_linux_set_pcomp_en,
2846 .show_pcomp_en = 1,
2847 .set_hold_mcs = ahd_linux_set_hold_mcs,
2848 .show_hold_mcs = 1,
2849 .get_signalling = ahd_linux_get_signalling,
2850};
2851
2852static int __init
2853ahd_linux_init(void)
2854{
2855 int error = 0;
2856
2857
2858
2859
2860 if (aic79xx)
2861 aic79xx_setup(aic79xx);
2862
2863 ahd_linux_transport_template =
2864 spi_attach_transport(&ahd_linux_transport_functions);
2865 if (!ahd_linux_transport_template)
2866 return -ENODEV;
2867
2868 scsi_transport_reserve_device(ahd_linux_transport_template,
2869 sizeof(struct ahd_linux_device));
2870
2871 error = ahd_linux_pci_init();
2872 if (error)
2873 spi_release_transport(ahd_linux_transport_template);
2874 return error;
2875}
2876
2877static void __exit
2878ahd_linux_exit(void)
2879{
2880 ahd_linux_pci_exit();
2881 spi_release_transport(ahd_linux_transport_template);
2882}
2883
2884module_init(ahd_linux_init);
2885module_exit(ahd_linux_exit);
2886