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 char channel = starget->channel + 'A';
568 unsigned int our_id = ahc->our_id;
569 unsigned int target_offset;
570
571 target_offset = starget->id;
572 if (starget->channel != 0)
573 target_offset += 8;
574
575 if (starget->channel)
576 our_id = ahc->our_id_b;
577
578 ahc_lock(ahc, &flags);
579
580 BUG_ON(*ahc_targp != NULL);
581
582 *ahc_targp = starget;
583
584 if (sc) {
585 int maxsync = AHC_SYNCRATE_DT;
586 int ultra = 0;
587 int flags = sc->device_flags[target_offset];
588
589 if (ahc->flags & AHC_NEWEEPROM_FMT) {
590 if (flags & CFSYNCHISULTRA)
591 ultra = 1;
592 } else if (flags & CFULTRAEN)
593 ultra = 1;
594
595
596 if(ultra && (flags & CFXFER) == 0x04) {
597 ultra = 0;
598 flags &= ~CFXFER;
599 }
600
601 if ((ahc->features & AHC_ULTRA2) != 0) {
602 scsirate = (flags & CFXFER) | (ultra ? 0x8 : 0);
603 } else {
604 scsirate = (flags & CFXFER) << 4;
605 maxsync = ultra ? AHC_SYNCRATE_ULTRA :
606 AHC_SYNCRATE_FAST;
607 }
608 spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0;
609 if (!(flags & CFSYNCH))
610 spi_max_offset(starget) = 0;
611 spi_min_period(starget) =
612 ahc_find_period(ahc, scsirate, maxsync);
613 }
614 ahc_compile_devinfo(&devinfo, our_id, starget->id,
615 CAM_LUN_WILDCARD, channel,
616 ROLE_INITIATOR);
617 ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0,
618 AHC_TRANS_GOAL, FALSE);
619 ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
620 AHC_TRANS_GOAL, FALSE);
621 ahc_unlock(ahc, &flags);
622
623 return 0;
624}
625
626static void
627ahc_linux_target_destroy(struct scsi_target *starget)
628{
629 struct scsi_target **ahc_targp = ahc_linux_target_in_softc(starget);
630
631 *ahc_targp = NULL;
632}
633
634static int
635ahc_linux_slave_alloc(struct scsi_device *sdev)
636{
637 struct ahc_softc *ahc =
638 *((struct ahc_softc **)sdev->host->hostdata);
639 struct scsi_target *starget = sdev->sdev_target;
640 struct ahc_linux_device *dev;
641
642 if (bootverbose)
643 printk("%s: Slave Alloc %d\n", ahc_name(ahc), sdev->id);
644
645 dev = scsi_transport_device_data(sdev);
646 memset(dev, 0, sizeof(*dev));
647
648
649
650
651
652 dev->openings = 1;
653
654
655
656
657
658
659 dev->maxtags = 0;
660
661 spi_period(starget) = 0;
662
663 return 0;
664}
665
666static int
667ahc_linux_slave_configure(struct scsi_device *sdev)
668{
669 if (bootverbose)
670 sdev_printk(KERN_INFO, sdev, "Slave Configure\n");
671
672 ahc_linux_device_queue_depth(sdev);
673
674
675 if (!spi_initial_dv(sdev->sdev_target))
676 spi_dv_device(sdev);
677
678 return 0;
679}
680
681#if defined(__i386__)
682
683
684
685static int
686ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
687 sector_t capacity, int geom[])
688{
689 int heads;
690 int sectors;
691 int cylinders;
692 int extended;
693 struct ahc_softc *ahc;
694 u_int channel;
695
696 ahc = *((struct ahc_softc **)sdev->host->hostdata);
697 channel = sdev_channel(sdev);
698
699 if (scsi_partsize(bdev, capacity, geom))
700 return 0;
701
702 heads = 64;
703 sectors = 32;
704 cylinders = aic_sector_div(capacity, heads, sectors);
705
706 if (aic7xxx_extended != 0)
707 extended = 1;
708 else if (channel == 0)
709 extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0;
710 else
711 extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0;
712 if (extended && cylinders >= 1024) {
713 heads = 255;
714 sectors = 63;
715 cylinders = aic_sector_div(capacity, heads, sectors);
716 }
717 geom[0] = heads;
718 geom[1] = sectors;
719 geom[2] = cylinders;
720 return (0);
721}
722#endif
723
724
725
726
727static int
728ahc_linux_abort(struct scsi_cmnd *cmd)
729{
730 int error;
731
732 error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT);
733 if (error != SUCCESS)
734 printk("aic7xxx_abort returns 0x%x\n", error);
735 return (error);
736}
737
738
739
740
741static int
742ahc_linux_dev_reset(struct scsi_cmnd *cmd)
743{
744 int error;
745
746 error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
747 if (error != SUCCESS)
748 printk("aic7xxx_dev_reset returns 0x%x\n", error);
749 return (error);
750}
751
752
753
754
755static int
756ahc_linux_bus_reset(struct scsi_cmnd *cmd)
757{
758 struct ahc_softc *ahc;
759 int found;
760 unsigned long flags;
761
762 ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
763
764 ahc_lock(ahc, &flags);
765 found = ahc_reset_channel(ahc, scmd_channel(cmd) + 'A',
766 TRUE);
767 ahc_unlock(ahc, &flags);
768
769 if (bootverbose)
770 printk("%s: SCSI bus reset delivered. "
771 "%d SCBs aborted.\n", ahc_name(ahc), found);
772
773 return SUCCESS;
774}
775
776struct scsi_host_template aic7xxx_driver_template = {
777 .module = THIS_MODULE,
778 .name = "aic7xxx",
779 .proc_name = "aic7xxx",
780 .show_info = ahc_linux_show_info,
781 .write_info = ahc_proc_write_seeprom,
782 .info = ahc_linux_info,
783 .queuecommand = ahc_linux_queue,
784 .eh_abort_handler = ahc_linux_abort,
785 .eh_device_reset_handler = ahc_linux_dev_reset,
786 .eh_bus_reset_handler = ahc_linux_bus_reset,
787#if defined(__i386__)
788 .bios_param = ahc_linux_biosparam,
789#endif
790 .can_queue = AHC_MAX_QUEUE,
791 .this_id = -1,
792 .max_sectors = 8192,
793 .cmd_per_lun = 2,
794 .slave_alloc = ahc_linux_slave_alloc,
795 .slave_configure = ahc_linux_slave_configure,
796 .target_alloc = ahc_linux_target_alloc,
797 .target_destroy = ahc_linux_target_destroy,
798};
799
800
801
802
803#define BUILD_SCSIID(ahc, cmd) \
804 ((((cmd)->device->id << TID_SHIFT) & TID) \
805 | (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \
806 | (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB))
807
808
809int
810ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent,
811 bus_size_t alignment, bus_size_t boundary,
812 dma_addr_t lowaddr, dma_addr_t highaddr,
813 bus_dma_filter_t *filter, void *filterarg,
814 bus_size_t maxsize, int nsegments,
815 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
816{
817 bus_dma_tag_t dmat;
818
819 dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC);
820 if (dmat == NULL)
821 return (ENOMEM);
822
823
824
825
826
827
828
829
830 dmat->alignment = alignment;
831 dmat->boundary = boundary;
832 dmat->maxsize = maxsize;
833 *ret_tag = dmat;
834 return (0);
835}
836
837void
838ahc_dma_tag_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat)
839{
840 kfree(dmat);
841}
842
843int
844ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr,
845 int flags, bus_dmamap_t *mapp)
846{
847
848 *vaddr = dma_alloc_coherent(ahc->dev, dmat->maxsize, mapp, GFP_ATOMIC);
849 if (*vaddr == NULL)
850 return ENOMEM;
851 return 0;
852}
853
854void
855ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat,
856 void* vaddr, bus_dmamap_t map)
857{
858 dma_free_coherent(ahc->dev, dmat->maxsize, vaddr, map);
859}
860
861int
862ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map,
863 void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
864 void *cb_arg, int flags)
865{
866
867
868
869
870 bus_dma_segment_t stack_sg;
871
872 stack_sg.ds_addr = map;
873 stack_sg.ds_len = dmat->maxsize;
874 cb(cb_arg, &stack_sg, 1, 0);
875 return (0);
876}
877
878void
879ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
880{
881}
882
883int
884ahc_dmamap_unload(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map)
885{
886
887 return (0);
888}
889
890static void
891ahc_linux_setup_tag_info_global(char *p)
892{
893 int tags, i, j;
894
895 tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
896 printk("Setting Global Tags= %d\n", tags);
897
898 for (i = 0; i < ARRAY_SIZE(aic7xxx_tag_info); i++) {
899 for (j = 0; j < AHC_NUM_TARGETS; j++) {
900 aic7xxx_tag_info[i].tag_commands[j] = tags;
901 }
902 }
903}
904
905static void
906ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
907{
908
909 if ((instance >= 0) && (targ >= 0)
910 && (instance < ARRAY_SIZE(aic7xxx_tag_info))
911 && (targ < AHC_NUM_TARGETS)) {
912 aic7xxx_tag_info[instance].tag_commands[targ] = value & 0xff;
913 if (bootverbose)
914 printk("tag_info[%d:%d] = %d\n", instance, targ, value);
915 }
916}
917
918static char *
919ahc_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
920 void (*callback)(u_long, int, int, int32_t),
921 u_long callback_arg)
922{
923 char *tok_end;
924 char *tok_end2;
925 int i;
926 int instance;
927 int targ;
928 int done;
929 char tok_list[] = {'.', ',', '{', '}', '\0'};
930
931
932 if (*opt_arg != ':')
933 return (opt_arg);
934 opt_arg++;
935 instance = -1;
936 targ = -1;
937 done = FALSE;
938
939
940
941
942 tok_end = strchr(opt_arg, '\0');
943 if (tok_end < end)
944 *tok_end = ',';
945 while (!done) {
946 switch (*opt_arg) {
947 case '{':
948 if (instance == -1) {
949 instance = 0;
950 } else {
951 if (depth > 1) {
952 if (targ == -1)
953 targ = 0;
954 } else {
955 printk("Malformed Option %s\n",
956 opt_name);
957 done = TRUE;
958 }
959 }
960 opt_arg++;
961 break;
962 case '}':
963 if (targ != -1)
964 targ = -1;
965 else if (instance != -1)
966 instance = -1;
967 opt_arg++;
968 break;
969 case ',':
970 case '.':
971 if (instance == -1)
972 done = TRUE;
973 else if (targ >= 0)
974 targ++;
975 else if (instance >= 0)
976 instance++;
977 opt_arg++;
978 break;
979 case '\0':
980 done = TRUE;
981 break;
982 default:
983 tok_end = end;
984 for (i = 0; tok_list[i]; i++) {
985 tok_end2 = strchr(opt_arg, tok_list[i]);
986 if ((tok_end2) && (tok_end2 < tok_end))
987 tok_end = tok_end2;
988 }
989 callback(callback_arg, instance, targ,
990 simple_strtol(opt_arg, NULL, 0));
991 opt_arg = tok_end;
992 break;
993 }
994 }
995 return (opt_arg);
996}
997
998
999
1000
1001
1002
1003static int
1004aic7xxx_setup(char *s)
1005{
1006 int i, n;
1007 char *p;
1008 char *end;
1009
1010 static const struct {
1011 const char *name;
1012 uint32_t *flag;
1013 } options[] = {
1014 { "extended", &aic7xxx_extended },
1015 { "no_reset", &aic7xxx_no_reset },
1016 { "verbose", &aic7xxx_verbose },
1017 { "allow_memio", &aic7xxx_allow_memio},
1018#ifdef AHC_DEBUG
1019 { "debug", &ahc_debug },
1020#endif
1021 { "periodic_otag", &aic7xxx_periodic_otag },
1022 { "pci_parity", &aic7xxx_pci_parity },
1023 { "seltime", &aic7xxx_seltime },
1024 { "tag_info", NULL },
1025 { "global_tag_depth", NULL },
1026 { "dv", NULL }
1027 };
1028
1029 end = strchr(s, '\0');
1030
1031
1032
1033
1034
1035 n = 0;
1036
1037 while ((p = strsep(&s, ",.")) != NULL) {
1038 if (*p == '\0')
1039 continue;
1040 for (i = 0; i < ARRAY_SIZE(options); i++) {
1041
1042 n = strlen(options[i].name);
1043 if (strncmp(options[i].name, p, n) == 0)
1044 break;
1045 }
1046 if (i == ARRAY_SIZE(options))
1047 continue;
1048
1049 if (strncmp(p, "global_tag_depth", n) == 0) {
1050 ahc_linux_setup_tag_info_global(p + n);
1051 } else if (strncmp(p, "tag_info", n) == 0) {
1052 s = ahc_parse_brace_option("tag_info", p + n, end,
1053 2, ahc_linux_setup_tag_info, 0);
1054 } else if (p[n] == ':') {
1055 *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
1056 } else if (strncmp(p, "verbose", n) == 0) {
1057 *(options[i].flag) = 1;
1058 } else {
1059 *(options[i].flag) ^= 0xFFFFFFFF;
1060 }
1061 }
1062 return 1;
1063}
1064
1065__setup("aic7xxx=", aic7xxx_setup);
1066
1067uint32_t aic7xxx_verbose;
1068
1069int
1070ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *template)
1071{
1072 char buf[80];
1073 struct Scsi_Host *host;
1074 char *new_name;
1075 u_long s;
1076 int retval;
1077
1078 template->name = ahc->description;
1079 host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
1080 if (host == NULL)
1081 return (ENOMEM);
1082
1083 *((struct ahc_softc **)host->hostdata) = ahc;
1084 ahc->platform_data->host = host;
1085 host->can_queue = AHC_MAX_QUEUE;
1086 host->cmd_per_lun = 2;
1087
1088 host->this_id = ahc->our_id;
1089 host->irq = ahc->platform_data->irq;
1090 host->max_id = (ahc->features & AHC_WIDE) ? 16 : 8;
1091 host->max_lun = AHC_NUM_LUNS;
1092 host->max_channel = (ahc->features & AHC_TWIN) ? 1 : 0;
1093 host->sg_tablesize = AHC_NSEG;
1094 ahc_lock(ahc, &s);
1095 ahc_set_unit(ahc, ahc_linux_unit++);
1096 ahc_unlock(ahc, &s);
1097 sprintf(buf, "scsi%d", host->host_no);
1098 new_name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
1099 if (new_name != NULL) {
1100 strcpy(new_name, buf);
1101 ahc_set_name(ahc, new_name);
1102 }
1103 host->unique_id = ahc->unit;
1104 ahc_linux_initialize_scsi_bus(ahc);
1105 ahc_intr_enable(ahc, TRUE);
1106
1107 host->transportt = ahc_linux_transport_template;
1108
1109 retval = scsi_add_host(host, ahc->dev);
1110 if (retval) {
1111 printk(KERN_WARNING "aic7xxx: scsi_add_host failed\n");
1112 scsi_host_put(host);
1113 return retval;
1114 }
1115
1116 scsi_scan_host(host);
1117 return 0;
1118}
1119
1120
1121
1122
1123
1124
1125static void
1126ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc)
1127{
1128 int i;
1129 int numtarg;
1130 unsigned long s;
1131
1132 i = 0;
1133 numtarg = 0;
1134
1135 ahc_lock(ahc, &s);
1136
1137 if (aic7xxx_no_reset != 0)
1138 ahc->flags &= ~(AHC_RESET_BUS_A|AHC_RESET_BUS_B);
1139
1140 if ((ahc->flags & AHC_RESET_BUS_A) != 0)
1141 ahc_reset_channel(ahc, 'A', TRUE);
1142 else
1143 numtarg = (ahc->features & AHC_WIDE) ? 16 : 8;
1144
1145 if ((ahc->features & AHC_TWIN) != 0) {
1146
1147 if ((ahc->flags & AHC_RESET_BUS_B) != 0) {
1148 ahc_reset_channel(ahc, 'B', TRUE);
1149 } else {
1150 if (numtarg == 0)
1151 i = 8;
1152 numtarg += 8;
1153 }
1154 }
1155
1156
1157
1158
1159
1160 for (; i < numtarg; i++) {
1161 struct ahc_devinfo devinfo;
1162 struct ahc_initiator_tinfo *tinfo;
1163 struct ahc_tmode_tstate *tstate;
1164 u_int our_id;
1165 u_int target_id;
1166 char channel;
1167
1168 channel = 'A';
1169 our_id = ahc->our_id;
1170 target_id = i;
1171 if (i > 7 && (ahc->features & AHC_TWIN) != 0) {
1172 channel = 'B';
1173 our_id = ahc->our_id_b;
1174 target_id = i % 8;
1175 }
1176 tinfo = ahc_fetch_transinfo(ahc, channel, our_id,
1177 target_id, &tstate);
1178 ahc_compile_devinfo(&devinfo, our_id, target_id,
1179 CAM_LUN_WILDCARD, channel, ROLE_INITIATOR);
1180 ahc_update_neg_request(ahc, &devinfo, tstate,
1181 tinfo, AHC_NEG_ALWAYS);
1182 }
1183 ahc_unlock(ahc, &s);
1184
1185 if ((ahc->flags & (AHC_RESET_BUS_A|AHC_RESET_BUS_B)) != 0) {
1186 ahc_linux_freeze_simq(ahc);
1187 msleep(AIC7XXX_RESET_DELAY);
1188 ahc_linux_release_simq(ahc);
1189 }
1190}
1191
1192int
1193ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg)
1194{
1195
1196 ahc->platform_data =
1197 kzalloc(sizeof(struct ahc_platform_data), GFP_ATOMIC);
1198 if (ahc->platform_data == NULL)
1199 return (ENOMEM);
1200 ahc->platform_data->irq = AHC_LINUX_NOIRQ;
1201 ahc_lockinit(ahc);
1202 ahc->seltime = (aic7xxx_seltime & 0x3) << 4;
1203 ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4;
1204 if (aic7xxx_pci_parity == 0)
1205 ahc->flags |= AHC_DISABLE_PCI_PERR;
1206
1207 return (0);
1208}
1209
1210void
1211ahc_platform_free(struct ahc_softc *ahc)
1212{
1213 struct scsi_target *starget;
1214 int i;
1215
1216 if (ahc->platform_data != NULL) {
1217
1218 for (i = 0; i < AHC_NUM_TARGETS; i++) {
1219 starget = ahc->platform_data->starget[i];
1220 if (starget != NULL) {
1221 ahc->platform_data->starget[i] = NULL;
1222 }
1223 }
1224
1225 if (ahc->platform_data->irq != AHC_LINUX_NOIRQ)
1226 free_irq(ahc->platform_data->irq, ahc);
1227 if (ahc->tag == BUS_SPACE_PIO
1228 && ahc->bsh.ioport != 0)
1229 release_region(ahc->bsh.ioport, 256);
1230 if (ahc->tag == BUS_SPACE_MEMIO
1231 && ahc->bsh.maddr != NULL) {
1232 iounmap(ahc->bsh.maddr);
1233 release_mem_region(ahc->platform_data->mem_busaddr,
1234 0x1000);
1235 }
1236
1237 if (ahc->platform_data->host)
1238 scsi_host_put(ahc->platform_data->host);
1239
1240 kfree(ahc->platform_data);
1241 }
1242}
1243
1244void
1245ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb)
1246{
1247 ahc_platform_abort_scbs(ahc, SCB_GET_TARGET(ahc, scb),
1248 SCB_GET_CHANNEL(ahc, scb),
1249 SCB_GET_LUN(scb), SCB_LIST_NULL,
1250 ROLE_UNKNOWN, CAM_REQUEUE_REQ);
1251}
1252
1253void
1254ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev,
1255 struct ahc_devinfo *devinfo, ahc_queue_alg alg)
1256{
1257 struct ahc_linux_device *dev;
1258 int was_queuing;
1259 int now_queuing;
1260
1261 if (sdev == NULL)
1262 return;
1263 dev = scsi_transport_device_data(sdev);
1264
1265 was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED);
1266 switch (alg) {
1267 default:
1268 case AHC_QUEUE_NONE:
1269 now_queuing = 0;
1270 break;
1271 case AHC_QUEUE_BASIC:
1272 now_queuing = AHC_DEV_Q_BASIC;
1273 break;
1274 case AHC_QUEUE_TAGGED:
1275 now_queuing = AHC_DEV_Q_TAGGED;
1276 break;
1277 }
1278 if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) == 0
1279 && (was_queuing != now_queuing)
1280 && (dev->active != 0)) {
1281 dev->flags |= AHC_DEV_FREEZE_TIL_EMPTY;
1282 dev->qfrozen++;
1283 }
1284
1285 dev->flags &= ~(AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED|AHC_DEV_PERIODIC_OTAG);
1286 if (now_queuing) {
1287 u_int usertags;
1288
1289 usertags = ahc_linux_user_tagdepth(ahc, devinfo);
1290 if (!was_queuing) {
1291
1292
1293
1294
1295
1296 dev->maxtags = usertags;
1297 dev->openings = dev->maxtags - dev->active;
1298 }
1299 if (dev->maxtags == 0) {
1300
1301
1302
1303 dev->openings = 1;
1304 } else if (alg == AHC_QUEUE_TAGGED) {
1305 dev->flags |= AHC_DEV_Q_TAGGED;
1306 if (aic7xxx_periodic_otag != 0)
1307 dev->flags |= AHC_DEV_PERIODIC_OTAG;
1308 } else
1309 dev->flags |= AHC_DEV_Q_BASIC;
1310 } else {
1311
1312 dev->maxtags = 0;
1313 dev->openings = 1 - dev->active;
1314 }
1315 switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) {
1316 case AHC_DEV_Q_BASIC:
1317 case AHC_DEV_Q_TAGGED:
1318 scsi_change_queue_depth(sdev,
1319 dev->openings + dev->active);
1320 break;
1321 default:
1322
1323
1324
1325
1326
1327
1328 scsi_change_queue_depth(sdev, 2);
1329 break;
1330 }
1331}
1332
1333int
1334ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel,
1335 int lun, u_int tag, role_t role, uint32_t status)
1336{
1337 return 0;
1338}
1339
1340static u_int
1341ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo)
1342{
1343 static int warned_user;
1344 u_int tags;
1345
1346 tags = 0;
1347 if ((ahc->user_discenable & devinfo->target_mask) != 0) {
1348 if (ahc->unit >= ARRAY_SIZE(aic7xxx_tag_info)) {
1349 if (warned_user == 0) {
1350
1351 printk(KERN_WARNING
1352"aic7xxx: WARNING: Insufficient tag_info instances\n"
1353"aic7xxx: for installed controllers. Using defaults\n"
1354"aic7xxx: Please update the aic7xxx_tag_info array in\n"
1355"aic7xxx: the aic7xxx_osm..c source file.\n");
1356 warned_user++;
1357 }
1358 tags = AHC_MAX_QUEUE;
1359 } else {
1360 adapter_tag_info_t *tag_info;
1361
1362 tag_info = &aic7xxx_tag_info[ahc->unit];
1363 tags = tag_info->tag_commands[devinfo->target_offset];
1364 if (tags > AHC_MAX_QUEUE)
1365 tags = AHC_MAX_QUEUE;
1366 }
1367 }
1368 return (tags);
1369}
1370
1371
1372
1373
1374static void
1375ahc_linux_device_queue_depth(struct scsi_device *sdev)
1376{
1377 struct ahc_devinfo devinfo;
1378 u_int tags;
1379 struct ahc_softc *ahc = *((struct ahc_softc **)sdev->host->hostdata);
1380
1381 ahc_compile_devinfo(&devinfo,
1382 sdev->sdev_target->channel == 0
1383 ? ahc->our_id : ahc->our_id_b,
1384 sdev->sdev_target->id, sdev->lun,
1385 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1386 ROLE_INITIATOR);
1387 tags = ahc_linux_user_tagdepth(ahc, &devinfo);
1388 if (tags != 0 && sdev->tagged_supported != 0) {
1389
1390 ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_TAGGED);
1391 ahc_send_async(ahc, devinfo.channel, devinfo.target,
1392 devinfo.lun, AC_TRANSFER_NEG);
1393 ahc_print_devinfo(ahc, &devinfo);
1394 printk("Tagged Queuing enabled. Depth %d\n", tags);
1395 } else {
1396 ahc_platform_set_tags(ahc, sdev, &devinfo, AHC_QUEUE_NONE);
1397 ahc_send_async(ahc, devinfo.channel, devinfo.target,
1398 devinfo.lun, AC_TRANSFER_NEG);
1399 }
1400}
1401
1402static int
1403ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
1404 struct scsi_cmnd *cmd)
1405{
1406 struct scb *scb;
1407 struct hardware_scb *hscb;
1408 struct ahc_initiator_tinfo *tinfo;
1409 struct ahc_tmode_tstate *tstate;
1410 uint16_t mask;
1411 struct scb_tailq *untagged_q = NULL;
1412 int nseg;
1413
1414
1415
1416
1417
1418 if (ahc->platform_data->qfrozen != 0)
1419 return SCSI_MLQUEUE_HOST_BUSY;
1420
1421
1422
1423
1424
1425
1426
1427 if (!(cmd->flags & SCMD_TAGGED)
1428 && (ahc->features & AHC_SCB_BTT) == 0) {
1429 int target_offset;
1430
1431 target_offset = cmd->device->id + cmd->device->channel * 8;
1432 untagged_q = &(ahc->untagged_queues[target_offset]);
1433 if (!TAILQ_EMPTY(untagged_q))
1434
1435
1436 return SCSI_MLQUEUE_DEVICE_BUSY;
1437 }
1438
1439 nseg = scsi_dma_map(cmd);
1440 if (nseg < 0)
1441 return SCSI_MLQUEUE_HOST_BUSY;
1442
1443
1444
1445
1446 scb = ahc_get_scb(ahc);
1447 if (!scb) {
1448 scsi_dma_unmap(cmd);
1449 return SCSI_MLQUEUE_HOST_BUSY;
1450 }
1451
1452 scb->io_ctx = cmd;
1453 scb->platform_data->dev = dev;
1454 hscb = scb->hscb;
1455 cmd->host_scribble = (char *)scb;
1456
1457
1458
1459
1460 hscb->control = 0;
1461 hscb->scsiid = BUILD_SCSIID(ahc, cmd);
1462 hscb->lun = cmd->device->lun;
1463 mask = SCB_GET_TARGET_MASK(ahc, scb);
1464 tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
1465 SCB_GET_OUR_ID(scb),
1466 SCB_GET_TARGET(ahc, scb), &tstate);
1467 hscb->scsirate = tinfo->scsirate;
1468 hscb->scsioffset = tinfo->curr.offset;
1469 if ((tstate->ultraenb & mask) != 0)
1470 hscb->control |= ULTRAENB;
1471
1472 if ((ahc->user_discenable & mask) != 0)
1473 hscb->control |= DISCENB;
1474
1475 if ((tstate->auto_negotiate & mask) != 0) {
1476 scb->flags |= SCB_AUTO_NEGOTIATE;
1477 scb->hscb->control |= MK_MESSAGE;
1478 }
1479
1480 if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) {
1481 if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH
1482 && (dev->flags & AHC_DEV_Q_TAGGED) != 0) {
1483 hscb->control |= MSG_ORDERED_TASK;
1484 dev->commands_since_idle_or_otag = 0;
1485 } else {
1486 hscb->control |= MSG_SIMPLE_TASK;
1487 }
1488 }
1489
1490 hscb->cdb_len = cmd->cmd_len;
1491 if (hscb->cdb_len <= 12) {
1492 memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len);
1493 } else {
1494 memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len);
1495 scb->flags |= SCB_CDB32_PTR;
1496 }
1497
1498 scb->platform_data->xfer_len = 0;
1499 ahc_set_residual(scb, 0);
1500 ahc_set_sense_residual(scb, 0);
1501 scb->sg_count = 0;
1502
1503 if (nseg > 0) {
1504 struct ahc_dma_seg *sg;
1505 struct scatterlist *cur_seg;
1506 int i;
1507
1508
1509 sg = scb->sg_list;
1510
1511
1512
1513
1514 scsi_for_each_sg(cmd, cur_seg, nseg, i) {
1515 dma_addr_t addr;
1516 bus_size_t len;
1517 int consumed;
1518
1519 addr = sg_dma_address(cur_seg);
1520 len = sg_dma_len(cur_seg);
1521 consumed = ahc_linux_map_seg(ahc, scb,
1522 sg, addr, len);
1523 sg += consumed;
1524 scb->sg_count += consumed;
1525 }
1526 sg--;
1527 sg->len |= ahc_htole32(AHC_DMA_LAST_SEG);
1528
1529
1530
1531
1532 scb->hscb->sgptr =
1533 ahc_htole32(scb->sg_list_phys | SG_FULL_RESID);
1534
1535
1536
1537
1538
1539 scb->hscb->dataptr = scb->sg_list->addr;
1540 scb->hscb->datacnt = scb->sg_list->len;
1541 } else {
1542 scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL);
1543 scb->hscb->dataptr = 0;
1544 scb->hscb->datacnt = 0;
1545 scb->sg_count = 0;
1546 }
1547
1548 LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links);
1549 dev->openings--;
1550 dev->active++;
1551 dev->commands_issued++;
1552 if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0)
1553 dev->commands_since_idle_or_otag++;
1554
1555 scb->flags |= SCB_ACTIVE;
1556 if (untagged_q) {
1557 TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe);
1558 scb->flags |= SCB_UNTAGGEDQ;
1559 }
1560 ahc_queue_scb(ahc, scb);
1561 return 0;
1562}
1563
1564
1565
1566
1567irqreturn_t
1568ahc_linux_isr(int irq, void *dev_id)
1569{
1570 struct ahc_softc *ahc;
1571 u_long flags;
1572 int ours;
1573
1574 ahc = (struct ahc_softc *) dev_id;
1575 ahc_lock(ahc, &flags);
1576 ours = ahc_intr(ahc);
1577 ahc_unlock(ahc, &flags);
1578 return IRQ_RETVAL(ours);
1579}
1580
1581void
1582ahc_platform_flushwork(struct ahc_softc *ahc)
1583{
1584
1585}
1586
1587void
1588ahc_send_async(struct ahc_softc *ahc, char channel,
1589 u_int target, u_int lun, ac_code code)
1590{
1591 switch (code) {
1592 case AC_TRANSFER_NEG:
1593 {
1594 struct scsi_target *starget;
1595 struct ahc_initiator_tinfo *tinfo;
1596 struct ahc_tmode_tstate *tstate;
1597 int target_offset;
1598 unsigned int target_ppr_options;
1599
1600 BUG_ON(target == CAM_TARGET_WILDCARD);
1601
1602 tinfo = ahc_fetch_transinfo(ahc, channel,
1603 channel == 'A' ? ahc->our_id
1604 : ahc->our_id_b,
1605 target, &tstate);
1606
1607
1608
1609
1610
1611 if (tinfo->curr.period != tinfo->goal.period
1612 || tinfo->curr.width != tinfo->goal.width
1613 || tinfo->curr.offset != tinfo->goal.offset
1614 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
1615 if (bootverbose == 0)
1616 break;
1617
1618
1619
1620
1621
1622 target_offset = target;
1623 if (channel == 'B')
1624 target_offset += 8;
1625 starget = ahc->platform_data->starget[target_offset];
1626 if (starget == NULL)
1627 break;
1628
1629 target_ppr_options =
1630 (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
1631 + (spi_qas(starget) ? MSG_EXT_PPR_QAS_REQ : 0)
1632 + (spi_iu(starget) ? MSG_EXT_PPR_IU_REQ : 0);
1633
1634 if (tinfo->curr.period == spi_period(starget)
1635 && tinfo->curr.width == spi_width(starget)
1636 && tinfo->curr.offset == spi_offset(starget)
1637 && tinfo->curr.ppr_options == target_ppr_options)
1638 if (bootverbose == 0)
1639 break;
1640
1641 spi_period(starget) = tinfo->curr.period;
1642 spi_width(starget) = tinfo->curr.width;
1643 spi_offset(starget) = tinfo->curr.offset;
1644 spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
1645 spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
1646 spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
1647 spi_display_xfer_agreement(starget);
1648 break;
1649 }
1650 case AC_SENT_BDR:
1651 {
1652 WARN_ON(lun != CAM_LUN_WILDCARD);
1653 scsi_report_device_reset(ahc->platform_data->host,
1654 channel - 'A', target);
1655 break;
1656 }
1657 case AC_BUS_RESET:
1658 if (ahc->platform_data->host != NULL) {
1659 scsi_report_bus_reset(ahc->platform_data->host,
1660 channel - 'A');
1661 }
1662 break;
1663 default:
1664 panic("ahc_send_async: Unexpected async event");
1665 }
1666}
1667
1668
1669
1670
1671void
1672ahc_done(struct ahc_softc *ahc, struct scb *scb)
1673{
1674 struct scsi_cmnd *cmd;
1675 struct ahc_linux_device *dev;
1676
1677 LIST_REMOVE(scb, pending_links);
1678 if ((scb->flags & SCB_UNTAGGEDQ) != 0) {
1679 struct scb_tailq *untagged_q;
1680 int target_offset;
1681
1682 target_offset = SCB_GET_TARGET_OFFSET(ahc, scb);
1683 untagged_q = &(ahc->untagged_queues[target_offset]);
1684 TAILQ_REMOVE(untagged_q, scb, links.tqe);
1685 BUG_ON(!TAILQ_EMPTY(untagged_q));
1686 } else if ((scb->flags & SCB_ACTIVE) == 0) {
1687
1688
1689
1690
1691
1692 printk("SCB %d done'd twice\n", scb->hscb->tag);
1693 ahc_dump_card_state(ahc);
1694 panic("Stopping for safety");
1695 }
1696 cmd = scb->io_ctx;
1697 dev = scb->platform_data->dev;
1698 dev->active--;
1699 dev->openings++;
1700 if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
1701 cmd->result &= ~(CAM_DEV_QFRZN << 16);
1702 dev->qfrozen--;
1703 }
1704 ahc_linux_unmap_scb(ahc, scb);
1705
1706
1707
1708
1709
1710
1711
1712 cmd->sense_buffer[0] = 0;
1713 if (ahc_get_transaction_status(scb) == CAM_REQ_INPROG) {
1714#ifdef AHC_REPORT_UNDERFLOWS
1715 uint32_t amount_xferred;
1716
1717 amount_xferred =
1718 ahc_get_transfer_length(scb) - ahc_get_residual(scb);
1719#endif
1720 if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
1721#ifdef AHC_DEBUG
1722 if ((ahc_debug & AHC_SHOW_MISC) != 0) {
1723 ahc_print_path(ahc, scb);
1724 printk("Set CAM_UNCOR_PARITY\n");
1725 }
1726#endif
1727 ahc_set_transaction_status(scb, CAM_UNCOR_PARITY);
1728#ifdef AHC_REPORT_UNDERFLOWS
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738 } else if (amount_xferred < scb->io_ctx->underflow) {
1739 u_int i;
1740
1741 ahc_print_path(ahc, scb);
1742 printk("CDB:");
1743 for (i = 0; i < scb->io_ctx->cmd_len; i++)
1744 printk(" 0x%x", scb->io_ctx->cmnd[i]);
1745 printk("\n");
1746 ahc_print_path(ahc, scb);
1747 printk("Saw underflow (%ld of %ld bytes). "
1748 "Treated as error\n",
1749 ahc_get_residual(scb),
1750 ahc_get_transfer_length(scb));
1751 ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1752#endif
1753 } else {
1754 ahc_set_transaction_status(scb, CAM_REQ_CMP);
1755 }
1756 } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
1757 ahc_linux_handle_scsi_status(ahc, cmd->device, scb);
1758 }
1759
1760 if (dev->openings == 1
1761 && ahc_get_transaction_status(scb) == CAM_REQ_CMP
1762 && ahc_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
1763 dev->tag_success_count++;
1764
1765
1766
1767
1768
1769
1770 if ((dev->openings + dev->active) < dev->maxtags
1771 && dev->tag_success_count > AHC_TAG_SUCCESS_INTERVAL) {
1772 dev->tag_success_count = 0;
1773 dev->openings++;
1774 }
1775
1776 if (dev->active == 0)
1777 dev->commands_since_idle_or_otag = 0;
1778
1779 if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
1780 printk("Recovery SCB completes\n");
1781 if (ahc_get_transaction_status(scb) == CAM_BDR_SENT
1782 || ahc_get_transaction_status(scb) == CAM_REQ_ABORTED)
1783 ahc_set_transaction_status(scb, CAM_CMD_TIMEOUT);
1784
1785 if (ahc->platform_data->eh_done)
1786 complete(ahc->platform_data->eh_done);
1787 }
1788
1789 ahc_free_scb(ahc, scb);
1790 ahc_linux_queue_cmd_complete(ahc, cmd);
1791}
1792
1793static void
1794ahc_linux_handle_scsi_status(struct ahc_softc *ahc,
1795 struct scsi_device *sdev, struct scb *scb)
1796{
1797 struct ahc_devinfo devinfo;
1798 struct ahc_linux_device *dev = scsi_transport_device_data(sdev);
1799
1800 ahc_compile_devinfo(&devinfo,
1801 ahc->our_id,
1802 sdev->sdev_target->id, sdev->lun,
1803 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1804 ROLE_INITIATOR);
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816 switch (ahc_get_scsi_status(scb)) {
1817 default:
1818 break;
1819 case SCSI_STATUS_CHECK_COND:
1820 case SCSI_STATUS_CMD_TERMINATED:
1821 {
1822 struct scsi_cmnd *cmd;
1823
1824
1825
1826
1827
1828 cmd = scb->io_ctx;
1829 if (scb->flags & SCB_SENSE) {
1830 u_int sense_size;
1831
1832 sense_size = min(sizeof(struct scsi_sense_data)
1833 - ahc_get_sense_residual(scb),
1834 (u_long)SCSI_SENSE_BUFFERSIZE);
1835 memcpy(cmd->sense_buffer,
1836 ahc_get_sense_buf(ahc, scb), sense_size);
1837 if (sense_size < SCSI_SENSE_BUFFERSIZE)
1838 memset(&cmd->sense_buffer[sense_size], 0,
1839 SCSI_SENSE_BUFFERSIZE - sense_size);
1840 cmd->result |= (DRIVER_SENSE << 24);
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 SCSI_STATUS_QUEUE_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, SCSI_STATUS_OK);
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, SCSI_STATUS_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, AHC_SYNCRATE_DT);
2365 ahc_lock(ahc, &flags);
2366 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
2367 ppr_options, AHC_TRANS_GOAL, FALSE);
2368 ahc_unlock(ahc, &flags);
2369}
2370
2371static void ahc_linux_set_offset(struct scsi_target *starget, int offset)
2372{
2373 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2374 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2375 struct ahc_tmode_tstate *tstate;
2376 struct ahc_initiator_tinfo *tinfo
2377 = ahc_fetch_transinfo(ahc,
2378 starget->channel + 'A',
2379 shost->this_id, starget->id, &tstate);
2380 struct ahc_devinfo devinfo;
2381 unsigned int ppr_options = 0;
2382 unsigned int period = 0;
2383 unsigned long flags;
2384 const struct ahc_syncrate *syncrate = NULL;
2385
2386 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2387 starget->channel + 'A', ROLE_INITIATOR);
2388 if (offset != 0) {
2389 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2390 period = tinfo->goal.period;
2391 ppr_options = tinfo->goal.ppr_options;
2392 }
2393 ahc_lock(ahc, &flags);
2394 ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset,
2395 ppr_options, AHC_TRANS_GOAL, FALSE);
2396 ahc_unlock(ahc, &flags);
2397}
2398
2399static void ahc_linux_set_dt(struct scsi_target *starget, int dt)
2400{
2401 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2402 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2403 struct ahc_tmode_tstate *tstate;
2404 struct ahc_initiator_tinfo *tinfo
2405 = ahc_fetch_transinfo(ahc,
2406 starget->channel + 'A',
2407 shost->this_id, starget->id, &tstate);
2408 struct ahc_devinfo devinfo;
2409 unsigned int ppr_options = tinfo->goal.ppr_options
2410 & ~MSG_EXT_PPR_DT_REQ;
2411 unsigned int period = tinfo->goal.period;
2412 unsigned int width = tinfo->goal.width;
2413 unsigned long flags;
2414 const struct ahc_syncrate *syncrate;
2415
2416 if (dt && spi_max_width(starget)) {
2417 ppr_options |= MSG_EXT_PPR_DT_REQ;
2418 if (!width)
2419 ahc_linux_set_width(starget, 1);
2420 } else if (period == 9)
2421 period = 10;
2422
2423 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2424 starget->channel + 'A', ROLE_INITIATOR);
2425 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT);
2426 ahc_lock(ahc, &flags);
2427 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
2428 ppr_options, AHC_TRANS_GOAL, FALSE);
2429 ahc_unlock(ahc, &flags);
2430}
2431
2432#if 0
2433
2434
2435
2436
2437static void ahc_linux_set_qas(struct scsi_target *starget, int qas)
2438{
2439 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2440 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2441 struct ahc_tmode_tstate *tstate;
2442 struct ahc_initiator_tinfo *tinfo
2443 = ahc_fetch_transinfo(ahc,
2444 starget->channel + 'A',
2445 shost->this_id, starget->id, &tstate);
2446 struct ahc_devinfo devinfo;
2447 unsigned int ppr_options = tinfo->goal.ppr_options
2448 & ~MSG_EXT_PPR_QAS_REQ;
2449 unsigned int period = tinfo->goal.period;
2450 unsigned long flags;
2451 struct ahc_syncrate *syncrate;
2452
2453 if (qas)
2454 ppr_options |= MSG_EXT_PPR_QAS_REQ;
2455
2456 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2457 starget->channel + 'A', ROLE_INITIATOR);
2458 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2459 ahc_lock(ahc, &flags);
2460 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
2461 ppr_options, AHC_TRANS_GOAL, FALSE);
2462 ahc_unlock(ahc, &flags);
2463}
2464
2465static void ahc_linux_set_iu(struct scsi_target *starget, int iu)
2466{
2467 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2468 struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata);
2469 struct ahc_tmode_tstate *tstate;
2470 struct ahc_initiator_tinfo *tinfo
2471 = ahc_fetch_transinfo(ahc,
2472 starget->channel + 'A',
2473 shost->this_id, starget->id, &tstate);
2474 struct ahc_devinfo devinfo;
2475 unsigned int ppr_options = tinfo->goal.ppr_options
2476 & ~MSG_EXT_PPR_IU_REQ;
2477 unsigned int period = tinfo->goal.period;
2478 unsigned long flags;
2479 struct ahc_syncrate *syncrate;
2480
2481 if (iu)
2482 ppr_options |= MSG_EXT_PPR_IU_REQ;
2483
2484 ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2485 starget->channel + 'A', ROLE_INITIATOR);
2486 syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT);
2487 ahc_lock(ahc, &flags);
2488 ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->goal.offset,
2489 ppr_options, AHC_TRANS_GOAL, FALSE);
2490 ahc_unlock(ahc, &flags);
2491}
2492#endif
2493
2494static void ahc_linux_get_signalling(struct Scsi_Host *shost)
2495{
2496 struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
2497 unsigned long flags;
2498 u8 mode;
2499
2500 if (!(ahc->features & AHC_ULTRA2)) {
2501
2502 spi_signalling(shost) =
2503 ahc->features & AHC_HVD ?
2504 SPI_SIGNAL_HVD :
2505 SPI_SIGNAL_SE;
2506 return;
2507 }
2508
2509 ahc_lock(ahc, &flags);
2510 ahc_pause(ahc);
2511 mode = ahc_inb(ahc, SBLKCTL);
2512 ahc_unpause(ahc);
2513 ahc_unlock(ahc, &flags);
2514
2515 if (mode & ENAB40)
2516 spi_signalling(shost) = SPI_SIGNAL_LVD;
2517 else if (mode & ENAB20)
2518 spi_signalling(shost) = SPI_SIGNAL_SE;
2519 else
2520 spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
2521}
2522
2523static struct spi_function_template ahc_linux_transport_functions = {
2524 .set_offset = ahc_linux_set_offset,
2525 .show_offset = 1,
2526 .set_period = ahc_linux_set_period,
2527 .show_period = 1,
2528 .set_width = ahc_linux_set_width,
2529 .show_width = 1,
2530 .set_dt = ahc_linux_set_dt,
2531 .show_dt = 1,
2532#if 0
2533 .set_iu = ahc_linux_set_iu,
2534 .show_iu = 1,
2535 .set_qas = ahc_linux_set_qas,
2536 .show_qas = 1,
2537#endif
2538 .get_signalling = ahc_linux_get_signalling,
2539};
2540
2541
2542
2543static int __init
2544ahc_linux_init(void)
2545{
2546
2547
2548
2549 if (aic7xxx)
2550 aic7xxx_setup(aic7xxx);
2551
2552 ahc_linux_transport_template =
2553 spi_attach_transport(&ahc_linux_transport_functions);
2554 if (!ahc_linux_transport_template)
2555 return -ENODEV;
2556
2557 scsi_transport_reserve_device(ahc_linux_transport_template,
2558 sizeof(struct ahc_linux_device));
2559
2560 ahc_linux_pci_init();
2561 ahc_linux_eisa_init();
2562 return 0;
2563}
2564
2565static void
2566ahc_linux_exit(void)
2567{
2568 ahc_linux_pci_exit();
2569 ahc_linux_eisa_exit();
2570 spi_release_transport(ahc_linux_transport_template);
2571}
2572
2573module_init(ahc_linux_init);
2574module_exit(ahc_linux_exit);
2575