1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122#include "aic7xxx_osm.h"
123#include "aic7xxx_inline.h"
124#include <scsi/scsicam.h>
125
126static struct scsi_transport_template *ahc_linux_transport_template = NULL;
127
128#include <linux/init.h>
129#include <linux/mm.h>
130#include <linux/blkdev.h>
131#include <linux/delay.h>
132#include <linux/slab.h>
133
134
135
136
137
138
139
140
141#ifdef CONFIG_AIC7XXX_RESET_DELAY_MS
142#define AIC7XXX_RESET_DELAY CONFIG_AIC7XXX_RESET_DELAY_MS
143#else
144#define AIC7XXX_RESET_DELAY 5000
145#endif
146
147
148
149
150
151
152
153
154
155
156
157
158typedef struct {
159 uint8_t tag_commands[16];
160} adapter_tag_info_t;
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205#ifdef CONFIG_AIC7XXX_CMDS_PER_DEVICE
206#define AIC7XXX_CMDS_PER_DEVICE CONFIG_AIC7XXX_CMDS_PER_DEVICE
207#else
208#define AIC7XXX_CMDS_PER_DEVICE AHC_MAX_QUEUE
209#endif
210
211#define AIC7XXX_CONFIGED_TAG_COMMANDS { \
212 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
213 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
214 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
215 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
216 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
217 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
218 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE, \
219 AIC7XXX_CMDS_PER_DEVICE, AIC7XXX_CMDS_PER_DEVICE \
220}
221
222
223
224
225
226static adapter_tag_info_t aic7xxx_tag_info[] =
227{
228 {AIC7XXX_CONFIGED_TAG_COMMANDS},
229 {AIC7XXX_CONFIGED_TAG_COMMANDS},
230 {AIC7XXX_CONFIGED_TAG_COMMANDS},
231 {AIC7XXX_CONFIGED_TAG_COMMANDS},
232 {AIC7XXX_CONFIGED_TAG_COMMANDS},
233 {AIC7XXX_CONFIGED_TAG_COMMANDS},
234 {AIC7XXX_CONFIGED_TAG_COMMANDS},
235 {AIC7XXX_CONFIGED_TAG_COMMANDS},
236 {AIC7XXX_CONFIGED_TAG_COMMANDS},
237 {AIC7XXX_CONFIGED_TAG_COMMANDS},
238 {AIC7XXX_CONFIGED_TAG_COMMANDS},
239 {AIC7XXX_CONFIGED_TAG_COMMANDS},
240 {AIC7XXX_CONFIGED_TAG_COMMANDS},
241 {AIC7XXX_CONFIGED_TAG_COMMANDS},
242 {AIC7XXX_CONFIGED_TAG_COMMANDS},
243 {AIC7XXX_CONFIGED_TAG_COMMANDS}
244};
245
246
247
248
249
250#define DID_UNDERFLOW DID_ERROR
251
252void
253ahc_print_path(struct ahc_softc *ahc, struct scb *scb)
254{
255 printk("(scsi%d:%c:%d:%d): ",
256 ahc->platform_data->host->host_no,
257 scb != NULL ? SCB_GET_CHANNEL(ahc, scb) : 'X',
258 scb != NULL ? SCB_GET_TARGET(ahc, scb) : -1,
259 scb != NULL ? SCB_GET_LUN(scb) : -1);
260}
261
262
263
264
265
266
267
268
269
270
271
272
273static uint32_t aic7xxx_no_reset;
274
275
276
277
278
279
280static uint32_t aic7xxx_extended;
281
282
283
284
285
286
287
288
289
290
291
292static uint32_t aic7xxx_pci_parity = ~0;
293
294
295
296
297
298
299
300uint32_t aic7xxx_allow_memio = ~0;
301
302
303
304
305
306
307
308
309
310
311
312static uint32_t aic7xxx_seltime;
313
314
315
316
317
318
319
320
321
322static uint32_t aic7xxx_periodic_otag;
323
324
325
326
327static char *aic7xxx = NULL;
328
329MODULE_AUTHOR("Maintainer: Hannes Reinecke <hare@suse.de>");
330MODULE_DESCRIPTION("Adaptec AIC77XX/78XX SCSI Host Bus Adapter driver");
331MODULE_LICENSE("Dual BSD/GPL");
332MODULE_VERSION(AIC7XXX_DRIVER_VERSION);
333module_param(aic7xxx, charp, 0444);
334MODULE_PARM_DESC(aic7xxx,
335"period-delimited options string:\n"
336" verbose Enable verbose/diagnostic logging\n"
337" allow_memio Allow device registers to be memory mapped\n"
338" debug Bitmask of debug values to enable\n"
339" no_probe Toggle EISA/VLB controller probing\n"
340" probe_eisa_vl Toggle EISA/VLB controller probing\n"
341" no_reset Suppress initial bus resets\n"
342" extended Enable extended geometry on all controllers\n"
343" periodic_otag Send an ordered tagged transaction\n"
344" periodically to prevent tag starvation.\n"
345" This may be required by some older disk\n"
346" drives or RAID arrays.\n"
347" tag_info:<tag_str> Set per-target tag depth\n"
348" global_tag_depth:<int> Global tag depth for every target\n"
349" on every bus\n"
350" seltime:<int> Selection Timeout\n"
351" (0/256ms,1/128ms,2/64ms,3/32ms)\n"
352"\n"
353" Sample modprobe configuration file:\n"
354" # Toggle EISA/VLB probing\n"
355" # Set tag depth on Controller 1/Target 1 to 10 tags\n"
356" # Shorten the selection timeout to 128ms\n"
357"\n"
358" options aic7xxx 'aic7xxx=probe_eisa_vl.tag_info:{{}.{.10}}.seltime:1'\n"
359);
360
361static void ahc_linux_handle_scsi_status(struct ahc_softc *,
362 struct scsi_device *,
363 struct scb *);
364static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
365 struct scsi_cmnd *cmd);
366static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
367static void ahc_linux_release_simq(struct ahc_softc *ahc);
368static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
369static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
370static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
371 struct ahc_devinfo *devinfo);
372static void ahc_linux_device_queue_depth(struct scsi_device *);
373static int ahc_linux_run_command(struct ahc_softc*,
374 struct ahc_linux_device *,
375 struct scsi_cmnd *);
376static void ahc_linux_setup_tag_info_global(char *p);
377static int aic7xxx_setup(char *s);
378
379static int ahc_linux_unit;
380
381
382
383void
384ahc_delay(long usec)
385{
386
387
388
389
390
391 while (usec > 0) {
392 udelay(usec % 1024);
393 usec -= 1024;
394 }
395}
396
397
398uint8_t
399ahc_inb(struct ahc_softc * ahc, long port)
400{
401 uint8_t x;
402
403 if (ahc->tag == BUS_SPACE_MEMIO) {
404 x = readb(ahc->bsh.maddr + port);
405 } else {
406 x = inb(ahc->bsh.ioport + port);
407 }
408 mb();
409 return (x);
410}
411
412void
413ahc_outb(struct ahc_softc * ahc, long port, uint8_t val)
414{
415 if (ahc->tag == BUS_SPACE_MEMIO) {
416 writeb(val, ahc->bsh.maddr + port);
417 } else {
418 outb(val, ahc->bsh.ioport + port);
419 }
420 mb();
421}
422
423void
424ahc_outsb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
425{
426 int i;
427
428
429
430
431
432
433 for (i = 0; i < count; i++)
434 ahc_outb(ahc, port, *array++);
435}
436
437void
438ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
439{
440 int i;
441
442
443
444
445
446
447 for (i = 0; i < count; i++)
448 *array++ = ahc_inb(ahc, port);
449}
450
451
452static void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*);
453
454static int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
455 struct ahc_dma_seg *sg,
456 dma_addr_t addr, bus_size_t len);
457
458static void
459ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb)
460{
461 struct scsi_cmnd *cmd;
462
463 cmd = scb->io_ctx;
464 ahc_sync_sglist(ahc, scb, BUS_DMASYNC_POSTWRITE);
465
466 scsi_dma_unmap(cmd);
467}
468
469static int
470ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb,
471 struct ahc_dma_seg *sg, dma_addr_t addr, bus_size_t len)
472{
473 int consumed;
474
475 if ((scb->sg_count + 1) > AHC_NSEG)
476 panic("Too few segs for dma mapping. "
477 "Increase AHC_NSEG\n");
478
479 consumed = 1;
480 sg->addr = ahc_htole32(addr & 0xFFFFFFFF);
481 scb->platform_data->xfer_len += len;
482
483 if (sizeof(dma_addr_t) > 4
484 && (ahc->flags & AHC_39BIT_ADDRESSING) != 0)
485 len |= (addr >> 8) & AHC_SG_HIGH_ADDR_MASK;
486
487 sg->len = ahc_htole32(len);
488 return (consumed);
489}
490
491
492
493
494static const char *
495ahc_linux_info(struct Scsi_Host *host)
496{
497 static char buffer[512];
498 char ahc_info[256];
499 char *bp;
500 struct ahc_softc *ahc;
501
502 bp = &buffer[0];
503 ahc = *(struct ahc_softc **)host->hostdata;
504 memset(bp, 0, sizeof(buffer));
505 strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev " AIC7XXX_DRIVER_VERSION "\n"
506 " <");
507 strcat(bp, ahc->description);
508 strcat(bp, ">\n"
509 " ");
510 ahc_controller_info(ahc, ahc_info);
511 strcat(bp, ahc_info);
512 strcat(bp, "\n");
513
514 return (bp);
515}
516
517
518
519
520static int
521ahc_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
522{
523 struct ahc_softc *ahc;
524 struct ahc_linux_device *dev = scsi_transport_device_data(cmd->device);
525 int rtn = SCSI_MLQUEUE_HOST_BUSY;
526 unsigned long flags;
527
528 ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
529
530 ahc_lock(ahc, &flags);
531 if (ahc->platform_data->qfrozen == 0) {
532 cmd->scsi_done = scsi_done;
533 cmd->result = CAM_REQ_INPROG << 16;
534 rtn = ahc_linux_run_command(ahc, dev, cmd);
535 }
536 ahc_unlock(ahc, &flags);
537
538 return rtn;
539}
540
541static DEF_SCSI_QCMD(ahc_linux_queue)
542
543static inline struct scsi_target **
544ahc_linux_target_in_softc(struct scsi_target *starget)
545{
546 struct ahc_softc *ahc =
547 *((struct ahc_softc **)dev_to_shost(&starget->dev)->hostdata);
548 unsigned int target_offset;
549
550 target_offset = starget->id;
551 if (starget->channel != 0)
552 target_offset += 8;
553
554 return &ahc->platform_data->starget[target_offset];
555}
556
557static int
558ahc_linux_target_alloc(struct scsi_target *starget)
559{
560 struct ahc_softc *ahc =
561 *((struct ahc_softc **)dev_to_shost(&starget->dev)->hostdata);
562 struct seeprom_config *sc = ahc->seep_config;
563 unsigned long flags;
564 struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget);
565 unsigned short scsirate;
566 struct ahc_devinfo devinfo;
567 struct ahc_initiator_tinfo *tinfo;
568 struct ahc_tmode_tstate *tstate;
569 char channel = starget->channel + 'A';
570 unsigned int our_id = ahc->our_id;
571 unsigned int target_offset;
572
573 target_offset = starget->id;
574 if (starget->channel != 0)
575 target_offset += 8;
576
577 if (starget->channel)
578 our_id = ahc->our_id_b;
579
580 ahc_lock(ahc, &flags);
581
582 BUG_ON(*ahc_targp != NULL);
583
584 *ahc_targp = starget;
585
586 if (sc) {
587 int maxsync = AHC_SYNCRATE_DT;
588 int ultra = 0;
589 int flags = sc->device_flags[target_offset];
590
591 if (ahc->flags & AHC_NEWEEPROM_FMT) {
592 if (flags & CFSYNCHISULTRA)
593 ultra = 1;
594 } else if (flags & CFULTRAEN)
595 ultra = 1;
596
597
598 if(ultra && (flags & CFXFER) == 0x04) {
599 ultra = 0;
600 flags &= ~CFXFER;
601 }
602
603 if ((ahc->features & AHC_ULTRA2) != 0) {
604 scsirate = (flags & CFXFER) | (ultra ? 0x8 : 0);
605 } else {
606 scsirate = (flags & CFXFER) << 4;
607 maxsync = ultra ? AHC_SYNCRATE_ULTRA :
608 AHC_SYNCRATE_FAST;
609 }
610 spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0;
611 if (!(flags & CFSYNCH))
612 spi_max_offset(starget) = 0;
613 spi_min_period(starget) =
614 ahc_find_period(ahc, scsirate, maxsync);
615
616 tinfo = ahc_fetch_transinfo(ahc, channel, ahc->our_id,
617 starget->id, &tstate);
618 }
619 ahc_compile_devinfo(&devinfo, our_id, starget->id,
620 CAM_LUN_WILDCARD, channel,
621 ROLE_INITIATOR);
622 ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0,
623 AHC_TRANS_GOAL, FALSE);
624 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
625 AHC_TRANS_GOAL, FALSE);
626 ahc_unlock(ahc, &flags);
627
628 return 0;
629}
630
631static void
632ahc_linux_target_destroy(struct scsi_target *starget)
633{
634 struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget);
635
636 *ahc_targp = NULL;
637}
638
639static int
640ahc_linux_slave_alloc(struct scsi_device *sdev)
641{
642 struct ahc_softc *ahc =
643 *((struct ahc_softc **)sdev->host->hostdata);
644 struct scsi_target *starget = sdev->sdev_target;
645 struct ahc_linux_device *dev;
646
647 if (bootverbose)
648 printk("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id);
649
650 dev = scsi_transport_device_data(sdev);
651 memset(dev, 0, sizeof(*dev));
652
653
654
655
656
657 dev->openings = 1;
658
659
660
661
662
663
664 dev->maxtags = 0;
665
666 spi_period(starget) = 0;
667
668 return 0;
669}
670
671static int
672ahc_linux_slave_configure(struct scsi_device *sdev)
673{
674 struct ahc_softc *ahc;
675
676 ahc = *((struct ahc_softc **)sdev->host->hostdata);
677
678 if (bootverbose)
679 sdev_printk(KERN_INFO, sdev, "Slave Configure\n");
680
681 ahc_linux_device_queue_depth(sdev);
682
683
684 if (!spi_initial_dv(sdev->sdev_target))
685 spi_dv_device(sdev);
686
687 return 0;
688}
689
690#if defined(__i386__)
691
692
693
694static int
695ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
696 sector_t capacity, int geom[])
697{
698 uint8_t *bh;
699 int heads;
700 int sectors;
701 int cylinders;
702 int ret;
703 int extended;
704 struct ahc_softc *ahc;
705 u_int channel;
706
707 ahc = *((struct ahc_softc **)sdev->host->hostdata);
708 channel = sdev_channel(sdev);
709
710 bh = scsi_bios_ptable(bdev);
711 if (bh) {
712 ret = scsi_partsize(bh, capacity,
713 &geom[2], &geom[0], &geom[1]);
714 kfree(bh);
715 if (ret != -1)
716 return (ret);
717 }
718 heads = 64;
719 sectors = 32;
720 cylinders = aic_sector_div(capacity, heads, sectors);
721
722 if (aic7xxx_extended != 0)
723 extended = 1;
724 else if (channel == 0)
725 extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0;
726 else
727 extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0;
728 if (extended && cylinders >= 1024) {
729 heads = 255;
730 sectors = 63;
731 cylinders = aic_sector_div(capacity, heads, sectors);
732 }
733 geom[0] = heads;
734 geom[1] = sectors;
735 geom[2] = cylinders;
736 return (0);
737}
738#endif
739
740
741
742
743static int
744ahc_linux_abort(struct scsi_cmnd *cmd)
745{
746 int error;
747
748 error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT);
749 if (error != 0)
750 printk("aic7xxx_abort returns 0x%x\n", error);
751 return (error);
752}
753
754
755
756
757static int
758ahc_linux_dev_reset(struct scsi_cmnd *cmd)
759{
760 int error;
761
762 error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
763 if (error != 0)
764 printk("aic7xxx_dev_reset returns 0x%x\n", error);
765 return (error);
766}
767
768
769
770
771static int
772ahc_linux_bus_reset(struct scsi_cmnd *cmd)
773{
774 struct ahc_softc *ahc;
775 int found;
776 unsigned long flags;
777
778 ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
779
780 ahc_lock(ahc, &flags);
781 found = ahc_reset_channel(ahc, scmd_channel(cmd) + 'A',
782 TRUE);
783 ahc_unlock(ahc, &flags);
784
785 if (bootverbose)
786 printk("%s: SCSI bus reset delivered. "
787 "%d SCBs aborted.\n", ahc_name(ahc), found);
788
789 return SUCCESS;
790}
791
792struct scsi_host_template aic7xxx_driver_template = {
793 .module = THIS_MODULE,
794 .name = "aic7xxx",
795 .proc_name = "aic7xxx",
796 .show_info = ahc_linux_show_info,
797 .write_info = ahc_proc_write_seeprom,
798 .info = ahc_linux_info,
799 .queuecommand = ahc_linux_queue,
800 .eh_abort_handler = ahc_linux_abort,
801 .eh_device_reset_handler = ahc_linux_dev_reset,
802 .eh_bus_reset_handler = ahc_linux_bus_reset,
803#if defined(__i386__)
804 .bios_param = ahc_linux_biosparam,
805#endif
806 .can_queue = AHC_MAX_QUEUE,
807 .this_id = -1,
808 .max_sectors = 8192,
809 .cmd_per_lun = 2,
810 .slave_alloc = ahc_linux_slave_alloc,
811 .slave_configure = ahc_linux_slave_configure,
812 .target_alloc = ahc_linux_target_alloc,
813 .target_destroy = ahc_linux_target_destroy,
814};
815
816
817
818
819#define BUILD_SCSIID(ahc, cmd) \
820 ((((cmd)->device->id << TID_SHIFT) & TID) \
821 | (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \
822 | (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB))
823
824
825int
826ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent,
827 bus_size_t alignment, bus_size_t boundary,
828 dma_addr_t lowaddr, dma_addr_t highaddr,
829 bus_dma_filter_t *filter, void *filterarg,
830 bus_size_t maxsize, int nsegments,
831 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
832{
833 bus_dma_tag_t dmat;
834
835 dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC);
836 if (dmat == NULL)
837 return (ENOMEM);
838
839
840
841
842
843
844
845
846 dmat->alignment = alignment;
847 dmat->boundary = boundary;
848 dmat->maxsize = maxsize;
849 *ret_tag = dmat;
850 return (0);
851}
852
853void
854ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat)
855{
856 kfree(dmat);
857}
858
859int
860ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr,
861 int flags, bus_dmamap_t *mapp)
862{
863
864 *vaddr = dma_alloc_coherent(ahc->dev, dmat->maxsize, mapp, GFP_ATOMIC);
865 if (*vaddr == NULL)
866 return ENOMEM;
867 return 0;
868}
869
870void
871ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat,
872 void* vaddr, bus_dmamap_t map)
873{
874 dma_free_coherent(ahc->dev, dmat->maxsize, vaddr, map);
875}
876
877int
878ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map,
879 void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
880 void *cb_arg, int flags)
881{
882
883
884
885
886 bus_dma_segment_t stack_sg;
887
888 stack_sg.ds_addr = map;
889 stack_sg.ds_len = dmat->maxsize;
890 cb(cb_arg, &stack_sg, 1, 0);
891 return (0);
892}
893
894void
895ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
896{
897}
898
899int
900ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
901{
902
903 return (0);
904}
905
906static void
907ahc_linux_setup_tag_info_global(char *p)
908{
909 int tags, i, j;
910
911 tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
912 printk("Setting Global Tags= %d\n", tags);
913
914 for (i = 0; i < ARRAY_SIZE(aic7xxx_tag_info); i++) {
915 for (j = 0; j < AHC_NUM_TARGETS; j++) {
916 aic7xxx_tag_info[i].tag_commands[j] = tags;
917 }
918 }
919}
920
921static void
922ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
923{
924
925 if ((instance >= 0) && (targ >= 0)
926 && (instance < ARRAY_SIZE(aic7xxx_tag_info))
927 && (targ < AHC_NUM_TARGETS)) {
928 aic7xxx_tag_info[instance].tag_commands[targ] = value & 0xff;
929 if (bootverbose)
930 printk("tag_info[%d:%d] = %d\n", instance, targ, value);
931 }
932}
933
934static char *
935ahc_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
936 void (*callback)(u_long, int, int, int32_t),
937 u_long callback_arg)
938{
939 char *tok_end;
940 char *tok_end2;
941 int i;
942 int instance;
943 int targ;
944 int done;
945 char tok_list[] = {'.', ',', '{', '}', '\0'};
946
947
948 if (*opt_arg != ':')
949 return (opt_arg);
950 opt_arg++;
951 instance = -1;
952 targ = -1;
953 done = FALSE;
954
955
956
957
958 tok_end = strchr(opt_arg, '\0');
959 if (tok_end < end)
960 *tok_end = ',';
961 while (!done) {
962 switch (*opt_arg) {
963 case '{':
964 if (instance == -1) {
965 instance = 0;
966 } else {
967 if (depth > 1) {
968 if (targ == -1)
969 targ = 0;
970 } else {
971 printk("Malformed Option %s\n",
972 opt_name);
973 done = TRUE;
974 }
975 }
976 opt_arg++;
977 break;
978 case '}':
979 if (targ != -1)
980 targ = -1;
981 else if (instance != -1)
982 instance = -1;
983 opt_arg++;
984 break;
985 case ',':
986 case '.':
987 if (instance == -1)
988 done = TRUE;
989 else if (targ >= 0)
990 targ++;
991 else if (instance >= 0)
992 instance++;
993 opt_arg++;
994 break;
995 case '\0':
996 done = TRUE;
997 break;
998 default:
999 tok_end = end;
1000 for (i = 0; tok_list[i]; i++) {
1001 tok_end2 = strchr(opt_arg, tok_list[i]);
1002 if ((tok_end2) && (tok_end2 < tok_end))
1003 tok_end = tok_end2;
1004 }
1005 callback(callback_arg, instance, targ,
1006 simple_strtol(opt_arg, NULL, 0));
1007 opt_arg = tok_end;
1008 break;
1009 }
1010 }
1011 return (opt_arg);
1012}
1013
1014
1015
1016
1017
1018
1019static int
1020aic7xxx_setup(char *s)
1021{
1022 int i, n;
1023 char *p;
1024 char *end;
1025
1026 static const struct {
1027 const char *name;
1028 uint32_t *flag;
1029 } options[] = {
1030 { "extended", &aic7xxx_extended },
1031 { "no_reset", &aic7xxx_no_reset },
1032 { "verbose", &aic7xxx_verbose },
1033 { "allow_memio", &aic7xxx_allow_memio},
1034#ifdef AHC_DEBUG
1035 { "debug", &ahc_debug },
1036#endif
1037 { "periodic_otag", &aic7xxx_periodic_otag },
1038 { "pci_parity", &aic7xxx_pci_parity },
1039 { "seltime", &aic7xxx_seltime },
1040 { "tag_info", NULL },
1041 { "global_tag_depth", NULL },
1042 { "dv", NULL }
1043 };
1044
1045 end = strchr(s, '\0');
1046
1047
1048
1049
1050
1051 n = 0;
1052
1053 while ((p = strsep(&s, ",.")) != NULL) {
1054 if (*p == '\0')
1055 continue;
1056 for (i = 0; i < ARRAY_SIZE(options); i++) {
1057
1058 n = strlen(options[i].name);
1059 if (strncmp(options[i].name, p, n) == 0)
1060 break;
1061 }
1062 if (i == ARRAY_SIZE(options))
1063 continue;
1064
1065 if (strncmp(p, "global_tag_depth", n) == 0) {
1066 ahc_linux_setup_tag_info_global(p + n);
1067 } else if (strncmp(p, "tag_info", n) == 0) {
1068 s = ahc_parse_brace_option("tag_info", p + n, end,
1069 2, ahc_linux_setup_tag_info, 0);
1070 } else if (p[n] == ':') {
1071 *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
1072 } else if (strncmp(p, "verbose", n) == 0) {
1073 *(options[i].flag) = 1;
1074 } else {
1075 *(options[i].flag) ^= 0xFFFFFFFF;
1076 }
1077 }
1078 return 1;
1079}
1080
1081__setup("aic7xxx=", aic7xxx_setup);
1082
1083uint32_t aic7xxx_verbose;
1084
1085int
1086ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *template)
1087{
1088 char buf[80];
1089 struct Scsi_Host *host;
1090 char *new_name;
1091 u_long s;
1092 int retval;
1093
1094 template->name = ahc->description;
1095 host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
1096 if (host == NULL)
1097 return (ENOMEM);
1098
1099 *((struct ahc_softc **)host->hostdata) = ahc;
1100 ahc->platform_data->host = host;
1101 host->can_queue = AHC_MAX_QUEUE;
1102 host->cmd_per_lun = 2;
1103
1104 host->this_id = ahc->our_id;
1105 host->irq = ahc->platform_data->irq;
1106 host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8;
1107 host->max_lun = AHC_NUM_LUNS;
1108 host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
1109 host->sg_tablesize = AHC_NSEG;
1110 ahc_lock(ahc, &s);
1111 ahc_set_unit(ahc, ahc_linux_unit++);
1112 ahc_unlock(ahc, &s);
1113 sprintf(buf, "scsi%d", host->host_no);
1114 new_name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
1115 if (new_name != NULL) {
1116 strcpy(new_name, buf);
1117 ahc_set_name(ahc, new_name);
1118 }
1119 host->unique_id = ahc->unit;
1120 ahc_linux_initialize_scsi_bus(ahc);
1121 ahc_intr_enable(ahc, TRUE);
1122
1123 host->transportt = ahc_linux_transport_template;
1124
1125 retval = scsi_add_host(host, ahc->dev);
1126 if (retval) {
1127 printk(KERN_WARNING "aic7xxx: scsi_add_host failed\n");
1128 scsi_host_put(host);
1129 return retval;
1130 }
1131
1132 scsi_scan_host(host);
1133 return 0;
1134}
1135
1136
1137
1138
1139
1140
1141static void
1142ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
1143{
1144 int i;
1145 int numtarg;
1146 unsigned long s;
1147
1148 i = 0;
1149 numtarg = 0;
1150
1151 ahc_lock(ahc, &s);
1152
1153 if (aic7xxx_no_reset != 0)
1154 ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B);
1155
1156 if ((ahc->flags & AHC_RESET_BUS_A) != 0)
1157 ahc_reset_channel(ahc, 'A', TRUE);
1158 else
1159 numtarg = (ahc->features & AHC_WIDE) ? 16 : 8;
1160
1161 if ((ahc->features & AHC_TWIN) != 0) {
1162
1163 if ((ahc->flags & AHC_RESET_BUS_B) != 0) {
1164 ahc_reset_channel(ahc, 'B', TRUE);
1165 } else {
1166 if (numtarg == 0)
1167 i = 8;
1168 numtarg += 8;
1169 }
1170 }
1171
1172
1173
1174
1175
1176 for (; i < numtarg; i++) {
1177 struct ahc_devinfo devinfo;
1178 struct ahc_initiator_tinfo *tinfo;
1179 struct ahc_tmode_tstate *tstate;
1180 u_int our_id;
1181 u_int target_id;
1182 char channel;
1183
1184 channel = 'A';
1185 our_id = ahc->our_id;
1186 target_id = i;
1187 if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
1188 channel = 'B';
1189 our_id = ahc->our_id_b;
1190 target_id = i % 8;
1191 }
1192 tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
1193 target_id, &tstate);
1194 ahc_compile_devinfo(&devinfo, our_id, target_id,
1195 CAM_LUN_WILDCARD, channel, ROLE_INITIATOR);
1196 ahc_update_neg_request(ahc, &devinfo, tstate,
1197 tinfo, AHC_NEG_ALWAYS);
1198 }
1199 ahc_unlock(ahc, &s);
1200
1201 if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
1202 ahc_linux_freeze_simq(ahc);
1203 msleep(AIC7XXX_RESET_DELAY);
1204 ahc_linux_release_simq(ahc);
1205 }
1206}
1207
1208int
1209ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
1210{
1211
1212 ahc->platform_data =
1213 kzalloc(sizeof(struct ahc_platform_data), GFP_ATOMIC);
1214 if (ahc->platform_data == NULL)
1215 return (ENOMEM);
1216 ahc->platform_data->irq = AHC_LINUX_NOIRQ;
1217 ahc_lockinit(ahc);
1218 ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
1219 ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
1220 if (aic7xxx_pci_parity == 0)
1221 ahc->flags |= AHC_DISABLE_PCI_PERR;
1222
1223 return (0);
1224}
1225
1226void
1227ahc_platform_free(struct ahc_softc *ahc)
1228{
1229 struct scsi_target *starget;
1230 int i;
1231
1232 if (ahc->platform_data != NULL) {
1233
1234 for (i = 0; i < AHC_NUM_TARGETS; i++) {
1235 starget = ahc->platform_data->starget[i];
1236 if (starget != NULL) {
1237 ahc->platform_data->starget[i] = NULL;
1238 }
1239 }
1240
1241 if (ahc->platform_data->irq != AHC_LINUX_NOIRQ)
1242 free_irq(ahc->platform_data->irq, ahc);
1243 if (ahc->tag == BUS_SPACE_PIO
1244 && ahc->bsh.ioport != 0)
1245 release_region(ahc->bsh.ioport, 256);
1246 if (ahc->tag == BUS_SPACE_MEMIO
1247 && ahc->bsh.maddr != NULL) {
1248 iounmap(ahc->bsh.maddr);
1249 release_mem_region(ahc->platform_data->mem_busaddr,
1250 0x1000);
1251 }
1252
1253 if (ahc->platform_data->host)
1254 scsi_host_put(ahc->platform_data->host);
1255
1256 kfree(ahc->platform_data);
1257 }
1258}
1259
1260void
1261ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
1262{
1263 ahc_platform_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb),
1264 SCB_GET_CHANNEL(ahc, scb),
1265 SCB_GET_LUN(scb), SCB_LIST_NULL,
1266 ROLE_UNKNOWN, CAM_REQUEUE_REQ);
1267}
1268
1269void
1270ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
1271 struct ahc_devinfo *devinfo, ahc_queue_alg alg)
1272{
1273 struct ahc_linux_device *dev;
1274 int was_queuing;
1275 int now_queuing;
1276
1277 if (sdev == NULL)
1278 return;
1279 dev = scsi_transport_device_data(sdev);
1280
1281 was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED);
1282 switch (alg) {
1283 default:
1284 case AHC_QUEUE_NONE:
1285 now_queuing = 0;
1286 break;
1287 case AHC_QUEUE_BASIC:
1288 now_queuing = AHC_DEV_Q_BASIC;
1289 break;
1290 case AHC_QUEUE_TAGGED:
1291 now_queuing = AHC_DEV_Q_TAGGED;
1292 break;
1293 }
1294 if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0
1295 && (was_queuing != now_queuing)
1296 && (dev->active != 0)) {
1297 dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY;
1298 dev->qfrozen++;
1299 }
1300
1301 dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG);
1302 if (now_queuing) {
1303 u_int usertags;
1304
1305 usertags = ahc_linux_user_tagdepth(ahc, devinfo);
1306 if (!was_queuing) {
1307
1308
1309
1310
1311
1312 dev->maxtags = usertags;
1313 dev->openings = dev->maxtags - dev->active;
1314 }
1315 if (dev->maxtags == 0) {
1316
1317
1318
1319 dev->openings = 1;
1320 } else if (alg == AHC_QUEUE_TAGGED) {
1321 dev->flags |= AHC_DEV_Q_TAGGED;
1322 if (aic7xxx_periodic_otag != 0)
1323 dev->flags |= AHC_DEV_PERIODIC_OTAG;
1324 } else
1325 dev->flags |= AHC_DEV_Q_BASIC;
1326 } else {
1327
1328 dev->maxtags = 0;
1329 dev->openings = 1 - dev->active;
1330 }
1331 switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
1332 case AHC_DEV_Q_BASIC:
1333 case AHC_DEV_Q_TAGGED:
1334 scsi_change_queue_depth(sdev,
1335 dev->openings + dev->active);
1336 break;
1337 default:
1338
1339
1340
1341
1342
1343
1344 scsi_change_queue_depth(sdev, 2);
1345 break;
1346 }
1347}
1348
1349int
1350ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel,
1351 int lun, u_int tag, role_t role, uint32_t status)
1352{
1353 return 0;
1354}
1355
1356static u_int
1357ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
1358{
1359 static int warned_user;
1360 u_int tags;
1361
1362 tags = 0;
1363 if ((ahc->user_discenable & devinfo->target_mask) != 0) {
1364 if (ahc->unit >= ARRAY_SIZE(aic7xxx_tag_info)) {
1365 if (warned_user == 0) {
1366
1367 printk(KERN_WARNING
1368"aic7xxx: WARNING: Insufficient tag_info instances\n"
1369"aic7xxx: for installed controllers. Using defaults\n"
1370"aic7xxx: Please update the aic7xxx_tag_info array in\n"
1371"aic7xxx: the aic7xxx_osm..c source file.\n");
1372 warned_user++;
1373 }
1374 tags = AHC_MAX_QUEUE;
1375 } else {
1376 adapter_tag_info_t *tag_info;
1377
1378 tag_info = &aic7xxx_tag_info[ahc->unit];
1379 tags = tag_info->tag_commands[devinfo->target_offset];
1380 if (tags > AHC_MAX_QUEUE)
1381 tags = AHC_MAX_QUEUE;
1382 }
1383 }
1384 return (tags);
1385}
1386
1387
1388
1389
1390static void
1391ahc_linux_device_queue_depth(struct scsi_device *sdev)
1392{
1393 struct ahc_devinfo devinfo;
1394 u_int tags;
1395 struct ahc_softc *ahc = *((struct ahc_softc **)sdev->host->hostdata);
1396
1397 ahc_compile_devinfo(&devinfo,
1398 sdev->sdev_target->channel == 0
1399 ? ahc->our_id : ahc->our_id_b,
1400 sdev->sdev_target->id, sdev->lun,
1401 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1402 ROLE_INITIATOR);
1403 tags = ahc_linux_user_tagdepth(ahc, &devinfo);
1404 if (tags != 0 && sdev->tagged_supported != 0) {
1405
1406 ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_TAGGED);
1407 ahc_send_async(ahc, devinfo.channel, devinfo.target,
1408 devinfo.lun, AC_TRANSFER_NEG);
1409 ahc_print_devinfo(ahc, &devinfo);
1410 printk("Tagged Queuing enabled. Depth %d\n", tags);
1411 } else {
1412 ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_NONE);
1413 ahc_send_async(ahc, devinfo.channel, devinfo.target,
1414 devinfo.lun, AC_TRANSFER_NEG);
1415 }
1416}
1417
1418static int
1419ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
1420 struct scsi_cmnd *cmd)
1421{
1422 struct scb *scb;
1423 struct hardware_scb *hscb;
1424 struct ahc_initiator_tinfo *tinfo;
1425 struct ahc_tmode_tstate *tstate;
1426 uint16_t mask;
1427 struct scb_tailq *untagged_q = NULL;
1428 int nseg;
1429
1430
1431
1432
1433
1434 if (ahc->platform_data->qfrozen != 0)
1435 return SCSI_MLQUEUE_HOST_BUSY;
1436
1437
1438
1439
1440
1441
1442
1443 if (!(cmd->flags & SCMD_TAGGED)
1444 && (ahc->features & AHC_SCB_BTT) == 0) {
1445 int target_offset;
1446
1447 target_offset = cmd->device->id + cmd->device->channel * 8;
1448 untagged_q = &(ahc->untagged_queues[target_offset]);
1449 if (!TAILQ_EMPTY(untagged_q))
1450
1451
1452 return SCSI_MLQUEUE_DEVICE_BUSY;
1453 }
1454
1455 nseg = scsi_dma_map(cmd);
1456 if (nseg < 0)
1457 return SCSI_MLQUEUE_HOST_BUSY;
1458
1459
1460
1461
1462 scb = ahc_get_scb(ahc);
1463 if (!scb) {
1464 scsi_dma_unmap(cmd);
1465 return SCSI_MLQUEUE_HOST_BUSY;
1466 }
1467
1468 scb->io_ctx = cmd;
1469 scb->platform_data->dev = dev;
1470 hscb = scb->hscb;
1471 cmd->host_scribble = (char *)scb;
1472
1473
1474
1475
1476 hscb->control = 0;
1477 hscb->scsiid = BUILD_SCSIID(ahc, cmd);
1478 hscb->lun = cmd->device->lun;
1479 mask = SCB_GET_TARGET_MASK(ahc, scb);
1480 tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
1481 SCB_GET_OUR_ID(scb),
1482 SCB_GET_TARGET(ahc, scb), &tstate);
1483 hscb->scsirate = tinfo->scsirate;
1484 hscb->scsioffset = tinfo->curr.offset;
1485 if ((tstate->ultraenb & mask) != 0)
1486 hscb->control |= ULTRAENB;
1487
1488 if ((ahc->user_discenable & mask) != 0)
1489 hscb->control |= DISCENB;
1490
1491 if ((tstate->auto_negotiate & mask) != 0) {
1492 scb->flags |= SCB_AUTO_NEGOTIATE;
1493 scb->hscb->control |= MK_MESSAGE;
1494 }
1495
1496 if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
1497 if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
1498 && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
1499 hscb->control |= MSG_ORDERED_TASK;
1500 dev->commands_since_idle_or_otag = 0;
1501 } else {
1502 hscb->control |= MSG_SIMPLE_TASK;
1503 }
1504 }
1505
1506 hscb->cdb_len = cmd->cmd_len;
1507 if (hscb->cdb_len <= 12) {
1508 memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len);
1509 } else {
1510 memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len);
1511 scb->flags |= SCB_CDB32_PTR;
1512 }
1513
1514 scb->platform_data->xfer_len = 0;
1515 ahc_set_residual(scb, 0);
1516 ahc_set_sense_residual(scb, 0);
1517 scb->sg_count = 0;
1518
1519 if (nseg > 0) {
1520 struct ahc_dma_seg *sg;
1521 struct scatterlist *cur_seg;
1522 int i;
1523
1524
1525 sg = scb->sg_list;
1526
1527
1528
1529
1530 scsi_for_each_sg(cmd, cur_seg, nseg, i) {
1531 dma_addr_t addr;
1532 bus_size_t len;
1533 int consumed;
1534
1535 addr = sg_dma_address(cur_seg);
1536 len = sg_dma_len(cur_seg);
1537 consumed = ahc_linux_map_seg(ahc, scb,
1538 sg, addr, len);
1539 sg += consumed;
1540 scb->sg_count += consumed;
1541 }
1542 sg--;
1543 sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
1544
1545
1546
1547
1548 scb->hscb->sgptr =
1549 ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
1550
1551
1552
1553
1554
1555 scb->hscb->dataptr = scb->sg_list->addr;
1556 scb->hscb->datacnt = scb->sg_list->len;
1557 } else {
1558 scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
1559 scb->hscb->dataptr = 0;
1560 scb->hscb->datacnt = 0;
1561 scb->sg_count = 0;
1562 }
1563
1564 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
1565 dev->openings--;
1566 dev->active++;
1567 dev->commands_issued++;
1568 if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0)
1569 dev->commands_since_idle_or_otag++;
1570
1571 scb->flags |= SCB_ACTIVE;
1572 if (untagged_q) {
1573 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
1574 scb->flags |= SCB_UNTAGGEDQ;
1575 }
1576 ahc_queue_scb(ahc, scb);
1577 return 0;
1578}
1579
1580
1581
1582
1583irqreturn_t
1584ahc_linux_isr(int irq, void *dev_id)
1585{
1586 struct ahc_softc *ahc;
1587 u_long flags;
1588 int ours;
1589
1590 ahc = (struct ahc_softc *) dev_id;
1591 ahc_lock(ahc, &flags);
1592 ours = ahc_intr(ahc);
1593 ahc_unlock(ahc, &flags);
1594 return IRQ_RETVAL(ours);
1595}
1596
1597void
1598ahc_platform_flushwork(struct ahc_softc *ahc)
1599{
1600
1601}
1602
1603void
1604ahc_send_async(struct ahc_softc *ahc, char channel,
1605 u_int target, u_int lun, ac_code code)
1606{
1607 switch (code) {
1608 case AC_TRANSFER_NEG:
1609 {
1610 struct scsi_target *starget;
1611 struct ahc_linux_target *targ;
1612 struct ahc_initiator_tinfo *tinfo;
1613 struct ahc_tmode_tstate *tstate;
1614 int target_offset;
1615 unsigned int target_ppr_options;
1616
1617 BUG_ON(target == CAM_TARGET_WILDCARD);
1618
1619 tinfo = ahc_fetch_transinfo(ahc, channel,
1620 channel == 'A' ? ahc->our_id
1621 : ahc->our_id_b,
1622 target, &tstate);
1623
1624
1625
1626
1627
1628 if (tinfo->curr.period != tinfo->goal.period
1629 || tinfo->curr.width != tinfo->goal.width
1630 || tinfo->curr.offset != tinfo->goal.offset
1631 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
1632 if (bootverbose == 0)
1633 break;
1634
1635
1636
1637
1638
1639 target_offset = target;
1640 if (channel == 'B')
1641 target_offset += 8;
1642 starget = ahc->platform_data->starget[target_offset];
1643 if (starget == NULL)
1644 break;
1645 targ = scsi_transport_target_data(starget);
1646
1647 target_ppr_options =
1648 (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
1649 + (spi_qas(starget) ? MSG_EXT_PPR_QAS_REQ : 0)
1650 + (spi_iu(starget) ? MSG_EXT_PPR_IU_REQ : 0);
1651
1652 if (tinfo->curr.period == spi_period(starget)
1653 && tinfo->curr.width == spi_width(starget)
1654 && tinfo->curr.offset == spi_offset(starget)
1655 && tinfo->curr.ppr_options == target_ppr_options)
1656 if (bootverbose == 0)
1657 break;
1658
1659 spi_period(starget) = tinfo->curr.period;
1660 spi_width(starget) = tinfo->curr.width;
1661 spi_offset(starget) = tinfo->curr.offset;
1662 spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
1663 spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
1664 spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
1665 spi_display_xfer_agreement(starget);
1666 break;
1667 }
1668 case AC_SENT_BDR:
1669 {
1670 WARN_ON(lun != CAM_LUN_WILDCARD);
1671 scsi_report_device_reset(ahc->platform_data->host,
1672 channel - 'A', target);
1673 break;
1674 }
1675 case AC_BUS_RESET:
1676 if (ahc->platform_data->host != NULL) {
1677 scsi_report_bus_reset(ahc->platform_data->host,
1678 channel - 'A');
1679 }
1680 break;
1681 default:
1682 panic("ahc_send_async: Unexpected async event");
1683 }
1684}
1685
1686
1687
1688
1689void
1690ahc_done(struct ahc_softc *ahc, struct scb *scb)
1691{
1692 struct scsi_cmnd *cmd;
1693 struct ahc_linux_device *dev;
1694
1695 LIST_REMOVE(scb, pending_links);
1696 if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
1697 struct scb_tailq *untagged_q;
1698 int target_offset;
1699
1700 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
1701 untagged_q = &(ahc->untagged_queues[target_offset]);
1702 TAILQ_REMOVE(untagged_q, scb, links.tqe);
1703 BUG_ON(!TAILQ_EMPTY(untagged_q));
1704 } else if ((scb->flags & SCB_ACTIVE) == 0) {
1705
1706
1707
1708
1709
1710 printk("SCB %d done'd twice\n", scb->hscb->tag);
1711 ahc_dump_card_state(ahc);
1712 panic("Stopping for safety");
1713 }
1714 cmd = scb->io_ctx;
1715 dev = scb->platform_data->dev;
1716 dev->active--;
1717 dev->openings++;
1718 if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
1719 cmd->result &= ~(CAM_DEV_QFRZN << 16);
1720 dev->qfrozen--;
1721 }
1722 ahc_linux_unmap_scb(ahc, scb);
1723
1724
1725
1726
1727
1728
1729
1730 cmd->sense_buffer[0] = 0;
1731 if (ahc_get_transaction_status(scb) == CAM_REQ_INPROG) {
1732 uint32_t amount_xferred;
1733
1734 amount_xferred =
1735 ahc_get_transfer_length(scb) - ahc_get_residual(scb);
1736 if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
1737#ifdef AHC_DEBUG
1738 if ((ahc_debug & AHC_SHOW_MISC) != 0) {
1739 ahc_print_path(ahc, scb);
1740 printk("Set CAM_UNCOR_PARITY\n");
1741 }
1742#endif
1743 ahc_set_transaction_status(scb, CAM_UNCOR_PARITY);
1744#ifdef AHC_REPORT_UNDERFLOWS
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754 } else if (amount_xferred < scb->io_ctx->underflow) {
1755 u_int i;
1756
1757 ahc_print_path(ahc, scb);
1758 printk("CDB:");
1759 for (i = 0; i < scb->io_ctx->cmd_len; i++)
1760 printk(" 0x%x", scb->io_ctx->cmnd[i]);
1761 printk("\n");
1762 ahc_print_path(ahc, scb);
1763 printk("Saw underflow (%ld of %ld bytes). "
1764 "Treated as error\n",
1765 ahc_get_residual(scb),
1766 ahc_get_transfer_length(scb));
1767 ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1768#endif
1769 } else {
1770 ahc_set_transaction_status(scb, CAM_REQ_CMP);
1771 }
1772 } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
1773 ahc_linux_handle_scsi_status(ahc, cmd->device, scb);
1774 }
1775
1776 if (dev->openings == 1
1777 && ahc_get_transaction_status(scb) == CAM_REQ_CMP
1778 && ahc_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
1779 dev->tag_success_count++;
1780
1781
1782
1783
1784
1785
1786 if ((dev->openings + dev->active) < dev->maxtags
1787 && dev->tag_success_count > AHC_TAG_SUCCESS_INTERVAL) {
1788 dev->tag_success_count = 0;
1789 dev->openings++;
1790 }
1791
1792 if (dev->active == 0)
1793 dev->commands_since_idle_or_otag = 0;
1794
1795 if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
1796 printk("Recovery SCB completes\n");
1797 if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
1798 || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
1799 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
1800
1801 if (ahc->platform_data->eh_done)
1802 complete(ahc->platform_data->eh_done);
1803 }
1804
1805 ahc_free_scb(ahc, scb);
1806 ahc_linux_queue_cmd_complete(ahc, cmd);
1807}
1808
1809static void
1810ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
1811 struct scsi_device *sdev, struct scb *scb)
1812{
1813 struct ahc_devinfo devinfo;
1814 struct ahc_linux_device *dev = scsi_transport_device_data(sdev);
1815
1816 ahc_compile_devinfo(&devinfo,
1817 ahc->our_id,
1818 sdev->sdev_target->id, sdev->lun,
1819 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1820 ROLE_INITIATOR);
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832 switch (ahc_get_scsi_status(scb)) {
1833 default:
1834 break;
1835 case SCSI_STATUS_CHECK_COND:
1836 case SCSI_STATUS_CMD_TERMINATED:
1837 {
1838 struct scsi_cmnd *cmd;
1839
1840
1841
1842
1843
1844 cmd = scb->io_ctx;
1845 if (scb->flags & SCB_SENSE) {
1846 u_int sense_size;
1847
1848 sense_size = min(sizeof(struct scsi_sense_data)
1849 - ahc_get_sense_residual(scb),
1850 (u_long)SCSI_SENSE_BUFFERSIZE);
1851 memcpy(cmd->sense_buffer,
1852 ahc_get_sense_buf(ahc, scb), sense_size);
1853 if (sense_size < SCSI_SENSE_BUFFERSIZE)
1854 memset(&cmd->sense_buffer[sense_size], 0,
1855 SCSI_SENSE_BUFFERSIZE - sense_size);
1856 cmd->result |= (DRIVER_SENSE << 24);
1857#ifdef AHC_DEBUG
1858 if (ahc_debug & AHC_SHOW_SENSE) {
1859 int i;
1860
1861 printk("Copied %d bytes of sense data:",
1862 sense_size);
1863 for (i = 0; i < sense_size; i++) {
1864 if ((i & 0xF) == 0)
1865 printk("\n");
1866 printk("0x%x ", cmd->sense_buffer[i]);
1867 }
1868 printk("\n");
1869 }
1870#endif
1871 }
1872 break;
1873 }
1874 case SCSI_STATUS_QUEUE_FULL:
1875 {
1876
1877
1878
1879
1880
1881
1882
1883
1884 dev->tag_success_count = 0;
1885 if (dev->active != 0) {
1886
1887
1888
1889
1890 dev->openings = 0;
1891
1892
1893
1894
1895 if (dev->active == dev->tags_on_last_queuefull) {
1896
1897 dev->last_queuefull_same_count++;
1898
1899
1900
1901
1902
1903
1904
1905
1906 if (dev->last_queuefull_same_count
1907 == AHC_LOCK_TAGS_COUNT) {
1908 dev->maxtags = dev->active;
1909 ahc_print_path(ahc, scb);
1910 printk("Locking max tag count at %d\n",
1911 dev->active);
1912 }
1913 } else {
1914 dev->tags_on_last_queuefull = dev->active;
1915 dev->last_queuefull_same_count = 0;
1916 }
1917 ahc_set_transaction_status(scb, CAM_REQUEUE_REQ);
1918 ahc_set_scsi_status(scb, SCSI_STATUS_OK);
1919 ahc_platform_set_tags(ahc, sdev, &devinfo,
1920 (dev->flags & AHC_DEV_Q_BASIC)
1921 ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
1922 break;
1923 }
1924
1925
1926
1927
1928 dev->openings = 1;
1929 ahc_set_scsi_status(scb, SCSI_STATUS_BUSY);
1930 ahc_platform_set_tags(ahc, sdev, &devinfo,
1931 (dev->flags & AHC_DEV_Q_BASIC)
1932 ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
1933 break;
1934 }
1935 }
1936}
1937
1938static void
1939ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
1940{
1941
1942
1943
1944
1945
1946
1947 {
1948 u_int new_status;
1949
1950 switch (ahc_cmd_get_transaction_status(cmd)) {
1951 case CAM_REQ_INPROG:
1952 case CAM_REQ_CMP:
1953 case CAM_SCSI_STATUS_ERROR:
1954 new_status = DID_OK;
1955 break;
1956 case CAM_REQ_ABORTED:
1957 new_status = DID_ABORT;
1958 break;
1959 case CAM_BUSY:
1960 new_status = DID_BUS_BUSY;
1961 break;
1962 case CAM_REQ_INVALID:
1963 case CAM_PATH_INVALID:
1964 new_status = DID_BAD_TARGET;
1965 break;
1966 case CAM_SEL_TIMEOUT:
1967 new_status = DID_NO_CONNECT;
1968 break;
1969 case CAM_SCSI_BUS_RESET:
1970 case CAM_BDR_SENT:
1971 new_status = DID_RESET;
1972 break;
1973 case CAM_UNCOR_PARITY:
1974 new_status = DID_PARITY;
1975 break;
1976 case CAM_CMD_TIMEOUT:
1977 new_status = DID_TIME_OUT;
1978 break;
1979 case CAM_UA_ABORT:
1980 case CAM_REQ_CMP_ERR:
1981 case CAM_AUTOSENSE_FAIL:
1982 case CAM_NO_HBA:
1983 case CAM_DATA_RUN_ERR:
1984 case CAM_UNEXP_BUSFREE:
1985 case CAM_SEQUENCE_FAIL:
1986 case CAM_CCB_LEN_ERR:
1987 case CAM_PROVIDE_FAIL:
1988 case CAM_REQ_TERMIO:
1989 case CAM_UNREC_HBA_ERROR:
1990 case CAM_REQ_TOO_BIG:
1991 new_status = DID_ERROR;
1992 break;
1993 case CAM_REQUEUE_REQ:
1994 new_status = DID_REQUEUE;
1995 break;
1996 default:
1997
1998 new_status = DID_ERROR;
1999 break;
2000 }
2001
2002 ahc_cmd_set_transaction_status(cmd, new_status);
2003 }
2004
2005 cmd->scsi_done(cmd);
2006}
2007
2008static void
2009ahc_linux_freeze_simq(struct ahc_softc *ahc)
2010{
2011 unsigned long s;
2012
2013 ahc_lock(ahc, &s);
2014 ahc->platform_data->qfrozen++;
2015 if (ahc->platform_data->qfrozen == 1) {
2016 scsi_block_requests(ahc->platform_data->host);
2017
2018
2019 ahc_platform_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
2020 CAM_LUN_WILDCARD, SCB_LIST_NULL,
2021 ROLE_INITIATOR, CAM_REQUEUE_REQ);
2022 }
2023 ahc_unlock(ahc, &s);
2024}
2025
2026static void
2027ahc_linux_release_simq(struct ahc_softc *ahc)
2028{
2029 u_long s;
2030 int unblock_reqs;
2031
2032 unblock_reqs = 0;
2033 ahc_lock(ahc, &s);
2034 if (ahc->platform_data->qfrozen > 0)
2035 ahc->platform_data->qfrozen--;
2036 if (ahc->platform_data->qfrozen == 0)
2037 unblock_reqs = 1;
2038 ahc_unlock(ahc, &s);
2039
2040
2041
2042
2043
2044
2045 if (unblock_reqs)
2046 scsi_unblock_requests(ahc->platform_data->host);
2047}
2048
2049static int
2050ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
2051{
2052 struct ahc_softc *ahc;
2053 struct ahc_linux_device *dev;
2054 struct scb *pending_scb;
2055 u_int saved_scbptr;
2056 u_int active_scb_index;
2057 u_int last_phase;
2058 u_int saved_scsiid;
2059 u_int cdb_byte;
2060 int retval;
2061 int was_paused;
2062 int paused;
2063 int wait;
2064 int disconnected;
2065 unsigned long flags;
2066
2067 pending_scb = NULL;
2068 paused = FALSE;
2069 wait = FALSE;
2070 ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
2071
2072 scmd_printk(KERN_INFO, cmd, "Attempting to queue a%s message\n",
2073 flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
2074
2075 printk("CDB:");
2076 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
2077 printk(" 0x%x", cmd->cmnd[cdb_byte]);
2078 printk("\n");
2079
2080 ahc_lock(ahc, &flags);
2081
2082
2083
2084
2085
2086
2087
2088
2089 dev = scsi_transport_device_data(cmd->device);
2090
2091 if (dev == NULL) {
2092
2093
2094
2095
2096 printk("%s:%d:%d:%d: Is not an active device\n",
2097 ahc_name(ahc), cmd->device->channel, cmd->device->id,
2098 (u8)cmd->device->lun);
2099 retval = SUCCESS;
2100 goto no_cmd;
2101 }
2102
2103 if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
2104 && ahc_search_untagged_queues(ahc, cmd, cmd->device->id,
2105 cmd->device->channel + 'A',
2106 (u8)cmd->device->lun,
2107 CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) {
2108 printk("%s:%d:%d:%d: Command found on untagged queue\n",
2109 ahc_name(ahc), cmd->device->channel, cmd->device->id,
2110 (u8)cmd->device->lun);
2111 retval = SUCCESS;
2112 goto done;
2113 }
2114
2115
2116
2117
2118 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
2119 if (pending_scb->io_ctx == cmd)
2120 break;
2121 }
2122
2123 if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {
2124
2125
2126 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
2127 if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd),
2128 scmd_channel(cmd) + 'A',
2129 CAM_LUN_WILDCARD,
2130 SCB_LIST_NULL, ROLE_INITIATOR))
2131 break;
2132 }
2133 }
2134
2135 if (pending_scb == NULL) {
2136 scmd_printk(KERN_INFO, cmd, "Command not found\n");
2137 goto no_cmd;
2138 }
2139
2140 if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
2141
2142
2143
2144 retval = FAILED;
2145 goto done;
2146 }
2147
2148
2149
2150
2151
2152
2153 was_paused = ahc_is_paused(ahc);
2154 ahc_pause_and_flushwork(ahc);
2155 paused = TRUE;
2156
2157 if ((pending_scb->flags & SCB_ACTIVE) == 0) {
2158 scmd_printk(KERN_INFO, cmd, "Command already completed\n");
2159 goto no_cmd;
2160 }
2161
2162 printk("%s: At time of recovery, card was %spaused\n",
2163 ahc_name(ahc), was_paused ? "" : "not ");
2164 ahc_dump_card_state(ahc);
2165
2166 disconnected = TRUE;
2167 if (flag == SCB_ABORT) {
2168 if (ahc_search_qinfifo(ahc, cmd->device->id,
2169 cmd->device->channel + 'A',
2170 cmd->device->lun,
2171 pending_scb->hscb->tag,
2172 ROLE_INITIATOR, CAM_REQ_ABORTED,
2173 SEARCH_COMPLETE) > 0) {
2174 printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
2175 ahc_name(ahc), cmd->device->channel,
2176 cmd->device->id, (u8)cmd->device->lun);
2177 retval = SUCCESS;
2178 goto done;
2179 }
2180 } else if (ahc_search_qinfifo(ahc, cmd->device->id,
2181 cmd->device->channel + 'A',
2182 cmd->device->lun,
2183 pending_scb->hscb->tag,
2184 ROLE_INITIATOR, 0,
2185 SEARCH_COUNT) > 0) {
2186 disconnected = FALSE;
2187 }
2188
2189 if (disconnected && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
2190 struct scb *bus_scb;
2191
2192 bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG));
2193 if (bus_scb == pending_scb)
2194 disconnected = FALSE;
2195 else if (flag != SCB_ABORT
2196 && ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid
2197 && ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb))
2198 disconnected = FALSE;
2199 }
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209 last_phase = ahc_inb(ahc, LASTPHASE);
2210 saved_scbptr = ahc_inb(ahc, SCBPTR);
2211 active_scb_index = ahc_inb(ahc, SCB_TAG);
2212 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
2213 if (last_phase != P_BUSFREE
2214 && (pending_scb->hscb->tag == active_scb_index
2215 || (flag == SCB_DEVICE_RESET
2216 && SCSIID_TARGET(ahc, saved_scsiid) == scmd_id(cmd)))) {
2217
2218
2219
2220
2221
2222 pending_scb = ahc_lookup_scb(ahc, active_scb_index);
2223 pending_scb->flags |= SCB_RECOVERY_SCB|flag;
2224 ahc_outb(ahc, MSG_OUT, HOST_MSG);
2225 ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
2226 scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
2227 wait = TRUE;
2228 } else if (disconnected) {
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246 pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
2247 pending_scb->flags |= SCB_RECOVERY_SCB|flag;
2248
2249
2250
2251
2252
2253
2254
2255
2256 ahc_search_disc_list(ahc, cmd->device->id,
2257 cmd->device->channel + 'A',
2258 cmd->device->lun, pending_scb->hscb->tag,
2259 TRUE,
2260 TRUE,
2261 FALSE);
2262
2263
2264
2265
2266
2267
2268
2269
2270 if ((ahc->flags & AHC_PAGESCBS) == 0) {
2271 ahc_outb(ahc, SCBPTR, pending_scb->hscb->tag);
2272 ahc_outb(ahc, SCB_CONTROL,
2273 ahc_inb(ahc, SCB_CONTROL)|MK_MESSAGE);
2274 }
2275
2276
2277
2278
2279
2280
2281 ahc_search_qinfifo(ahc, cmd->device->id,
2282 cmd->device->channel + 'A',
2283 cmd->device->lun, SCB_LIST_NULL,
2284 ROLE_INITIATOR, CAM_REQUEUE_REQ,
2285 SEARCH_COMPLETE);
2286 ahc_qinfifo_requeue_tail(ahc, pending_scb);
2287 ahc_outb(ahc, SCBPTR, saved_scbptr);
2288 ahc_print_path(ahc, pending_scb);
2289 printk("Device is disconnected, re-queuing SCB\n");
2290 wait = TRUE;
2291 } else {
2292 scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
2293 retval = FAILED;
2294 goto done;
2295 }
2296
2297no_cmd:
2298
2299
2300
2301
2302
2303
2304 retval = SUCCESS;
2305done:
2306 if (paused)
2307 ahc_unpause(ahc);
2308 if (wait) {
2309 DECLARE_COMPLETION_ONSTACK(done);
2310
2311 ahc->platform_data->eh_done = &done;
2312 ahc_unlock(ahc, &flags);
2313
2314 printk("Recovery code sleeping\n");
2315 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
2316 ahc_lock(ahc, &flags);
2317 ahc->platform_data->eh_done = NULL;
2318 ahc_unlock(ahc, &flags);
2319
2320 printk("Timer Expired\n");
2321 retval = FAILED;
2322 }
2323 printk("Recovery code awake\n");
2324 } else
2325 ahc_unlock(ahc, &flags);
2326 return (retval);
2327}
2328
2329static void ahc_linux_set_width(struct scsi_target *starget, int width)
2330{
2331 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2332 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2333 struct ahc_devinfo devinfo;
2334 unsigned long flags;
2335
2336 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2337 starget->channel + 'A', ROLE_INITIATOR);
2338 ahc_lock(ahc, &flags);
2339 ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
2340 ahc_unlock(ahc, &flags);
2341}
2342
2343static void ahc_linux_set_period(struct scsi_target *starget, int period)
2344{
2345 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2346 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2347 struct ahc_tmode_tstate *tstate;
2348 struct ahc_initiator_tinfo *tinfo
2349 = ahc_fetch_transinfo(ahc,
2350 starget->channel + 'A',
2351 shost->this_id, starget->id, &tstate);
2352 struct ahc_devinfo devinfo;
2353 unsigned int ppr_options = tinfo->goal.ppr_options;
2354 unsigned long flags;
2355 unsigned long offset = tinfo->goal.offset;
2356 const struct ahc_syncrate *syncrate;
2357
2358 if (offset == 0)
2359 offset = MAX_OFFSET;
2360
2361 if (period < 9)
2362 period = 9;
2363 if (period == 9) {
2364 if (spi_max_width(starget))
2365 ppr_options |= MSG_EXT_PPR_DT_REQ;
2366 else
2367
2368 period = 10;
2369 }
2370
2371 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2372 starget->channel + 'A', ROLE_INITIATOR);
2373
2374
2375 if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) {
2376 if (spi_width(starget) == 0)
2377 ppr_options &= MSG_EXT_PPR_QAS_REQ;
2378 }
2379
2380 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2381 ahc_lock(ahc, &flags);
2382 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
2383 ppr_options, AHC_TRANS_GOAL, FALSE);
2384 ahc_unlock(ahc, &flags);
2385}
2386
2387static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
2388{
2389 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2390 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2391 struct ahc_tmode_tstate *tstate;
2392 struct ahc_initiator_tinfo *tinfo
2393 = ahc_fetch_transinfo(ahc,
2394 starget->channel + 'A',
2395 shost->this_id, starget->id, &tstate);
2396 struct ahc_devinfo devinfo;
2397 unsigned int ppr_options = 0;
2398 unsigned int period = 0;
2399 unsigned long flags;
2400 const struct ahc_syncrate *syncrate = NULL;
2401
2402 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2403 starget->channel + 'A', ROLE_INITIATOR);
2404 if (offset != 0) {
2405 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2406 period = tinfo->goal.period;
2407 ppr_options = tinfo->goal.ppr_options;
2408 }
2409 ahc_lock(ahc, &flags);
2410 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
2411 ppr_options, AHC_TRANS_GOAL, FALSE);
2412 ahc_unlock(ahc, &flags);
2413}
2414
2415static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
2416{
2417 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2418 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2419 struct ahc_tmode_tstate *tstate;
2420 struct ahc_initiator_tinfo *tinfo
2421 = ahc_fetch_transinfo(ahc,
2422 starget->channel + 'A',
2423 shost->this_id, starget->id, &tstate);
2424 struct ahc_devinfo devinfo;
2425 unsigned int ppr_options = tinfo->goal.ppr_options
2426 & ~MSG_EXT_PPR_DT_REQ;
2427 unsigned int period = tinfo->goal.period;
2428 unsigned int width = tinfo->goal.width;
2429 unsigned long flags;
2430 const struct ahc_syncrate *syncrate;
2431
2432 if (dt && spi_max_width(starget)) {
2433 ppr_options |= MSG_EXT_PPR_DT_REQ;
2434 if (!width)
2435 ahc_linux_set_width(starget, 1);
2436 } else if (period == 9)
2437 period = 10;
2438
2439 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2440 starget->channel + 'A', ROLE_INITIATOR);
2441 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT);
2442 ahc_lock(ahc, &flags);
2443 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
2444 ppr_options, AHC_TRANS_GOAL, FALSE);
2445 ahc_unlock(ahc, &flags);
2446}
2447
2448#if 0
2449
2450
2451
2452
2453static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
2454{
2455 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2456 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2457 struct ahc_tmode_tstate *tstate;
2458 struct ahc_initiator_tinfo *tinfo
2459 = ahc_fetch_transinfo(ahc,
2460 starget->channel + 'A',
2461 shost->this_id, starget->id, &tstate);
2462 struct ahc_devinfo devinfo;
2463 unsigned int ppr_options = tinfo->goal.ppr_options
2464 & ~MSG_EXT_PPR_QAS_REQ;
2465 unsigned int period = tinfo->goal.period;
2466 unsigned long flags;
2467 struct ahc_syncrate *syncrate;
2468
2469 if (qas)
2470 ppr_options |= MSG_EXT_PPR_QAS_REQ;
2471
2472 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2473 starget->channel + 'A', ROLE_INITIATOR);
2474 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2475 ahc_lock(ahc, &flags);
2476 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
2477 ppr_options, AHC_TRANS_GOAL, FALSE);
2478 ahc_unlock(ahc, &flags);
2479}
2480
2481static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
2482{
2483 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2484 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2485 struct ahc_tmode_tstate *tstate;
2486 struct ahc_initiator_tinfo *tinfo
2487 = ahc_fetch_transinfo(ahc,
2488 starget->channel + 'A',
2489 shost->this_id, starget->id, &tstate);
2490 struct ahc_devinfo devinfo;
2491 unsigned int ppr_options = tinfo->goal.ppr_options
2492 & ~MSG_EXT_PPR_IU_REQ;
2493 unsigned int period = tinfo->goal.period;
2494 unsigned long flags;
2495 struct ahc_syncrate *syncrate;
2496
2497 if (iu)
2498 ppr_options |= MSG_EXT_PPR_IU_REQ;
2499
2500 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2501 starget->channel + 'A', ROLE_INITIATOR);
2502 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2503 ahc_lock(ahc, &flags);
2504 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
2505 ppr_options, AHC_TRANS_GOAL, FALSE);
2506 ahc_unlock(ahc, &flags);
2507}
2508#endif
2509
2510static void ahc_linux_get_signalling(struct Scsi_Host *shost)
2511{
2512 struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
2513 unsigned long flags;
2514 u8 mode;
2515
2516 if (!(ahc->features & AHC_ULTRA2)) {
2517
2518 spi_signalling(shost) =
2519 ahc->features & AHC_HVD ?
2520 SPI_SIGNAL_HVD :
2521 SPI_SIGNAL_SE;
2522 return;
2523 }
2524
2525 ahc_lock(ahc, &flags);
2526 ahc_pause(ahc);
2527 mode = ahc_inb(ahc, SBLKCTL);
2528 ahc_unpause(ahc);
2529 ahc_unlock(ahc, &flags);
2530
2531 if (mode & ENAB40)
2532 spi_signalling(shost) = SPI_SIGNAL_LVD;
2533 else if (mode & ENAB20)
2534 spi_signalling(shost) = SPI_SIGNAL_SE;
2535 else
2536 spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
2537}
2538
2539static struct spi_function_template ahc_linux_transport_functions = {
2540 .set_offset = ahc_linux_set_offset,
2541 .show_offset = 1,
2542 .set_period = ahc_linux_set_period,
2543 .show_period = 1,
2544 .set_width = ahc_linux_set_width,
2545 .show_width = 1,
2546 .set_dt = ahc_linux_set_dt,
2547 .show_dt = 1,
2548#if 0
2549 .set_iu = ahc_linux_set_iu,
2550 .show_iu = 1,
2551 .set_qas = ahc_linux_set_qas,
2552 .show_qas = 1,
2553#endif
2554 .get_signalling = ahc_linux_get_signalling,
2555};
2556
2557
2558
2559static int __init
2560ahc_linux_init(void)
2561{
2562
2563
2564
2565 if (aic7xxx)
2566 aic7xxx_setup(aic7xxx);
2567
2568 ahc_linux_transport_template =
2569 spi_attach_transport(&ahc_linux_transport_functions);
2570 if (!ahc_linux_transport_template)
2571 return -ENODEV;
2572
2573 scsi_transport_reserve_device(ahc_linux_transport_template,
2574 sizeof(struct ahc_linux_device));
2575
2576 ahc_linux_pci_init();
2577 ahc_linux_eisa_init();
2578 return 0;
2579}
2580
2581static void
2582ahc_linux_exit(void)
2583{
2584 ahc_linux_pci_exit();
2585 ahc_linux_eisa_exit();
2586 spi_release_transport(ahc_linux_transport_template);
2587}
2588
2589module_init(ahc_linux_init);
2590module_exit(ahc_linux_exit);
2591