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