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 if (bootverbose)
704 sdev_printk(KERN_INFO, sdev, "Slave Configure\n");
705
706 ahd_linux_device_queue_depth(sdev);
707
708
709 if (!spi_initial_dv(sdev->sdev_target))
710 spi_dv_device(sdev);
711
712 return 0;
713}
714
715#if defined(__i386__)
716
717
718
719static int
720ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
721 sector_t capacity, int geom[])
722{
723 int heads;
724 int sectors;
725 int cylinders;
726 int extended;
727 struct ahd_softc *ahd;
728
729 ahd = *((struct ahd_softc **)sdev->host->hostdata);
730
731 if (scsi_partsize(bdev, capacity, geom))
732 return 0;
733
734 heads = 64;
735 sectors = 32;
736 cylinders = aic_sector_div(capacity, heads, sectors);
737
738 if (aic79xx_extended != 0)
739 extended = 1;
740 else
741 extended = (ahd->flags & AHD_EXTENDED_TRANS_A) != 0;
742 if (extended && cylinders >= 1024) {
743 heads = 255;
744 sectors = 63;
745 cylinders = aic_sector_div(capacity, heads, sectors);
746 }
747 geom[0] = heads;
748 geom[1] = sectors;
749 geom[2] = cylinders;
750 return (0);
751}
752#endif
753
754
755
756
757static int
758ahd_linux_abort(struct scsi_cmnd *cmd)
759{
760 int error;
761
762 error = ahd_linux_queue_abort_cmd(cmd);
763
764 return error;
765}
766
767
768
769
770static int
771ahd_linux_dev_reset(struct scsi_cmnd *cmd)
772{
773 struct ahd_softc *ahd;
774 struct ahd_linux_device *dev;
775 struct scb *reset_scb;
776 u_int cdb_byte;
777 int retval = SUCCESS;
778 struct ahd_initiator_tinfo *tinfo;
779 struct ahd_tmode_tstate *tstate;
780 unsigned long flags;
781 DECLARE_COMPLETION_ONSTACK(done);
782
783 reset_scb = NULL;
784
785 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
786
787 scmd_printk(KERN_INFO, cmd,
788 "Attempting to queue a TARGET RESET message:");
789
790 printk("CDB:");
791 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
792 printk(" 0x%x", cmd->cmnd[cdb_byte]);
793 printk("\n");
794
795
796
797
798 dev = scsi_transport_device_data(cmd->device);
799
800 if (dev == NULL) {
801
802
803
804
805 scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
806 return SUCCESS;
807 }
808
809
810
811
812 reset_scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX);
813 if (!reset_scb) {
814 scmd_printk(KERN_INFO, cmd, "No SCB available\n");
815 return FAILED;
816 }
817
818 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
819 cmd->device->id, &tstate);
820 reset_scb->io_ctx = cmd;
821 reset_scb->platform_data->dev = dev;
822 reset_scb->sg_count = 0;
823 ahd_set_residual(reset_scb, 0);
824 ahd_set_sense_residual(reset_scb, 0);
825 reset_scb->platform_data->xfer_len = 0;
826 reset_scb->hscb->control = 0;
827 reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd);
828 reset_scb->hscb->lun = cmd->device->lun;
829 reset_scb->hscb->cdb_len = 0;
830 reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET;
831 reset_scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE;
832 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
833 reset_scb->flags |= SCB_PACKETIZED;
834 } else {
835 reset_scb->hscb->control |= MK_MESSAGE;
836 }
837 dev->openings--;
838 dev->active++;
839 dev->commands_issued++;
840
841 ahd_lock(ahd, &flags);
842
843 LIST_INSERT_HEAD(&ahd->pending_scbs, reset_scb, pending_links);
844 ahd_queue_scb(ahd, reset_scb);
845
846 ahd->platform_data->eh_done = &done;
847 ahd_unlock(ahd, &flags);
848
849 printk("%s: Device reset code sleeping\n", ahd_name(ahd));
850 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
851 ahd_lock(ahd, &flags);
852 ahd->platform_data->eh_done = NULL;
853 ahd_unlock(ahd, &flags);
854 printk("%s: Device reset timer expired (active %d)\n",
855 ahd_name(ahd), dev->active);
856 retval = FAILED;
857 }
858 printk("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
859
860 return (retval);
861}
862
863
864
865
866static int
867ahd_linux_bus_reset(struct scsi_cmnd *cmd)
868{
869 struct ahd_softc *ahd;
870 int found;
871 unsigned long flags;
872
873 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
874#ifdef AHD_DEBUG
875 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
876 printk("%s: Bus reset called for cmd %p\n",
877 ahd_name(ahd), cmd);
878#endif
879 ahd_lock(ahd, &flags);
880
881 found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A',
882 TRUE);
883 ahd_unlock(ahd, &flags);
884
885 if (bootverbose)
886 printk("%s: SCSI bus reset delivered. "
887 "%d SCBs aborted.\n", ahd_name(ahd), found);
888
889 return (SUCCESS);
890}
891
892struct scsi_host_template aic79xx_driver_template = {
893 .module = THIS_MODULE,
894 .name = "aic79xx",
895 .proc_name = "aic79xx",
896 .show_info = ahd_linux_show_info,
897 .write_info = ahd_proc_write_seeprom,
898 .info = ahd_linux_info,
899 .queuecommand = ahd_linux_queue,
900 .eh_abort_handler = ahd_linux_abort,
901 .eh_device_reset_handler = ahd_linux_dev_reset,
902 .eh_bus_reset_handler = ahd_linux_bus_reset,
903#if defined(__i386__)
904 .bios_param = ahd_linux_biosparam,
905#endif
906 .can_queue = AHD_MAX_QUEUE,
907 .this_id = -1,
908 .max_sectors = 8192,
909 .cmd_per_lun = 2,
910 .slave_alloc = ahd_linux_slave_alloc,
911 .slave_configure = ahd_linux_slave_configure,
912 .target_alloc = ahd_linux_target_alloc,
913 .target_destroy = ahd_linux_target_destroy,
914};
915
916
917int
918ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent,
919 bus_size_t alignment, bus_size_t boundary,
920 dma_addr_t lowaddr, dma_addr_t highaddr,
921 bus_dma_filter_t *filter, void *filterarg,
922 bus_size_t maxsize, int nsegments,
923 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
924{
925 bus_dma_tag_t dmat;
926
927 dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC);
928 if (dmat == NULL)
929 return (ENOMEM);
930
931
932
933
934
935
936
937
938 dmat->alignment = alignment;
939 dmat->boundary = boundary;
940 dmat->maxsize = maxsize;
941 *ret_tag = dmat;
942 return (0);
943}
944
945void
946ahd_dma_tag_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat)
947{
948 kfree(dmat);
949}
950
951int
952ahd_dmamem_alloc(struct ahd_softc *ahd, bus_dma_tag_t dmat, void** vaddr,
953 int flags, bus_dmamap_t *mapp)
954{
955 *vaddr = dma_alloc_coherent(&ahd->dev_softc->dev, dmat->maxsize, mapp,
956 GFP_ATOMIC);
957 if (*vaddr == NULL)
958 return (ENOMEM);
959 return(0);
960}
961
962void
963ahd_dmamem_free(struct ahd_softc *ahd, bus_dma_tag_t dmat,
964 void* vaddr, bus_dmamap_t map)
965{
966 dma_free_coherent(&ahd->dev_softc->dev, dmat->maxsize, vaddr, map);
967}
968
969int
970ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map,
971 void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
972 void *cb_arg, int flags)
973{
974
975
976
977
978 bus_dma_segment_t stack_sg;
979
980 stack_sg.ds_addr = map;
981 stack_sg.ds_len = dmat->maxsize;
982 cb(cb_arg, &stack_sg, 1, 0);
983 return (0);
984}
985
986void
987ahd_dmamap_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
988{
989}
990
991int
992ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
993{
994
995 return (0);
996}
997
998
999static void
1000ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value)
1001{
1002
1003 if ((instance >= 0)
1004 && (instance < ARRAY_SIZE(aic79xx_iocell_info))) {
1005 uint8_t *iocell_info;
1006
1007 iocell_info = (uint8_t*)&aic79xx_iocell_info[instance];
1008 iocell_info[index] = value & 0xFFFF;
1009 if (bootverbose)
1010 printk("iocell[%d:%ld] = %d\n", instance, index, value);
1011 }
1012}
1013
1014static void
1015ahd_linux_setup_tag_info_global(char *p)
1016{
1017 int tags, i, j;
1018
1019 tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
1020 printk("Setting Global Tags= %d\n", tags);
1021
1022 for (i = 0; i < ARRAY_SIZE(aic79xx_tag_info); i++) {
1023 for (j = 0; j < AHD_NUM_TARGETS; j++) {
1024 aic79xx_tag_info[i].tag_commands[j] = tags;
1025 }
1026 }
1027}
1028
1029static void
1030ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
1031{
1032
1033 if ((instance >= 0) && (targ >= 0)
1034 && (instance < ARRAY_SIZE(aic79xx_tag_info))
1035 && (targ < AHD_NUM_TARGETS)) {
1036 aic79xx_tag_info[instance].tag_commands[targ] = value & 0x1FF;
1037 if (bootverbose)
1038 printk("tag_info[%d:%d] = %d\n", instance, targ, value);
1039 }
1040}
1041
1042static char *
1043ahd_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
1044 void (*callback)(u_long, int, int, int32_t),
1045 u_long callback_arg)
1046{
1047 char *tok_end;
1048 char *tok_end2;
1049 int i;
1050 int instance;
1051 int targ;
1052 int done;
1053 char tok_list[] = {'.', ',', '{', '}', '\0'};
1054
1055
1056 if (*opt_arg != ':')
1057 return (opt_arg);
1058 opt_arg++;
1059 instance = -1;
1060 targ = -1;
1061 done = FALSE;
1062
1063
1064
1065
1066 tok_end = strchr(opt_arg, '\0');
1067 if (tok_end < end)
1068 *tok_end = ',';
1069 while (!done) {
1070 switch (*opt_arg) {
1071 case '{':
1072 if (instance == -1) {
1073 instance = 0;
1074 } else {
1075 if (depth > 1) {
1076 if (targ == -1)
1077 targ = 0;
1078 } else {
1079 printk("Malformed Option %s\n",
1080 opt_name);
1081 done = TRUE;
1082 }
1083 }
1084 opt_arg++;
1085 break;
1086 case '}':
1087 if (targ != -1)
1088 targ = -1;
1089 else if (instance != -1)
1090 instance = -1;
1091 opt_arg++;
1092 break;
1093 case ',':
1094 case '.':
1095 if (instance == -1)
1096 done = TRUE;
1097 else if (targ >= 0)
1098 targ++;
1099 else if (instance >= 0)
1100 instance++;
1101 opt_arg++;
1102 break;
1103 case '\0':
1104 done = TRUE;
1105 break;
1106 default:
1107 tok_end = end;
1108 for (i = 0; tok_list[i]; i++) {
1109 tok_end2 = strchr(opt_arg, tok_list[i]);
1110 if ((tok_end2) && (tok_end2 < tok_end))
1111 tok_end = tok_end2;
1112 }
1113 callback(callback_arg, instance, targ,
1114 simple_strtol(opt_arg, NULL, 0));
1115 opt_arg = tok_end;
1116 break;
1117 }
1118 }
1119 return (opt_arg);
1120}
1121
1122
1123
1124
1125
1126
1127static int
1128aic79xx_setup(char *s)
1129{
1130 int i, n;
1131 char *p;
1132 char *end;
1133
1134 static const struct {
1135 const char *name;
1136 uint32_t *flag;
1137 } options[] = {
1138 { "extended", &aic79xx_extended },
1139 { "no_reset", &aic79xx_no_reset },
1140 { "verbose", &aic79xx_verbose },
1141 { "allow_memio", &aic79xx_allow_memio},
1142#ifdef AHD_DEBUG
1143 { "debug", &ahd_debug },
1144#endif
1145 { "periodic_otag", &aic79xx_periodic_otag },
1146 { "pci_parity", &aic79xx_pci_parity },
1147 { "seltime", &aic79xx_seltime },
1148 { "tag_info", NULL },
1149 { "global_tag_depth", NULL},
1150 { "slewrate", NULL },
1151 { "precomp", NULL },
1152 { "amplitude", NULL },
1153 { "slowcrc", &aic79xx_slowcrc },
1154 };
1155
1156 end = strchr(s, '\0');
1157
1158
1159
1160
1161
1162 n = 0;
1163
1164 while ((p = strsep(&s, ",.")) != NULL) {
1165 if (*p == '\0')
1166 continue;
1167 for (i = 0; i < ARRAY_SIZE(options); i++) {
1168
1169 n = strlen(options[i].name);
1170 if (strncmp(options[i].name, p, n) == 0)
1171 break;
1172 }
1173 if (i == ARRAY_SIZE(options))
1174 continue;
1175
1176 if (strncmp(p, "global_tag_depth", n) == 0) {
1177 ahd_linux_setup_tag_info_global(p + n);
1178 } else if (strncmp(p, "tag_info", n) == 0) {
1179 s = ahd_parse_brace_option("tag_info", p + n, end,
1180 2, ahd_linux_setup_tag_info, 0);
1181 } else if (strncmp(p, "slewrate", n) == 0) {
1182 s = ahd_parse_brace_option("slewrate",
1183 p + n, end, 1, ahd_linux_setup_iocell_info,
1184 AIC79XX_SLEWRATE_INDEX);
1185 } else if (strncmp(p, "precomp", n) == 0) {
1186 s = ahd_parse_brace_option("precomp",
1187 p + n, end, 1, ahd_linux_setup_iocell_info,
1188 AIC79XX_PRECOMP_INDEX);
1189 } else if (strncmp(p, "amplitude", n) == 0) {
1190 s = ahd_parse_brace_option("amplitude",
1191 p + n, end, 1, ahd_linux_setup_iocell_info,
1192 AIC79XX_AMPLITUDE_INDEX);
1193 } else if (p[n] == ':') {
1194 *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
1195 } else if (!strncmp(p, "verbose", n)) {
1196 *(options[i].flag) = 1;
1197 } else {
1198 *(options[i].flag) ^= 0xFFFFFFFF;
1199 }
1200 }
1201 return 1;
1202}
1203
1204__setup("aic79xx=", aic79xx_setup);
1205
1206uint32_t aic79xx_verbose;
1207
1208int
1209ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *template)
1210{
1211 char buf[80];
1212 struct Scsi_Host *host;
1213 char *new_name;
1214 u_long s;
1215 int retval;
1216
1217 template->name = ahd->description;
1218 host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
1219 if (host == NULL)
1220 return (ENOMEM);
1221
1222 *((struct ahd_softc **)host->hostdata) = ahd;
1223 ahd->platform_data->host = host;
1224 host->can_queue = AHD_MAX_QUEUE;
1225 host->cmd_per_lun = 2;
1226 host->sg_tablesize = AHD_NSEG;
1227 host->this_id = ahd->our_id;
1228 host->irq = ahd->platform_data->irq;
1229 host->max_id = (ahd->features & AHD_WIDE) ? 16 : 8;
1230 host->max_lun = AHD_NUM_LUNS;
1231 host->max_channel = 0;
1232 host->sg_tablesize = AHD_NSEG;
1233 ahd_lock(ahd, &s);
1234 ahd_set_unit(ahd, ahd_linux_unit++);
1235 ahd_unlock(ahd, &s);
1236 sprintf(buf, "scsi%d", host->host_no);
1237 new_name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
1238 if (new_name != NULL) {
1239 strcpy(new_name, buf);
1240 ahd_set_name(ahd, new_name);
1241 }
1242 host->unique_id = ahd->unit;
1243 ahd_linux_initialize_scsi_bus(ahd);
1244 ahd_intr_enable(ahd, TRUE);
1245
1246 host->transportt = ahd_linux_transport_template;
1247
1248 retval = scsi_add_host(host, &ahd->dev_softc->dev);
1249 if (retval) {
1250 printk(KERN_WARNING "aic79xx: scsi_add_host failed\n");
1251 scsi_host_put(host);
1252 return retval;
1253 }
1254
1255 scsi_scan_host(host);
1256 return 0;
1257}
1258
1259
1260
1261
1262
1263
1264static void
1265ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd)
1266{
1267 u_int target_id;
1268 u_int numtarg;
1269 unsigned long s;
1270
1271 target_id = 0;
1272 numtarg = 0;
1273
1274 if (aic79xx_no_reset != 0)
1275 ahd->flags &= ~AHD_RESET_BUS_A;
1276
1277 if ((ahd->flags & AHD_RESET_BUS_A) != 0)
1278 ahd_reset_channel(ahd, 'A', TRUE);
1279 else
1280 numtarg = (ahd->features & AHD_WIDE) ? 16 : 8;
1281
1282 ahd_lock(ahd, &s);
1283
1284
1285
1286
1287
1288 for (; target_id < numtarg; target_id++) {
1289 struct ahd_devinfo devinfo;
1290 struct ahd_initiator_tinfo *tinfo;
1291 struct ahd_tmode_tstate *tstate;
1292
1293 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
1294 target_id, &tstate);
1295 ahd_compile_devinfo(&devinfo, ahd->our_id, target_id,
1296 CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR);
1297 ahd_update_neg_request(ahd, &devinfo, tstate,
1298 tinfo, AHD_NEG_ALWAYS);
1299 }
1300 ahd_unlock(ahd, &s);
1301
1302 if ((ahd->flags & AHD_RESET_BUS_A) != 0) {
1303 ahd_freeze_simq(ahd);
1304 msleep(AIC79XX_RESET_DELAY);
1305 ahd_release_simq(ahd);
1306 }
1307}
1308
1309int
1310ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg)
1311{
1312 ahd->platform_data =
1313 kzalloc(sizeof(struct ahd_platform_data), GFP_ATOMIC);
1314 if (ahd->platform_data == NULL)
1315 return (ENOMEM);
1316 ahd->platform_data->irq = AHD_LINUX_NOIRQ;
1317 ahd_lockinit(ahd);
1318 ahd->seltime = (aic79xx_seltime & 0x3) << 4;
1319 return (0);
1320}
1321
1322void
1323ahd_platform_free(struct ahd_softc *ahd)
1324{
1325 struct scsi_target *starget;
1326 int i;
1327
1328 if (ahd->platform_data != NULL) {
1329
1330 for (i = 0; i < AHD_NUM_TARGETS; i++) {
1331 starget = ahd->platform_data->starget[i];
1332 if (starget != NULL) {
1333 ahd->platform_data->starget[i] = NULL;
1334 }
1335 }
1336
1337 if (ahd->platform_data->irq != AHD_LINUX_NOIRQ)
1338 free_irq(ahd->platform_data->irq, ahd);
1339 if (ahd->tags[0] == BUS_SPACE_PIO
1340 && ahd->bshs[0].ioport != 0)
1341 release_region(ahd->bshs[0].ioport, 256);
1342 if (ahd->tags[1] == BUS_SPACE_PIO
1343 && ahd->bshs[1].ioport != 0)
1344 release_region(ahd->bshs[1].ioport, 256);
1345 if (ahd->tags[0] == BUS_SPACE_MEMIO
1346 && ahd->bshs[0].maddr != NULL) {
1347 iounmap(ahd->bshs[0].maddr);
1348 release_mem_region(ahd->platform_data->mem_busaddr,
1349 0x1000);
1350 }
1351 if (ahd->platform_data->host)
1352 scsi_host_put(ahd->platform_data->host);
1353
1354 kfree(ahd->platform_data);
1355 }
1356}
1357
1358void
1359ahd_platform_init(struct ahd_softc *ahd)
1360{
1361
1362
1363
1364 if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
1365 const struct ahd_linux_iocell_opts *iocell_opts;
1366
1367 iocell_opts = &aic79xx_iocell_info[ahd->unit];
1368 if (iocell_opts->precomp != AIC79XX_DEFAULT_PRECOMP)
1369 AHD_SET_PRECOMP(ahd, iocell_opts->precomp);
1370 if (iocell_opts->slewrate != AIC79XX_DEFAULT_SLEWRATE)
1371 AHD_SET_SLEWRATE(ahd, iocell_opts->slewrate);
1372 if (iocell_opts->amplitude != AIC79XX_DEFAULT_AMPLITUDE)
1373 AHD_SET_AMPLITUDE(ahd, iocell_opts->amplitude);
1374 }
1375
1376}
1377
1378void
1379ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
1380{
1381 ahd_platform_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
1382 SCB_GET_CHANNEL(ahd, scb),
1383 SCB_GET_LUN(scb), SCB_LIST_NULL,
1384 ROLE_UNKNOWN, CAM_REQUEUE_REQ);
1385}
1386
1387void
1388ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
1389 struct ahd_devinfo *devinfo, ahd_queue_alg alg)
1390{
1391 struct ahd_linux_device *dev;
1392 int was_queuing;
1393 int now_queuing;
1394
1395 if (sdev == NULL)
1396 return;
1397
1398 dev = scsi_transport_device_data(sdev);
1399
1400 if (dev == NULL)
1401 return;
1402 was_queuing = dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED);
1403 switch (alg) {
1404 default:
1405 case AHD_QUEUE_NONE:
1406 now_queuing = 0;
1407 break;
1408 case AHD_QUEUE_BASIC:
1409 now_queuing = AHD_DEV_Q_BASIC;
1410 break;
1411 case AHD_QUEUE_TAGGED:
1412 now_queuing = AHD_DEV_Q_TAGGED;
1413 break;
1414 }
1415 if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) == 0
1416 && (was_queuing != now_queuing)
1417 && (dev->active != 0)) {
1418 dev->flags |= AHD_DEV_FREEZE_TIL_EMPTY;
1419 dev->qfrozen++;
1420 }
1421
1422 dev->flags &= ~(AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED|AHD_DEV_PERIODIC_OTAG);
1423 if (now_queuing) {
1424 u_int usertags;
1425
1426 usertags = ahd_linux_user_tagdepth(ahd, devinfo);
1427 if (!was_queuing) {
1428
1429
1430
1431
1432
1433 dev->maxtags = usertags;
1434 dev->openings = dev->maxtags - dev->active;
1435 }
1436 if (dev->maxtags == 0) {
1437
1438
1439
1440 dev->openings = 1;
1441 } else if (alg == AHD_QUEUE_TAGGED) {
1442 dev->flags |= AHD_DEV_Q_TAGGED;
1443 if (aic79xx_periodic_otag != 0)
1444 dev->flags |= AHD_DEV_PERIODIC_OTAG;
1445 } else
1446 dev->flags |= AHD_DEV_Q_BASIC;
1447 } else {
1448
1449 dev->maxtags = 0;
1450 dev->openings = 1 - dev->active;
1451 }
1452
1453 switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) {
1454 case AHD_DEV_Q_BASIC:
1455 case AHD_DEV_Q_TAGGED:
1456 scsi_change_queue_depth(sdev,
1457 dev->openings + dev->active);
1458 break;
1459 default:
1460
1461
1462
1463
1464
1465
1466 scsi_change_queue_depth(sdev, 1);
1467 break;
1468 }
1469}
1470
1471int
1472ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel,
1473 int lun, u_int tag, role_t role, uint32_t status)
1474{
1475 return 0;
1476}
1477
1478static u_int
1479ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
1480{
1481 static int warned_user;
1482 u_int tags;
1483
1484 tags = 0;
1485 if ((ahd->user_discenable & devinfo->target_mask) != 0) {
1486 if (ahd->unit >= ARRAY_SIZE(aic79xx_tag_info)) {
1487
1488 if (warned_user == 0) {
1489 printk(KERN_WARNING
1490"aic79xx: WARNING: Insufficient tag_info instances\n"
1491"aic79xx: for installed controllers. Using defaults\n"
1492"aic79xx: Please update the aic79xx_tag_info array in\n"
1493"aic79xx: the aic79xx_osm.c source file.\n");
1494 warned_user++;
1495 }
1496 tags = AHD_MAX_QUEUE;
1497 } else {
1498 adapter_tag_info_t *tag_info;
1499
1500 tag_info = &aic79xx_tag_info[ahd->unit];
1501 tags = tag_info->tag_commands[devinfo->target_offset];
1502 if (tags > AHD_MAX_QUEUE)
1503 tags = AHD_MAX_QUEUE;
1504 }
1505 }
1506 return (tags);
1507}
1508
1509
1510
1511
1512static void
1513ahd_linux_device_queue_depth(struct scsi_device *sdev)
1514{
1515 struct ahd_devinfo devinfo;
1516 u_int tags;
1517 struct ahd_softc *ahd = *((struct ahd_softc **)sdev->host->hostdata);
1518
1519 ahd_compile_devinfo(&devinfo,
1520 ahd->our_id,
1521 sdev->sdev_target->id, sdev->lun,
1522 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1523 ROLE_INITIATOR);
1524 tags = ahd_linux_user_tagdepth(ahd, &devinfo);
1525 if (tags != 0 && sdev->tagged_supported != 0) {
1526
1527 ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_TAGGED);
1528 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1529 devinfo.lun, AC_TRANSFER_NEG);
1530 ahd_print_devinfo(ahd, &devinfo);
1531 printk("Tagged Queuing enabled. Depth %d\n", tags);
1532 } else {
1533 ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE);
1534 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1535 devinfo.lun, AC_TRANSFER_NEG);
1536 }
1537}
1538
1539static int
1540ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
1541 struct scsi_cmnd *cmd)
1542{
1543 struct scb *scb;
1544 struct hardware_scb *hscb;
1545 struct ahd_initiator_tinfo *tinfo;
1546 struct ahd_tmode_tstate *tstate;
1547 u_int col_idx;
1548 uint16_t mask;
1549 unsigned long flags;
1550 int nseg;
1551
1552 nseg = scsi_dma_map(cmd);
1553 if (nseg < 0)
1554 return SCSI_MLQUEUE_HOST_BUSY;
1555
1556 ahd_lock(ahd, &flags);
1557
1558
1559
1560
1561 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
1562 cmd->device->id, &tstate);
1563 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0
1564 || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
1565 col_idx = AHD_NEVER_COL_IDX;
1566 } else {
1567 col_idx = AHD_BUILD_COL_IDX(cmd->device->id,
1568 cmd->device->lun);
1569 }
1570 if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
1571 ahd->flags |= AHD_RESOURCE_SHORTAGE;
1572 ahd_unlock(ahd, &flags);
1573 scsi_dma_unmap(cmd);
1574 return SCSI_MLQUEUE_HOST_BUSY;
1575 }
1576
1577 scb->io_ctx = cmd;
1578 scb->platform_data->dev = dev;
1579 hscb = scb->hscb;
1580 cmd->host_scribble = (char *)scb;
1581
1582
1583
1584
1585 hscb->control = 0;
1586 hscb->scsiid = BUILD_SCSIID(ahd, cmd);
1587 hscb->lun = cmd->device->lun;
1588 scb->hscb->task_management = 0;
1589 mask = SCB_GET_TARGET_MASK(ahd, scb);
1590
1591 if ((ahd->user_discenable & mask) != 0)
1592 hscb->control |= DISCENB;
1593
1594 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0)
1595 scb->flags |= SCB_PACKETIZED;
1596
1597 if ((tstate->auto_negotiate & mask) != 0) {
1598 scb->flags |= SCB_AUTO_NEGOTIATE;
1599 scb->hscb->control |= MK_MESSAGE;
1600 }
1601
1602 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
1603 if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH
1604 && (dev->flags & AHD_DEV_Q_TAGGED) != 0) {
1605 hscb->control |= ORDERED_QUEUE_TAG;
1606 dev->commands_since_idle_or_otag = 0;
1607 } else {
1608 hscb->control |= SIMPLE_QUEUE_TAG;
1609 }
1610 }
1611
1612 hscb->cdb_len = cmd->cmd_len;
1613 memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len);
1614
1615 scb->platform_data->xfer_len = 0;
1616 ahd_set_residual(scb, 0);
1617 ahd_set_sense_residual(scb, 0);
1618 scb->sg_count = 0;
1619
1620 if (nseg > 0) {
1621 void *sg = scb->sg_list;
1622 struct scatterlist *cur_seg;
1623 int i;
1624
1625 scb->platform_data->xfer_len = 0;
1626
1627 scsi_for_each_sg(cmd, cur_seg, nseg, i) {
1628 dma_addr_t addr;
1629 bus_size_t len;
1630
1631 addr = sg_dma_address(cur_seg);
1632 len = sg_dma_len(cur_seg);
1633 scb->platform_data->xfer_len += len;
1634 sg = ahd_sg_setup(ahd, scb, sg, addr, len,
1635 i == (nseg - 1));
1636 }
1637 }
1638
1639 LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
1640 dev->openings--;
1641 dev->active++;
1642 dev->commands_issued++;
1643
1644 if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0)
1645 dev->commands_since_idle_or_otag++;
1646 scb->flags |= SCB_ACTIVE;
1647 ahd_queue_scb(ahd, scb);
1648
1649 ahd_unlock(ahd, &flags);
1650
1651 return 0;
1652}
1653
1654
1655
1656
1657irqreturn_t
1658ahd_linux_isr(int irq, void *dev_id)
1659{
1660 struct ahd_softc *ahd;
1661 u_long flags;
1662 int ours;
1663
1664 ahd = (struct ahd_softc *) dev_id;
1665 ahd_lock(ahd, &flags);
1666 ours = ahd_intr(ahd);
1667 ahd_unlock(ahd, &flags);
1668 return IRQ_RETVAL(ours);
1669}
1670
1671void
1672ahd_send_async(struct ahd_softc *ahd, char channel,
1673 u_int target, u_int lun, ac_code code)
1674{
1675 switch (code) {
1676 case AC_TRANSFER_NEG:
1677 {
1678 struct scsi_target *starget;
1679 struct ahd_initiator_tinfo *tinfo;
1680 struct ahd_tmode_tstate *tstate;
1681 unsigned int target_ppr_options;
1682
1683 BUG_ON(target == CAM_TARGET_WILDCARD);
1684
1685 tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
1686 target, &tstate);
1687
1688
1689
1690
1691
1692 if (tinfo->curr.period != tinfo->goal.period
1693 || tinfo->curr.width != tinfo->goal.width
1694 || tinfo->curr.offset != tinfo->goal.offset
1695 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
1696 if (bootverbose == 0)
1697 break;
1698
1699
1700
1701
1702
1703 starget = ahd->platform_data->starget[target];
1704 if (starget == NULL)
1705 break;
1706
1707 target_ppr_options =
1708 (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
1709 + (spi_qas(starget) ? MSG_EXT_PPR_QAS_REQ : 0)
1710 + (spi_iu(starget) ? MSG_EXT_PPR_IU_REQ : 0)
1711 + (spi_rd_strm(starget) ? MSG_EXT_PPR_RD_STRM : 0)
1712 + (spi_pcomp_en(starget) ? MSG_EXT_PPR_PCOMP_EN : 0)
1713 + (spi_rti(starget) ? MSG_EXT_PPR_RTI : 0)
1714 + (spi_wr_flow(starget) ? MSG_EXT_PPR_WR_FLOW : 0)
1715 + (spi_hold_mcs(starget) ? MSG_EXT_PPR_HOLD_MCS : 0);
1716
1717 if (tinfo->curr.period == spi_period(starget)
1718 && tinfo->curr.width == spi_width(starget)
1719 && tinfo->curr.offset == spi_offset(starget)
1720 && tinfo->curr.ppr_options == target_ppr_options)
1721 if (bootverbose == 0)
1722 break;
1723
1724 spi_period(starget) = tinfo->curr.period;
1725 spi_width(starget) = tinfo->curr.width;
1726 spi_offset(starget) = tinfo->curr.offset;
1727 spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
1728 spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
1729 spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
1730 spi_rd_strm(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_RD_STRM ? 1 : 0;
1731 spi_pcomp_en(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_PCOMP_EN ? 1 : 0;
1732 spi_rti(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_RTI ? 1 : 0;
1733 spi_wr_flow(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_WR_FLOW ? 1 : 0;
1734 spi_hold_mcs(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_HOLD_MCS ? 1 : 0;
1735 spi_display_xfer_agreement(starget);
1736 break;
1737 }
1738 case AC_SENT_BDR:
1739 {
1740 WARN_ON(lun != CAM_LUN_WILDCARD);
1741 scsi_report_device_reset(ahd->platform_data->host,
1742 channel - 'A', target);
1743 break;
1744 }
1745 case AC_BUS_RESET:
1746 if (ahd->platform_data->host != NULL) {
1747 scsi_report_bus_reset(ahd->platform_data->host,
1748 channel - 'A');
1749 }
1750 break;
1751 default:
1752 panic("ahd_send_async: Unexpected async event");
1753 }
1754}
1755
1756
1757
1758
1759void
1760ahd_done(struct ahd_softc *ahd, struct scb *scb)
1761{
1762 struct scsi_cmnd *cmd;
1763 struct ahd_linux_device *dev;
1764
1765 if ((scb->flags & SCB_ACTIVE) == 0) {
1766 printk("SCB %d done'd twice\n", SCB_GET_TAG(scb));
1767 ahd_dump_card_state(ahd);
1768 panic("Stopping for safety");
1769 }
1770 LIST_REMOVE(scb, pending_links);
1771 cmd = scb->io_ctx;
1772 dev = scb->platform_data->dev;
1773 dev->active--;
1774 dev->openings++;
1775 if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
1776 cmd->result &= ~(CAM_DEV_QFRZN << 16);
1777 dev->qfrozen--;
1778 }
1779 ahd_linux_unmap_scb(ahd, scb);
1780
1781
1782
1783
1784
1785
1786
1787 cmd->sense_buffer[0] = 0;
1788 if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) {
1789#ifdef AHD_REPORT_UNDERFLOWS
1790 uint32_t amount_xferred;
1791
1792 amount_xferred =
1793 ahd_get_transfer_length(scb) - ahd_get_residual(scb);
1794#endif
1795 if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
1796#ifdef AHD_DEBUG
1797 if ((ahd_debug & AHD_SHOW_MISC) != 0) {
1798 ahd_print_path(ahd, scb);
1799 printk("Set CAM_UNCOR_PARITY\n");
1800 }
1801#endif
1802 ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
1803#ifdef AHD_REPORT_UNDERFLOWS
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813 } else if (amount_xferred < scb->io_ctx->underflow) {
1814 u_int i;
1815
1816 ahd_print_path(ahd, scb);
1817 printk("CDB:");
1818 for (i = 0; i < scb->io_ctx->cmd_len; i++)
1819 printk(" 0x%x", scb->io_ctx->cmnd[i]);
1820 printk("\n");
1821 ahd_print_path(ahd, scb);
1822 printk("Saw underflow (%ld of %ld bytes). "
1823 "Treated as error\n",
1824 ahd_get_residual(scb),
1825 ahd_get_transfer_length(scb));
1826 ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1827#endif
1828 } else {
1829 ahd_set_transaction_status(scb, CAM_REQ_CMP);
1830 }
1831 } else if (ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
1832 ahd_linux_handle_scsi_status(ahd, cmd->device, scb);
1833 }
1834
1835 if (dev->openings == 1
1836 && ahd_get_transaction_status(scb) == CAM_REQ_CMP
1837 && ahd_get_scsi_status(scb) != SAM_STAT_TASK_SET_FULL)
1838 dev->tag_success_count++;
1839
1840
1841
1842
1843
1844
1845 if ((dev->openings + dev->active) < dev->maxtags
1846 && dev->tag_success_count > AHD_TAG_SUCCESS_INTERVAL) {
1847 dev->tag_success_count = 0;
1848 dev->openings++;
1849 }
1850
1851 if (dev->active == 0)
1852 dev->commands_since_idle_or_otag = 0;
1853
1854 if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
1855 printk("Recovery SCB completes\n");
1856 if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
1857 || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
1858 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
1859
1860 if (ahd->platform_data->eh_done)
1861 complete(ahd->platform_data->eh_done);
1862 }
1863
1864 ahd_free_scb(ahd, scb);
1865 ahd_linux_queue_cmd_complete(ahd, cmd);
1866}
1867
1868static void
1869ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
1870 struct scsi_device *sdev, struct scb *scb)
1871{
1872 struct ahd_devinfo devinfo;
1873 struct ahd_linux_device *dev = scsi_transport_device_data(sdev);
1874
1875 ahd_compile_devinfo(&devinfo,
1876 ahd->our_id,
1877 sdev->sdev_target->id, sdev->lun,
1878 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1879 ROLE_INITIATOR);
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891 switch (ahd_get_scsi_status(scb)) {
1892 default:
1893 break;
1894 case SAM_STAT_CHECK_CONDITION:
1895 case SAM_STAT_COMMAND_TERMINATED:
1896 {
1897 struct scsi_cmnd *cmd;
1898
1899
1900
1901
1902
1903 cmd = scb->io_ctx;
1904 if ((scb->flags & (SCB_SENSE|SCB_PKT_SENSE)) != 0) {
1905 struct scsi_status_iu_header *siu;
1906 u_int sense_size;
1907 u_int sense_offset;
1908
1909 if (scb->flags & SCB_SENSE) {
1910 sense_size = min(sizeof(struct scsi_sense_data)
1911 - ahd_get_sense_residual(scb),
1912 (u_long)SCSI_SENSE_BUFFERSIZE);
1913 sense_offset = 0;
1914 } else {
1915
1916
1917
1918
1919 siu = (struct scsi_status_iu_header *)
1920 scb->sense_data;
1921 sense_size = min_t(size_t,
1922 scsi_4btoul(siu->sense_length),
1923 SCSI_SENSE_BUFFERSIZE);
1924 sense_offset = SIU_SENSE_OFFSET(siu);
1925 }
1926
1927 memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
1928 memcpy(cmd->sense_buffer,
1929 ahd_get_sense_buf(ahd, scb)
1930 + sense_offset, sense_size);
1931 set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);
1932
1933#ifdef AHD_DEBUG
1934 if (ahd_debug & AHD_SHOW_SENSE) {
1935 int i;
1936
1937 printk("Copied %d bytes of sense data at %d:",
1938 sense_size, sense_offset);
1939 for (i = 0; i < sense_size; i++) {
1940 if ((i & 0xF) == 0)
1941 printk("\n");
1942 printk("0x%x ", cmd->sense_buffer[i]);
1943 }
1944 printk("\n");
1945 }
1946#endif
1947 }
1948 break;
1949 }
1950 case SAM_STAT_TASK_SET_FULL:
1951
1952
1953
1954
1955
1956
1957
1958
1959 dev->tag_success_count = 0;
1960 if (dev->active != 0) {
1961
1962
1963
1964
1965 dev->openings = 0;
1966#ifdef AHD_DEBUG
1967 if ((ahd_debug & AHD_SHOW_QFULL) != 0) {
1968 ahd_print_path(ahd, scb);
1969 printk("Dropping tag count to %d\n",
1970 dev->active);
1971 }
1972#endif
1973 if (dev->active == dev->tags_on_last_queuefull) {
1974
1975 dev->last_queuefull_same_count++;
1976
1977
1978
1979
1980
1981
1982
1983
1984 if (dev->last_queuefull_same_count
1985 == AHD_LOCK_TAGS_COUNT) {
1986 dev->maxtags = dev->active;
1987 ahd_print_path(ahd, scb);
1988 printk("Locking max tag count at %d\n",
1989 dev->active);
1990 }
1991 } else {
1992 dev->tags_on_last_queuefull = dev->active;
1993 dev->last_queuefull_same_count = 0;
1994 }
1995 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
1996 ahd_set_scsi_status(scb, SAM_STAT_GOOD);
1997 ahd_platform_set_tags(ahd, sdev, &devinfo,
1998 (dev->flags & AHD_DEV_Q_BASIC)
1999 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
2000 break;
2001 }
2002
2003
2004
2005
2006 dev->openings = 1;
2007 ahd_platform_set_tags(ahd, sdev, &devinfo,
2008 (dev->flags & AHD_DEV_Q_BASIC)
2009 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
2010 ahd_set_scsi_status(scb, SAM_STAT_BUSY);
2011 }
2012}
2013
2014static void
2015ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
2016{
2017 int status;
2018 int new_status = DID_OK;
2019 int do_fallback = 0;
2020 int scsi_status;
2021 struct scsi_sense_data *sense;
2022
2023
2024
2025
2026
2027
2028
2029
2030 status = ahd_cmd_get_transaction_status(cmd);
2031 switch (status) {
2032 case CAM_REQ_INPROG:
2033 case CAM_REQ_CMP:
2034 new_status = DID_OK;
2035 break;
2036 case CAM_AUTOSENSE_FAIL:
2037 new_status = DID_ERROR;
2038 fallthrough;
2039 case CAM_SCSI_STATUS_ERROR:
2040 scsi_status = ahd_cmd_get_scsi_status(cmd);
2041
2042 switch(scsi_status) {
2043 case SAM_STAT_COMMAND_TERMINATED:
2044 case SAM_STAT_CHECK_CONDITION:
2045 sense = (struct scsi_sense_data *)
2046 cmd->sense_buffer;
2047 if (sense->extra_len >= 5 &&
2048 (sense->add_sense_code == 0x47
2049 || sense->add_sense_code == 0x48))
2050 do_fallback = 1;
2051 break;
2052 default:
2053 break;
2054 }
2055 break;
2056 case CAM_REQ_ABORTED:
2057 new_status = DID_ABORT;
2058 break;
2059 case CAM_BUSY:
2060 new_status = DID_BUS_BUSY;
2061 break;
2062 case CAM_REQ_INVALID:
2063 case CAM_PATH_INVALID:
2064 new_status = DID_BAD_TARGET;
2065 break;
2066 case CAM_SEL_TIMEOUT:
2067 new_status = DID_NO_CONNECT;
2068 break;
2069 case CAM_SCSI_BUS_RESET:
2070 case CAM_BDR_SENT:
2071 new_status = DID_RESET;
2072 break;
2073 case CAM_UNCOR_PARITY:
2074 new_status = DID_PARITY;
2075 do_fallback = 1;
2076 break;
2077 case CAM_CMD_TIMEOUT:
2078 new_status = DID_TIME_OUT;
2079 do_fallback = 1;
2080 break;
2081 case CAM_REQ_CMP_ERR:
2082 case CAM_UNEXP_BUSFREE:
2083 case CAM_DATA_RUN_ERR:
2084 new_status = DID_ERROR;
2085 do_fallback = 1;
2086 break;
2087 case CAM_UA_ABORT:
2088 case CAM_NO_HBA:
2089 case CAM_SEQUENCE_FAIL:
2090 case CAM_CCB_LEN_ERR:
2091 case CAM_PROVIDE_FAIL:
2092 case CAM_REQ_TERMIO:
2093 case CAM_UNREC_HBA_ERROR:
2094 case CAM_REQ_TOO_BIG:
2095 new_status = DID_ERROR;
2096 break;
2097 case CAM_REQUEUE_REQ:
2098 new_status = DID_REQUEUE;
2099 break;
2100 default:
2101
2102 new_status = DID_ERROR;
2103 break;
2104 }
2105
2106 if (do_fallback) {
2107 printk("%s: device overrun (status %x) on %d:%d:%d\n",
2108 ahd_name(ahd), status, cmd->device->channel,
2109 cmd->device->id, (u8)cmd->device->lun);
2110 }
2111
2112 ahd_cmd_set_transaction_status(cmd, new_status);
2113
2114 cmd->scsi_done(cmd);
2115}
2116
2117static void
2118ahd_freeze_simq(struct ahd_softc *ahd)
2119{
2120 scsi_block_requests(ahd->platform_data->host);
2121}
2122
2123static void
2124ahd_release_simq(struct ahd_softc *ahd)
2125{
2126 scsi_unblock_requests(ahd->platform_data->host);
2127}
2128
2129static int
2130ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
2131{
2132 struct ahd_softc *ahd;
2133 struct ahd_linux_device *dev;
2134 struct scb *pending_scb;
2135 u_int saved_scbptr;
2136 u_int active_scbptr;
2137 u_int last_phase;
2138 u_int cdb_byte;
2139 int retval = SUCCESS;
2140 int was_paused;
2141 int paused;
2142 int wait;
2143 int disconnected;
2144 ahd_mode_state saved_modes;
2145 unsigned long flags;
2146
2147 pending_scb = NULL;
2148 paused = FALSE;
2149 wait = FALSE;
2150 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
2151
2152 scmd_printk(KERN_INFO, cmd,
2153 "Attempting to queue an ABORT message:");
2154
2155 printk("CDB:");
2156 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
2157 printk(" 0x%x", cmd->cmnd[cdb_byte]);
2158 printk("\n");
2159
2160 ahd_lock(ahd, &flags);
2161
2162
2163
2164
2165
2166
2167
2168
2169 dev = scsi_transport_device_data(cmd->device);
2170
2171 if (dev == NULL) {
2172
2173
2174
2175
2176 scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
2177 goto done;
2178 }
2179
2180
2181
2182
2183 LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
2184 if (pending_scb->io_ctx == cmd)
2185 break;
2186 }
2187
2188 if (pending_scb == NULL) {
2189 scmd_printk(KERN_INFO, cmd, "Command not found\n");
2190 goto done;
2191 }
2192
2193 if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
2194
2195
2196
2197 retval = FAILED;
2198 goto done;
2199 }
2200
2201
2202
2203
2204
2205
2206
2207 was_paused = ahd_is_paused(ahd);
2208 ahd_pause_and_flushwork(ahd);
2209 paused = TRUE;
2210
2211 if ((pending_scb->flags & SCB_ACTIVE) == 0) {
2212 scmd_printk(KERN_INFO, cmd, "Command already completed\n");
2213 goto done;
2214 }
2215
2216 printk("%s: At time of recovery, card was %spaused\n",
2217 ahd_name(ahd), was_paused ? "" : "not ");
2218 ahd_dump_card_state(ahd);
2219
2220 disconnected = TRUE;
2221 if (ahd_search_qinfifo(ahd, cmd->device->id,
2222 cmd->device->channel + 'A',
2223 cmd->device->lun,
2224 pending_scb->hscb->tag,
2225 ROLE_INITIATOR, CAM_REQ_ABORTED,
2226 SEARCH_COMPLETE) > 0) {
2227 printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
2228 ahd_name(ahd), cmd->device->channel,
2229 cmd->device->id, (u8)cmd->device->lun);
2230 goto done;
2231 }
2232
2233 saved_modes = ahd_save_modes(ahd);
2234 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2235 last_phase = ahd_inb(ahd, LASTPHASE);
2236 saved_scbptr = ahd_get_scbptr(ahd);
2237 active_scbptr = saved_scbptr;
2238 if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
2239 struct scb *bus_scb;
2240
2241 bus_scb = ahd_lookup_scb(ahd, active_scbptr);
2242 if (bus_scb == pending_scb)
2243 disconnected = FALSE;
2244 }
2245
2246
2247
2248
2249
2250
2251 ahd_inb(ahd, SAVED_SCSIID);
2252 if (last_phase != P_BUSFREE
2253 && SCB_GET_TAG(pending_scb) == active_scbptr) {
2254
2255
2256
2257
2258
2259 pending_scb = ahd_lookup_scb(ahd, active_scbptr);
2260 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
2261 ahd_outb(ahd, MSG_OUT, HOST_MSG);
2262 ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
2263 scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
2264 wait = TRUE;
2265 } else if (disconnected) {
2266
2267
2268
2269
2270
2271 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
2272 ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));
2273 pending_scb->hscb->cdb_len = 0;
2274 pending_scb->hscb->task_attribute = 0;
2275 pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK;
2276
2277 if ((pending_scb->flags & SCB_PACKETIZED) != 0) {
2278
2279
2280
2281
2282
2283
2284
2285 ahd_outb(ahd, SCB_TASK_MANAGEMENT,
2286 pending_scb->hscb->task_management);
2287 } else {
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297 pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
2298
2299
2300
2301
2302
2303
2304
2305 ahd_outb(ahd, SCB_CONTROL,
2306 ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE);
2307 }
2308
2309
2310
2311
2312
2313
2314 ahd_search_qinfifo(ahd, cmd->device->id,
2315 cmd->device->channel + 'A', cmd->device->lun,
2316 SCB_LIST_NULL, ROLE_INITIATOR,
2317 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
2318 ahd_qinfifo_requeue_tail(ahd, pending_scb);
2319 ahd_set_scbptr(ahd, saved_scbptr);
2320 ahd_print_path(ahd, pending_scb);
2321 printk("Device is disconnected, re-queuing SCB\n");
2322 wait = TRUE;
2323 } else {
2324 scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
2325 retval = FAILED;
2326 }
2327
2328
2329 ahd_restore_modes(ahd, saved_modes);
2330done:
2331 if (paused)
2332 ahd_unpause(ahd);
2333 if (wait) {
2334 DECLARE_COMPLETION_ONSTACK(done);
2335
2336 ahd->platform_data->eh_done = &done;
2337 ahd_unlock(ahd, &flags);
2338
2339 printk("%s: Recovery code sleeping\n", ahd_name(ahd));
2340 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
2341 ahd_lock(ahd, &flags);
2342 ahd->platform_data->eh_done = NULL;
2343 ahd_unlock(ahd, &flags);
2344 printk("%s: Timer Expired (active %d)\n",
2345 ahd_name(ahd), dev->active);
2346 retval = FAILED;
2347 }
2348 printk("Recovery code awake\n");
2349 } else
2350 ahd_unlock(ahd, &flags);
2351
2352 if (retval != SUCCESS)
2353 printk("%s: Command abort returning 0x%x\n",
2354 ahd_name(ahd), retval);
2355
2356 return retval;
2357}
2358
2359static void ahd_linux_set_width(struct scsi_target *starget, int width)
2360{
2361 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2362 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2363 struct ahd_devinfo devinfo;
2364 unsigned long flags;
2365
2366 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2367 starget->channel + 'A', ROLE_INITIATOR);
2368 ahd_lock(ahd, &flags);
2369 ahd_set_width(ahd, &devinfo, width, AHD_TRANS_GOAL, FALSE);
2370 ahd_unlock(ahd, &flags);
2371}
2372
2373static void ahd_linux_set_period(struct scsi_target *starget, int period)
2374{
2375 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2376 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2377 struct ahd_tmode_tstate *tstate;
2378 struct ahd_initiator_tinfo *tinfo
2379 = ahd_fetch_transinfo(ahd,
2380 starget->channel + 'A',
2381 shost->this_id, starget->id, &tstate);
2382 struct ahd_devinfo devinfo;
2383 unsigned int ppr_options = tinfo->goal.ppr_options;
2384 unsigned int dt;
2385 unsigned long flags;
2386 unsigned long offset = tinfo->goal.offset;
2387
2388#ifdef AHD_DEBUG
2389 if ((ahd_debug & AHD_SHOW_DV) != 0)
2390 printk("%s: set period to %d\n", ahd_name(ahd), period);
2391#endif
2392 if (offset == 0)
2393 offset = MAX_OFFSET;
2394
2395 if (period < 8)
2396 period = 8;
2397 if (period < 10) {
2398 if (spi_max_width(starget)) {
2399 ppr_options |= MSG_EXT_PPR_DT_REQ;
2400 if (period == 8)
2401 ppr_options |= MSG_EXT_PPR_IU_REQ;
2402 } else
2403 period = 10;
2404 }
2405
2406 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2407
2408 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2409 starget->channel + 'A', ROLE_INITIATOR);
2410
2411
2412 if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) {
2413 if (spi_width(starget) == 0)
2414 ppr_options &= MSG_EXT_PPR_QAS_REQ;
2415 }
2416
2417 ahd_find_syncrate(ahd, &period, &ppr_options,
2418 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2419
2420 ahd_lock(ahd, &flags);
2421 ahd_set_syncrate(ahd, &devinfo, period, offset,
2422 ppr_options, AHD_TRANS_GOAL, FALSE);
2423 ahd_unlock(ahd, &flags);
2424}
2425
2426static void ahd_linux_set_offset(struct scsi_target *starget, int offset)
2427{
2428 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2429 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2430 struct ahd_tmode_tstate *tstate;
2431 struct ahd_initiator_tinfo *tinfo
2432 = ahd_fetch_transinfo(ahd,
2433 starget->channel + 'A',
2434 shost->this_id, starget->id, &tstate);
2435 struct ahd_devinfo devinfo;
2436 unsigned int ppr_options = 0;
2437 unsigned int period = 0;
2438 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2439 unsigned long flags;
2440
2441#ifdef AHD_DEBUG
2442 if ((ahd_debug & AHD_SHOW_DV) != 0)
2443 printk("%s: set offset to %d\n", ahd_name(ahd), offset);
2444#endif
2445
2446 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2447 starget->channel + 'A', ROLE_INITIATOR);
2448 if (offset != 0) {
2449 period = tinfo->goal.period;
2450 ppr_options = tinfo->goal.ppr_options;
2451 ahd_find_syncrate(ahd, &period, &ppr_options,
2452 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2453 }
2454
2455 ahd_lock(ahd, &flags);
2456 ahd_set_syncrate(ahd, &devinfo, period, offset, ppr_options,
2457 AHD_TRANS_GOAL, FALSE);
2458 ahd_unlock(ahd, &flags);
2459}
2460
2461static void ahd_linux_set_dt(struct scsi_target *starget, int dt)
2462{
2463 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2464 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2465 struct ahd_tmode_tstate *tstate;
2466 struct ahd_initiator_tinfo *tinfo
2467 = ahd_fetch_transinfo(ahd,
2468 starget->channel + 'A',
2469 shost->this_id, starget->id, &tstate);
2470 struct ahd_devinfo devinfo;
2471 unsigned int ppr_options = tinfo->goal.ppr_options
2472 & ~MSG_EXT_PPR_DT_REQ;
2473 unsigned int period = tinfo->goal.period;
2474 unsigned int width = tinfo->goal.width;
2475 unsigned long flags;
2476
2477#ifdef AHD_DEBUG
2478 if ((ahd_debug & AHD_SHOW_DV) != 0)
2479 printk("%s: %s DT\n", ahd_name(ahd),
2480 dt ? "enabling" : "disabling");
2481#endif
2482 if (dt && spi_max_width(starget)) {
2483 ppr_options |= MSG_EXT_PPR_DT_REQ;
2484 if (!width)
2485 ahd_linux_set_width(starget, 1);
2486 } else {
2487 if (period <= 9)
2488 period = 10;
2489
2490 ppr_options &= ~MSG_EXT_PPR_IU_REQ;
2491 }
2492 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2493 starget->channel + 'A', ROLE_INITIATOR);
2494 ahd_find_syncrate(ahd, &period, &ppr_options,
2495 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2496
2497 ahd_lock(ahd, &flags);
2498 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2499 ppr_options, AHD_TRANS_GOAL, FALSE);
2500 ahd_unlock(ahd, &flags);
2501}
2502
2503static void ahd_linux_set_qas(struct scsi_target *starget, int qas)
2504{
2505 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2506 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2507 struct ahd_tmode_tstate *tstate;
2508 struct ahd_initiator_tinfo *tinfo
2509 = ahd_fetch_transinfo(ahd,
2510 starget->channel + 'A',
2511 shost->this_id, starget->id, &tstate);
2512 struct ahd_devinfo devinfo;
2513 unsigned int ppr_options = tinfo->goal.ppr_options
2514 & ~MSG_EXT_PPR_QAS_REQ;
2515 unsigned int period = tinfo->goal.period;
2516 unsigned int dt;
2517 unsigned long flags;
2518
2519#ifdef AHD_DEBUG
2520 if ((ahd_debug & AHD_SHOW_DV) != 0)
2521 printk("%s: %s QAS\n", ahd_name(ahd),
2522 qas ? "enabling" : "disabling");
2523#endif
2524
2525 if (qas) {
2526 ppr_options |= MSG_EXT_PPR_QAS_REQ;
2527 }
2528
2529 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2530
2531 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2532 starget->channel + 'A', ROLE_INITIATOR);
2533 ahd_find_syncrate(ahd, &period, &ppr_options,
2534 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2535
2536 ahd_lock(ahd, &flags);
2537 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2538 ppr_options, AHD_TRANS_GOAL, FALSE);
2539 ahd_unlock(ahd, &flags);
2540}
2541
2542static void ahd_linux_set_iu(struct scsi_target *starget, int iu)
2543{
2544 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2545 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2546 struct ahd_tmode_tstate *tstate;
2547 struct ahd_initiator_tinfo *tinfo
2548 = ahd_fetch_transinfo(ahd,
2549 starget->channel + 'A',
2550 shost->this_id, starget->id, &tstate);
2551 struct ahd_devinfo devinfo;
2552 unsigned int ppr_options = tinfo->goal.ppr_options
2553 & ~MSG_EXT_PPR_IU_REQ;
2554 unsigned int period = tinfo->goal.period;
2555 unsigned int dt;
2556 unsigned long flags;
2557
2558#ifdef AHD_DEBUG
2559 if ((ahd_debug & AHD_SHOW_DV) != 0)
2560 printk("%s: %s IU\n", ahd_name(ahd),
2561 iu ? "enabling" : "disabling");
2562#endif
2563
2564 if (iu && spi_max_width(starget)) {
2565 ppr_options |= MSG_EXT_PPR_IU_REQ;
2566 ppr_options |= MSG_EXT_PPR_DT_REQ;
2567 }
2568
2569 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2570
2571 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2572 starget->channel + 'A', ROLE_INITIATOR);
2573 ahd_find_syncrate(ahd, &period, &ppr_options,
2574 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2575
2576 ahd_lock(ahd, &flags);
2577 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2578 ppr_options, AHD_TRANS_GOAL, FALSE);
2579 ahd_unlock(ahd, &flags);
2580}
2581
2582static void ahd_linux_set_rd_strm(struct scsi_target *starget, int rdstrm)
2583{
2584 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2585 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2586 struct ahd_tmode_tstate *tstate;
2587 struct ahd_initiator_tinfo *tinfo
2588 = ahd_fetch_transinfo(ahd,
2589 starget->channel + 'A',
2590 shost->this_id, starget->id, &tstate);
2591 struct ahd_devinfo devinfo;
2592 unsigned int ppr_options = tinfo->goal.ppr_options
2593 & ~MSG_EXT_PPR_RD_STRM;
2594 unsigned int period = tinfo->goal.period;
2595 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2596 unsigned long flags;
2597
2598#ifdef AHD_DEBUG
2599 if ((ahd_debug & AHD_SHOW_DV) != 0)
2600 printk("%s: %s Read Streaming\n", ahd_name(ahd),
2601 rdstrm ? "enabling" : "disabling");
2602#endif
2603
2604 if (rdstrm && spi_max_width(starget))
2605 ppr_options |= MSG_EXT_PPR_RD_STRM;
2606
2607 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2608 starget->channel + 'A', ROLE_INITIATOR);
2609 ahd_find_syncrate(ahd, &period, &ppr_options,
2610 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2611
2612 ahd_lock(ahd, &flags);
2613 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2614 ppr_options, AHD_TRANS_GOAL, FALSE);
2615 ahd_unlock(ahd, &flags);
2616}
2617
2618static void ahd_linux_set_wr_flow(struct scsi_target *starget, int wrflow)
2619{
2620 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2621 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2622 struct ahd_tmode_tstate *tstate;
2623 struct ahd_initiator_tinfo *tinfo
2624 = ahd_fetch_transinfo(ahd,
2625 starget->channel + 'A',
2626 shost->this_id, starget->id, &tstate);
2627 struct ahd_devinfo devinfo;
2628 unsigned int ppr_options = tinfo->goal.ppr_options
2629 & ~MSG_EXT_PPR_WR_FLOW;
2630 unsigned int period = tinfo->goal.period;
2631 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2632 unsigned long flags;
2633
2634#ifdef AHD_DEBUG
2635 if ((ahd_debug & AHD_SHOW_DV) != 0)
2636 printk("%s: %s Write Flow Control\n", ahd_name(ahd),
2637 wrflow ? "enabling" : "disabling");
2638#endif
2639
2640 if (wrflow && spi_max_width(starget))
2641 ppr_options |= MSG_EXT_PPR_WR_FLOW;
2642
2643 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2644 starget->channel + 'A', ROLE_INITIATOR);
2645 ahd_find_syncrate(ahd, &period, &ppr_options,
2646 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2647
2648 ahd_lock(ahd, &flags);
2649 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2650 ppr_options, AHD_TRANS_GOAL, FALSE);
2651 ahd_unlock(ahd, &flags);
2652}
2653
2654static void ahd_linux_set_rti(struct scsi_target *starget, int rti)
2655{
2656 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2657 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2658 struct ahd_tmode_tstate *tstate;
2659 struct ahd_initiator_tinfo *tinfo
2660 = ahd_fetch_transinfo(ahd,
2661 starget->channel + 'A',
2662 shost->this_id, starget->id, &tstate);
2663 struct ahd_devinfo devinfo;
2664 unsigned int ppr_options = tinfo->goal.ppr_options
2665 & ~MSG_EXT_PPR_RTI;
2666 unsigned int period = tinfo->goal.period;
2667 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2668 unsigned long flags;
2669
2670 if ((ahd->features & AHD_RTI) == 0) {
2671#ifdef AHD_DEBUG
2672 if ((ahd_debug & AHD_SHOW_DV) != 0)
2673 printk("%s: RTI not available\n", ahd_name(ahd));
2674#endif
2675 return;
2676 }
2677
2678#ifdef AHD_DEBUG
2679 if ((ahd_debug & AHD_SHOW_DV) != 0)
2680 printk("%s: %s RTI\n", ahd_name(ahd),
2681 rti ? "enabling" : "disabling");
2682#endif
2683
2684 if (rti && spi_max_width(starget))
2685 ppr_options |= MSG_EXT_PPR_RTI;
2686
2687 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2688 starget->channel + 'A', ROLE_INITIATOR);
2689 ahd_find_syncrate(ahd, &period, &ppr_options,
2690 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2691
2692 ahd_lock(ahd, &flags);
2693 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2694 ppr_options, AHD_TRANS_GOAL, FALSE);
2695 ahd_unlock(ahd, &flags);
2696}
2697
2698static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp)
2699{
2700 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2701 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2702 struct ahd_tmode_tstate *tstate;
2703 struct ahd_initiator_tinfo *tinfo
2704 = ahd_fetch_transinfo(ahd,
2705 starget->channel + 'A',
2706 shost->this_id, starget->id, &tstate);
2707 struct ahd_devinfo devinfo;
2708 unsigned int ppr_options = tinfo->goal.ppr_options
2709 & ~MSG_EXT_PPR_PCOMP_EN;
2710 unsigned int period = tinfo->goal.period;
2711 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2712 unsigned long flags;
2713
2714#ifdef AHD_DEBUG
2715 if ((ahd_debug & AHD_SHOW_DV) != 0)
2716 printk("%s: %s Precompensation\n", ahd_name(ahd),
2717 pcomp ? "Enable" : "Disable");
2718#endif
2719
2720 if (pcomp && spi_max_width(starget)) {
2721 uint8_t precomp;
2722
2723 if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
2724 const struct ahd_linux_iocell_opts *iocell_opts;
2725
2726 iocell_opts = &aic79xx_iocell_info[ahd->unit];
2727 precomp = iocell_opts->precomp;
2728 } else {
2729 precomp = AIC79XX_DEFAULT_PRECOMP;
2730 }
2731 ppr_options |= MSG_EXT_PPR_PCOMP_EN;
2732 AHD_SET_PRECOMP(ahd, precomp);
2733 } else {
2734 AHD_SET_PRECOMP(ahd, 0);
2735 }
2736
2737 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2738 starget->channel + 'A', ROLE_INITIATOR);
2739 ahd_find_syncrate(ahd, &period, &ppr_options,
2740 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2741
2742 ahd_lock(ahd, &flags);
2743 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2744 ppr_options, AHD_TRANS_GOAL, FALSE);
2745 ahd_unlock(ahd, &flags);
2746}
2747
2748static void ahd_linux_set_hold_mcs(struct scsi_target *starget, int hold)
2749{
2750 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2751 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2752 struct ahd_tmode_tstate *tstate;
2753 struct ahd_initiator_tinfo *tinfo
2754 = ahd_fetch_transinfo(ahd,
2755 starget->channel + 'A',
2756 shost->this_id, starget->id, &tstate);
2757 struct ahd_devinfo devinfo;
2758 unsigned int ppr_options = tinfo->goal.ppr_options
2759 & ~MSG_EXT_PPR_HOLD_MCS;
2760 unsigned int period = tinfo->goal.period;
2761 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2762 unsigned long flags;
2763
2764 if (hold && spi_max_width(starget))
2765 ppr_options |= MSG_EXT_PPR_HOLD_MCS;
2766
2767 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2768 starget->channel + 'A', ROLE_INITIATOR);
2769 ahd_find_syncrate(ahd, &period, &ppr_options,
2770 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2771
2772 ahd_lock(ahd, &flags);
2773 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2774 ppr_options, AHD_TRANS_GOAL, FALSE);
2775 ahd_unlock(ahd, &flags);
2776}
2777
2778static void ahd_linux_get_signalling(struct Scsi_Host *shost)
2779{
2780 struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata;
2781 unsigned long flags;
2782 u8 mode;
2783
2784 ahd_lock(ahd, &flags);
2785 ahd_pause(ahd);
2786 mode = ahd_inb(ahd, SBLKCTL);
2787 ahd_unpause(ahd);
2788 ahd_unlock(ahd, &flags);
2789
2790 if (mode & ENAB40)
2791 spi_signalling(shost) = SPI_SIGNAL_LVD;
2792 else if (mode & ENAB20)
2793 spi_signalling(shost) = SPI_SIGNAL_SE;
2794 else
2795 spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
2796}
2797
2798static struct spi_function_template ahd_linux_transport_functions = {
2799 .set_offset = ahd_linux_set_offset,
2800 .show_offset = 1,
2801 .set_period = ahd_linux_set_period,
2802 .show_period = 1,
2803 .set_width = ahd_linux_set_width,
2804 .show_width = 1,
2805 .set_dt = ahd_linux_set_dt,
2806 .show_dt = 1,
2807 .set_iu = ahd_linux_set_iu,
2808 .show_iu = 1,
2809 .set_qas = ahd_linux_set_qas,
2810 .show_qas = 1,
2811 .set_rd_strm = ahd_linux_set_rd_strm,
2812 .show_rd_strm = 1,
2813 .set_wr_flow = ahd_linux_set_wr_flow,
2814 .show_wr_flow = 1,
2815 .set_rti = ahd_linux_set_rti,
2816 .show_rti = 1,
2817 .set_pcomp_en = ahd_linux_set_pcomp_en,
2818 .show_pcomp_en = 1,
2819 .set_hold_mcs = ahd_linux_set_hold_mcs,
2820 .show_hold_mcs = 1,
2821 .get_signalling = ahd_linux_get_signalling,
2822};
2823
2824static int __init
2825ahd_linux_init(void)
2826{
2827 int error = 0;
2828
2829
2830
2831
2832 if (aic79xx)
2833 aic79xx_setup(aic79xx);
2834
2835 ahd_linux_transport_template =
2836 spi_attach_transport(&ahd_linux_transport_functions);
2837 if (!ahd_linux_transport_template)
2838 return -ENODEV;
2839
2840 scsi_transport_reserve_device(ahd_linux_transport_template,
2841 sizeof(struct ahd_linux_device));
2842
2843 error = ahd_linux_pci_init();
2844 if (error)
2845 spi_release_transport(ahd_linux_transport_template);
2846 return error;
2847}
2848
2849static void __exit
2850ahd_linux_exit(void)
2851{
2852 ahd_linux_pci_exit();
2853 spi_release_transport(ahd_linux_transport_template);
2854}
2855
2856module_init(ahd_linux_init);
2857module_exit(ahd_linux_exit);
2858