This source file includes following definitions.
- ahd_print_path
- ahd_delay
- ahd_inb
- ahd_inw_atomic
- ahd_outb
- ahd_outw_atomic
- ahd_outsb
- ahd_insb
- ahd_pci_read_config
- ahd_pci_write_config
- ahd_linux_unmap_scb
- ahd_linux_info
- ahd_linux_queue_lck
- DEF_SCSI_QCMD
- ahd_linux_target_alloc
- ahd_linux_target_destroy
- ahd_linux_slave_alloc
- ahd_linux_slave_configure
- ahd_linux_biosparam
- ahd_linux_abort
- ahd_linux_dev_reset
- ahd_linux_bus_reset
- ahd_dma_tag_create
- ahd_dma_tag_destroy
- ahd_dmamem_alloc
- ahd_dmamem_free
- ahd_dmamap_load
- ahd_dmamap_destroy
- ahd_dmamap_unload
- ahd_linux_setup_iocell_info
- ahd_linux_setup_tag_info_global
- ahd_linux_setup_tag_info
- ahd_parse_brace_option
- aic79xx_setup
- ahd_linux_register_host
- ahd_linux_initialize_scsi_bus
- ahd_platform_alloc
- ahd_platform_free
- ahd_platform_init
- ahd_platform_freeze_devq
- ahd_platform_set_tags
- ahd_platform_abort_scbs
- ahd_linux_user_tagdepth
- ahd_linux_device_queue_depth
- ahd_linux_run_command
- ahd_linux_isr
- ahd_send_async
- ahd_done
- ahd_linux_handle_scsi_status
- ahd_linux_queue_cmd_complete
- ahd_freeze_simq
- ahd_release_simq
- ahd_linux_queue_abort_cmd
- ahd_linux_set_width
- ahd_linux_set_period
- ahd_linux_set_offset
- ahd_linux_set_dt
- ahd_linux_set_qas
- ahd_linux_set_iu
- ahd_linux_set_rd_strm
- ahd_linux_set_wr_flow
- ahd_linux_set_rti
- ahd_linux_set_pcomp_en
- ahd_linux_set_hold_mcs
- ahd_linux_get_signalling
- ahd_linux_init
- ahd_linux_exit
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 #include "aic79xx_osm.h"
46 #include "aic79xx_inline.h"
47 #include <scsi/scsicam.h>
48
49 static struct scsi_transport_template *ahd_linux_transport_template = NULL;
50
51 #include <linux/init.h>
52 #include <linux/mm.h>
53 #include <linux/blkdev.h>
54 #include <linux/delay.h>
55 #include <linux/device.h>
56 #include <linux/slab.h>
57
58
59
60
61 #define AHD_LINUX_ERR_THRESH 1000
62
63
64
65
66
67
68
69 #ifdef CONFIG_AIC79XX_RESET_DELAY_MS
70 #define AIC79XX_RESET_DELAY CONFIG_AIC79XX_RESET_DELAY_MS
71 #else
72 #define AIC79XX_RESET_DELAY 5000
73 #endif
74
75
76
77
78
79
80
81
82
83
84
85
86 typedef struct {
87 uint16_t tag_commands[16];
88 } adapter_tag_info_t;
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 #ifdef CONFIG_AIC79XX_CMDS_PER_DEVICE
134 #define AIC79XX_CMDS_PER_DEVICE CONFIG_AIC79XX_CMDS_PER_DEVICE
135 #else
136 #define AIC79XX_CMDS_PER_DEVICE AHD_MAX_QUEUE
137 #endif
138
139 #define AIC79XX_CONFIGED_TAG_COMMANDS { \
140 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
141 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
142 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
143 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
144 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
145 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
146 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
147 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE \
148 }
149
150
151
152
153
154 static adapter_tag_info_t aic79xx_tag_info[] =
155 {
156 {AIC79XX_CONFIGED_TAG_COMMANDS},
157 {AIC79XX_CONFIGED_TAG_COMMANDS},
158 {AIC79XX_CONFIGED_TAG_COMMANDS},
159 {AIC79XX_CONFIGED_TAG_COMMANDS},
160 {AIC79XX_CONFIGED_TAG_COMMANDS},
161 {AIC79XX_CONFIGED_TAG_COMMANDS},
162 {AIC79XX_CONFIGED_TAG_COMMANDS},
163 {AIC79XX_CONFIGED_TAG_COMMANDS},
164 {AIC79XX_CONFIGED_TAG_COMMANDS},
165 {AIC79XX_CONFIGED_TAG_COMMANDS},
166 {AIC79XX_CONFIGED_TAG_COMMANDS},
167 {AIC79XX_CONFIGED_TAG_COMMANDS},
168 {AIC79XX_CONFIGED_TAG_COMMANDS},
169 {AIC79XX_CONFIGED_TAG_COMMANDS},
170 {AIC79XX_CONFIGED_TAG_COMMANDS},
171 {AIC79XX_CONFIGED_TAG_COMMANDS}
172 };
173
174
175
176
177
178
179 struct ahd_linux_iocell_opts
180 {
181 uint8_t precomp;
182 uint8_t slewrate;
183 uint8_t amplitude;
184 };
185 #define AIC79XX_DEFAULT_PRECOMP 0xFF
186 #define AIC79XX_DEFAULT_SLEWRATE 0xFF
187 #define AIC79XX_DEFAULT_AMPLITUDE 0xFF
188 #define AIC79XX_DEFAULT_IOOPTS \
189 { \
190 AIC79XX_DEFAULT_PRECOMP, \
191 AIC79XX_DEFAULT_SLEWRATE, \
192 AIC79XX_DEFAULT_AMPLITUDE \
193 }
194 #define AIC79XX_PRECOMP_INDEX 0
195 #define AIC79XX_SLEWRATE_INDEX 1
196 #define AIC79XX_AMPLITUDE_INDEX 2
197 static const struct ahd_linux_iocell_opts aic79xx_iocell_info[] =
198 {
199 AIC79XX_DEFAULT_IOOPTS,
200 AIC79XX_DEFAULT_IOOPTS,
201 AIC79XX_DEFAULT_IOOPTS,
202 AIC79XX_DEFAULT_IOOPTS,
203 AIC79XX_DEFAULT_IOOPTS,
204 AIC79XX_DEFAULT_IOOPTS,
205 AIC79XX_DEFAULT_IOOPTS,
206 AIC79XX_DEFAULT_IOOPTS,
207 AIC79XX_DEFAULT_IOOPTS,
208 AIC79XX_DEFAULT_IOOPTS,
209 AIC79XX_DEFAULT_IOOPTS,
210 AIC79XX_DEFAULT_IOOPTS,
211 AIC79XX_DEFAULT_IOOPTS,
212 AIC79XX_DEFAULT_IOOPTS,
213 AIC79XX_DEFAULT_IOOPTS,
214 AIC79XX_DEFAULT_IOOPTS
215 };
216
217
218
219
220
221 #define DID_UNDERFLOW DID_ERROR
222
223 void
224 ahd_print_path(struct ahd_softc *ahd, struct scb *scb)
225 {
226 printk("(scsi%d:%c:%d:%d): ",
227 ahd->platform_data->host->host_no,
228 scb != NULL ? SCB_GET_CHANNEL(ahd, scb) : 'X',
229 scb != NULL ? SCB_GET_TARGET(ahd, scb) : -1,
230 scb != NULL ? SCB_GET_LUN(scb) : -1);
231 }
232
233
234
235
236
237
238
239
240
241
242
243
244 static uint32_t aic79xx_no_reset;
245
246
247
248
249
250
251 static uint32_t aic79xx_extended;
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267 static uint32_t aic79xx_pci_parity = ~0;
268
269
270
271
272
273
274
275 uint32_t aic79xx_allow_memio = ~0;
276
277
278
279
280
281
282
283
284
285
286
287 static uint32_t aic79xx_seltime;
288
289
290
291
292
293
294
295
296
297 static uint32_t aic79xx_periodic_otag;
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312 uint32_t aic79xx_slowcrc;
313
314
315
316
317 static char *aic79xx = NULL;
318
319 MODULE_AUTHOR("Maintainer: Hannes Reinecke <hare@suse.de>");
320 MODULE_DESCRIPTION("Adaptec AIC790X U320 SCSI Host Bus Adapter driver");
321 MODULE_LICENSE("Dual BSD/GPL");
322 MODULE_VERSION(AIC79XX_DRIVER_VERSION);
323 module_param(aic79xx, charp, 0444);
324 MODULE_PARM_DESC(aic79xx,
325 "period-delimited options string:\n"
326 " verbose Enable verbose/diagnostic logging\n"
327 " allow_memio Allow device registers to be memory mapped\n"
328 " debug Bitmask of debug values to enable\n"
329 " no_reset Suppress initial bus resets\n"
330 " extended Enable extended geometry on all controllers\n"
331 " periodic_otag Send an ordered tagged transaction\n"
332 " periodically to prevent tag starvation.\n"
333 " This may be required by some older disk\n"
334 " or drives/RAID arrays.\n"
335 " tag_info:<tag_str> Set per-target tag depth\n"
336 " global_tag_depth:<int> Global tag depth for all targets on all buses\n"
337 " slewrate:<slewrate_list>Set the signal slew rate (0-15).\n"
338 " precomp:<pcomp_list> Set the signal precompensation (0-7).\n"
339 " amplitude:<int> Set the signal amplitude (0-7).\n"
340 " seltime:<int> Selection Timeout:\n"
341 " (0/256ms,1/128ms,2/64ms,3/32ms)\n"
342 " slowcrc Turn on the SLOWCRC bit (Rev B only)\n"
343 "\n"
344 " Sample modprobe configuration file:\n"
345 " # Enable verbose logging\n"
346 " # Set tag depth on Controller 2/Target 2 to 10 tags\n"
347 " # Shorten the selection timeout to 128ms\n"
348 "\n"
349 " options aic79xx 'aic79xx=verbose.tag_info:{{}.{}.{..10}}.seltime:1'\n"
350 );
351
352 static void ahd_linux_handle_scsi_status(struct ahd_softc *,
353 struct scsi_device *,
354 struct scb *);
355 static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd,
356 struct scsi_cmnd *cmd);
357 static int ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd);
358 static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd);
359 static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd,
360 struct ahd_devinfo *devinfo);
361 static void ahd_linux_device_queue_depth(struct scsi_device *);
362 static int ahd_linux_run_command(struct ahd_softc*,
363 struct ahd_linux_device *,
364 struct scsi_cmnd *);
365 static void ahd_linux_setup_tag_info_global(char *p);
366 static int aic79xx_setup(char *c);
367 static void ahd_freeze_simq(struct ahd_softc *ahd);
368 static void ahd_release_simq(struct ahd_softc *ahd);
369
370 static int ahd_linux_unit;
371
372
373
374 void ahd_delay(long);
375 void
376 ahd_delay(long usec)
377 {
378
379
380
381
382
383 while (usec > 0) {
384 udelay(usec % 1024);
385 usec -= 1024;
386 }
387 }
388
389
390
391 uint8_t ahd_inb(struct ahd_softc * ahd, long port);
392 void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
393 void ahd_outw_atomic(struct ahd_softc * ahd,
394 long port, uint16_t val);
395 void ahd_outsb(struct ahd_softc * ahd, long port,
396 uint8_t *, int count);
397 void ahd_insb(struct ahd_softc * ahd, long port,
398 uint8_t *, int count);
399
400 uint8_t
401 ahd_inb(struct ahd_softc * ahd, long port)
402 {
403 uint8_t x;
404
405 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
406 x = readb(ahd->bshs[0].maddr + port);
407 } else {
408 x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
409 }
410 mb();
411 return (x);
412 }
413
414 #if 0
415 static uint16_t
416 ahd_inw_atomic(struct ahd_softc * ahd, long port)
417 {
418 uint8_t x;
419
420 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
421 x = readw(ahd->bshs[0].maddr + port);
422 } else {
423 x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
424 }
425 mb();
426 return (x);
427 }
428 #endif
429
430 void
431 ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
432 {
433 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
434 writeb(val, ahd->bshs[0].maddr + port);
435 } else {
436 outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
437 }
438 mb();
439 }
440
441 void
442 ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
443 {
444 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
445 writew(val, ahd->bshs[0].maddr + port);
446 } else {
447 outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
448 }
449 mb();
450 }
451
452 void
453 ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
454 {
455 int i;
456
457
458
459
460
461
462 for (i = 0; i < count; i++)
463 ahd_outb(ahd, port, *array++);
464 }
465
466 void
467 ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
468 {
469 int i;
470
471
472
473
474
475
476 for (i = 0; i < count; i++)
477 *array++ = ahd_inb(ahd, port);
478 }
479
480
481 uint32_t
482 ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width)
483 {
484 switch (width) {
485 case 1:
486 {
487 uint8_t retval;
488
489 pci_read_config_byte(pci, reg, &retval);
490 return (retval);
491 }
492 case 2:
493 {
494 uint16_t retval;
495 pci_read_config_word(pci, reg, &retval);
496 return (retval);
497 }
498 case 4:
499 {
500 uint32_t retval;
501 pci_read_config_dword(pci, reg, &retval);
502 return (retval);
503 }
504 default:
505 panic("ahd_pci_read_config: Read size too big");
506
507 return (0);
508 }
509 }
510
511 void
512 ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width)
513 {
514 switch (width) {
515 case 1:
516 pci_write_config_byte(pci, reg, value);
517 break;
518 case 2:
519 pci_write_config_word(pci, reg, value);
520 break;
521 case 4:
522 pci_write_config_dword(pci, reg, value);
523 break;
524 default:
525 panic("ahd_pci_write_config: Write size too big");
526
527 }
528 }
529
530
531 static void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
532
533 static void
534 ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
535 {
536 struct scsi_cmnd *cmd;
537
538 cmd = scb->io_ctx;
539 ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
540 scsi_dma_unmap(cmd);
541 }
542
543
544 #define BUILD_SCSIID(ahd, cmd) \
545 (((scmd_id(cmd) << TID_SHIFT) & TID) | (ahd)->our_id)
546
547
548
549
550 static const char *
551 ahd_linux_info(struct Scsi_Host *host)
552 {
553 static char buffer[512];
554 char ahd_info[256];
555 char *bp;
556 struct ahd_softc *ahd;
557
558 bp = &buffer[0];
559 ahd = *(struct ahd_softc **)host->hostdata;
560 memset(bp, 0, sizeof(buffer));
561 strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev " AIC79XX_DRIVER_VERSION "\n"
562 " <");
563 strcat(bp, ahd->description);
564 strcat(bp, ">\n"
565 " ");
566 ahd_controller_info(ahd, ahd_info);
567 strcat(bp, ahd_info);
568
569 return (bp);
570 }
571
572
573
574
575 static int
576 ahd_linux_queue_lck(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
577 {
578 struct ahd_softc *ahd;
579 struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
580 int rtn = SCSI_MLQUEUE_HOST_BUSY;
581
582 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
583
584 cmd->scsi_done = scsi_done;
585 cmd->result = CAM_REQ_INPROG << 16;
586 rtn = ahd_linux_run_command(ahd, dev, cmd);
587
588 return rtn;
589 }
590
591 static DEF_SCSI_QCMD(ahd_linux_queue)
592
593 static struct scsi_target **
594 ahd_linux_target_in_softc(struct scsi_target *starget)
595 {
596 struct ahd_softc *ahd =
597 *((struct ahd_softc **)dev_to_shost(&starget->dev)->hostdata);
598 unsigned int target_offset;
599
600 target_offset = starget->id;
601 if (starget->channel != 0)
602 target_offset += 8;
603
604 return &ahd->platform_data->starget[target_offset];
605 }
606
607 static int
608 ahd_linux_target_alloc(struct scsi_target *starget)
609 {
610 struct ahd_softc *ahd =
611 *((struct ahd_softc **)dev_to_shost(&starget->dev)->hostdata);
612 struct seeprom_config *sc = ahd->seep_config;
613 unsigned long flags;
614 struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
615 struct ahd_devinfo devinfo;
616 struct ahd_initiator_tinfo *tinfo;
617 struct ahd_tmode_tstate *tstate;
618 char channel = starget->channel + 'A';
619
620 ahd_lock(ahd, &flags);
621
622 BUG_ON(*ahd_targp != NULL);
623
624 *ahd_targp = starget;
625
626 if (sc) {
627 int flags = sc->device_flags[starget->id];
628
629 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
630 starget->id, &tstate);
631
632 if ((flags & CFPACKETIZED) == 0) {
633
634 spi_max_iu(starget) = 0;
635 } else {
636 if ((ahd->features & AHD_RTI) == 0)
637 spi_rti(starget) = 0;
638 }
639
640 if ((flags & CFQAS) == 0)
641 spi_max_qas(starget) = 0;
642
643
644 spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0;
645 spi_min_period(starget) = tinfo->user.period;
646 spi_max_offset(starget) = tinfo->user.offset;
647 }
648
649 tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
650 starget->id, &tstate);
651 ahd_compile_devinfo(&devinfo, ahd->our_id, starget->id,
652 CAM_LUN_WILDCARD, channel,
653 ROLE_INITIATOR);
654 ahd_set_syncrate(ahd, &devinfo, 0, 0, 0,
655 AHD_TRANS_GOAL, FALSE);
656 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
657 AHD_TRANS_GOAL, FALSE);
658 ahd_unlock(ahd, &flags);
659
660 return 0;
661 }
662
663 static void
664 ahd_linux_target_destroy(struct scsi_target *starget)
665 {
666 struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
667
668 *ahd_targp = NULL;
669 }
670
671 static int
672 ahd_linux_slave_alloc(struct scsi_device *sdev)
673 {
674 struct ahd_softc *ahd =
675 *((struct ahd_softc **)sdev->host->hostdata);
676 struct ahd_linux_device *dev;
677
678 if (bootverbose)
679 printk("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id);
680
681 dev = scsi_transport_device_data(sdev);
682 memset(dev, 0, sizeof(*dev));
683
684
685
686
687
688 dev->openings = 1;
689
690
691
692
693
694
695 dev->maxtags = 0;
696
697 return (0);
698 }
699
700 static int
701 ahd_linux_slave_configure(struct scsi_device *sdev)
702 {
703 struct ahd_softc *ahd;
704
705 ahd = *((struct ahd_softc **)sdev->host->hostdata);
706 if (bootverbose)
707 sdev_printk(KERN_INFO, sdev, "Slave Configure\n");
708
709 ahd_linux_device_queue_depth(sdev);
710
711
712 if (!spi_initial_dv(sdev->sdev_target))
713 spi_dv_device(sdev);
714
715 return 0;
716 }
717
718 #if defined(__i386__)
719
720
721
722 static int
723 ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
724 sector_t capacity, int geom[])
725 {
726 uint8_t *bh;
727 int heads;
728 int sectors;
729 int cylinders;
730 int ret;
731 int extended;
732 struct ahd_softc *ahd;
733
734 ahd = *((struct ahd_softc **)sdev->host->hostdata);
735
736 bh = scsi_bios_ptable(bdev);
737 if (bh) {
738 ret = scsi_partsize(bh, capacity,
739 &geom[2], &geom[0], &geom[1]);
740 kfree(bh);
741 if (ret != -1)
742 return (ret);
743 }
744 heads = 64;
745 sectors = 32;
746 cylinders = aic_sector_div(capacity, heads, sectors);
747
748 if (aic79xx_extended != 0)
749 extended = 1;
750 else
751 extended = (ahd->flags & AHD_EXTENDED_TRANS_A) != 0;
752 if (extended && cylinders >= 1024) {
753 heads = 255;
754 sectors = 63;
755 cylinders = aic_sector_div(capacity, heads, sectors);
756 }
757 geom[0] = heads;
758 geom[1] = sectors;
759 geom[2] = cylinders;
760 return (0);
761 }
762 #endif
763
764
765
766
767 static int
768 ahd_linux_abort(struct scsi_cmnd *cmd)
769 {
770 int error;
771
772 error = ahd_linux_queue_abort_cmd(cmd);
773
774 return error;
775 }
776
777
778
779
780 static int
781 ahd_linux_dev_reset(struct scsi_cmnd *cmd)
782 {
783 struct ahd_softc *ahd;
784 struct ahd_linux_device *dev;
785 struct scb *reset_scb;
786 u_int cdb_byte;
787 int retval = SUCCESS;
788 int paused;
789 int wait;
790 struct ahd_initiator_tinfo *tinfo;
791 struct ahd_tmode_tstate *tstate;
792 unsigned long flags;
793 DECLARE_COMPLETION_ONSTACK(done);
794
795 reset_scb = NULL;
796 paused = FALSE;
797 wait = FALSE;
798 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
799
800 scmd_printk(KERN_INFO, cmd,
801 "Attempting to queue a TARGET RESET message:");
802
803 printk("CDB:");
804 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
805 printk(" 0x%x", cmd->cmnd[cdb_byte]);
806 printk("\n");
807
808
809
810
811 dev = scsi_transport_device_data(cmd->device);
812
813 if (dev == NULL) {
814
815
816
817
818 scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
819 return SUCCESS;
820 }
821
822
823
824
825 reset_scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX);
826 if (!reset_scb) {
827 scmd_printk(KERN_INFO, cmd, "No SCB available\n");
828 return FAILED;
829 }
830
831 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
832 cmd->device->id, &tstate);
833 reset_scb->io_ctx = cmd;
834 reset_scb->platform_data->dev = dev;
835 reset_scb->sg_count = 0;
836 ahd_set_residual(reset_scb, 0);
837 ahd_set_sense_residual(reset_scb, 0);
838 reset_scb->platform_data->xfer_len = 0;
839 reset_scb->hscb->control = 0;
840 reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd);
841 reset_scb->hscb->lun = cmd->device->lun;
842 reset_scb->hscb->cdb_len = 0;
843 reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET;
844 reset_scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE;
845 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
846 reset_scb->flags |= SCB_PACKETIZED;
847 } else {
848 reset_scb->hscb->control |= MK_MESSAGE;
849 }
850 dev->openings--;
851 dev->active++;
852 dev->commands_issued++;
853
854 ahd_lock(ahd, &flags);
855
856 LIST_INSERT_HEAD(&ahd->pending_scbs, reset_scb, pending_links);
857 ahd_queue_scb(ahd, reset_scb);
858
859 ahd->platform_data->eh_done = &done;
860 ahd_unlock(ahd, &flags);
861
862 printk("%s: Device reset code sleeping\n", ahd_name(ahd));
863 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
864 ahd_lock(ahd, &flags);
865 ahd->platform_data->eh_done = NULL;
866 ahd_unlock(ahd, &flags);
867 printk("%s: Device reset timer expired (active %d)\n",
868 ahd_name(ahd), dev->active);
869 retval = FAILED;
870 }
871 printk("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
872
873 return (retval);
874 }
875
876
877
878
879 static int
880 ahd_linux_bus_reset(struct scsi_cmnd *cmd)
881 {
882 struct ahd_softc *ahd;
883 int found;
884 unsigned long flags;
885
886 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
887 #ifdef AHD_DEBUG
888 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
889 printk("%s: Bus reset called for cmd %p\n",
890 ahd_name(ahd), cmd);
891 #endif
892 ahd_lock(ahd, &flags);
893
894 found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A',
895 TRUE);
896 ahd_unlock(ahd, &flags);
897
898 if (bootverbose)
899 printk("%s: SCSI bus reset delivered. "
900 "%d SCBs aborted.\n", ahd_name(ahd), found);
901
902 return (SUCCESS);
903 }
904
905 struct scsi_host_template aic79xx_driver_template = {
906 .module = THIS_MODULE,
907 .name = "aic79xx",
908 .proc_name = "aic79xx",
909 .show_info = ahd_linux_show_info,
910 .write_info = ahd_proc_write_seeprom,
911 .info = ahd_linux_info,
912 .queuecommand = ahd_linux_queue,
913 .eh_abort_handler = ahd_linux_abort,
914 .eh_device_reset_handler = ahd_linux_dev_reset,
915 .eh_bus_reset_handler = ahd_linux_bus_reset,
916 #if defined(__i386__)
917 .bios_param = ahd_linux_biosparam,
918 #endif
919 .can_queue = AHD_MAX_QUEUE,
920 .this_id = -1,
921 .max_sectors = 8192,
922 .cmd_per_lun = 2,
923 .slave_alloc = ahd_linux_slave_alloc,
924 .slave_configure = ahd_linux_slave_configure,
925 .target_alloc = ahd_linux_target_alloc,
926 .target_destroy = ahd_linux_target_destroy,
927 };
928
929
930 int
931 ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent,
932 bus_size_t alignment, bus_size_t boundary,
933 dma_addr_t lowaddr, dma_addr_t highaddr,
934 bus_dma_filter_t *filter, void *filterarg,
935 bus_size_t maxsize, int nsegments,
936 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
937 {
938 bus_dma_tag_t dmat;
939
940 dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC);
941 if (dmat == NULL)
942 return (ENOMEM);
943
944
945
946
947
948
949
950
951 dmat->alignment = alignment;
952 dmat->boundary = boundary;
953 dmat->maxsize = maxsize;
954 *ret_tag = dmat;
955 return (0);
956 }
957
958 void
959 ahd_dma_tag_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat)
960 {
961 kfree(dmat);
962 }
963
964 int
965 ahd_dmamem_alloc(struct ahd_softc *ahd, bus_dma_tag_t dmat, void** vaddr,
966 int flags, bus_dmamap_t *mapp)
967 {
968 *vaddr = pci_alloc_consistent(ahd->dev_softc,
969 dmat->maxsize, mapp);
970 if (*vaddr == NULL)
971 return (ENOMEM);
972 return(0);
973 }
974
975 void
976 ahd_dmamem_free(struct ahd_softc *ahd, bus_dma_tag_t dmat,
977 void* vaddr, bus_dmamap_t map)
978 {
979 pci_free_consistent(ahd->dev_softc, dmat->maxsize,
980 vaddr, map);
981 }
982
983 int
984 ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map,
985 void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
986 void *cb_arg, int flags)
987 {
988
989
990
991
992 bus_dma_segment_t stack_sg;
993
994 stack_sg.ds_addr = map;
995 stack_sg.ds_len = dmat->maxsize;
996 cb(cb_arg, &stack_sg, 1, 0);
997 return (0);
998 }
999
1000 void
1001 ahd_dmamap_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
1002 {
1003 }
1004
1005 int
1006 ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
1007 {
1008
1009 return (0);
1010 }
1011
1012
1013 static void
1014 ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value)
1015 {
1016
1017 if ((instance >= 0)
1018 && (instance < ARRAY_SIZE(aic79xx_iocell_info))) {
1019 uint8_t *iocell_info;
1020
1021 iocell_info = (uint8_t*)&aic79xx_iocell_info[instance];
1022 iocell_info[index] = value & 0xFFFF;
1023 if (bootverbose)
1024 printk("iocell[%d:%ld] = %d\n", instance, index, value);
1025 }
1026 }
1027
1028 static void
1029 ahd_linux_setup_tag_info_global(char *p)
1030 {
1031 int tags, i, j;
1032
1033 tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
1034 printk("Setting Global Tags= %d\n", tags);
1035
1036 for (i = 0; i < ARRAY_SIZE(aic79xx_tag_info); i++) {
1037 for (j = 0; j < AHD_NUM_TARGETS; j++) {
1038 aic79xx_tag_info[i].tag_commands[j] = tags;
1039 }
1040 }
1041 }
1042
1043 static void
1044 ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
1045 {
1046
1047 if ((instance >= 0) && (targ >= 0)
1048 && (instance < ARRAY_SIZE(aic79xx_tag_info))
1049 && (targ < AHD_NUM_TARGETS)) {
1050 aic79xx_tag_info[instance].tag_commands[targ] = value & 0x1FF;
1051 if (bootverbose)
1052 printk("tag_info[%d:%d] = %d\n", instance, targ, value);
1053 }
1054 }
1055
1056 static char *
1057 ahd_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
1058 void (*callback)(u_long, int, int, int32_t),
1059 u_long callback_arg)
1060 {
1061 char *tok_end;
1062 char *tok_end2;
1063 int i;
1064 int instance;
1065 int targ;
1066 int done;
1067 char tok_list[] = {'.', ',', '{', '}', '\0'};
1068
1069
1070 if (*opt_arg != ':')
1071 return (opt_arg);
1072 opt_arg++;
1073 instance = -1;
1074 targ = -1;
1075 done = FALSE;
1076
1077
1078
1079
1080 tok_end = strchr(opt_arg, '\0');
1081 if (tok_end < end)
1082 *tok_end = ',';
1083 while (!done) {
1084 switch (*opt_arg) {
1085 case '{':
1086 if (instance == -1) {
1087 instance = 0;
1088 } else {
1089 if (depth > 1) {
1090 if (targ == -1)
1091 targ = 0;
1092 } else {
1093 printk("Malformed Option %s\n",
1094 opt_name);
1095 done = TRUE;
1096 }
1097 }
1098 opt_arg++;
1099 break;
1100 case '}':
1101 if (targ != -1)
1102 targ = -1;
1103 else if (instance != -1)
1104 instance = -1;
1105 opt_arg++;
1106 break;
1107 case ',':
1108 case '.':
1109 if (instance == -1)
1110 done = TRUE;
1111 else if (targ >= 0)
1112 targ++;
1113 else if (instance >= 0)
1114 instance++;
1115 opt_arg++;
1116 break;
1117 case '\0':
1118 done = TRUE;
1119 break;
1120 default:
1121 tok_end = end;
1122 for (i = 0; tok_list[i]; i++) {
1123 tok_end2 = strchr(opt_arg, tok_list[i]);
1124 if ((tok_end2) && (tok_end2 < tok_end))
1125 tok_end = tok_end2;
1126 }
1127 callback(callback_arg, instance, targ,
1128 simple_strtol(opt_arg, NULL, 0));
1129 opt_arg = tok_end;
1130 break;
1131 }
1132 }
1133 return (opt_arg);
1134 }
1135
1136
1137
1138
1139
1140
1141 static int
1142 aic79xx_setup(char *s)
1143 {
1144 int i, n;
1145 char *p;
1146 char *end;
1147
1148 static const struct {
1149 const char *name;
1150 uint32_t *flag;
1151 } options[] = {
1152 { "extended", &aic79xx_extended },
1153 { "no_reset", &aic79xx_no_reset },
1154 { "verbose", &aic79xx_verbose },
1155 { "allow_memio", &aic79xx_allow_memio},
1156 #ifdef AHD_DEBUG
1157 { "debug", &ahd_debug },
1158 #endif
1159 { "periodic_otag", &aic79xx_periodic_otag },
1160 { "pci_parity", &aic79xx_pci_parity },
1161 { "seltime", &aic79xx_seltime },
1162 { "tag_info", NULL },
1163 { "global_tag_depth", NULL},
1164 { "slewrate", NULL },
1165 { "precomp", NULL },
1166 { "amplitude", NULL },
1167 { "slowcrc", &aic79xx_slowcrc },
1168 };
1169
1170 end = strchr(s, '\0');
1171
1172
1173
1174
1175
1176 n = 0;
1177
1178 while ((p = strsep(&s, ",.")) != NULL) {
1179 if (*p == '\0')
1180 continue;
1181 for (i = 0; i < ARRAY_SIZE(options); i++) {
1182
1183 n = strlen(options[i].name);
1184 if (strncmp(options[i].name, p, n) == 0)
1185 break;
1186 }
1187 if (i == ARRAY_SIZE(options))
1188 continue;
1189
1190 if (strncmp(p, "global_tag_depth", n) == 0) {
1191 ahd_linux_setup_tag_info_global(p + n);
1192 } else if (strncmp(p, "tag_info", n) == 0) {
1193 s = ahd_parse_brace_option("tag_info", p + n, end,
1194 2, ahd_linux_setup_tag_info, 0);
1195 } else if (strncmp(p, "slewrate", n) == 0) {
1196 s = ahd_parse_brace_option("slewrate",
1197 p + n, end, 1, ahd_linux_setup_iocell_info,
1198 AIC79XX_SLEWRATE_INDEX);
1199 } else if (strncmp(p, "precomp", n) == 0) {
1200 s = ahd_parse_brace_option("precomp",
1201 p + n, end, 1, ahd_linux_setup_iocell_info,
1202 AIC79XX_PRECOMP_INDEX);
1203 } else if (strncmp(p, "amplitude", n) == 0) {
1204 s = ahd_parse_brace_option("amplitude",
1205 p + n, end, 1, ahd_linux_setup_iocell_info,
1206 AIC79XX_AMPLITUDE_INDEX);
1207 } else if (p[n] == ':') {
1208 *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
1209 } else if (!strncmp(p, "verbose", n)) {
1210 *(options[i].flag) = 1;
1211 } else {
1212 *(options[i].flag) ^= 0xFFFFFFFF;
1213 }
1214 }
1215 return 1;
1216 }
1217
1218 __setup("aic79xx=", aic79xx_setup);
1219
1220 uint32_t aic79xx_verbose;
1221
1222 int
1223 ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *template)
1224 {
1225 char buf[80];
1226 struct Scsi_Host *host;
1227 char *new_name;
1228 u_long s;
1229 int retval;
1230
1231 template->name = ahd->description;
1232 host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
1233 if (host == NULL)
1234 return (ENOMEM);
1235
1236 *((struct ahd_softc **)host->hostdata) = ahd;
1237 ahd->platform_data->host = host;
1238 host->can_queue = AHD_MAX_QUEUE;
1239 host->cmd_per_lun = 2;
1240 host->sg_tablesize = AHD_NSEG;
1241 host->this_id = ahd->our_id;
1242 host->irq = ahd->platform_data->irq;
1243 host->max_id = (ahd->features & AHD_WIDE) ? 16 : 8;
1244 host->max_lun = AHD_NUM_LUNS;
1245 host->max_channel = 0;
1246 host->sg_tablesize = AHD_NSEG;
1247 ahd_lock(ahd, &s);
1248 ahd_set_unit(ahd, ahd_linux_unit++);
1249 ahd_unlock(ahd, &s);
1250 sprintf(buf, "scsi%d", host->host_no);
1251 new_name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
1252 if (new_name != NULL) {
1253 strcpy(new_name, buf);
1254 ahd_set_name(ahd, new_name);
1255 }
1256 host->unique_id = ahd->unit;
1257 ahd_linux_initialize_scsi_bus(ahd);
1258 ahd_intr_enable(ahd, TRUE);
1259
1260 host->transportt = ahd_linux_transport_template;
1261
1262 retval = scsi_add_host(host, &ahd->dev_softc->dev);
1263 if (retval) {
1264 printk(KERN_WARNING "aic79xx: scsi_add_host failed\n");
1265 scsi_host_put(host);
1266 return retval;
1267 }
1268
1269 scsi_scan_host(host);
1270 return 0;
1271 }
1272
1273
1274
1275
1276
1277
1278 static void
1279 ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd)
1280 {
1281 u_int target_id;
1282 u_int numtarg;
1283 unsigned long s;
1284
1285 target_id = 0;
1286 numtarg = 0;
1287
1288 if (aic79xx_no_reset != 0)
1289 ahd->flags &= ~AHD_RESET_BUS_A;
1290
1291 if ((ahd->flags & AHD_RESET_BUS_A) != 0)
1292 ahd_reset_channel(ahd, 'A', TRUE);
1293 else
1294 numtarg = (ahd->features & AHD_WIDE) ? 16 : 8;
1295
1296 ahd_lock(ahd, &s);
1297
1298
1299
1300
1301
1302 for (; target_id < numtarg; target_id++) {
1303 struct ahd_devinfo devinfo;
1304 struct ahd_initiator_tinfo *tinfo;
1305 struct ahd_tmode_tstate *tstate;
1306
1307 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
1308 target_id, &tstate);
1309 ahd_compile_devinfo(&devinfo, ahd->our_id, target_id,
1310 CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR);
1311 ahd_update_neg_request(ahd, &devinfo, tstate,
1312 tinfo, AHD_NEG_ALWAYS);
1313 }
1314 ahd_unlock(ahd, &s);
1315
1316 if ((ahd->flags & AHD_RESET_BUS_A) != 0) {
1317 ahd_freeze_simq(ahd);
1318 msleep(AIC79XX_RESET_DELAY);
1319 ahd_release_simq(ahd);
1320 }
1321 }
1322
1323 int
1324 ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg)
1325 {
1326 ahd->platform_data =
1327 kzalloc(sizeof(struct ahd_platform_data), GFP_ATOMIC);
1328 if (ahd->platform_data == NULL)
1329 return (ENOMEM);
1330 ahd->platform_data->irq = AHD_LINUX_NOIRQ;
1331 ahd_lockinit(ahd);
1332 ahd->seltime = (aic79xx_seltime & 0x3) << 4;
1333 return (0);
1334 }
1335
1336 void
1337 ahd_platform_free(struct ahd_softc *ahd)
1338 {
1339 struct scsi_target *starget;
1340 int i;
1341
1342 if (ahd->platform_data != NULL) {
1343
1344 for (i = 0; i < AHD_NUM_TARGETS; i++) {
1345 starget = ahd->platform_data->starget[i];
1346 if (starget != NULL) {
1347 ahd->platform_data->starget[i] = NULL;
1348 }
1349 }
1350
1351 if (ahd->platform_data->irq != AHD_LINUX_NOIRQ)
1352 free_irq(ahd->platform_data->irq, ahd);
1353 if (ahd->tags[0] == BUS_SPACE_PIO
1354 && ahd->bshs[0].ioport != 0)
1355 release_region(ahd->bshs[0].ioport, 256);
1356 if (ahd->tags[1] == BUS_SPACE_PIO
1357 && ahd->bshs[1].ioport != 0)
1358 release_region(ahd->bshs[1].ioport, 256);
1359 if (ahd->tags[0] == BUS_SPACE_MEMIO
1360 && ahd->bshs[0].maddr != NULL) {
1361 iounmap(ahd->bshs[0].maddr);
1362 release_mem_region(ahd->platform_data->mem_busaddr,
1363 0x1000);
1364 }
1365 if (ahd->platform_data->host)
1366 scsi_host_put(ahd->platform_data->host);
1367
1368 kfree(ahd->platform_data);
1369 }
1370 }
1371
1372 void
1373 ahd_platform_init(struct ahd_softc *ahd)
1374 {
1375
1376
1377
1378 if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
1379 const struct ahd_linux_iocell_opts *iocell_opts;
1380
1381 iocell_opts = &aic79xx_iocell_info[ahd->unit];
1382 if (iocell_opts->precomp != AIC79XX_DEFAULT_PRECOMP)
1383 AHD_SET_PRECOMP(ahd, iocell_opts->precomp);
1384 if (iocell_opts->slewrate != AIC79XX_DEFAULT_SLEWRATE)
1385 AHD_SET_SLEWRATE(ahd, iocell_opts->slewrate);
1386 if (iocell_opts->amplitude != AIC79XX_DEFAULT_AMPLITUDE)
1387 AHD_SET_AMPLITUDE(ahd, iocell_opts->amplitude);
1388 }
1389
1390 }
1391
1392 void
1393 ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
1394 {
1395 ahd_platform_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
1396 SCB_GET_CHANNEL(ahd, scb),
1397 SCB_GET_LUN(scb), SCB_LIST_NULL,
1398 ROLE_UNKNOWN, CAM_REQUEUE_REQ);
1399 }
1400
1401 void
1402 ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
1403 struct ahd_devinfo *devinfo, ahd_queue_alg alg)
1404 {
1405 struct ahd_linux_device *dev;
1406 int was_queuing;
1407 int now_queuing;
1408
1409 if (sdev == NULL)
1410 return;
1411
1412 dev = scsi_transport_device_data(sdev);
1413
1414 if (dev == NULL)
1415 return;
1416 was_queuing = dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED);
1417 switch (alg) {
1418 default:
1419 case AHD_QUEUE_NONE:
1420 now_queuing = 0;
1421 break;
1422 case AHD_QUEUE_BASIC:
1423 now_queuing = AHD_DEV_Q_BASIC;
1424 break;
1425 case AHD_QUEUE_TAGGED:
1426 now_queuing = AHD_DEV_Q_TAGGED;
1427 break;
1428 }
1429 if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) == 0
1430 && (was_queuing != now_queuing)
1431 && (dev->active != 0)) {
1432 dev->flags |= AHD_DEV_FREEZE_TIL_EMPTY;
1433 dev->qfrozen++;
1434 }
1435
1436 dev->flags &= ~(AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED|AHD_DEV_PERIODIC_OTAG);
1437 if (now_queuing) {
1438 u_int usertags;
1439
1440 usertags = ahd_linux_user_tagdepth(ahd, devinfo);
1441 if (!was_queuing) {
1442
1443
1444
1445
1446
1447 dev->maxtags = usertags;
1448 dev->openings = dev->maxtags - dev->active;
1449 }
1450 if (dev->maxtags == 0) {
1451
1452
1453
1454 dev->openings = 1;
1455 } else if (alg == AHD_QUEUE_TAGGED) {
1456 dev->flags |= AHD_DEV_Q_TAGGED;
1457 if (aic79xx_periodic_otag != 0)
1458 dev->flags |= AHD_DEV_PERIODIC_OTAG;
1459 } else
1460 dev->flags |= AHD_DEV_Q_BASIC;
1461 } else {
1462
1463 dev->maxtags = 0;
1464 dev->openings = 1 - dev->active;
1465 }
1466
1467 switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) {
1468 case AHD_DEV_Q_BASIC:
1469 case AHD_DEV_Q_TAGGED:
1470 scsi_change_queue_depth(sdev,
1471 dev->openings + dev->active);
1472 break;
1473 default:
1474
1475
1476
1477
1478
1479
1480 scsi_change_queue_depth(sdev, 1);
1481 break;
1482 }
1483 }
1484
1485 int
1486 ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel,
1487 int lun, u_int tag, role_t role, uint32_t status)
1488 {
1489 return 0;
1490 }
1491
1492 static u_int
1493 ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
1494 {
1495 static int warned_user;
1496 u_int tags;
1497
1498 tags = 0;
1499 if ((ahd->user_discenable & devinfo->target_mask) != 0) {
1500 if (ahd->unit >= ARRAY_SIZE(aic79xx_tag_info)) {
1501
1502 if (warned_user == 0) {
1503 printk(KERN_WARNING
1504 "aic79xx: WARNING: Insufficient tag_info instances\n"
1505 "aic79xx: for installed controllers. Using defaults\n"
1506 "aic79xx: Please update the aic79xx_tag_info array in\n"
1507 "aic79xx: the aic79xx_osm.c source file.\n");
1508 warned_user++;
1509 }
1510 tags = AHD_MAX_QUEUE;
1511 } else {
1512 adapter_tag_info_t *tag_info;
1513
1514 tag_info = &aic79xx_tag_info[ahd->unit];
1515 tags = tag_info->tag_commands[devinfo->target_offset];
1516 if (tags > AHD_MAX_QUEUE)
1517 tags = AHD_MAX_QUEUE;
1518 }
1519 }
1520 return (tags);
1521 }
1522
1523
1524
1525
1526 static void
1527 ahd_linux_device_queue_depth(struct scsi_device *sdev)
1528 {
1529 struct ahd_devinfo devinfo;
1530 u_int tags;
1531 struct ahd_softc *ahd = *((struct ahd_softc **)sdev->host->hostdata);
1532
1533 ahd_compile_devinfo(&devinfo,
1534 ahd->our_id,
1535 sdev->sdev_target->id, sdev->lun,
1536 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1537 ROLE_INITIATOR);
1538 tags = ahd_linux_user_tagdepth(ahd, &devinfo);
1539 if (tags != 0 && sdev->tagged_supported != 0) {
1540
1541 ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_TAGGED);
1542 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1543 devinfo.lun, AC_TRANSFER_NEG);
1544 ahd_print_devinfo(ahd, &devinfo);
1545 printk("Tagged Queuing enabled. Depth %d\n", tags);
1546 } else {
1547 ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE);
1548 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1549 devinfo.lun, AC_TRANSFER_NEG);
1550 }
1551 }
1552
1553 static int
1554 ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
1555 struct scsi_cmnd *cmd)
1556 {
1557 struct scb *scb;
1558 struct hardware_scb *hscb;
1559 struct ahd_initiator_tinfo *tinfo;
1560 struct ahd_tmode_tstate *tstate;
1561 u_int col_idx;
1562 uint16_t mask;
1563 unsigned long flags;
1564 int nseg;
1565
1566 nseg = scsi_dma_map(cmd);
1567 if (nseg < 0)
1568 return SCSI_MLQUEUE_HOST_BUSY;
1569
1570 ahd_lock(ahd, &flags);
1571
1572
1573
1574
1575 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
1576 cmd->device->id, &tstate);
1577 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0
1578 || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
1579 col_idx = AHD_NEVER_COL_IDX;
1580 } else {
1581 col_idx = AHD_BUILD_COL_IDX(cmd->device->id,
1582 cmd->device->lun);
1583 }
1584 if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
1585 ahd->flags |= AHD_RESOURCE_SHORTAGE;
1586 ahd_unlock(ahd, &flags);
1587 scsi_dma_unmap(cmd);
1588 return SCSI_MLQUEUE_HOST_BUSY;
1589 }
1590
1591 scb->io_ctx = cmd;
1592 scb->platform_data->dev = dev;
1593 hscb = scb->hscb;
1594 cmd->host_scribble = (char *)scb;
1595
1596
1597
1598
1599 hscb->control = 0;
1600 hscb->scsiid = BUILD_SCSIID(ahd, cmd);
1601 hscb->lun = cmd->device->lun;
1602 scb->hscb->task_management = 0;
1603 mask = SCB_GET_TARGET_MASK(ahd, scb);
1604
1605 if ((ahd->user_discenable & mask) != 0)
1606 hscb->control |= DISCENB;
1607
1608 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0)
1609 scb->flags |= SCB_PACKETIZED;
1610
1611 if ((tstate->auto_negotiate & mask) != 0) {
1612 scb->flags |= SCB_AUTO_NEGOTIATE;
1613 scb->hscb->control |= MK_MESSAGE;
1614 }
1615
1616 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
1617 if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH
1618 && (dev->flags & AHD_DEV_Q_TAGGED) != 0) {
1619 hscb->control |= MSG_ORDERED_TASK;
1620 dev->commands_since_idle_or_otag = 0;
1621 } else {
1622 hscb->control |= MSG_SIMPLE_TASK;
1623 }
1624 }
1625
1626 hscb->cdb_len = cmd->cmd_len;
1627 memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len);
1628
1629 scb->platform_data->xfer_len = 0;
1630 ahd_set_residual(scb, 0);
1631 ahd_set_sense_residual(scb, 0);
1632 scb->sg_count = 0;
1633
1634 if (nseg > 0) {
1635 void *sg = scb->sg_list;
1636 struct scatterlist *cur_seg;
1637 int i;
1638
1639 scb->platform_data->xfer_len = 0;
1640
1641 scsi_for_each_sg(cmd, cur_seg, nseg, i) {
1642 dma_addr_t addr;
1643 bus_size_t len;
1644
1645 addr = sg_dma_address(cur_seg);
1646 len = sg_dma_len(cur_seg);
1647 scb->platform_data->xfer_len += len;
1648 sg = ahd_sg_setup(ahd, scb, sg, addr, len,
1649 i == (nseg - 1));
1650 }
1651 }
1652
1653 LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
1654 dev->openings--;
1655 dev->active++;
1656 dev->commands_issued++;
1657
1658 if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0)
1659 dev->commands_since_idle_or_otag++;
1660 scb->flags |= SCB_ACTIVE;
1661 ahd_queue_scb(ahd, scb);
1662
1663 ahd_unlock(ahd, &flags);
1664
1665 return 0;
1666 }
1667
1668
1669
1670
1671 irqreturn_t
1672 ahd_linux_isr(int irq, void *dev_id)
1673 {
1674 struct ahd_softc *ahd;
1675 u_long flags;
1676 int ours;
1677
1678 ahd = (struct ahd_softc *) dev_id;
1679 ahd_lock(ahd, &flags);
1680 ours = ahd_intr(ahd);
1681 ahd_unlock(ahd, &flags);
1682 return IRQ_RETVAL(ours);
1683 }
1684
1685 void
1686 ahd_send_async(struct ahd_softc *ahd, char channel,
1687 u_int target, u_int lun, ac_code code)
1688 {
1689 switch (code) {
1690 case AC_TRANSFER_NEG:
1691 {
1692 struct scsi_target *starget;
1693 struct ahd_initiator_tinfo *tinfo;
1694 struct ahd_tmode_tstate *tstate;
1695 unsigned int target_ppr_options;
1696
1697 BUG_ON(target == CAM_TARGET_WILDCARD);
1698
1699 tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
1700 target, &tstate);
1701
1702
1703
1704
1705
1706 if (tinfo->curr.period != tinfo->goal.period
1707 || tinfo->curr.width != tinfo->goal.width
1708 || tinfo->curr.offset != tinfo->goal.offset
1709 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
1710 if (bootverbose == 0)
1711 break;
1712
1713
1714
1715
1716
1717 starget = ahd->platform_data->starget[target];
1718 if (starget == NULL)
1719 break;
1720
1721 target_ppr_options =
1722 (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
1723 + (spi_qas(starget) ? MSG_EXT_PPR_QAS_REQ : 0)
1724 + (spi_iu(starget) ? MSG_EXT_PPR_IU_REQ : 0)
1725 + (spi_rd_strm(starget) ? MSG_EXT_PPR_RD_STRM : 0)
1726 + (spi_pcomp_en(starget) ? MSG_EXT_PPR_PCOMP_EN : 0)
1727 + (spi_rti(starget) ? MSG_EXT_PPR_RTI : 0)
1728 + (spi_wr_flow(starget) ? MSG_EXT_PPR_WR_FLOW : 0)
1729 + (spi_hold_mcs(starget) ? MSG_EXT_PPR_HOLD_MCS : 0);
1730
1731 if (tinfo->curr.period == spi_period(starget)
1732 && tinfo->curr.width == spi_width(starget)
1733 && tinfo->curr.offset == spi_offset(starget)
1734 && tinfo->curr.ppr_options == target_ppr_options)
1735 if (bootverbose == 0)
1736 break;
1737
1738 spi_period(starget) = tinfo->curr.period;
1739 spi_width(starget) = tinfo->curr.width;
1740 spi_offset(starget) = tinfo->curr.offset;
1741 spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
1742 spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
1743 spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
1744 spi_rd_strm(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_RD_STRM ? 1 : 0;
1745 spi_pcomp_en(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_PCOMP_EN ? 1 : 0;
1746 spi_rti(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_RTI ? 1 : 0;
1747 spi_wr_flow(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_WR_FLOW ? 1 : 0;
1748 spi_hold_mcs(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_HOLD_MCS ? 1 : 0;
1749 spi_display_xfer_agreement(starget);
1750 break;
1751 }
1752 case AC_SENT_BDR:
1753 {
1754 WARN_ON(lun != CAM_LUN_WILDCARD);
1755 scsi_report_device_reset(ahd->platform_data->host,
1756 channel - 'A', target);
1757 break;
1758 }
1759 case AC_BUS_RESET:
1760 if (ahd->platform_data->host != NULL) {
1761 scsi_report_bus_reset(ahd->platform_data->host,
1762 channel - 'A');
1763 }
1764 break;
1765 default:
1766 panic("ahd_send_async: Unexpected async event");
1767 }
1768 }
1769
1770
1771
1772
1773 void
1774 ahd_done(struct ahd_softc *ahd, struct scb *scb)
1775 {
1776 struct scsi_cmnd *cmd;
1777 struct ahd_linux_device *dev;
1778
1779 if ((scb->flags & SCB_ACTIVE) == 0) {
1780 printk("SCB %d done'd twice\n", SCB_GET_TAG(scb));
1781 ahd_dump_card_state(ahd);
1782 panic("Stopping for safety");
1783 }
1784 LIST_REMOVE(scb, pending_links);
1785 cmd = scb->io_ctx;
1786 dev = scb->platform_data->dev;
1787 dev->active--;
1788 dev->openings++;
1789 if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
1790 cmd->result &= ~(CAM_DEV_QFRZN << 16);
1791 dev->qfrozen--;
1792 }
1793 ahd_linux_unmap_scb(ahd, scb);
1794
1795
1796
1797
1798
1799
1800
1801 cmd->sense_buffer[0] = 0;
1802 if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) {
1803 uint32_t amount_xferred;
1804
1805 amount_xferred =
1806 ahd_get_transfer_length(scb) - ahd_get_residual(scb);
1807 if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
1808 #ifdef AHD_DEBUG
1809 if ((ahd_debug & AHD_SHOW_MISC) != 0) {
1810 ahd_print_path(ahd, scb);
1811 printk("Set CAM_UNCOR_PARITY\n");
1812 }
1813 #endif
1814 ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
1815 #ifdef AHD_REPORT_UNDERFLOWS
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825 } else if (amount_xferred < scb->io_ctx->underflow) {
1826 u_int i;
1827
1828 ahd_print_path(ahd, scb);
1829 printk("CDB:");
1830 for (i = 0; i < scb->io_ctx->cmd_len; i++)
1831 printk(" 0x%x", scb->io_ctx->cmnd[i]);
1832 printk("\n");
1833 ahd_print_path(ahd, scb);
1834 printk("Saw underflow (%ld of %ld bytes). "
1835 "Treated as error\n",
1836 ahd_get_residual(scb),
1837 ahd_get_transfer_length(scb));
1838 ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1839 #endif
1840 } else {
1841 ahd_set_transaction_status(scb, CAM_REQ_CMP);
1842 }
1843 } else if (ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
1844 ahd_linux_handle_scsi_status(ahd, cmd->device, scb);
1845 }
1846
1847 if (dev->openings == 1
1848 && ahd_get_transaction_status(scb) == CAM_REQ_CMP
1849 && ahd_get_scsi_status(scb) != SCSI_STATUS_QUEUE_FULL)
1850 dev->tag_success_count++;
1851
1852
1853
1854
1855
1856
1857 if ((dev->openings + dev->active) < dev->maxtags
1858 && dev->tag_success_count > AHD_TAG_SUCCESS_INTERVAL) {
1859 dev->tag_success_count = 0;
1860 dev->openings++;
1861 }
1862
1863 if (dev->active == 0)
1864 dev->commands_since_idle_or_otag = 0;
1865
1866 if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
1867 printk("Recovery SCB completes\n");
1868 if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
1869 || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
1870 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
1871
1872 if (ahd->platform_data->eh_done)
1873 complete(ahd->platform_data->eh_done);
1874 }
1875
1876 ahd_free_scb(ahd, scb);
1877 ahd_linux_queue_cmd_complete(ahd, cmd);
1878 }
1879
1880 static void
1881 ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
1882 struct scsi_device *sdev, struct scb *scb)
1883 {
1884 struct ahd_devinfo devinfo;
1885 struct ahd_linux_device *dev = scsi_transport_device_data(sdev);
1886
1887 ahd_compile_devinfo(&devinfo,
1888 ahd->our_id,
1889 sdev->sdev_target->id, sdev->lun,
1890 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1891 ROLE_INITIATOR);
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903 switch (ahd_get_scsi_status(scb)) {
1904 default:
1905 break;
1906 case SCSI_STATUS_CHECK_COND:
1907 case SCSI_STATUS_CMD_TERMINATED:
1908 {
1909 struct scsi_cmnd *cmd;
1910
1911
1912
1913
1914
1915 cmd = scb->io_ctx;
1916 if ((scb->flags & (SCB_SENSE|SCB_PKT_SENSE)) != 0) {
1917 struct scsi_status_iu_header *siu;
1918 u_int sense_size;
1919 u_int sense_offset;
1920
1921 if (scb->flags & SCB_SENSE) {
1922 sense_size = min(sizeof(struct scsi_sense_data)
1923 - ahd_get_sense_residual(scb),
1924 (u_long)SCSI_SENSE_BUFFERSIZE);
1925 sense_offset = 0;
1926 } else {
1927
1928
1929
1930
1931 siu = (struct scsi_status_iu_header *)
1932 scb->sense_data;
1933 sense_size = min_t(size_t,
1934 scsi_4btoul(siu->sense_length),
1935 SCSI_SENSE_BUFFERSIZE);
1936 sense_offset = SIU_SENSE_OFFSET(siu);
1937 }
1938
1939 memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
1940 memcpy(cmd->sense_buffer,
1941 ahd_get_sense_buf(ahd, scb)
1942 + sense_offset, sense_size);
1943 cmd->result |= (DRIVER_SENSE << 24);
1944
1945 #ifdef AHD_DEBUG
1946 if (ahd_debug & AHD_SHOW_SENSE) {
1947 int i;
1948
1949 printk("Copied %d bytes of sense data at %d:",
1950 sense_size, sense_offset);
1951 for (i = 0; i < sense_size; i++) {
1952 if ((i & 0xF) == 0)
1953 printk("\n");
1954 printk("0x%x ", cmd->sense_buffer[i]);
1955 }
1956 printk("\n");
1957 }
1958 #endif
1959 }
1960 break;
1961 }
1962 case SCSI_STATUS_QUEUE_FULL:
1963
1964
1965
1966
1967
1968
1969
1970
1971 dev->tag_success_count = 0;
1972 if (dev->active != 0) {
1973
1974
1975
1976
1977 dev->openings = 0;
1978 #ifdef AHD_DEBUG
1979 if ((ahd_debug & AHD_SHOW_QFULL) != 0) {
1980 ahd_print_path(ahd, scb);
1981 printk("Dropping tag count to %d\n",
1982 dev->active);
1983 }
1984 #endif
1985 if (dev->active == dev->tags_on_last_queuefull) {
1986
1987 dev->last_queuefull_same_count++;
1988
1989
1990
1991
1992
1993
1994
1995
1996 if (dev->last_queuefull_same_count
1997 == AHD_LOCK_TAGS_COUNT) {
1998 dev->maxtags = dev->active;
1999 ahd_print_path(ahd, scb);
2000 printk("Locking max tag count at %d\n",
2001 dev->active);
2002 }
2003 } else {
2004 dev->tags_on_last_queuefull = dev->active;
2005 dev->last_queuefull_same_count = 0;
2006 }
2007 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
2008 ahd_set_scsi_status(scb, SCSI_STATUS_OK);
2009 ahd_platform_set_tags(ahd, sdev, &devinfo,
2010 (dev->flags & AHD_DEV_Q_BASIC)
2011 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
2012 break;
2013 }
2014
2015
2016
2017
2018 dev->openings = 1;
2019 ahd_platform_set_tags(ahd, sdev, &devinfo,
2020 (dev->flags & AHD_DEV_Q_BASIC)
2021 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
2022 ahd_set_scsi_status(scb, SCSI_STATUS_BUSY);
2023 }
2024 }
2025
2026 static void
2027 ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
2028 {
2029 int status;
2030 int new_status = DID_OK;
2031 int do_fallback = 0;
2032 int scsi_status;
2033
2034
2035
2036
2037
2038
2039
2040
2041 status = ahd_cmd_get_transaction_status(cmd);
2042 switch (status) {
2043 case CAM_REQ_INPROG:
2044 case CAM_REQ_CMP:
2045 new_status = DID_OK;
2046 break;
2047 case CAM_AUTOSENSE_FAIL:
2048 new_status = DID_ERROR;
2049
2050 case CAM_SCSI_STATUS_ERROR:
2051 scsi_status = ahd_cmd_get_scsi_status(cmd);
2052
2053 switch(scsi_status) {
2054 case SCSI_STATUS_CMD_TERMINATED:
2055 case SCSI_STATUS_CHECK_COND:
2056 if ((cmd->result >> 24) != DRIVER_SENSE) {
2057 do_fallback = 1;
2058 } else {
2059 struct scsi_sense_data *sense;
2060
2061 sense = (struct scsi_sense_data *)
2062 cmd->sense_buffer;
2063 if (sense->extra_len >= 5 &&
2064 (sense->add_sense_code == 0x47
2065 || sense->add_sense_code == 0x48))
2066 do_fallback = 1;
2067 }
2068 break;
2069 default:
2070 break;
2071 }
2072 break;
2073 case CAM_REQ_ABORTED:
2074 new_status = DID_ABORT;
2075 break;
2076 case CAM_BUSY:
2077 new_status = DID_BUS_BUSY;
2078 break;
2079 case CAM_REQ_INVALID:
2080 case CAM_PATH_INVALID:
2081 new_status = DID_BAD_TARGET;
2082 break;
2083 case CAM_SEL_TIMEOUT:
2084 new_status = DID_NO_CONNECT;
2085 break;
2086 case CAM_SCSI_BUS_RESET:
2087 case CAM_BDR_SENT:
2088 new_status = DID_RESET;
2089 break;
2090 case CAM_UNCOR_PARITY:
2091 new_status = DID_PARITY;
2092 do_fallback = 1;
2093 break;
2094 case CAM_CMD_TIMEOUT:
2095 new_status = DID_TIME_OUT;
2096 do_fallback = 1;
2097 break;
2098 case CAM_REQ_CMP_ERR:
2099 case CAM_UNEXP_BUSFREE:
2100 case CAM_DATA_RUN_ERR:
2101 new_status = DID_ERROR;
2102 do_fallback = 1;
2103 break;
2104 case CAM_UA_ABORT:
2105 case CAM_NO_HBA:
2106 case CAM_SEQUENCE_FAIL:
2107 case CAM_CCB_LEN_ERR:
2108 case CAM_PROVIDE_FAIL:
2109 case CAM_REQ_TERMIO:
2110 case CAM_UNREC_HBA_ERROR:
2111 case CAM_REQ_TOO_BIG:
2112 new_status = DID_ERROR;
2113 break;
2114 case CAM_REQUEUE_REQ:
2115 new_status = DID_REQUEUE;
2116 break;
2117 default:
2118
2119 new_status = DID_ERROR;
2120 break;
2121 }
2122
2123 if (do_fallback) {
2124 printk("%s: device overrun (status %x) on %d:%d:%d\n",
2125 ahd_name(ahd), status, cmd->device->channel,
2126 cmd->device->id, (u8)cmd->device->lun);
2127 }
2128
2129 ahd_cmd_set_transaction_status(cmd, new_status);
2130
2131 cmd->scsi_done(cmd);
2132 }
2133
2134 static void
2135 ahd_freeze_simq(struct ahd_softc *ahd)
2136 {
2137 scsi_block_requests(ahd->platform_data->host);
2138 }
2139
2140 static void
2141 ahd_release_simq(struct ahd_softc *ahd)
2142 {
2143 scsi_unblock_requests(ahd->platform_data->host);
2144 }
2145
2146 static int
2147 ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
2148 {
2149 struct ahd_softc *ahd;
2150 struct ahd_linux_device *dev;
2151 struct scb *pending_scb;
2152 u_int saved_scbptr;
2153 u_int active_scbptr;
2154 u_int last_phase;
2155 u_int saved_scsiid;
2156 u_int cdb_byte;
2157 int retval;
2158 int was_paused;
2159 int paused;
2160 int wait;
2161 int disconnected;
2162 ahd_mode_state saved_modes;
2163 unsigned long flags;
2164
2165 pending_scb = NULL;
2166 paused = FALSE;
2167 wait = FALSE;
2168 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
2169
2170 scmd_printk(KERN_INFO, cmd,
2171 "Attempting to queue an ABORT message:");
2172
2173 printk("CDB:");
2174 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
2175 printk(" 0x%x", cmd->cmnd[cdb_byte]);
2176 printk("\n");
2177
2178 ahd_lock(ahd, &flags);
2179
2180
2181
2182
2183
2184
2185
2186
2187 dev = scsi_transport_device_data(cmd->device);
2188
2189 if (dev == NULL) {
2190
2191
2192
2193
2194 scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
2195 retval = SUCCESS;
2196 goto no_cmd;
2197 }
2198
2199
2200
2201
2202 LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
2203 if (pending_scb->io_ctx == cmd)
2204 break;
2205 }
2206
2207 if (pending_scb == NULL) {
2208 scmd_printk(KERN_INFO, cmd, "Command not found\n");
2209 goto no_cmd;
2210 }
2211
2212 if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
2213
2214
2215
2216 retval = FAILED;
2217 goto done;
2218 }
2219
2220
2221
2222
2223
2224
2225
2226 was_paused = ahd_is_paused(ahd);
2227 ahd_pause_and_flushwork(ahd);
2228 paused = TRUE;
2229
2230 if ((pending_scb->flags & SCB_ACTIVE) == 0) {
2231 scmd_printk(KERN_INFO, cmd, "Command already completed\n");
2232 goto no_cmd;
2233 }
2234
2235 printk("%s: At time of recovery, card was %spaused\n",
2236 ahd_name(ahd), was_paused ? "" : "not ");
2237 ahd_dump_card_state(ahd);
2238
2239 disconnected = TRUE;
2240 if (ahd_search_qinfifo(ahd, cmd->device->id,
2241 cmd->device->channel + 'A',
2242 cmd->device->lun,
2243 pending_scb->hscb->tag,
2244 ROLE_INITIATOR, CAM_REQ_ABORTED,
2245 SEARCH_COMPLETE) > 0) {
2246 printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
2247 ahd_name(ahd), cmd->device->channel,
2248 cmd->device->id, (u8)cmd->device->lun);
2249 retval = SUCCESS;
2250 goto done;
2251 }
2252
2253 saved_modes = ahd_save_modes(ahd);
2254 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2255 last_phase = ahd_inb(ahd, LASTPHASE);
2256 saved_scbptr = ahd_get_scbptr(ahd);
2257 active_scbptr = saved_scbptr;
2258 if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
2259 struct scb *bus_scb;
2260
2261 bus_scb = ahd_lookup_scb(ahd, active_scbptr);
2262 if (bus_scb == pending_scb)
2263 disconnected = FALSE;
2264 }
2265
2266
2267
2268
2269
2270
2271 saved_scsiid = ahd_inb(ahd, SAVED_SCSIID);
2272 if (last_phase != P_BUSFREE
2273 && SCB_GET_TAG(pending_scb) == active_scbptr) {
2274
2275
2276
2277
2278
2279 pending_scb = ahd_lookup_scb(ahd, active_scbptr);
2280 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
2281 ahd_outb(ahd, MSG_OUT, HOST_MSG);
2282 ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
2283 scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
2284 wait = TRUE;
2285 } else if (disconnected) {
2286
2287
2288
2289
2290
2291 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
2292 ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));
2293 pending_scb->hscb->cdb_len = 0;
2294 pending_scb->hscb->task_attribute = 0;
2295 pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK;
2296
2297 if ((pending_scb->flags & SCB_PACKETIZED) != 0) {
2298
2299
2300
2301
2302
2303
2304
2305 ahd_outb(ahd, SCB_TASK_MANAGEMENT,
2306 pending_scb->hscb->task_management);
2307 } else {
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317 pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
2318
2319
2320
2321
2322
2323
2324
2325 ahd_outb(ahd, SCB_CONTROL,
2326 ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE);
2327 }
2328
2329
2330
2331
2332
2333
2334 ahd_search_qinfifo(ahd, cmd->device->id,
2335 cmd->device->channel + 'A', cmd->device->lun,
2336 SCB_LIST_NULL, ROLE_INITIATOR,
2337 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
2338 ahd_qinfifo_requeue_tail(ahd, pending_scb);
2339 ahd_set_scbptr(ahd, saved_scbptr);
2340 ahd_print_path(ahd, pending_scb);
2341 printk("Device is disconnected, re-queuing SCB\n");
2342 wait = TRUE;
2343 } else {
2344 scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
2345 retval = FAILED;
2346 goto done;
2347 }
2348
2349 no_cmd:
2350
2351
2352
2353
2354
2355
2356 retval = SUCCESS;
2357 done:
2358 if (paused)
2359 ahd_unpause(ahd);
2360 if (wait) {
2361 DECLARE_COMPLETION_ONSTACK(done);
2362
2363 ahd->platform_data->eh_done = &done;
2364 ahd_unlock(ahd, &flags);
2365
2366 printk("%s: Recovery code sleeping\n", ahd_name(ahd));
2367 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
2368 ahd_lock(ahd, &flags);
2369 ahd->platform_data->eh_done = NULL;
2370 ahd_unlock(ahd, &flags);
2371 printk("%s: Timer Expired (active %d)\n",
2372 ahd_name(ahd), dev->active);
2373 retval = FAILED;
2374 }
2375 printk("Recovery code awake\n");
2376 } else
2377 ahd_unlock(ahd, &flags);
2378
2379 if (retval != SUCCESS)
2380 printk("%s: Command abort returning 0x%x\n",
2381 ahd_name(ahd), retval);
2382
2383 return retval;
2384 }
2385
2386 static void ahd_linux_set_width(struct scsi_target *starget, int width)
2387 {
2388 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2389 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2390 struct ahd_devinfo devinfo;
2391 unsigned long flags;
2392
2393 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2394 starget->channel + 'A', ROLE_INITIATOR);
2395 ahd_lock(ahd, &flags);
2396 ahd_set_width(ahd, &devinfo, width, AHD_TRANS_GOAL, FALSE);
2397 ahd_unlock(ahd, &flags);
2398 }
2399
2400 static void ahd_linux_set_period(struct scsi_target *starget, int period)
2401 {
2402 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2403 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2404 struct ahd_tmode_tstate *tstate;
2405 struct ahd_initiator_tinfo *tinfo
2406 = ahd_fetch_transinfo(ahd,
2407 starget->channel + 'A',
2408 shost->this_id, starget->id, &tstate);
2409 struct ahd_devinfo devinfo;
2410 unsigned int ppr_options = tinfo->goal.ppr_options;
2411 unsigned int dt;
2412 unsigned long flags;
2413 unsigned long offset = tinfo->goal.offset;
2414
2415 #ifdef AHD_DEBUG
2416 if ((ahd_debug & AHD_SHOW_DV) != 0)
2417 printk("%s: set period to %d\n", ahd_name(ahd), period);
2418 #endif
2419 if (offset == 0)
2420 offset = MAX_OFFSET;
2421
2422 if (period < 8)
2423 period = 8;
2424 if (period < 10) {
2425 if (spi_max_width(starget)) {
2426 ppr_options |= MSG_EXT_PPR_DT_REQ;
2427 if (period == 8)
2428 ppr_options |= MSG_EXT_PPR_IU_REQ;
2429 } else
2430 period = 10;
2431 }
2432
2433 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2434
2435 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2436 starget->channel + 'A', ROLE_INITIATOR);
2437
2438
2439 if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) {
2440 if (spi_width(starget) == 0)
2441 ppr_options &= MSG_EXT_PPR_QAS_REQ;
2442 }
2443
2444 ahd_find_syncrate(ahd, &period, &ppr_options,
2445 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2446
2447 ahd_lock(ahd, &flags);
2448 ahd_set_syncrate(ahd, &devinfo, period, offset,
2449 ppr_options, AHD_TRANS_GOAL, FALSE);
2450 ahd_unlock(ahd, &flags);
2451 }
2452
2453 static void ahd_linux_set_offset(struct scsi_target *starget, int offset)
2454 {
2455 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2456 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2457 struct ahd_tmode_tstate *tstate;
2458 struct ahd_initiator_tinfo *tinfo
2459 = ahd_fetch_transinfo(ahd,
2460 starget->channel + 'A',
2461 shost->this_id, starget->id, &tstate);
2462 struct ahd_devinfo devinfo;
2463 unsigned int ppr_options = 0;
2464 unsigned int period = 0;
2465 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2466 unsigned long flags;
2467
2468 #ifdef AHD_DEBUG
2469 if ((ahd_debug & AHD_SHOW_DV) != 0)
2470 printk("%s: set offset to %d\n", ahd_name(ahd), offset);
2471 #endif
2472
2473 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2474 starget->channel + 'A', ROLE_INITIATOR);
2475 if (offset != 0) {
2476 period = tinfo->goal.period;
2477 ppr_options = tinfo->goal.ppr_options;
2478 ahd_find_syncrate(ahd, &period, &ppr_options,
2479 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2480 }
2481
2482 ahd_lock(ahd, &flags);
2483 ahd_set_syncrate(ahd, &devinfo, period, offset, ppr_options,
2484 AHD_TRANS_GOAL, FALSE);
2485 ahd_unlock(ahd, &flags);
2486 }
2487
2488 static void ahd_linux_set_dt(struct scsi_target *starget, int dt)
2489 {
2490 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2491 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2492 struct ahd_tmode_tstate *tstate;
2493 struct ahd_initiator_tinfo *tinfo
2494 = ahd_fetch_transinfo(ahd,
2495 starget->channel + 'A',
2496 shost->this_id, starget->id, &tstate);
2497 struct ahd_devinfo devinfo;
2498 unsigned int ppr_options = tinfo->goal.ppr_options
2499 & ~MSG_EXT_PPR_DT_REQ;
2500 unsigned int period = tinfo->goal.period;
2501 unsigned int width = tinfo->goal.width;
2502 unsigned long flags;
2503
2504 #ifdef AHD_DEBUG
2505 if ((ahd_debug & AHD_SHOW_DV) != 0)
2506 printk("%s: %s DT\n", ahd_name(ahd),
2507 dt ? "enabling" : "disabling");
2508 #endif
2509 if (dt && spi_max_width(starget)) {
2510 ppr_options |= MSG_EXT_PPR_DT_REQ;
2511 if (!width)
2512 ahd_linux_set_width(starget, 1);
2513 } else {
2514 if (period <= 9)
2515 period = 10;
2516
2517 ppr_options &= ~MSG_EXT_PPR_IU_REQ;
2518 }
2519 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2520 starget->channel + 'A', ROLE_INITIATOR);
2521 ahd_find_syncrate(ahd, &period, &ppr_options,
2522 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2523
2524 ahd_lock(ahd, &flags);
2525 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2526 ppr_options, AHD_TRANS_GOAL, FALSE);
2527 ahd_unlock(ahd, &flags);
2528 }
2529
2530 static void ahd_linux_set_qas(struct scsi_target *starget, int qas)
2531 {
2532 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2533 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2534 struct ahd_tmode_tstate *tstate;
2535 struct ahd_initiator_tinfo *tinfo
2536 = ahd_fetch_transinfo(ahd,
2537 starget->channel + 'A',
2538 shost->this_id, starget->id, &tstate);
2539 struct ahd_devinfo devinfo;
2540 unsigned int ppr_options = tinfo->goal.ppr_options
2541 & ~MSG_EXT_PPR_QAS_REQ;
2542 unsigned int period = tinfo->goal.period;
2543 unsigned int dt;
2544 unsigned long flags;
2545
2546 #ifdef AHD_DEBUG
2547 if ((ahd_debug & AHD_SHOW_DV) != 0)
2548 printk("%s: %s QAS\n", ahd_name(ahd),
2549 qas ? "enabling" : "disabling");
2550 #endif
2551
2552 if (qas) {
2553 ppr_options |= MSG_EXT_PPR_QAS_REQ;
2554 }
2555
2556 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2557
2558 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2559 starget->channel + 'A', ROLE_INITIATOR);
2560 ahd_find_syncrate(ahd, &period, &ppr_options,
2561 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2562
2563 ahd_lock(ahd, &flags);
2564 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2565 ppr_options, AHD_TRANS_GOAL, FALSE);
2566 ahd_unlock(ahd, &flags);
2567 }
2568
2569 static void ahd_linux_set_iu(struct scsi_target *starget, int iu)
2570 {
2571 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2572 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2573 struct ahd_tmode_tstate *tstate;
2574 struct ahd_initiator_tinfo *tinfo
2575 = ahd_fetch_transinfo(ahd,
2576 starget->channel + 'A',
2577 shost->this_id, starget->id, &tstate);
2578 struct ahd_devinfo devinfo;
2579 unsigned int ppr_options = tinfo->goal.ppr_options
2580 & ~MSG_EXT_PPR_IU_REQ;
2581 unsigned int period = tinfo->goal.period;
2582 unsigned int dt;
2583 unsigned long flags;
2584
2585 #ifdef AHD_DEBUG
2586 if ((ahd_debug & AHD_SHOW_DV) != 0)
2587 printk("%s: %s IU\n", ahd_name(ahd),
2588 iu ? "enabling" : "disabling");
2589 #endif
2590
2591 if (iu && spi_max_width(starget)) {
2592 ppr_options |= MSG_EXT_PPR_IU_REQ;
2593 ppr_options |= MSG_EXT_PPR_DT_REQ;
2594 }
2595
2596 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2597
2598 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2599 starget->channel + 'A', ROLE_INITIATOR);
2600 ahd_find_syncrate(ahd, &period, &ppr_options,
2601 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2602
2603 ahd_lock(ahd, &flags);
2604 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2605 ppr_options, AHD_TRANS_GOAL, FALSE);
2606 ahd_unlock(ahd, &flags);
2607 }
2608
2609 static void ahd_linux_set_rd_strm(struct scsi_target *starget, int rdstrm)
2610 {
2611 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2612 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2613 struct ahd_tmode_tstate *tstate;
2614 struct ahd_initiator_tinfo *tinfo
2615 = ahd_fetch_transinfo(ahd,
2616 starget->channel + 'A',
2617 shost->this_id, starget->id, &tstate);
2618 struct ahd_devinfo devinfo;
2619 unsigned int ppr_options = tinfo->goal.ppr_options
2620 & ~MSG_EXT_PPR_RD_STRM;
2621 unsigned int period = tinfo->goal.period;
2622 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2623 unsigned long flags;
2624
2625 #ifdef AHD_DEBUG
2626 if ((ahd_debug & AHD_SHOW_DV) != 0)
2627 printk("%s: %s Read Streaming\n", ahd_name(ahd),
2628 rdstrm ? "enabling" : "disabling");
2629 #endif
2630
2631 if (rdstrm && spi_max_width(starget))
2632 ppr_options |= MSG_EXT_PPR_RD_STRM;
2633
2634 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2635 starget->channel + 'A', ROLE_INITIATOR);
2636 ahd_find_syncrate(ahd, &period, &ppr_options,
2637 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2638
2639 ahd_lock(ahd, &flags);
2640 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2641 ppr_options, AHD_TRANS_GOAL, FALSE);
2642 ahd_unlock(ahd, &flags);
2643 }
2644
2645 static void ahd_linux_set_wr_flow(struct scsi_target *starget, int wrflow)
2646 {
2647 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2648 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2649 struct ahd_tmode_tstate *tstate;
2650 struct ahd_initiator_tinfo *tinfo
2651 = ahd_fetch_transinfo(ahd,
2652 starget->channel + 'A',
2653 shost->this_id, starget->id, &tstate);
2654 struct ahd_devinfo devinfo;
2655 unsigned int ppr_options = tinfo->goal.ppr_options
2656 & ~MSG_EXT_PPR_WR_FLOW;
2657 unsigned int period = tinfo->goal.period;
2658 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2659 unsigned long flags;
2660
2661 #ifdef AHD_DEBUG
2662 if ((ahd_debug & AHD_SHOW_DV) != 0)
2663 printk("%s: %s Write Flow Control\n", ahd_name(ahd),
2664 wrflow ? "enabling" : "disabling");
2665 #endif
2666
2667 if (wrflow && spi_max_width(starget))
2668 ppr_options |= MSG_EXT_PPR_WR_FLOW;
2669
2670 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2671 starget->channel + 'A', ROLE_INITIATOR);
2672 ahd_find_syncrate(ahd, &period, &ppr_options,
2673 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2674
2675 ahd_lock(ahd, &flags);
2676 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2677 ppr_options, AHD_TRANS_GOAL, FALSE);
2678 ahd_unlock(ahd, &flags);
2679 }
2680
2681 static void ahd_linux_set_rti(struct scsi_target *starget, int rti)
2682 {
2683 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2684 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2685 struct ahd_tmode_tstate *tstate;
2686 struct ahd_initiator_tinfo *tinfo
2687 = ahd_fetch_transinfo(ahd,
2688 starget->channel + 'A',
2689 shost->this_id, starget->id, &tstate);
2690 struct ahd_devinfo devinfo;
2691 unsigned int ppr_options = tinfo->goal.ppr_options
2692 & ~MSG_EXT_PPR_RTI;
2693 unsigned int period = tinfo->goal.period;
2694 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2695 unsigned long flags;
2696
2697 if ((ahd->features & AHD_RTI) == 0) {
2698 #ifdef AHD_DEBUG
2699 if ((ahd_debug & AHD_SHOW_DV) != 0)
2700 printk("%s: RTI not available\n", ahd_name(ahd));
2701 #endif
2702 return;
2703 }
2704
2705 #ifdef AHD_DEBUG
2706 if ((ahd_debug & AHD_SHOW_DV) != 0)
2707 printk("%s: %s RTI\n", ahd_name(ahd),
2708 rti ? "enabling" : "disabling");
2709 #endif
2710
2711 if (rti && spi_max_width(starget))
2712 ppr_options |= MSG_EXT_PPR_RTI;
2713
2714 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2715 starget->channel + 'A', ROLE_INITIATOR);
2716 ahd_find_syncrate(ahd, &period, &ppr_options,
2717 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2718
2719 ahd_lock(ahd, &flags);
2720 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2721 ppr_options, AHD_TRANS_GOAL, FALSE);
2722 ahd_unlock(ahd, &flags);
2723 }
2724
2725 static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp)
2726 {
2727 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2728 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2729 struct ahd_tmode_tstate *tstate;
2730 struct ahd_initiator_tinfo *tinfo
2731 = ahd_fetch_transinfo(ahd,
2732 starget->channel + 'A',
2733 shost->this_id, starget->id, &tstate);
2734 struct ahd_devinfo devinfo;
2735 unsigned int ppr_options = tinfo->goal.ppr_options
2736 & ~MSG_EXT_PPR_PCOMP_EN;
2737 unsigned int period = tinfo->goal.period;
2738 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2739 unsigned long flags;
2740
2741 #ifdef AHD_DEBUG
2742 if ((ahd_debug & AHD_SHOW_DV) != 0)
2743 printk("%s: %s Precompensation\n", ahd_name(ahd),
2744 pcomp ? "Enable" : "Disable");
2745 #endif
2746
2747 if (pcomp && spi_max_width(starget)) {
2748 uint8_t precomp;
2749
2750 if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
2751 const struct ahd_linux_iocell_opts *iocell_opts;
2752
2753 iocell_opts = &aic79xx_iocell_info[ahd->unit];
2754 precomp = iocell_opts->precomp;
2755 } else {
2756 precomp = AIC79XX_DEFAULT_PRECOMP;
2757 }
2758 ppr_options |= MSG_EXT_PPR_PCOMP_EN;
2759 AHD_SET_PRECOMP(ahd, precomp);
2760 } else {
2761 AHD_SET_PRECOMP(ahd, 0);
2762 }
2763
2764 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2765 starget->channel + 'A', ROLE_INITIATOR);
2766 ahd_find_syncrate(ahd, &period, &ppr_options,
2767 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2768
2769 ahd_lock(ahd, &flags);
2770 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2771 ppr_options, AHD_TRANS_GOAL, FALSE);
2772 ahd_unlock(ahd, &flags);
2773 }
2774
2775 static void ahd_linux_set_hold_mcs(struct scsi_target *starget, int hold)
2776 {
2777 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2778 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2779 struct ahd_tmode_tstate *tstate;
2780 struct ahd_initiator_tinfo *tinfo
2781 = ahd_fetch_transinfo(ahd,
2782 starget->channel + 'A',
2783 shost->this_id, starget->id, &tstate);
2784 struct ahd_devinfo devinfo;
2785 unsigned int ppr_options = tinfo->goal.ppr_options
2786 & ~MSG_EXT_PPR_HOLD_MCS;
2787 unsigned int period = tinfo->goal.period;
2788 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2789 unsigned long flags;
2790
2791 if (hold && spi_max_width(starget))
2792 ppr_options |= MSG_EXT_PPR_HOLD_MCS;
2793
2794 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2795 starget->channel + 'A', ROLE_INITIATOR);
2796 ahd_find_syncrate(ahd, &period, &ppr_options,
2797 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2798
2799 ahd_lock(ahd, &flags);
2800 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2801 ppr_options, AHD_TRANS_GOAL, FALSE);
2802 ahd_unlock(ahd, &flags);
2803 }
2804
2805 static void ahd_linux_get_signalling(struct Scsi_Host *shost)
2806 {
2807 struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata;
2808 unsigned long flags;
2809 u8 mode;
2810
2811 ahd_lock(ahd, &flags);
2812 ahd_pause(ahd);
2813 mode = ahd_inb(ahd, SBLKCTL);
2814 ahd_unpause(ahd);
2815 ahd_unlock(ahd, &flags);
2816
2817 if (mode & ENAB40)
2818 spi_signalling(shost) = SPI_SIGNAL_LVD;
2819 else if (mode & ENAB20)
2820 spi_signalling(shost) = SPI_SIGNAL_SE;
2821 else
2822 spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
2823 }
2824
2825 static struct spi_function_template ahd_linux_transport_functions = {
2826 .set_offset = ahd_linux_set_offset,
2827 .show_offset = 1,
2828 .set_period = ahd_linux_set_period,
2829 .show_period = 1,
2830 .set_width = ahd_linux_set_width,
2831 .show_width = 1,
2832 .set_dt = ahd_linux_set_dt,
2833 .show_dt = 1,
2834 .set_iu = ahd_linux_set_iu,
2835 .show_iu = 1,
2836 .set_qas = ahd_linux_set_qas,
2837 .show_qas = 1,
2838 .set_rd_strm = ahd_linux_set_rd_strm,
2839 .show_rd_strm = 1,
2840 .set_wr_flow = ahd_linux_set_wr_flow,
2841 .show_wr_flow = 1,
2842 .set_rti = ahd_linux_set_rti,
2843 .show_rti = 1,
2844 .set_pcomp_en = ahd_linux_set_pcomp_en,
2845 .show_pcomp_en = 1,
2846 .set_hold_mcs = ahd_linux_set_hold_mcs,
2847 .show_hold_mcs = 1,
2848 .get_signalling = ahd_linux_get_signalling,
2849 };
2850
2851 static int __init
2852 ahd_linux_init(void)
2853 {
2854 int error = 0;
2855
2856
2857
2858
2859 if (aic79xx)
2860 aic79xx_setup(aic79xx);
2861
2862 ahd_linux_transport_template =
2863 spi_attach_transport(&ahd_linux_transport_functions);
2864 if (!ahd_linux_transport_template)
2865 return -ENODEV;
2866
2867 scsi_transport_reserve_device(ahd_linux_transport_template,
2868 sizeof(struct ahd_linux_device));
2869
2870 error = ahd_linux_pci_init();
2871 if (error)
2872 spi_release_transport(ahd_linux_transport_template);
2873 return error;
2874 }
2875
2876 static void __exit
2877 ahd_linux_exit(void)
2878 {
2879 ahd_linux_pci_exit();
2880 spi_release_transport(ahd_linux_transport_template);
2881 }
2882
2883 module_init(ahd_linux_init);
2884 module_exit(ahd_linux_exit);