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 .use_clustering = ENABLE_CLUSTERING,
811 .slave_alloc = ahc_linux_slave_alloc,
812 .slave_configure = ahc_linux_slave_configure,
813 .target_alloc = ahc_linux_target_alloc,
814 .target_destroy = ahc_linux_target_destroy,
815};
816
817
818
819
820#define BUILD_SCSIID(ahc, cmd) \
821 ((((cmd)->device->id << TID_SHIFT) & TID) \
822 | (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \
823 | (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB))
824
825
826int
827ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent,
828 bus_size_t alignment, bus_size_t boundary,
829 dma_addr_t lowaddr, dma_addr_t highaddr,
830 bus_dma_filter_t *filter, void *filterarg,
831 bus_size_t maxsize, int nsegments,
832 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
833{
834 bus_dma_tag_t dmat;
835
836 dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC);
837 if (dmat == NULL)
838 return (ENOMEM);
839
840
841
842
843
844
845
846
847 dmat->alignment = alignment;
848 dmat->boundary = boundary;
849 dmat->maxsize = maxsize;
850 *ret_tag = dmat;
851 return (0);
852}
853
854void
855ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat)
856{
857 kfree(dmat);
858}
859
860int
861ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr,
862 int flags, bus_dmamap_t *mapp)
863{
864 *vaddr = pci_alloc_consistent(ahc->dev_softc,
865 dmat->maxsize, mapp);
866 if (*vaddr == NULL)
867 return ENOMEM;
868 return 0;
869}
870
871void
872ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat,
873 void* vaddr, bus_dmamap_t map)
874{
875 pci_free_consistent(ahc->dev_softc, dmat->maxsize,
876 vaddr, map);
877}
878
879int
880ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map,
881 void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
882 void *cb_arg, int flags)
883{
884
885
886
887
888 bus_dma_segment_t stack_sg;
889
890 stack_sg.ds_addr = map;
891 stack_sg.ds_len = dmat->maxsize;
892 cb(cb_arg, &stack_sg, 1, 0);
893 return (0);
894}
895
896void
897ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
898{
899}
900
901int
902ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
903{
904
905 return (0);
906}
907
908static void
909ahc_linux_setup_tag_info_global(char *p)
910{
911 int tags, i, j;
912
913 tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
914 printk("Setting Global Tags= %d\n", tags);
915
916 for (i = 0; i < ARRAY_SIZE(aic7xxx_tag_info); i++) {
917 for (j = 0; j < AHC_NUM_TARGETS; j++) {
918 aic7xxx_tag_info[i].tag_commands[j] = tags;
919 }
920 }
921}
922
923static void
924ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
925{
926
927 if ((instance >= 0) && (targ >= 0)
928 && (instance < ARRAY_SIZE(aic7xxx_tag_info))
929 && (targ < AHC_NUM_TARGETS)) {
930 aic7xxx_tag_info[instance].tag_commands[targ] = value & 0xff;
931 if (bootverbose)
932 printk("tag_info[%d:%d] = %d\n", instance, targ, value);
933 }
934}
935
936static char *
937ahc_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
938 void (*callback)(u_long, int, int, int32_t),
939 u_long callback_arg)
940{
941 char *tok_end;
942 char *tok_end2;
943 int i;
944 int instance;
945 int targ;
946 int done;
947 char tok_list[] = {'.', ',', '{', '}', '\0'};
948
949
950 if (*opt_arg != ':')
951 return (opt_arg);
952 opt_arg++;
953 instance = -1;
954 targ = -1;
955 done = FALSE;
956
957
958
959
960 tok_end = strchr(opt_arg, '\0');
961 if (tok_end < end)
962 *tok_end = ',';
963 while (!done) {
964 switch (*opt_arg) {
965 case '{':
966 if (instance == -1) {
967 instance = 0;
968 } else {
969 if (depth > 1) {
970 if (targ == -1)
971 targ = 0;
972 } else {
973 printk("Malformed Option %s\n",
974 opt_name);
975 done = TRUE;
976 }
977 }
978 opt_arg++;
979 break;
980 case '}':
981 if (targ != -1)
982 targ = -1;
983 else if (instance != -1)
984 instance = -1;
985 opt_arg++;
986 break;
987 case ',':
988 case '.':
989 if (instance == -1)
990 done = TRUE;
991 else if (targ >= 0)
992 targ++;
993 else if (instance >= 0)
994 instance++;
995 opt_arg++;
996 break;
997 case '\0':
998 done = TRUE;
999 break;
1000 default:
1001 tok_end = end;
1002 for (i = 0; tok_list[i]; i++) {
1003 tok_end2 = strchr(opt_arg, tok_list[i]);
1004 if ((tok_end2) && (tok_end2 < tok_end))
1005 tok_end = tok_end2;
1006 }
1007 callback(callback_arg, instance, targ,
1008 simple_strtol(opt_arg, NULL, 0));
1009 opt_arg = tok_end;
1010 break;
1011 }
1012 }
1013 return (opt_arg);
1014}
1015
1016
1017
1018
1019
1020
1021static int
1022aic7xxx_setup(char *s)
1023{
1024 int i, n;
1025 char *p;
1026 char *end;
1027
1028 static const struct {
1029 const char *name;
1030 uint32_t *flag;
1031 } options[] = {
1032 { "extended", &aic7xxx_extended },
1033 { "no_reset", &aic7xxx_no_reset },
1034 { "verbose", &aic7xxx_verbose },
1035 { "allow_memio", &aic7xxx_allow_memio},
1036#ifdef AHC_DEBUG
1037 { "debug", &ahc_debug },
1038#endif
1039 { "periodic_otag", &aic7xxx_periodic_otag },
1040 { "pci_parity", &aic7xxx_pci_parity },
1041 { "seltime", &aic7xxx_seltime },
1042 { "tag_info", NULL },
1043 { "global_tag_depth", NULL },
1044 { "dv", NULL }
1045 };
1046
1047 end = strchr(s, '\0');
1048
1049
1050
1051
1052
1053 n = 0;
1054
1055 while ((p = strsep(&s, ",.")) != NULL) {
1056 if (*p == '\0')
1057 continue;
1058 for (i = 0; i < ARRAY_SIZE(options); i++) {
1059
1060 n = strlen(options[i].name);
1061 if (strncmp(options[i].name, p, n) == 0)
1062 break;
1063 }
1064 if (i == ARRAY_SIZE(options))
1065 continue;
1066
1067 if (strncmp(p, "global_tag_depth", n) == 0) {
1068 ahc_linux_setup_tag_info_global(p + n);
1069 } else if (strncmp(p, "tag_info", n) == 0) {
1070 s = ahc_parse_brace_option("tag_info", p + n, end,
1071 2, ahc_linux_setup_tag_info, 0);
1072 } else if (p[n] == ':') {
1073 *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
1074 } else if (strncmp(p, "verbose", n) == 0) {
1075 *(options[i].flag) = 1;
1076 } else {
1077 *(options[i].flag) ^= 0xFFFFFFFF;
1078 }
1079 }
1080 return 1;
1081}
1082
1083__setup("aic7xxx=", aic7xxx_setup);
1084
1085uint32_t aic7xxx_verbose;
1086
1087int
1088ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *template)
1089{
1090 char buf[80];
1091 struct Scsi_Host *host;
1092 char *new_name;
1093 u_long s;
1094 int retval;
1095
1096 template->name = ahc->description;
1097 host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
1098 if (host == NULL)
1099 return (ENOMEM);
1100
1101 *((struct ahc_softc **)host->hostdata) = ahc;
1102 ahc->platform_data->host = host;
1103 host->can_queue = AHC_MAX_QUEUE;
1104 host->cmd_per_lun = 2;
1105
1106 host->this_id = ahc->our_id;
1107 host->irq = ahc->platform_data->irq;
1108 host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8;
1109 host->max_lun = AHC_NUM_LUNS;
1110 host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
1111 host->sg_tablesize = AHC_NSEG;
1112 ahc_lock(ahc, &s);
1113 ahc_set_unit(ahc, ahc_linux_unit++);
1114 ahc_unlock(ahc, &s);
1115 sprintf(buf, "scsi%d", host->host_no);
1116 new_name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
1117 if (new_name != NULL) {
1118 strcpy(new_name, buf);
1119 ahc_set_name(ahc, new_name);
1120 }
1121 host->unique_id = ahc->unit;
1122 ahc_linux_initialize_scsi_bus(ahc);
1123 ahc_intr_enable(ahc, TRUE);
1124
1125 host->transportt = ahc_linux_transport_template;
1126
1127 retval = scsi_add_host(host,
1128 (ahc->dev_softc ? &ahc->dev_softc->dev : NULL));
1129 if (retval) {
1130 printk(KERN_WARNING "aic7xxx: scsi_add_host failed\n");
1131 scsi_host_put(host);
1132 return retval;
1133 }
1134
1135 scsi_scan_host(host);
1136 return 0;
1137}
1138
1139
1140
1141
1142
1143
1144void
1145ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
1146{
1147 int i;
1148 int numtarg;
1149 unsigned long s;
1150
1151 i = 0;
1152 numtarg = 0;
1153
1154 ahc_lock(ahc, &s);
1155
1156 if (aic7xxx_no_reset != 0)
1157 ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B);
1158
1159 if ((ahc->flags & AHC_RESET_BUS_A) != 0)
1160 ahc_reset_channel(ahc, 'A', TRUE);
1161 else
1162 numtarg = (ahc->features & AHC_WIDE) ? 16 : 8;
1163
1164 if ((ahc->features & AHC_TWIN) != 0) {
1165
1166 if ((ahc->flags & AHC_RESET_BUS_B) != 0) {
1167 ahc_reset_channel(ahc, 'B', TRUE);
1168 } else {
1169 if (numtarg == 0)
1170 i = 8;
1171 numtarg += 8;
1172 }
1173 }
1174
1175
1176
1177
1178
1179 for (; i < numtarg; i++) {
1180 struct ahc_devinfo devinfo;
1181 struct ahc_initiator_tinfo *tinfo;
1182 struct ahc_tmode_tstate *tstate;
1183 u_int our_id;
1184 u_int target_id;
1185 char channel;
1186
1187 channel = 'A';
1188 our_id = ahc->our_id;
1189 target_id = i;
1190 if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
1191 channel = 'B';
1192 our_id = ahc->our_id_b;
1193 target_id = i % 8;
1194 }
1195 tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
1196 target_id, &tstate);
1197 ahc_compile_devinfo(&devinfo, our_id, target_id,
1198 CAM_LUN_WILDCARD, channel, ROLE_INITIATOR);
1199 ahc_update_neg_request(ahc, &devinfo, tstate,
1200 tinfo, AHC_NEG_ALWAYS);
1201 }
1202 ahc_unlock(ahc, &s);
1203
1204 if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
1205 ahc_linux_freeze_simq(ahc);
1206 msleep(AIC7XXX_RESET_DELAY);
1207 ahc_linux_release_simq(ahc);
1208 }
1209}
1210
1211int
1212ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
1213{
1214
1215 ahc->platform_data =
1216 kzalloc(sizeof(struct ahc_platform_data), GFP_ATOMIC);
1217 if (ahc->platform_data == NULL)
1218 return (ENOMEM);
1219 ahc->platform_data->irq = AHC_LINUX_NOIRQ;
1220 ahc_lockinit(ahc);
1221 ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
1222 ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
1223 if (aic7xxx_pci_parity == 0)
1224 ahc->flags |= AHC_DISABLE_PCI_PERR;
1225
1226 return (0);
1227}
1228
1229void
1230ahc_platform_free(struct ahc_softc *ahc)
1231{
1232 struct scsi_target *starget;
1233 int i;
1234
1235 if (ahc->platform_data != NULL) {
1236
1237 for (i = 0; i < AHC_NUM_TARGETS; i++) {
1238 starget = ahc->platform_data->starget[i];
1239 if (starget != NULL) {
1240 ahc->platform_data->starget[i] = NULL;
1241 }
1242 }
1243
1244 if (ahc->platform_data->irq != AHC_LINUX_NOIRQ)
1245 free_irq(ahc->platform_data->irq, ahc);
1246 if (ahc->tag == BUS_SPACE_PIO
1247 && ahc->bsh.ioport != 0)
1248 release_region(ahc->bsh.ioport, 256);
1249 if (ahc->tag == BUS_SPACE_MEMIO
1250 && ahc->bsh.maddr != NULL) {
1251 iounmap(ahc->bsh.maddr);
1252 release_mem_region(ahc->platform_data->mem_busaddr,
1253 0x1000);
1254 }
1255
1256 if (ahc->platform_data->host)
1257 scsi_host_put(ahc->platform_data->host);
1258
1259 kfree(ahc->platform_data);
1260 }
1261}
1262
1263void
1264ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
1265{
1266 ahc_platform_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb),
1267 SCB_GET_CHANNEL(ahc, scb),
1268 SCB_GET_LUN(scb), SCB_LIST_NULL,
1269 ROLE_UNKNOWN, CAM_REQUEUE_REQ);
1270}
1271
1272void
1273ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
1274 struct ahc_devinfo *devinfo, ahc_queue_alg alg)
1275{
1276 struct ahc_linux_device *dev;
1277 int was_queuing;
1278 int now_queuing;
1279
1280 if (sdev == NULL)
1281 return;
1282 dev = scsi_transport_device_data(sdev);
1283
1284 was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED);
1285 switch (alg) {
1286 default:
1287 case AHC_QUEUE_NONE:
1288 now_queuing = 0;
1289 break;
1290 case AHC_QUEUE_BASIC:
1291 now_queuing = AHC_DEV_Q_BASIC;
1292 break;
1293 case AHC_QUEUE_TAGGED:
1294 now_queuing = AHC_DEV_Q_TAGGED;
1295 break;
1296 }
1297 if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0
1298 && (was_queuing != now_queuing)
1299 && (dev->active != 0)) {
1300 dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY;
1301 dev->qfrozen++;
1302 }
1303
1304 dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG);
1305 if (now_queuing) {
1306 u_int usertags;
1307
1308 usertags = ahc_linux_user_tagdepth(ahc, devinfo);
1309 if (!was_queuing) {
1310
1311
1312
1313
1314
1315 dev->maxtags = usertags;
1316 dev->openings = dev->maxtags - dev->active;
1317 }
1318 if (dev->maxtags == 0) {
1319
1320
1321
1322 dev->openings = 1;
1323 } else if (alg == AHC_QUEUE_TAGGED) {
1324 dev->flags |= AHC_DEV_Q_TAGGED;
1325 if (aic7xxx_periodic_otag != 0)
1326 dev->flags |= AHC_DEV_PERIODIC_OTAG;
1327 } else
1328 dev->flags |= AHC_DEV_Q_BASIC;
1329 } else {
1330
1331 dev->maxtags = 0;
1332 dev->openings = 1 - dev->active;
1333 }
1334 switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
1335 case AHC_DEV_Q_BASIC:
1336 case AHC_DEV_Q_TAGGED:
1337 scsi_change_queue_depth(sdev,
1338 dev->openings + dev->active);
1339 break;
1340 default:
1341
1342
1343
1344
1345
1346
1347 scsi_change_queue_depth(sdev, 2);
1348 break;
1349 }
1350}
1351
1352int
1353ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel,
1354 int lun, u_int tag, role_t role, uint32_t status)
1355{
1356 return 0;
1357}
1358
1359static u_int
1360ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
1361{
1362 static int warned_user;
1363 u_int tags;
1364
1365 tags = 0;
1366 if ((ahc->user_discenable & devinfo->target_mask) != 0) {
1367 if (ahc->unit >= ARRAY_SIZE(aic7xxx_tag_info)) {
1368 if (warned_user == 0) {
1369
1370 printk(KERN_WARNING
1371"aic7xxx: WARNING: Insufficient tag_info instances\n"
1372"aic7xxx: for installed controllers. Using defaults\n"
1373"aic7xxx: Please update the aic7xxx_tag_info array in\n"
1374"aic7xxx: the aic7xxx_osm..c source file.\n");
1375 warned_user++;
1376 }
1377 tags = AHC_MAX_QUEUE;
1378 } else {
1379 adapter_tag_info_t *tag_info;
1380
1381 tag_info = &aic7xxx_tag_info[ahc->unit];
1382 tags = tag_info->tag_commands[devinfo->target_offset];
1383 if (tags > AHC_MAX_QUEUE)
1384 tags = AHC_MAX_QUEUE;
1385 }
1386 }
1387 return (tags);
1388}
1389
1390
1391
1392
1393static void
1394ahc_linux_device_queue_depth(struct scsi_device *sdev)
1395{
1396 struct ahc_devinfo devinfo;
1397 u_int tags;
1398 struct ahc_softc *ahc = *((struct ahc_softc **)sdev->host->hostdata);
1399
1400 ahc_compile_devinfo(&devinfo,
1401 sdev->sdev_target->channel == 0
1402 ? ahc->our_id : ahc->our_id_b,
1403 sdev->sdev_target->id, sdev->lun,
1404 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1405 ROLE_INITIATOR);
1406 tags = ahc_linux_user_tagdepth(ahc, &devinfo);
1407 if (tags != 0 && sdev->tagged_supported != 0) {
1408
1409 ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_TAGGED);
1410 ahc_send_async(ahc, devinfo.channel, devinfo.target,
1411 devinfo.lun, AC_TRANSFER_NEG);
1412 ahc_print_devinfo(ahc, &devinfo);
1413 printk("Tagged Queuing enabled. Depth %d\n", tags);
1414 } else {
1415 ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_NONE);
1416 ahc_send_async(ahc, devinfo.channel, devinfo.target,
1417 devinfo.lun, AC_TRANSFER_NEG);
1418 }
1419}
1420
1421static int
1422ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
1423 struct scsi_cmnd *cmd)
1424{
1425 struct scb *scb;
1426 struct hardware_scb *hscb;
1427 struct ahc_initiator_tinfo *tinfo;
1428 struct ahc_tmode_tstate *tstate;
1429 uint16_t mask;
1430 struct scb_tailq *untagged_q = NULL;
1431 int nseg;
1432
1433
1434
1435
1436
1437 if (ahc->platform_data->qfrozen != 0)
1438 return SCSI_MLQUEUE_HOST_BUSY;
1439
1440
1441
1442
1443
1444
1445
1446 if (!(cmd->flags & SCMD_TAGGED)
1447 && (ahc->features & AHC_SCB_BTT) == 0) {
1448 int target_offset;
1449
1450 target_offset = cmd->device->id + cmd->device->channel * 8;
1451 untagged_q = &(ahc->untagged_queues[target_offset]);
1452 if (!TAILQ_EMPTY(untagged_q))
1453
1454
1455 return SCSI_MLQUEUE_DEVICE_BUSY;
1456 }
1457
1458 nseg = scsi_dma_map(cmd);
1459 if (nseg < 0)
1460 return SCSI_MLQUEUE_HOST_BUSY;
1461
1462
1463
1464
1465 scb = ahc_get_scb(ahc);
1466 if (!scb) {
1467 scsi_dma_unmap(cmd);
1468 return SCSI_MLQUEUE_HOST_BUSY;
1469 }
1470
1471 scb->io_ctx = cmd;
1472 scb->platform_data->dev = dev;
1473 hscb = scb->hscb;
1474 cmd->host_scribble = (char *)scb;
1475
1476
1477
1478
1479 hscb->control = 0;
1480 hscb->scsiid = BUILD_SCSIID(ahc, cmd);
1481 hscb->lun = cmd->device->lun;
1482 mask = SCB_GET_TARGET_MASK(ahc, scb);
1483 tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
1484 SCB_GET_OUR_ID(scb),
1485 SCB_GET_TARGET(ahc, scb), &tstate);
1486 hscb->scsirate = tinfo->scsirate;
1487 hscb->scsioffset = tinfo->curr.offset;
1488 if ((tstate->ultraenb & mask) != 0)
1489 hscb->control |= ULTRAENB;
1490
1491 if ((ahc->user_discenable & mask) != 0)
1492 hscb->control |= DISCENB;
1493
1494 if ((tstate->auto_negotiate & mask) != 0) {
1495 scb->flags |= SCB_AUTO_NEGOTIATE;
1496 scb->hscb->control |= MK_MESSAGE;
1497 }
1498
1499 if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
1500 if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
1501 && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
1502 hscb->control |= MSG_ORDERED_TASK;
1503 dev->commands_since_idle_or_otag = 0;
1504 } else {
1505 hscb->control |= MSG_SIMPLE_TASK;
1506 }
1507 }
1508
1509 hscb->cdb_len = cmd->cmd_len;
1510 if (hscb->cdb_len <= 12) {
1511 memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len);
1512 } else {
1513 memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len);
1514 scb->flags |= SCB_CDB32_PTR;
1515 }
1516
1517 scb->platform_data->xfer_len = 0;
1518 ahc_set_residual(scb, 0);
1519 ahc_set_sense_residual(scb, 0);
1520 scb->sg_count = 0;
1521
1522 if (nseg > 0) {
1523 struct ahc_dma_seg *sg;
1524 struct scatterlist *cur_seg;
1525 int i;
1526
1527
1528 sg = scb->sg_list;
1529
1530
1531
1532
1533 scsi_for_each_sg(cmd, cur_seg, nseg, i) {
1534 dma_addr_t addr;
1535 bus_size_t len;
1536 int consumed;
1537
1538 addr = sg_dma_address(cur_seg);
1539 len = sg_dma_len(cur_seg);
1540 consumed = ahc_linux_map_seg(ahc, scb,
1541 sg, addr, len);
1542 sg += consumed;
1543 scb->sg_count += consumed;
1544 }
1545 sg--;
1546 sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
1547
1548
1549
1550
1551 scb->hscb->sgptr =
1552 ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
1553
1554
1555
1556
1557
1558 scb->hscb->dataptr = scb->sg_list->addr;
1559 scb->hscb->datacnt = scb->sg_list->len;
1560 } else {
1561 scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
1562 scb->hscb->dataptr = 0;
1563 scb->hscb->datacnt = 0;
1564 scb->sg_count = 0;
1565 }
1566
1567 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
1568 dev->openings--;
1569 dev->active++;
1570 dev->commands_issued++;
1571 if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0)
1572 dev->commands_since_idle_or_otag++;
1573
1574 scb->flags |= SCB_ACTIVE;
1575 if (untagged_q) {
1576 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
1577 scb->flags |= SCB_UNTAGGEDQ;
1578 }
1579 ahc_queue_scb(ahc, scb);
1580 return 0;
1581}
1582
1583
1584
1585
1586irqreturn_t
1587ahc_linux_isr(int irq, void *dev_id)
1588{
1589 struct ahc_softc *ahc;
1590 u_long flags;
1591 int ours;
1592
1593 ahc = (struct ahc_softc *) dev_id;
1594 ahc_lock(ahc, &flags);
1595 ours = ahc_intr(ahc);
1596 ahc_unlock(ahc, &flags);
1597 return IRQ_RETVAL(ours);
1598}
1599
1600void
1601ahc_platform_flushwork(struct ahc_softc *ahc)
1602{
1603
1604}
1605
1606void
1607ahc_send_async(struct ahc_softc *ahc, char channel,
1608 u_int target, u_int lun, ac_code code)
1609{
1610 switch (code) {
1611 case AC_TRANSFER_NEG:
1612 {
1613 struct scsi_target *starget;
1614 struct ahc_linux_target *targ;
1615 struct ahc_initiator_tinfo *tinfo;
1616 struct ahc_tmode_tstate *tstate;
1617 int target_offset;
1618 unsigned int target_ppr_options;
1619
1620 BUG_ON(target == CAM_TARGET_WILDCARD);
1621
1622 tinfo = ahc_fetch_transinfo(ahc, channel,
1623 channel == 'A' ? ahc->our_id
1624 : ahc->our_id_b,
1625 target, &tstate);
1626
1627
1628
1629
1630
1631 if (tinfo->curr.period != tinfo->goal.period
1632 || tinfo->curr.width != tinfo->goal.width
1633 || tinfo->curr.offset != tinfo->goal.offset
1634 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
1635 if (bootverbose == 0)
1636 break;
1637
1638
1639
1640
1641
1642 target_offset = target;
1643 if (channel == 'B')
1644 target_offset += 8;
1645 starget = ahc->platform_data->starget[target_offset];
1646 if (starget == NULL)
1647 break;
1648 targ = scsi_transport_target_data(starget);
1649
1650 target_ppr_options =
1651 (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
1652 + (spi_qas(starget) ? MSG_EXT_PPR_QAS_REQ : 0)
1653 + (spi_iu(starget) ? MSG_EXT_PPR_IU_REQ : 0);
1654
1655 if (tinfo->curr.period == spi_period(starget)
1656 && tinfo->curr.width == spi_width(starget)
1657 && tinfo->curr.offset == spi_offset(starget)
1658 && tinfo->curr.ppr_options == target_ppr_options)
1659 if (bootverbose == 0)
1660 break;
1661
1662 spi_period(starget) = tinfo->curr.period;
1663 spi_width(starget) = tinfo->curr.width;
1664 spi_offset(starget) = tinfo->curr.offset;
1665 spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
1666 spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
1667 spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
1668 spi_display_xfer_agreement(starget);
1669 break;
1670 }
1671 case AC_SENT_BDR:
1672 {
1673 WARN_ON(lun != CAM_LUN_WILDCARD);
1674 scsi_report_device_reset(ahc->platform_data->host,
1675 channel - 'A', target);
1676 break;
1677 }
1678 case AC_BUS_RESET:
1679 if (ahc->platform_data->host != NULL) {
1680 scsi_report_bus_reset(ahc->platform_data->host,
1681 channel - 'A');
1682 }
1683 break;
1684 default:
1685 panic("ahc_send_async: Unexpected async event");
1686 }
1687}
1688
1689
1690
1691
1692void
1693ahc_done(struct ahc_softc *ahc, struct scb *scb)
1694{
1695 struct scsi_cmnd *cmd;
1696 struct ahc_linux_device *dev;
1697
1698 LIST_REMOVE(scb, pending_links);
1699 if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
1700 struct scb_tailq *untagged_q;
1701 int target_offset;
1702
1703 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
1704 untagged_q = &(ahc->untagged_queues[target_offset]);
1705 TAILQ_REMOVE(untagged_q, scb, links.tqe);
1706 BUG_ON(!TAILQ_EMPTY(untagged_q));
1707 } else if ((scb->flags & SCB_ACTIVE) == 0) {
1708
1709
1710
1711
1712
1713 printk("SCB %d done'd twice\n", scb->hscb->tag);
1714 ahc_dump_card_state(ahc);
1715 panic("Stopping for safety");
1716 }
1717 cmd = scb->io_ctx;
1718 dev = scb->platform_data->dev;
1719 dev->active--;
1720 dev->openings++;
1721 if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
1722 cmd->result &= ~(CAM_DEV_QFRZN << 16);
1723 dev->qfrozen--;
1724 }
1725 ahc_linux_unmap_scb(ahc, scb);
1726
1727
1728
1729
1730
1731
1732
1733 cmd->sense_buffer[0] = 0;
1734 if (ahc_get_transaction_status(scb) == CAM_REQ_INPROG) {
1735 uint32_t amount_xferred;
1736
1737 amount_xferred =
1738 ahc_get_transfer_length(scb) - ahc_get_residual(scb);
1739 if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
1740#ifdef AHC_DEBUG
1741 if ((ahc_debug & AHC_SHOW_MISC) != 0) {
1742 ahc_print_path(ahc, scb);
1743 printk("Set CAM_UNCOR_PARITY\n");
1744 }
1745#endif
1746 ahc_set_transaction_status(scb, CAM_UNCOR_PARITY);
1747#ifdef AHC_REPORT_UNDERFLOWS
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757 } else if (amount_xferred < scb->io_ctx->underflow) {
1758 u_int i;
1759
1760 ahc_print_path(ahc, scb);
1761 printk("CDB:");
1762 for (i = 0; i < scb->io_ctx->cmd_len; i++)
1763 printk(" 0x%x", scb->io_ctx->cmnd[i]);
1764 printk("\n");
1765 ahc_print_path(ahc, scb);
1766 printk("Saw underflow (%ld of %ld bytes). "
1767 "Treated as error\n",
1768 ahc_get_residual(scb),
1769 ahc_get_transfer_length(scb));
1770 ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1771#endif
1772 } else {
1773 ahc_set_transaction_status(scb, CAM_REQ_CMP);
1774 }
1775 } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
1776 ahc_linux_handle_scsi_status(ahc, cmd->device, scb);
1777 }
1778
1779 if (dev->openings == 1
1780 && ahc_get_transaction_status(scb) == CAM_REQ_CMP
1781 && ahc_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
1782 dev->tag_success_count++;
1783
1784
1785
1786
1787
1788
1789 if ((dev->openings + dev->active) < dev->maxtags
1790 && dev->tag_success_count > AHC_TAG_SUCCESS_INTERVAL) {
1791 dev->tag_success_count = 0;
1792 dev->openings++;
1793 }
1794
1795 if (dev->active == 0)
1796 dev->commands_since_idle_or_otag = 0;
1797
1798 if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
1799 printk("Recovery SCB completes\n");
1800 if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
1801 || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
1802 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
1803
1804 if (ahc->platform_data->eh_done)
1805 complete(ahc->platform_data->eh_done);
1806 }
1807
1808 ahc_free_scb(ahc, scb);
1809 ahc_linux_queue_cmd_complete(ahc, cmd);
1810}
1811
1812static void
1813ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
1814 struct scsi_device *sdev, struct scb *scb)
1815{
1816 struct ahc_devinfo devinfo;
1817 struct ahc_linux_device *dev = scsi_transport_device_data(sdev);
1818
1819 ahc_compile_devinfo(&devinfo,
1820 ahc->our_id,
1821 sdev->sdev_target->id, sdev->lun,
1822 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1823 ROLE_INITIATOR);
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835 switch (ahc_get_scsi_status(scb)) {
1836 default:
1837 break;
1838 case SCSI_STATUS_CHECK_COND:
1839 case SCSI_STATUS_CMD_TERMINATED:
1840 {
1841 struct scsi_cmnd *cmd;
1842
1843
1844
1845
1846
1847 cmd = scb->io_ctx;
1848 if (scb->flags & SCB_SENSE) {
1849 u_int sense_size;
1850
1851 sense_size = min(sizeof(struct scsi_sense_data)
1852 - ahc_get_sense_residual(scb),
1853 (u_long)SCSI_SENSE_BUFFERSIZE);
1854 memcpy(cmd->sense_buffer,
1855 ahc_get_sense_buf(ahc, scb), sense_size);
1856 if (sense_size < SCSI_SENSE_BUFFERSIZE)
1857 memset(&cmd->sense_buffer[sense_size], 0,
1858 SCSI_SENSE_BUFFERSIZE - sense_size);
1859 cmd->result |= (DRIVER_SENSE << 24);
1860#ifdef AHC_DEBUG
1861 if (ahc_debug & AHC_SHOW_SENSE) {
1862 int i;
1863
1864 printk("Copied %d bytes of sense data:",
1865 sense_size);
1866 for (i = 0; i < sense_size; i++) {
1867 if ((i & 0xF) == 0)
1868 printk("\n");
1869 printk("0x%x ", cmd->sense_buffer[i]);
1870 }
1871 printk("\n");
1872 }
1873#endif
1874 }
1875 break;
1876 }
1877 case SCSI_STATUS_QUEUE_FULL:
1878 {
1879
1880
1881
1882
1883
1884
1885
1886
1887 dev->tag_success_count = 0;
1888 if (dev->active != 0) {
1889
1890
1891
1892
1893 dev->openings = 0;
1894
1895
1896
1897
1898 if (dev->active == dev->tags_on_last_queuefull) {
1899
1900 dev->last_queuefull_same_count++;
1901
1902
1903
1904
1905
1906
1907
1908
1909 if (dev->last_queuefull_same_count
1910 == AHC_LOCK_TAGS_COUNT) {
1911 dev->maxtags = dev->active;
1912 ahc_print_path(ahc, scb);
1913 printk("Locking max tag count at %d\n",
1914 dev->active);
1915 }
1916 } else {
1917 dev->tags_on_last_queuefull = dev->active;
1918 dev->last_queuefull_same_count = 0;
1919 }
1920 ahc_set_transaction_status(scb, CAM_REQUEUE_REQ);
1921 ahc_set_scsi_status(scb, SCSI_STATUS_OK);
1922 ahc_platform_set_tags(ahc, sdev, &devinfo,
1923 (dev->flags & AHC_DEV_Q_BASIC)
1924 ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
1925 break;
1926 }
1927
1928
1929
1930
1931 dev->openings = 1;
1932 ahc_set_scsi_status(scb, SCSI_STATUS_BUSY);
1933 ahc_platform_set_tags(ahc, sdev, &devinfo,
1934 (dev->flags & AHC_DEV_Q_BASIC)
1935 ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED);
1936 break;
1937 }
1938 }
1939}
1940
1941static void
1942ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd)
1943{
1944
1945
1946
1947
1948
1949
1950 {
1951 u_int new_status;
1952
1953 switch (ahc_cmd_get_transaction_status(cmd)) {
1954 case CAM_REQ_INPROG:
1955 case CAM_REQ_CMP:
1956 case CAM_SCSI_STATUS_ERROR:
1957 new_status = DID_OK;
1958 break;
1959 case CAM_REQ_ABORTED:
1960 new_status = DID_ABORT;
1961 break;
1962 case CAM_BUSY:
1963 new_status = DID_BUS_BUSY;
1964 break;
1965 case CAM_REQ_INVALID:
1966 case CAM_PATH_INVALID:
1967 new_status = DID_BAD_TARGET;
1968 break;
1969 case CAM_SEL_TIMEOUT:
1970 new_status = DID_NO_CONNECT;
1971 break;
1972 case CAM_SCSI_BUS_RESET:
1973 case CAM_BDR_SENT:
1974 new_status = DID_RESET;
1975 break;
1976 case CAM_UNCOR_PARITY:
1977 new_status = DID_PARITY;
1978 break;
1979 case CAM_CMD_TIMEOUT:
1980 new_status = DID_TIME_OUT;
1981 break;
1982 case CAM_UA_ABORT:
1983 case CAM_REQ_CMP_ERR:
1984 case CAM_AUTOSENSE_FAIL:
1985 case CAM_NO_HBA:
1986 case CAM_DATA_RUN_ERR:
1987 case CAM_UNEXP_BUSFREE:
1988 case CAM_SEQUENCE_FAIL:
1989 case CAM_CCB_LEN_ERR:
1990 case CAM_PROVIDE_FAIL:
1991 case CAM_REQ_TERMIO:
1992 case CAM_UNREC_HBA_ERROR:
1993 case CAM_REQ_TOO_BIG:
1994 new_status = DID_ERROR;
1995 break;
1996 case CAM_REQUEUE_REQ:
1997 new_status = DID_REQUEUE;
1998 break;
1999 default:
2000
2001 new_status = DID_ERROR;
2002 break;
2003 }
2004
2005 ahc_cmd_set_transaction_status(cmd, new_status);
2006 }
2007
2008 cmd->scsi_done(cmd);
2009}
2010
2011static void
2012ahc_linux_freeze_simq(struct ahc_softc *ahc)
2013{
2014 unsigned long s;
2015
2016 ahc_lock(ahc, &s);
2017 ahc->platform_data->qfrozen++;
2018 if (ahc->platform_data->qfrozen == 1) {
2019 scsi_block_requests(ahc->platform_data->host);
2020
2021
2022 ahc_platform_abort_scbs(ahc, CAM_TARGET_WILDCARD, ALL_CHANNELS,
2023 CAM_LUN_WILDCARD, SCB_LIST_NULL,
2024 ROLE_INITIATOR, CAM_REQUEUE_REQ);
2025 }
2026 ahc_unlock(ahc, &s);
2027}
2028
2029static void
2030ahc_linux_release_simq(struct ahc_softc *ahc)
2031{
2032 u_long s;
2033 int unblock_reqs;
2034
2035 unblock_reqs = 0;
2036 ahc_lock(ahc, &s);
2037 if (ahc->platform_data->qfrozen > 0)
2038 ahc->platform_data->qfrozen--;
2039 if (ahc->platform_data->qfrozen == 0)
2040 unblock_reqs = 1;
2041 ahc_unlock(ahc, &s);
2042
2043
2044
2045
2046
2047
2048 if (unblock_reqs)
2049 scsi_unblock_requests(ahc->platform_data->host);
2050}
2051
2052static int
2053ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
2054{
2055 struct ahc_softc *ahc;
2056 struct ahc_linux_device *dev;
2057 struct scb *pending_scb;
2058 u_int saved_scbptr;
2059 u_int active_scb_index;
2060 u_int last_phase;
2061 u_int saved_scsiid;
2062 u_int cdb_byte;
2063 int retval;
2064 int was_paused;
2065 int paused;
2066 int wait;
2067 int disconnected;
2068 unsigned long flags;
2069
2070 pending_scb = NULL;
2071 paused = FALSE;
2072 wait = FALSE;
2073 ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
2074
2075 scmd_printk(KERN_INFO, cmd, "Attempting to queue a%s message\n",
2076 flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
2077
2078 printk("CDB:");
2079 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
2080 printk(" 0x%x", cmd->cmnd[cdb_byte]);
2081 printk("\n");
2082
2083 ahc_lock(ahc, &flags);
2084
2085
2086
2087
2088
2089
2090
2091
2092 dev = scsi_transport_device_data(cmd->device);
2093
2094 if (dev == NULL) {
2095
2096
2097
2098
2099 printk("%s:%d:%d:%d: Is not an active device\n",
2100 ahc_name(ahc), cmd->device->channel, cmd->device->id,
2101 (u8)cmd->device->lun);
2102 retval = SUCCESS;
2103 goto no_cmd;
2104 }
2105
2106 if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
2107 && ahc_search_untagged_queues(ahc, cmd, cmd->device->id,
2108 cmd->device->channel + 'A',
2109 (u8)cmd->device->lun,
2110 CAM_REQ_ABORTED, SEARCH_COMPLETE) != 0) {
2111 printk("%s:%d:%d:%d: Command found on untagged queue\n",
2112 ahc_name(ahc), cmd->device->channel, cmd->device->id,
2113 (u8)cmd->device->lun);
2114 retval = SUCCESS;
2115 goto done;
2116 }
2117
2118
2119
2120
2121 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
2122 if (pending_scb->io_ctx == cmd)
2123 break;
2124 }
2125
2126 if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {
2127
2128
2129 LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
2130 if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd),
2131 scmd_channel(cmd) + 'A',
2132 CAM_LUN_WILDCARD,
2133 SCB_LIST_NULL, ROLE_INITIATOR))
2134 break;
2135 }
2136 }
2137
2138 if (pending_scb == NULL) {
2139 scmd_printk(KERN_INFO, cmd, "Command not found\n");
2140 goto no_cmd;
2141 }
2142
2143 if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
2144
2145
2146
2147 retval = FAILED;
2148 goto done;
2149 }
2150
2151
2152
2153
2154
2155
2156 was_paused = ahc_is_paused(ahc);
2157 ahc_pause_and_flushwork(ahc);
2158 paused = TRUE;
2159
2160 if ((pending_scb->flags & SCB_ACTIVE) == 0) {
2161 scmd_printk(KERN_INFO, cmd, "Command already completed\n");
2162 goto no_cmd;
2163 }
2164
2165 printk("%s: At time of recovery, card was %spaused\n",
2166 ahc_name(ahc), was_paused ? "" : "not ");
2167 ahc_dump_card_state(ahc);
2168
2169 disconnected = TRUE;
2170 if (flag == SCB_ABORT) {
2171 if (ahc_search_qinfifo(ahc, cmd->device->id,
2172 cmd->device->channel + 'A',
2173 cmd->device->lun,
2174 pending_scb->hscb->tag,
2175 ROLE_INITIATOR, CAM_REQ_ABORTED,
2176 SEARCH_COMPLETE) > 0) {
2177 printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
2178 ahc_name(ahc), cmd->device->channel,
2179 cmd->device->id, (u8)cmd->device->lun);
2180 retval = SUCCESS;
2181 goto done;
2182 }
2183 } else if (ahc_search_qinfifo(ahc, cmd->device->id,
2184 cmd->device->channel + 'A',
2185 cmd->device->lun,
2186 pending_scb->hscb->tag,
2187 ROLE_INITIATOR, 0,
2188 SEARCH_COUNT) > 0) {
2189 disconnected = FALSE;
2190 }
2191
2192 if (disconnected && (ahc_inb(ahc, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
2193 struct scb *bus_scb;
2194
2195 bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG));
2196 if (bus_scb == pending_scb)
2197 disconnected = FALSE;
2198 else if (flag != SCB_ABORT
2199 && ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid
2200 && ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb))
2201 disconnected = FALSE;
2202 }
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212 last_phase = ahc_inb(ahc, LASTPHASE);
2213 saved_scbptr = ahc_inb(ahc, SCBPTR);
2214 active_scb_index = ahc_inb(ahc, SCB_TAG);
2215 saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
2216 if (last_phase != P_BUSFREE
2217 && (pending_scb->hscb->tag == active_scb_index
2218 || (flag == SCB_DEVICE_RESET
2219 && SCSIID_TARGET(ahc, saved_scsiid) == scmd_id(cmd)))) {
2220
2221
2222
2223
2224
2225 pending_scb = ahc_lookup_scb(ahc, active_scb_index);
2226 pending_scb->flags |= SCB_RECOVERY_SCB|flag;
2227 ahc_outb(ahc, MSG_OUT, HOST_MSG);
2228 ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
2229 scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
2230 wait = TRUE;
2231 } else if (disconnected) {
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249 pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
2250 pending_scb->flags |= SCB_RECOVERY_SCB|flag;
2251
2252
2253
2254
2255
2256
2257
2258
2259 ahc_search_disc_list(ahc, cmd->device->id,
2260 cmd->device->channel + 'A',
2261 cmd->device->lun, pending_scb->hscb->tag,
2262 TRUE,
2263 TRUE,
2264 FALSE);
2265
2266
2267
2268
2269
2270
2271
2272
2273 if ((ahc->flags & AHC_PAGESCBS) == 0) {
2274 ahc_outb(ahc, SCBPTR, pending_scb->hscb->tag);
2275 ahc_outb(ahc, SCB_CONTROL,
2276 ahc_inb(ahc, SCB_CONTROL)|MK_MESSAGE);
2277 }
2278
2279
2280
2281
2282
2283
2284 ahc_search_qinfifo(ahc, cmd->device->id,
2285 cmd->device->channel + 'A',
2286 cmd->device->lun, SCB_LIST_NULL,
2287 ROLE_INITIATOR, CAM_REQUEUE_REQ,
2288 SEARCH_COMPLETE);
2289 ahc_qinfifo_requeue_tail(ahc, pending_scb);
2290 ahc_outb(ahc, SCBPTR, saved_scbptr);
2291 ahc_print_path(ahc, pending_scb);
2292 printk("Device is disconnected, re-queuing SCB\n");
2293 wait = TRUE;
2294 } else {
2295 scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
2296 retval = FAILED;
2297 goto done;
2298 }
2299
2300no_cmd:
2301
2302
2303
2304
2305
2306
2307 retval = SUCCESS;
2308done:
2309 if (paused)
2310 ahc_unpause(ahc);
2311 if (wait) {
2312 DECLARE_COMPLETION_ONSTACK(done);
2313
2314 ahc->platform_data->eh_done = &done;
2315 ahc_unlock(ahc, &flags);
2316
2317 printk("Recovery code sleeping\n");
2318 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
2319 ahc_lock(ahc, &flags);
2320 ahc->platform_data->eh_done = NULL;
2321 ahc_unlock(ahc, &flags);
2322
2323 printk("Timer Expired\n");
2324 retval = FAILED;
2325 }
2326 printk("Recovery code awake\n");
2327 } else
2328 ahc_unlock(ahc, &flags);
2329 return (retval);
2330}
2331
2332void
2333ahc_platform_dump_card_state(struct ahc_softc *ahc)
2334{
2335}
2336
2337static void ahc_linux_set_width(struct scsi_target *starget, int width)
2338{
2339 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2340 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2341 struct ahc_devinfo devinfo;
2342 unsigned long flags;
2343
2344 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2345 starget->channel + 'A', ROLE_INITIATOR);
2346 ahc_lock(ahc, &flags);
2347 ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE);
2348 ahc_unlock(ahc, &flags);
2349}
2350
2351static void ahc_linux_set_period(struct scsi_target *starget, int period)
2352{
2353 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2354 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2355 struct ahc_tmode_tstate *tstate;
2356 struct ahc_initiator_tinfo *tinfo
2357 = ahc_fetch_transinfo(ahc,
2358 starget->channel + 'A',
2359 shost->this_id, starget->id, &tstate);
2360 struct ahc_devinfo devinfo;
2361 unsigned int ppr_options = tinfo->goal.ppr_options;
2362 unsigned long flags;
2363 unsigned long offset = tinfo->goal.offset;
2364 const struct ahc_syncrate *syncrate;
2365
2366 if (offset == 0)
2367 offset = MAX_OFFSET;
2368
2369 if (period < 9)
2370 period = 9;
2371 if (period == 9) {
2372 if (spi_max_width(starget))
2373 ppr_options |= MSG_EXT_PPR_DT_REQ;
2374 else
2375
2376 period = 10;
2377 }
2378
2379 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2380 starget->channel + 'A', ROLE_INITIATOR);
2381
2382
2383 if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) {
2384 if (spi_width(starget) == 0)
2385 ppr_options &= MSG_EXT_PPR_QAS_REQ;
2386 }
2387
2388 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2389 ahc_lock(ahc, &flags);
2390 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
2391 ppr_options, AHC_TRANS_GOAL, FALSE);
2392 ahc_unlock(ahc, &flags);
2393}
2394
2395static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
2396{
2397 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2398 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2399 struct ahc_tmode_tstate *tstate;
2400 struct ahc_initiator_tinfo *tinfo
2401 = ahc_fetch_transinfo(ahc,
2402 starget->channel + 'A',
2403 shost->this_id, starget->id, &tstate);
2404 struct ahc_devinfo devinfo;
2405 unsigned int ppr_options = 0;
2406 unsigned int period = 0;
2407 unsigned long flags;
2408 const struct ahc_syncrate *syncrate = NULL;
2409
2410 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2411 starget->channel + 'A', ROLE_INITIATOR);
2412 if (offset != 0) {
2413 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2414 period = tinfo->goal.period;
2415 ppr_options = tinfo->goal.ppr_options;
2416 }
2417 ahc_lock(ahc, &flags);
2418 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
2419 ppr_options, AHC_TRANS_GOAL, FALSE);
2420 ahc_unlock(ahc, &flags);
2421}
2422
2423static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
2424{
2425 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2426 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2427 struct ahc_tmode_tstate *tstate;
2428 struct ahc_initiator_tinfo *tinfo
2429 = ahc_fetch_transinfo(ahc,
2430 starget->channel + 'A',
2431 shost->this_id, starget->id, &tstate);
2432 struct ahc_devinfo devinfo;
2433 unsigned int ppr_options = tinfo->goal.ppr_options
2434 & ~MSG_EXT_PPR_DT_REQ;
2435 unsigned int period = tinfo->goal.period;
2436 unsigned int width = tinfo->goal.width;
2437 unsigned long flags;
2438 const struct ahc_syncrate *syncrate;
2439
2440 if (dt && spi_max_width(starget)) {
2441 ppr_options |= MSG_EXT_PPR_DT_REQ;
2442 if (!width)
2443 ahc_linux_set_width(starget, 1);
2444 } else if (period == 9)
2445 period = 10;
2446
2447 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2448 starget->channel + 'A', ROLE_INITIATOR);
2449 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT);
2450 ahc_lock(ahc, &flags);
2451 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
2452 ppr_options, AHC_TRANS_GOAL, FALSE);
2453 ahc_unlock(ahc, &flags);
2454}
2455
2456#if 0
2457
2458
2459
2460
2461static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
2462{
2463 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2464 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2465 struct ahc_tmode_tstate *tstate;
2466 struct ahc_initiator_tinfo *tinfo
2467 = ahc_fetch_transinfo(ahc,
2468 starget->channel + 'A',
2469 shost->this_id, starget->id, &tstate);
2470 struct ahc_devinfo devinfo;
2471 unsigned int ppr_options = tinfo->goal.ppr_options
2472 & ~MSG_EXT_PPR_QAS_REQ;
2473 unsigned int period = tinfo->goal.period;
2474 unsigned long flags;
2475 struct ahc_syncrate *syncrate;
2476
2477 if (qas)
2478 ppr_options |= MSG_EXT_PPR_QAS_REQ;
2479
2480 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2481 starget->channel + 'A', ROLE_INITIATOR);
2482 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2483 ahc_lock(ahc, &flags);
2484 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
2485 ppr_options, AHC_TRANS_GOAL, FALSE);
2486 ahc_unlock(ahc, &flags);
2487}
2488
2489static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
2490{
2491 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2492 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2493 struct ahc_tmode_tstate *tstate;
2494 struct ahc_initiator_tinfo *tinfo
2495 = ahc_fetch_transinfo(ahc,
2496 starget->channel + 'A',
2497 shost->this_id, starget->id, &tstate);
2498 struct ahc_devinfo devinfo;
2499 unsigned int ppr_options = tinfo->goal.ppr_options
2500 & ~MSG_EXT_PPR_IU_REQ;
2501 unsigned int period = tinfo->goal.period;
2502 unsigned long flags;
2503 struct ahc_syncrate *syncrate;
2504
2505 if (iu)
2506 ppr_options |= MSG_EXT_PPR_IU_REQ;
2507
2508 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2509 starget->channel + 'A', ROLE_INITIATOR);
2510 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2511 ahc_lock(ahc, &flags);
2512 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
2513 ppr_options, AHC_TRANS_GOAL, FALSE);
2514 ahc_unlock(ahc, &flags);
2515}
2516#endif
2517
2518static void ahc_linux_get_signalling(struct Scsi_Host *shost)
2519{
2520 struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
2521 unsigned long flags;
2522 u8 mode;
2523
2524 if (!(ahc->features & AHC_ULTRA2)) {
2525
2526 spi_signalling(shost) =
2527 ahc->features & AHC_HVD ?
2528 SPI_SIGNAL_HVD :
2529 SPI_SIGNAL_SE;
2530 return;
2531 }
2532
2533 ahc_lock(ahc, &flags);
2534 ahc_pause(ahc);
2535 mode = ahc_inb(ahc, SBLKCTL);
2536 ahc_unpause(ahc);
2537 ahc_unlock(ahc, &flags);
2538
2539 if (mode & ENAB40)
2540 spi_signalling(shost) = SPI_SIGNAL_LVD;
2541 else if (mode & ENAB20)
2542 spi_signalling(shost) = SPI_SIGNAL_SE;
2543 else
2544 spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
2545}
2546
2547static struct spi_function_template ahc_linux_transport_functions = {
2548 .set_offset = ahc_linux_set_offset,
2549 .show_offset = 1,
2550 .set_period = ahc_linux_set_period,
2551 .show_period = 1,
2552 .set_width = ahc_linux_set_width,
2553 .show_width = 1,
2554 .set_dt = ahc_linux_set_dt,
2555 .show_dt = 1,
2556#if 0
2557 .set_iu = ahc_linux_set_iu,
2558 .show_iu = 1,
2559 .set_qas = ahc_linux_set_qas,
2560 .show_qas = 1,
2561#endif
2562 .get_signalling = ahc_linux_get_signalling,
2563};
2564
2565
2566
2567static int __init
2568ahc_linux_init(void)
2569{
2570
2571
2572
2573 if (aic7xxx)
2574 aic7xxx_setup(aic7xxx);
2575
2576 ahc_linux_transport_template =
2577 spi_attach_transport(&ahc_linux_transport_functions);
2578 if (!ahc_linux_transport_template)
2579 return -ENODEV;
2580
2581 scsi_transport_reserve_device(ahc_linux_transport_template,
2582 sizeof(struct ahc_linux_device));
2583
2584 ahc_linux_pci_init();
2585 ahc_linux_eisa_init();
2586 return 0;
2587}
2588
2589static void
2590ahc_linux_exit(void)
2591{
2592 ahc_linux_pci_exit();
2593 ahc_linux_eisa_exit();
2594 spi_release_transport(ahc_linux_transport_template);
2595}
2596
2597module_init(ahc_linux_init);
2598module_exit(ahc_linux_exit);
2599