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