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