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