0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 #include "aic79xx_osm.h"
0046 #include "aic79xx_inline.h"
0047 #include <scsi/scsicam.h>
0048
0049 static struct scsi_transport_template *ahd_linux_transport_template = NULL;
0050
0051 #include <linux/init.h> /* __setup */
0052 #include <linux/mm.h> /* For fetching system memory size */
0053 #include <linux/blkdev.h> /* For block_size() */
0054 #include <linux/delay.h> /* For ssleep/msleep */
0055 #include <linux/device.h>
0056 #include <linux/slab.h>
0057
0058
0059
0060
0061 #define AHD_LINUX_ERR_THRESH 1000
0062
0063
0064
0065
0066
0067
0068
0069 #ifdef CONFIG_AIC79XX_RESET_DELAY_MS
0070 #define AIC79XX_RESET_DELAY CONFIG_AIC79XX_RESET_DELAY_MS
0071 #else
0072 #define AIC79XX_RESET_DELAY 5000
0073 #endif
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 typedef struct {
0087 uint16_t tag_commands[16];
0088 } adapter_tag_info_t;
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 #ifdef CONFIG_AIC79XX_CMDS_PER_DEVICE
0134 #define AIC79XX_CMDS_PER_DEVICE CONFIG_AIC79XX_CMDS_PER_DEVICE
0135 #else
0136 #define AIC79XX_CMDS_PER_DEVICE AHD_MAX_QUEUE
0137 #endif
0138
0139 #define AIC79XX_CONFIGED_TAG_COMMANDS { \
0140 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
0141 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
0142 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
0143 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
0144 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
0145 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
0146 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE, \
0147 AIC79XX_CMDS_PER_DEVICE, AIC79XX_CMDS_PER_DEVICE \
0148 }
0149
0150
0151
0152
0153
0154 static adapter_tag_info_t aic79xx_tag_info[] =
0155 {
0156 {AIC79XX_CONFIGED_TAG_COMMANDS},
0157 {AIC79XX_CONFIGED_TAG_COMMANDS},
0158 {AIC79XX_CONFIGED_TAG_COMMANDS},
0159 {AIC79XX_CONFIGED_TAG_COMMANDS},
0160 {AIC79XX_CONFIGED_TAG_COMMANDS},
0161 {AIC79XX_CONFIGED_TAG_COMMANDS},
0162 {AIC79XX_CONFIGED_TAG_COMMANDS},
0163 {AIC79XX_CONFIGED_TAG_COMMANDS},
0164 {AIC79XX_CONFIGED_TAG_COMMANDS},
0165 {AIC79XX_CONFIGED_TAG_COMMANDS},
0166 {AIC79XX_CONFIGED_TAG_COMMANDS},
0167 {AIC79XX_CONFIGED_TAG_COMMANDS},
0168 {AIC79XX_CONFIGED_TAG_COMMANDS},
0169 {AIC79XX_CONFIGED_TAG_COMMANDS},
0170 {AIC79XX_CONFIGED_TAG_COMMANDS},
0171 {AIC79XX_CONFIGED_TAG_COMMANDS}
0172 };
0173
0174
0175
0176
0177
0178
0179 struct ahd_linux_iocell_opts
0180 {
0181 uint8_t precomp;
0182 uint8_t slewrate;
0183 uint8_t amplitude;
0184 };
0185 #define AIC79XX_DEFAULT_PRECOMP 0xFF
0186 #define AIC79XX_DEFAULT_SLEWRATE 0xFF
0187 #define AIC79XX_DEFAULT_AMPLITUDE 0xFF
0188 #define AIC79XX_DEFAULT_IOOPTS \
0189 { \
0190 AIC79XX_DEFAULT_PRECOMP, \
0191 AIC79XX_DEFAULT_SLEWRATE, \
0192 AIC79XX_DEFAULT_AMPLITUDE \
0193 }
0194 #define AIC79XX_PRECOMP_INDEX 0
0195 #define AIC79XX_SLEWRATE_INDEX 1
0196 #define AIC79XX_AMPLITUDE_INDEX 2
0197 static const struct ahd_linux_iocell_opts aic79xx_iocell_info[] =
0198 {
0199 AIC79XX_DEFAULT_IOOPTS,
0200 AIC79XX_DEFAULT_IOOPTS,
0201 AIC79XX_DEFAULT_IOOPTS,
0202 AIC79XX_DEFAULT_IOOPTS,
0203 AIC79XX_DEFAULT_IOOPTS,
0204 AIC79XX_DEFAULT_IOOPTS,
0205 AIC79XX_DEFAULT_IOOPTS,
0206 AIC79XX_DEFAULT_IOOPTS,
0207 AIC79XX_DEFAULT_IOOPTS,
0208 AIC79XX_DEFAULT_IOOPTS,
0209 AIC79XX_DEFAULT_IOOPTS,
0210 AIC79XX_DEFAULT_IOOPTS,
0211 AIC79XX_DEFAULT_IOOPTS,
0212 AIC79XX_DEFAULT_IOOPTS,
0213 AIC79XX_DEFAULT_IOOPTS,
0214 AIC79XX_DEFAULT_IOOPTS
0215 };
0216
0217
0218
0219
0220
0221 #define DID_UNDERFLOW DID_ERROR
0222
0223 void
0224 ahd_print_path(struct ahd_softc *ahd, struct scb *scb)
0225 {
0226 printk("(scsi%d:%c:%d:%d): ",
0227 ahd->platform_data->host->host_no,
0228 scb != NULL ? SCB_GET_CHANNEL(ahd, scb) : 'X',
0229 scb != NULL ? SCB_GET_TARGET(ahd, scb) : -1,
0230 scb != NULL ? SCB_GET_LUN(scb) : -1);
0231 }
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 static uint32_t aic79xx_no_reset;
0245
0246
0247
0248
0249
0250
0251 static uint32_t aic79xx_extended;
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267 static uint32_t aic79xx_pci_parity = ~0;
0268
0269
0270
0271
0272
0273
0274
0275 uint32_t aic79xx_allow_memio = ~0;
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 static uint32_t aic79xx_seltime;
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 static uint32_t aic79xx_periodic_otag;
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312 uint32_t aic79xx_slowcrc;
0313
0314
0315
0316
0317 static char *aic79xx = NULL;
0318
0319 MODULE_AUTHOR("Maintainer: Hannes Reinecke <hare@suse.de>");
0320 MODULE_DESCRIPTION("Adaptec AIC790X U320 SCSI Host Bus Adapter driver");
0321 MODULE_LICENSE("Dual BSD/GPL");
0322 MODULE_VERSION(AIC79XX_DRIVER_VERSION);
0323 module_param(aic79xx, charp, 0444);
0324 MODULE_PARM_DESC(aic79xx,
0325 "period-delimited options string:\n"
0326 " verbose Enable verbose/diagnostic logging\n"
0327 " allow_memio Allow device registers to be memory mapped\n"
0328 " debug Bitmask of debug values to enable\n"
0329 " no_reset Suppress initial bus resets\n"
0330 " extended Enable extended geometry on all controllers\n"
0331 " periodic_otag Send an ordered tagged transaction\n"
0332 " periodically to prevent tag starvation.\n"
0333 " This may be required by some older disk\n"
0334 " or drives/RAID arrays.\n"
0335 " tag_info:<tag_str> Set per-target tag depth\n"
0336 " global_tag_depth:<int> Global tag depth for all targets on all buses\n"
0337 " slewrate:<slewrate_list>Set the signal slew rate (0-15).\n"
0338 " precomp:<pcomp_list> Set the signal precompensation (0-7).\n"
0339 " amplitude:<int> Set the signal amplitude (0-7).\n"
0340 " seltime:<int> Selection Timeout:\n"
0341 " (0/256ms,1/128ms,2/64ms,3/32ms)\n"
0342 " slowcrc Turn on the SLOWCRC bit (Rev B only)\n"
0343 "\n"
0344 " Sample modprobe configuration file:\n"
0345 " # Enable verbose logging\n"
0346 " # Set tag depth on Controller 2/Target 2 to 10 tags\n"
0347 " # Shorten the selection timeout to 128ms\n"
0348 "\n"
0349 " options aic79xx 'aic79xx=verbose.tag_info:{{}.{}.{..10}}.seltime:1'\n"
0350 );
0351
0352 static void ahd_linux_handle_scsi_status(struct ahd_softc *,
0353 struct scsi_device *,
0354 struct scb *);
0355 static void ahd_linux_queue_cmd_complete(struct ahd_softc *ahd,
0356 struct scsi_cmnd *cmd);
0357 static int ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd);
0358 static void ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd);
0359 static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd,
0360 struct ahd_devinfo *devinfo);
0361 static void ahd_linux_device_queue_depth(struct scsi_device *);
0362 static int ahd_linux_run_command(struct ahd_softc*,
0363 struct ahd_linux_device *,
0364 struct scsi_cmnd *);
0365 static void ahd_linux_setup_tag_info_global(char *p);
0366 static int aic79xx_setup(char *c);
0367 static void ahd_freeze_simq(struct ahd_softc *ahd);
0368 static void ahd_release_simq(struct ahd_softc *ahd);
0369
0370 static int ahd_linux_unit;
0371
0372
0373
0374 void ahd_delay(long);
0375 void
0376 ahd_delay(long usec)
0377 {
0378
0379
0380
0381
0382
0383 while (usec > 0) {
0384 udelay(usec % 1024);
0385 usec -= 1024;
0386 }
0387 }
0388
0389
0390
0391 uint8_t ahd_inb(struct ahd_softc * ahd, long port);
0392 void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
0393 void ahd_outw_atomic(struct ahd_softc * ahd,
0394 long port, uint16_t val);
0395 void ahd_outsb(struct ahd_softc * ahd, long port,
0396 uint8_t *, int count);
0397 void ahd_insb(struct ahd_softc * ahd, long port,
0398 uint8_t *, int count);
0399
0400 uint8_t
0401 ahd_inb(struct ahd_softc * ahd, long port)
0402 {
0403 uint8_t x;
0404
0405 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
0406 x = readb(ahd->bshs[0].maddr + port);
0407 } else {
0408 x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
0409 }
0410 mb();
0411 return (x);
0412 }
0413
0414 #if 0
0415 static uint16_t
0416 ahd_inw_atomic(struct ahd_softc * ahd, long port)
0417 {
0418 uint8_t x;
0419
0420 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
0421 x = readw(ahd->bshs[0].maddr + port);
0422 } else {
0423 x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
0424 }
0425 mb();
0426 return (x);
0427 }
0428 #endif
0429
0430 void
0431 ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
0432 {
0433 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
0434 writeb(val, ahd->bshs[0].maddr + port);
0435 } else {
0436 outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
0437 }
0438 mb();
0439 }
0440
0441 void
0442 ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
0443 {
0444 if (ahd->tags[0] == BUS_SPACE_MEMIO) {
0445 writew(val, ahd->bshs[0].maddr + port);
0446 } else {
0447 outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
0448 }
0449 mb();
0450 }
0451
0452 void
0453 ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
0454 {
0455 int i;
0456
0457
0458
0459
0460
0461
0462 for (i = 0; i < count; i++)
0463 ahd_outb(ahd, port, *array++);
0464 }
0465
0466 void
0467 ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
0468 {
0469 int i;
0470
0471
0472
0473
0474
0475
0476 for (i = 0; i < count; i++)
0477 *array++ = ahd_inb(ahd, port);
0478 }
0479
0480
0481 uint32_t
0482 ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width)
0483 {
0484 switch (width) {
0485 case 1:
0486 {
0487 uint8_t retval;
0488
0489 pci_read_config_byte(pci, reg, &retval);
0490 return (retval);
0491 }
0492 case 2:
0493 {
0494 uint16_t retval;
0495 pci_read_config_word(pci, reg, &retval);
0496 return (retval);
0497 }
0498 case 4:
0499 {
0500 uint32_t retval;
0501 pci_read_config_dword(pci, reg, &retval);
0502 return (retval);
0503 }
0504 default:
0505 panic("ahd_pci_read_config: Read size too big");
0506
0507 return (0);
0508 }
0509 }
0510
0511 void
0512 ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width)
0513 {
0514 switch (width) {
0515 case 1:
0516 pci_write_config_byte(pci, reg, value);
0517 break;
0518 case 2:
0519 pci_write_config_word(pci, reg, value);
0520 break;
0521 case 4:
0522 pci_write_config_dword(pci, reg, value);
0523 break;
0524 default:
0525 panic("ahd_pci_write_config: Write size too big");
0526
0527 }
0528 }
0529
0530
0531 static void ahd_linux_unmap_scb(struct ahd_softc*, struct scb*);
0532
0533 static void
0534 ahd_linux_unmap_scb(struct ahd_softc *ahd, struct scb *scb)
0535 {
0536 struct scsi_cmnd *cmd;
0537
0538 cmd = scb->io_ctx;
0539 ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
0540 scsi_dma_unmap(cmd);
0541 }
0542
0543
0544 #define BUILD_SCSIID(ahd, cmd) \
0545 (((scmd_id(cmd) << TID_SHIFT) & TID) | (ahd)->our_id)
0546
0547
0548
0549
0550 static const char *
0551 ahd_linux_info(struct Scsi_Host *host)
0552 {
0553 static char buffer[512];
0554 char ahd_info[256];
0555 char *bp;
0556 struct ahd_softc *ahd;
0557
0558 bp = &buffer[0];
0559 ahd = *(struct ahd_softc **)host->hostdata;
0560 memset(bp, 0, sizeof(buffer));
0561 strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev " AIC79XX_DRIVER_VERSION "\n"
0562 " <");
0563 strcat(bp, ahd->description);
0564 strcat(bp, ">\n"
0565 " ");
0566 ahd_controller_info(ahd, ahd_info);
0567 strcat(bp, ahd_info);
0568
0569 return (bp);
0570 }
0571
0572
0573
0574
0575 static int ahd_linux_queue_lck(struct scsi_cmnd *cmd)
0576 {
0577 struct ahd_softc *ahd;
0578 struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
0579 int rtn = SCSI_MLQUEUE_HOST_BUSY;
0580
0581 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
0582
0583 cmd->result = CAM_REQ_INPROG << 16;
0584 rtn = ahd_linux_run_command(ahd, dev, cmd);
0585
0586 return rtn;
0587 }
0588
0589 static DEF_SCSI_QCMD(ahd_linux_queue)
0590
0591 static struct scsi_target **
0592 ahd_linux_target_in_softc(struct scsi_target *starget)
0593 {
0594 struct ahd_softc *ahd =
0595 *((struct ahd_softc **)dev_to_shost(&starget->dev)->hostdata);
0596 unsigned int target_offset;
0597
0598 target_offset = starget->id;
0599 if (starget->channel != 0)
0600 target_offset += 8;
0601
0602 return &ahd->platform_data->starget[target_offset];
0603 }
0604
0605 static int
0606 ahd_linux_target_alloc(struct scsi_target *starget)
0607 {
0608 struct ahd_softc *ahd =
0609 *((struct ahd_softc **)dev_to_shost(&starget->dev)->hostdata);
0610 struct seeprom_config *sc = ahd->seep_config;
0611 unsigned long flags;
0612 struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
0613 struct ahd_devinfo devinfo;
0614 struct ahd_initiator_tinfo *tinfo;
0615 struct ahd_tmode_tstate *tstate;
0616 char channel = starget->channel + 'A';
0617
0618 ahd_lock(ahd, &flags);
0619
0620 BUG_ON(*ahd_targp != NULL);
0621
0622 *ahd_targp = starget;
0623
0624 if (sc) {
0625 int flags = sc->device_flags[starget->id];
0626
0627 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
0628 starget->id, &tstate);
0629
0630 if ((flags & CFPACKETIZED) == 0) {
0631
0632 spi_max_iu(starget) = 0;
0633 } else {
0634 if ((ahd->features & AHD_RTI) == 0)
0635 spi_rti(starget) = 0;
0636 }
0637
0638 if ((flags & CFQAS) == 0)
0639 spi_max_qas(starget) = 0;
0640
0641
0642 spi_max_width(starget) = (flags & CFWIDEB) ? 1 : 0;
0643 spi_min_period(starget) = tinfo->user.period;
0644 spi_max_offset(starget) = tinfo->user.offset;
0645 }
0646
0647 tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
0648 starget->id, &tstate);
0649 ahd_compile_devinfo(&devinfo, ahd->our_id, starget->id,
0650 CAM_LUN_WILDCARD, channel,
0651 ROLE_INITIATOR);
0652 ahd_set_syncrate(ahd, &devinfo, 0, 0, 0,
0653 AHD_TRANS_GOAL, FALSE);
0654 ahd_set_width(ahd, &devinfo, MSG_EXT_WDTR_BUS_8_BIT,
0655 AHD_TRANS_GOAL, FALSE);
0656 ahd_unlock(ahd, &flags);
0657
0658 return 0;
0659 }
0660
0661 static void
0662 ahd_linux_target_destroy(struct scsi_target *starget)
0663 {
0664 struct scsi_target **ahd_targp = ahd_linux_target_in_softc(starget);
0665
0666 *ahd_targp = NULL;
0667 }
0668
0669 static int
0670 ahd_linux_slave_alloc(struct scsi_device *sdev)
0671 {
0672 struct ahd_softc *ahd =
0673 *((struct ahd_softc **)sdev->host->hostdata);
0674 struct ahd_linux_device *dev;
0675
0676 if (bootverbose)
0677 printk("%s: Slave Alloc %d\n", ahd_name(ahd), sdev->id);
0678
0679 dev = scsi_transport_device_data(sdev);
0680 memset(dev, 0, sizeof(*dev));
0681
0682
0683
0684
0685
0686 dev->openings = 1;
0687
0688
0689
0690
0691
0692
0693 dev->maxtags = 0;
0694
0695 return (0);
0696 }
0697
0698 static int
0699 ahd_linux_slave_configure(struct scsi_device *sdev)
0700 {
0701 if (bootverbose)
0702 sdev_printk(KERN_INFO, sdev, "Slave Configure\n");
0703
0704 ahd_linux_device_queue_depth(sdev);
0705
0706
0707 if (!spi_initial_dv(sdev->sdev_target))
0708 spi_dv_device(sdev);
0709
0710 return 0;
0711 }
0712
0713 #if defined(__i386__)
0714
0715
0716
0717 static int
0718 ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev,
0719 sector_t capacity, int geom[])
0720 {
0721 int heads;
0722 int sectors;
0723 int cylinders;
0724 int extended;
0725 struct ahd_softc *ahd;
0726
0727 ahd = *((struct ahd_softc **)sdev->host->hostdata);
0728
0729 if (scsi_partsize(bdev, capacity, geom))
0730 return 0;
0731
0732 heads = 64;
0733 sectors = 32;
0734 cylinders = aic_sector_div(capacity, heads, sectors);
0735
0736 if (aic79xx_extended != 0)
0737 extended = 1;
0738 else
0739 extended = (ahd->flags & AHD_EXTENDED_TRANS_A) != 0;
0740 if (extended && cylinders >= 1024) {
0741 heads = 255;
0742 sectors = 63;
0743 cylinders = aic_sector_div(capacity, heads, sectors);
0744 }
0745 geom[0] = heads;
0746 geom[1] = sectors;
0747 geom[2] = cylinders;
0748 return (0);
0749 }
0750 #endif
0751
0752
0753
0754
0755 static int
0756 ahd_linux_abort(struct scsi_cmnd *cmd)
0757 {
0758 return ahd_linux_queue_abort_cmd(cmd);
0759 }
0760
0761
0762
0763
0764 static int
0765 ahd_linux_dev_reset(struct scsi_cmnd *cmd)
0766 {
0767 struct ahd_softc *ahd;
0768 struct ahd_linux_device *dev;
0769 struct scb *reset_scb;
0770 u_int cdb_byte;
0771 int retval = SUCCESS;
0772 struct ahd_initiator_tinfo *tinfo;
0773 struct ahd_tmode_tstate *tstate;
0774 unsigned long flags;
0775 DECLARE_COMPLETION_ONSTACK(done);
0776
0777 reset_scb = NULL;
0778
0779 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
0780
0781 scmd_printk(KERN_INFO, cmd,
0782 "Attempting to queue a TARGET RESET message:");
0783
0784 printk("CDB:");
0785 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
0786 printk(" 0x%x", cmd->cmnd[cdb_byte]);
0787 printk("\n");
0788
0789
0790
0791
0792 dev = scsi_transport_device_data(cmd->device);
0793
0794 if (dev == NULL) {
0795
0796
0797
0798
0799 scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
0800 return SUCCESS;
0801 }
0802
0803
0804
0805
0806 reset_scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX);
0807 if (!reset_scb) {
0808 scmd_printk(KERN_INFO, cmd, "No SCB available\n");
0809 return FAILED;
0810 }
0811
0812 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
0813 cmd->device->id, &tstate);
0814 reset_scb->io_ctx = cmd;
0815 reset_scb->platform_data->dev = dev;
0816 reset_scb->sg_count = 0;
0817 ahd_set_residual(reset_scb, 0);
0818 ahd_set_sense_residual(reset_scb, 0);
0819 reset_scb->platform_data->xfer_len = 0;
0820 reset_scb->hscb->control = 0;
0821 reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd);
0822 reset_scb->hscb->lun = cmd->device->lun;
0823 reset_scb->hscb->cdb_len = 0;
0824 reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET;
0825 reset_scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE;
0826 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
0827 reset_scb->flags |= SCB_PACKETIZED;
0828 } else {
0829 reset_scb->hscb->control |= MK_MESSAGE;
0830 }
0831 dev->openings--;
0832 dev->active++;
0833 dev->commands_issued++;
0834
0835 ahd_lock(ahd, &flags);
0836
0837 LIST_INSERT_HEAD(&ahd->pending_scbs, reset_scb, pending_links);
0838 ahd_queue_scb(ahd, reset_scb);
0839
0840 ahd->platform_data->eh_done = &done;
0841 ahd_unlock(ahd, &flags);
0842
0843 printk("%s: Device reset code sleeping\n", ahd_name(ahd));
0844 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
0845 ahd_lock(ahd, &flags);
0846 ahd->platform_data->eh_done = NULL;
0847 ahd_unlock(ahd, &flags);
0848 printk("%s: Device reset timer expired (active %d)\n",
0849 ahd_name(ahd), dev->active);
0850 retval = FAILED;
0851 }
0852 printk("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
0853
0854 return (retval);
0855 }
0856
0857
0858
0859
0860 static int
0861 ahd_linux_bus_reset(struct scsi_cmnd *cmd)
0862 {
0863 struct ahd_softc *ahd;
0864 int found;
0865 unsigned long flags;
0866
0867 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
0868 #ifdef AHD_DEBUG
0869 if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
0870 printk("%s: Bus reset called for cmd %p\n",
0871 ahd_name(ahd), cmd);
0872 #endif
0873 ahd_lock(ahd, &flags);
0874
0875 found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A',
0876 TRUE);
0877 ahd_unlock(ahd, &flags);
0878
0879 if (bootverbose)
0880 printk("%s: SCSI bus reset delivered. "
0881 "%d SCBs aborted.\n", ahd_name(ahd), found);
0882
0883 return (SUCCESS);
0884 }
0885
0886 struct scsi_host_template aic79xx_driver_template = {
0887 .module = THIS_MODULE,
0888 .name = "aic79xx",
0889 .proc_name = "aic79xx",
0890 .show_info = ahd_linux_show_info,
0891 .write_info = ahd_proc_write_seeprom,
0892 .info = ahd_linux_info,
0893 .queuecommand = ahd_linux_queue,
0894 .eh_abort_handler = ahd_linux_abort,
0895 .eh_device_reset_handler = ahd_linux_dev_reset,
0896 .eh_bus_reset_handler = ahd_linux_bus_reset,
0897 #if defined(__i386__)
0898 .bios_param = ahd_linux_biosparam,
0899 #endif
0900 .can_queue = AHD_MAX_QUEUE,
0901 .this_id = -1,
0902 .max_sectors = 8192,
0903 .cmd_per_lun = 2,
0904 .slave_alloc = ahd_linux_slave_alloc,
0905 .slave_configure = ahd_linux_slave_configure,
0906 .target_alloc = ahd_linux_target_alloc,
0907 .target_destroy = ahd_linux_target_destroy,
0908 };
0909
0910
0911 int
0912 ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent,
0913 bus_size_t alignment, bus_size_t boundary,
0914 dma_addr_t lowaddr, dma_addr_t highaddr,
0915 bus_dma_filter_t *filter, void *filterarg,
0916 bus_size_t maxsize, int nsegments,
0917 bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag)
0918 {
0919 bus_dma_tag_t dmat;
0920
0921 dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC);
0922 if (dmat == NULL)
0923 return (ENOMEM);
0924
0925
0926
0927
0928
0929
0930
0931
0932 dmat->alignment = alignment;
0933 dmat->boundary = boundary;
0934 dmat->maxsize = maxsize;
0935 *ret_tag = dmat;
0936 return (0);
0937 }
0938
0939 void
0940 ahd_dma_tag_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat)
0941 {
0942 kfree(dmat);
0943 }
0944
0945 int
0946 ahd_dmamem_alloc(struct ahd_softc *ahd, bus_dma_tag_t dmat, void** vaddr,
0947 int flags, bus_dmamap_t *mapp)
0948 {
0949 *vaddr = dma_alloc_coherent(&ahd->dev_softc->dev, dmat->maxsize, mapp,
0950 GFP_ATOMIC);
0951 if (*vaddr == NULL)
0952 return (ENOMEM);
0953 return(0);
0954 }
0955
0956 void
0957 ahd_dmamem_free(struct ahd_softc *ahd, bus_dma_tag_t dmat,
0958 void* vaddr, bus_dmamap_t map)
0959 {
0960 dma_free_coherent(&ahd->dev_softc->dev, dmat->maxsize, vaddr, map);
0961 }
0962
0963 int
0964 ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map,
0965 void *buf, bus_size_t buflen, bus_dmamap_callback_t *cb,
0966 void *cb_arg, int flags)
0967 {
0968
0969
0970
0971
0972 bus_dma_segment_t stack_sg;
0973
0974 stack_sg.ds_addr = map;
0975 stack_sg.ds_len = dmat->maxsize;
0976 cb(cb_arg, &stack_sg, 1, 0);
0977 return (0);
0978 }
0979
0980 void
0981 ahd_dmamap_destroy(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
0982 {
0983 }
0984
0985 int
0986 ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
0987 {
0988
0989 return (0);
0990 }
0991
0992
0993 static void
0994 ahd_linux_setup_iocell_info(u_long index, int instance, int targ, int32_t value)
0995 {
0996
0997 if ((instance >= 0)
0998 && (instance < ARRAY_SIZE(aic79xx_iocell_info))) {
0999 uint8_t *iocell_info;
1000
1001 iocell_info = (uint8_t*)&aic79xx_iocell_info[instance];
1002 iocell_info[index] = value & 0xFFFF;
1003 if (bootverbose)
1004 printk("iocell[%d:%ld] = %d\n", instance, index, value);
1005 }
1006 }
1007
1008 static void
1009 ahd_linux_setup_tag_info_global(char *p)
1010 {
1011 int tags, i, j;
1012
1013 tags = simple_strtoul(p + 1, NULL, 0) & 0xff;
1014 printk("Setting Global Tags= %d\n", tags);
1015
1016 for (i = 0; i < ARRAY_SIZE(aic79xx_tag_info); i++) {
1017 for (j = 0; j < AHD_NUM_TARGETS; j++) {
1018 aic79xx_tag_info[i].tag_commands[j] = tags;
1019 }
1020 }
1021 }
1022
1023 static void
1024 ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value)
1025 {
1026
1027 if ((instance >= 0) && (targ >= 0)
1028 && (instance < ARRAY_SIZE(aic79xx_tag_info))
1029 && (targ < AHD_NUM_TARGETS)) {
1030 aic79xx_tag_info[instance].tag_commands[targ] = value & 0x1FF;
1031 if (bootverbose)
1032 printk("tag_info[%d:%d] = %d\n", instance, targ, value);
1033 }
1034 }
1035
1036 static char *
1037 ahd_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth,
1038 void (*callback)(u_long, int, int, int32_t),
1039 u_long callback_arg)
1040 {
1041 char *tok_end;
1042 char *tok_end2;
1043 int i;
1044 int instance;
1045 int targ;
1046 int done;
1047 char tok_list[] = {'.', ',', '{', '}', '\0'};
1048
1049
1050 if (*opt_arg != ':')
1051 return (opt_arg);
1052 opt_arg++;
1053 instance = -1;
1054 targ = -1;
1055 done = FALSE;
1056
1057
1058
1059
1060 tok_end = strchr(opt_arg, '\0');
1061 if (tok_end < end)
1062 *tok_end = ',';
1063 while (!done) {
1064 switch (*opt_arg) {
1065 case '{':
1066 if (instance == -1) {
1067 instance = 0;
1068 } else {
1069 if (depth > 1) {
1070 if (targ == -1)
1071 targ = 0;
1072 } else {
1073 printk("Malformed Option %s\n",
1074 opt_name);
1075 done = TRUE;
1076 }
1077 }
1078 opt_arg++;
1079 break;
1080 case '}':
1081 if (targ != -1)
1082 targ = -1;
1083 else if (instance != -1)
1084 instance = -1;
1085 opt_arg++;
1086 break;
1087 case ',':
1088 case '.':
1089 if (instance == -1)
1090 done = TRUE;
1091 else if (targ >= 0)
1092 targ++;
1093 else if (instance >= 0)
1094 instance++;
1095 opt_arg++;
1096 break;
1097 case '\0':
1098 done = TRUE;
1099 break;
1100 default:
1101 tok_end = end;
1102 for (i = 0; tok_list[i]; i++) {
1103 tok_end2 = strchr(opt_arg, tok_list[i]);
1104 if ((tok_end2) && (tok_end2 < tok_end))
1105 tok_end = tok_end2;
1106 }
1107 callback(callback_arg, instance, targ,
1108 simple_strtol(opt_arg, NULL, 0));
1109 opt_arg = tok_end;
1110 break;
1111 }
1112 }
1113 return (opt_arg);
1114 }
1115
1116
1117
1118
1119
1120
1121 static int
1122 aic79xx_setup(char *s)
1123 {
1124 int i, n;
1125 char *p;
1126 char *end;
1127
1128 static const struct {
1129 const char *name;
1130 uint32_t *flag;
1131 } options[] = {
1132 { "extended", &aic79xx_extended },
1133 { "no_reset", &aic79xx_no_reset },
1134 { "verbose", &aic79xx_verbose },
1135 { "allow_memio", &aic79xx_allow_memio},
1136 #ifdef AHD_DEBUG
1137 { "debug", &ahd_debug },
1138 #endif
1139 { "periodic_otag", &aic79xx_periodic_otag },
1140 { "pci_parity", &aic79xx_pci_parity },
1141 { "seltime", &aic79xx_seltime },
1142 { "tag_info", NULL },
1143 { "global_tag_depth", NULL},
1144 { "slewrate", NULL },
1145 { "precomp", NULL },
1146 { "amplitude", NULL },
1147 { "slowcrc", &aic79xx_slowcrc },
1148 };
1149
1150 end = strchr(s, '\0');
1151
1152
1153
1154
1155
1156 n = 0;
1157
1158 while ((p = strsep(&s, ",.")) != NULL) {
1159 if (*p == '\0')
1160 continue;
1161 for (i = 0; i < ARRAY_SIZE(options); i++) {
1162
1163 n = strlen(options[i].name);
1164 if (strncmp(options[i].name, p, n) == 0)
1165 break;
1166 }
1167 if (i == ARRAY_SIZE(options))
1168 continue;
1169
1170 if (strncmp(p, "global_tag_depth", n) == 0) {
1171 ahd_linux_setup_tag_info_global(p + n);
1172 } else if (strncmp(p, "tag_info", n) == 0) {
1173 s = ahd_parse_brace_option("tag_info", p + n, end,
1174 2, ahd_linux_setup_tag_info, 0);
1175 } else if (strncmp(p, "slewrate", n) == 0) {
1176 s = ahd_parse_brace_option("slewrate",
1177 p + n, end, 1, ahd_linux_setup_iocell_info,
1178 AIC79XX_SLEWRATE_INDEX);
1179 } else if (strncmp(p, "precomp", n) == 0) {
1180 s = ahd_parse_brace_option("precomp",
1181 p + n, end, 1, ahd_linux_setup_iocell_info,
1182 AIC79XX_PRECOMP_INDEX);
1183 } else if (strncmp(p, "amplitude", n) == 0) {
1184 s = ahd_parse_brace_option("amplitude",
1185 p + n, end, 1, ahd_linux_setup_iocell_info,
1186 AIC79XX_AMPLITUDE_INDEX);
1187 } else if (p[n] == ':') {
1188 *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
1189 } else if (!strncmp(p, "verbose", n)) {
1190 *(options[i].flag) = 1;
1191 } else {
1192 *(options[i].flag) ^= 0xFFFFFFFF;
1193 }
1194 }
1195 return 1;
1196 }
1197
1198 __setup("aic79xx=", aic79xx_setup);
1199
1200 uint32_t aic79xx_verbose;
1201
1202 int
1203 ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *template)
1204 {
1205 char buf[80];
1206 struct Scsi_Host *host;
1207 char *new_name;
1208 u_long s;
1209 int retval;
1210
1211 template->name = ahd->description;
1212 host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
1213 if (host == NULL)
1214 return (ENOMEM);
1215
1216 *((struct ahd_softc **)host->hostdata) = ahd;
1217 ahd->platform_data->host = host;
1218 host->can_queue = AHD_MAX_QUEUE;
1219 host->cmd_per_lun = 2;
1220 host->sg_tablesize = AHD_NSEG;
1221 host->this_id = ahd->our_id;
1222 host->irq = ahd->platform_data->irq;
1223 host->max_id = (ahd->features & AHD_WIDE) ? 16 : 8;
1224 host->max_lun = AHD_NUM_LUNS;
1225 host->max_channel = 0;
1226 host->sg_tablesize = AHD_NSEG;
1227 ahd_lock(ahd, &s);
1228 ahd_set_unit(ahd, ahd_linux_unit++);
1229 ahd_unlock(ahd, &s);
1230 sprintf(buf, "scsi%d", host->host_no);
1231 new_name = kmalloc(strlen(buf) + 1, GFP_ATOMIC);
1232 if (new_name != NULL) {
1233 strcpy(new_name, buf);
1234 ahd_set_name(ahd, new_name);
1235 }
1236 host->unique_id = ahd->unit;
1237 ahd_linux_initialize_scsi_bus(ahd);
1238 ahd_intr_enable(ahd, TRUE);
1239
1240 host->transportt = ahd_linux_transport_template;
1241
1242 retval = scsi_add_host(host, &ahd->dev_softc->dev);
1243 if (retval) {
1244 printk(KERN_WARNING "aic79xx: scsi_add_host failed\n");
1245 scsi_host_put(host);
1246 return retval;
1247 }
1248
1249 scsi_scan_host(host);
1250 return 0;
1251 }
1252
1253
1254
1255
1256
1257
1258 static void
1259 ahd_linux_initialize_scsi_bus(struct ahd_softc *ahd)
1260 {
1261 u_int target_id;
1262 u_int numtarg;
1263 unsigned long s;
1264
1265 target_id = 0;
1266 numtarg = 0;
1267
1268 if (aic79xx_no_reset != 0)
1269 ahd->flags &= ~AHD_RESET_BUS_A;
1270
1271 if ((ahd->flags & AHD_RESET_BUS_A) != 0)
1272 ahd_reset_channel(ahd, 'A', TRUE);
1273 else
1274 numtarg = (ahd->features & AHD_WIDE) ? 16 : 8;
1275
1276 ahd_lock(ahd, &s);
1277
1278
1279
1280
1281
1282 for (; target_id < numtarg; target_id++) {
1283 struct ahd_devinfo devinfo;
1284 struct ahd_initiator_tinfo *tinfo;
1285 struct ahd_tmode_tstate *tstate;
1286
1287 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
1288 target_id, &tstate);
1289 ahd_compile_devinfo(&devinfo, ahd->our_id, target_id,
1290 CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR);
1291 ahd_update_neg_request(ahd, &devinfo, tstate,
1292 tinfo, AHD_NEG_ALWAYS);
1293 }
1294 ahd_unlock(ahd, &s);
1295
1296 if ((ahd->flags & AHD_RESET_BUS_A) != 0) {
1297 ahd_freeze_simq(ahd);
1298 msleep(AIC79XX_RESET_DELAY);
1299 ahd_release_simq(ahd);
1300 }
1301 }
1302
1303 int
1304 ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg)
1305 {
1306 ahd->platform_data =
1307 kzalloc(sizeof(struct ahd_platform_data), GFP_ATOMIC);
1308 if (ahd->platform_data == NULL)
1309 return (ENOMEM);
1310 ahd->platform_data->irq = AHD_LINUX_NOIRQ;
1311 ahd_lockinit(ahd);
1312 ahd->seltime = (aic79xx_seltime & 0x3) << 4;
1313 return (0);
1314 }
1315
1316 void
1317 ahd_platform_free(struct ahd_softc *ahd)
1318 {
1319 struct scsi_target *starget;
1320 int i;
1321
1322 if (ahd->platform_data != NULL) {
1323
1324 for (i = 0; i < AHD_NUM_TARGETS; i++) {
1325 starget = ahd->platform_data->starget[i];
1326 if (starget != NULL) {
1327 ahd->platform_data->starget[i] = NULL;
1328 }
1329 }
1330
1331 if (ahd->platform_data->irq != AHD_LINUX_NOIRQ)
1332 free_irq(ahd->platform_data->irq, ahd);
1333 if (ahd->tags[0] == BUS_SPACE_PIO
1334 && ahd->bshs[0].ioport != 0)
1335 release_region(ahd->bshs[0].ioport, 256);
1336 if (ahd->tags[1] == BUS_SPACE_PIO
1337 && ahd->bshs[1].ioport != 0)
1338 release_region(ahd->bshs[1].ioport, 256);
1339 if (ahd->tags[0] == BUS_SPACE_MEMIO
1340 && ahd->bshs[0].maddr != NULL) {
1341 iounmap(ahd->bshs[0].maddr);
1342 release_mem_region(ahd->platform_data->mem_busaddr,
1343 0x1000);
1344 }
1345 if (ahd->platform_data->host)
1346 scsi_host_put(ahd->platform_data->host);
1347
1348 kfree(ahd->platform_data);
1349 }
1350 }
1351
1352 void
1353 ahd_platform_init(struct ahd_softc *ahd)
1354 {
1355
1356
1357
1358 if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
1359 const struct ahd_linux_iocell_opts *iocell_opts;
1360
1361 iocell_opts = &aic79xx_iocell_info[ahd->unit];
1362 if (iocell_opts->precomp != AIC79XX_DEFAULT_PRECOMP)
1363 AHD_SET_PRECOMP(ahd, iocell_opts->precomp);
1364 if (iocell_opts->slewrate != AIC79XX_DEFAULT_SLEWRATE)
1365 AHD_SET_SLEWRATE(ahd, iocell_opts->slewrate);
1366 if (iocell_opts->amplitude != AIC79XX_DEFAULT_AMPLITUDE)
1367 AHD_SET_AMPLITUDE(ahd, iocell_opts->amplitude);
1368 }
1369
1370 }
1371
1372 void
1373 ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb)
1374 {
1375 ahd_platform_abort_scbs(ahd, SCB_GET_TARGET(ahd, scb),
1376 SCB_GET_CHANNEL(ahd, scb),
1377 SCB_GET_LUN(scb), SCB_LIST_NULL,
1378 ROLE_UNKNOWN, CAM_REQUEUE_REQ);
1379 }
1380
1381 void
1382 ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
1383 struct ahd_devinfo *devinfo, ahd_queue_alg alg)
1384 {
1385 struct ahd_linux_device *dev;
1386 int was_queuing;
1387 int now_queuing;
1388
1389 if (sdev == NULL)
1390 return;
1391
1392 dev = scsi_transport_device_data(sdev);
1393
1394 if (dev == NULL)
1395 return;
1396 was_queuing = dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED);
1397 switch (alg) {
1398 default:
1399 case AHD_QUEUE_NONE:
1400 now_queuing = 0;
1401 break;
1402 case AHD_QUEUE_BASIC:
1403 now_queuing = AHD_DEV_Q_BASIC;
1404 break;
1405 case AHD_QUEUE_TAGGED:
1406 now_queuing = AHD_DEV_Q_TAGGED;
1407 break;
1408 }
1409 if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) == 0
1410 && (was_queuing != now_queuing)
1411 && (dev->active != 0)) {
1412 dev->flags |= AHD_DEV_FREEZE_TIL_EMPTY;
1413 dev->qfrozen++;
1414 }
1415
1416 dev->flags &= ~(AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED|AHD_DEV_PERIODIC_OTAG);
1417 if (now_queuing) {
1418 u_int usertags;
1419
1420 usertags = ahd_linux_user_tagdepth(ahd, devinfo);
1421 if (!was_queuing) {
1422
1423
1424
1425
1426
1427 dev->maxtags = usertags;
1428 dev->openings = dev->maxtags - dev->active;
1429 }
1430 if (dev->maxtags == 0) {
1431
1432
1433
1434 dev->openings = 1;
1435 } else if (alg == AHD_QUEUE_TAGGED) {
1436 dev->flags |= AHD_DEV_Q_TAGGED;
1437 if (aic79xx_periodic_otag != 0)
1438 dev->flags |= AHD_DEV_PERIODIC_OTAG;
1439 } else
1440 dev->flags |= AHD_DEV_Q_BASIC;
1441 } else {
1442
1443 dev->maxtags = 0;
1444 dev->openings = 1 - dev->active;
1445 }
1446
1447 switch ((dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED))) {
1448 case AHD_DEV_Q_BASIC:
1449 case AHD_DEV_Q_TAGGED:
1450 scsi_change_queue_depth(sdev,
1451 dev->openings + dev->active);
1452 break;
1453 default:
1454
1455
1456
1457
1458
1459
1460 scsi_change_queue_depth(sdev, 1);
1461 break;
1462 }
1463 }
1464
1465 int
1466 ahd_platform_abort_scbs(struct ahd_softc *ahd, int target, char channel,
1467 int lun, u_int tag, role_t role, uint32_t status)
1468 {
1469 return 0;
1470 }
1471
1472 static u_int
1473 ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
1474 {
1475 static int warned_user;
1476 u_int tags;
1477
1478 tags = 0;
1479 if ((ahd->user_discenable & devinfo->target_mask) != 0) {
1480 if (ahd->unit >= ARRAY_SIZE(aic79xx_tag_info)) {
1481
1482 if (warned_user == 0) {
1483 printk(KERN_WARNING
1484 "aic79xx: WARNING: Insufficient tag_info instances\n"
1485 "aic79xx: for installed controllers. Using defaults\n"
1486 "aic79xx: Please update the aic79xx_tag_info array in\n"
1487 "aic79xx: the aic79xx_osm.c source file.\n");
1488 warned_user++;
1489 }
1490 tags = AHD_MAX_QUEUE;
1491 } else {
1492 adapter_tag_info_t *tag_info;
1493
1494 tag_info = &aic79xx_tag_info[ahd->unit];
1495 tags = tag_info->tag_commands[devinfo->target_offset];
1496 if (tags > AHD_MAX_QUEUE)
1497 tags = AHD_MAX_QUEUE;
1498 }
1499 }
1500 return (tags);
1501 }
1502
1503
1504
1505
1506 static void
1507 ahd_linux_device_queue_depth(struct scsi_device *sdev)
1508 {
1509 struct ahd_devinfo devinfo;
1510 u_int tags;
1511 struct ahd_softc *ahd = *((struct ahd_softc **)sdev->host->hostdata);
1512
1513 ahd_compile_devinfo(&devinfo,
1514 ahd->our_id,
1515 sdev->sdev_target->id, sdev->lun,
1516 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1517 ROLE_INITIATOR);
1518 tags = ahd_linux_user_tagdepth(ahd, &devinfo);
1519 if (tags != 0 && sdev->tagged_supported != 0) {
1520
1521 ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_TAGGED);
1522 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1523 devinfo.lun, AC_TRANSFER_NEG);
1524 ahd_print_devinfo(ahd, &devinfo);
1525 printk("Tagged Queuing enabled. Depth %d\n", tags);
1526 } else {
1527 ahd_platform_set_tags(ahd, sdev, &devinfo, AHD_QUEUE_NONE);
1528 ahd_send_async(ahd, devinfo.channel, devinfo.target,
1529 devinfo.lun, AC_TRANSFER_NEG);
1530 }
1531 }
1532
1533 static int
1534 ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
1535 struct scsi_cmnd *cmd)
1536 {
1537 struct scb *scb;
1538 struct hardware_scb *hscb;
1539 struct ahd_initiator_tinfo *tinfo;
1540 struct ahd_tmode_tstate *tstate;
1541 u_int col_idx;
1542 uint16_t mask;
1543 unsigned long flags;
1544 int nseg;
1545
1546 nseg = scsi_dma_map(cmd);
1547 if (nseg < 0)
1548 return SCSI_MLQUEUE_HOST_BUSY;
1549
1550 ahd_lock(ahd, &flags);
1551
1552
1553
1554
1555 tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
1556 cmd->device->id, &tstate);
1557 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) == 0
1558 || (tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0) {
1559 col_idx = AHD_NEVER_COL_IDX;
1560 } else {
1561 col_idx = AHD_BUILD_COL_IDX(cmd->device->id,
1562 cmd->device->lun);
1563 }
1564 if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
1565 ahd->flags |= AHD_RESOURCE_SHORTAGE;
1566 ahd_unlock(ahd, &flags);
1567 scsi_dma_unmap(cmd);
1568 return SCSI_MLQUEUE_HOST_BUSY;
1569 }
1570
1571 scb->io_ctx = cmd;
1572 scb->platform_data->dev = dev;
1573 hscb = scb->hscb;
1574 cmd->host_scribble = (char *)scb;
1575
1576
1577
1578
1579 hscb->control = 0;
1580 hscb->scsiid = BUILD_SCSIID(ahd, cmd);
1581 hscb->lun = cmd->device->lun;
1582 scb->hscb->task_management = 0;
1583 mask = SCB_GET_TARGET_MASK(ahd, scb);
1584
1585 if ((ahd->user_discenable & mask) != 0)
1586 hscb->control |= DISCENB;
1587
1588 if ((tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ) != 0)
1589 scb->flags |= SCB_PACKETIZED;
1590
1591 if ((tstate->auto_negotiate & mask) != 0) {
1592 scb->flags |= SCB_AUTO_NEGOTIATE;
1593 scb->hscb->control |= MK_MESSAGE;
1594 }
1595
1596 if ((dev->flags & (AHD_DEV_Q_TAGGED|AHD_DEV_Q_BASIC)) != 0) {
1597 if (dev->commands_since_idle_or_otag == AHD_OTAG_THRESH
1598 && (dev->flags & AHD_DEV_Q_TAGGED) != 0) {
1599 hscb->control |= ORDERED_QUEUE_TAG;
1600 dev->commands_since_idle_or_otag = 0;
1601 } else {
1602 hscb->control |= SIMPLE_QUEUE_TAG;
1603 }
1604 }
1605
1606 hscb->cdb_len = cmd->cmd_len;
1607 memcpy(hscb->shared_data.idata.cdb, cmd->cmnd, hscb->cdb_len);
1608
1609 scb->platform_data->xfer_len = 0;
1610 ahd_set_residual(scb, 0);
1611 ahd_set_sense_residual(scb, 0);
1612 scb->sg_count = 0;
1613
1614 if (nseg > 0) {
1615 void *sg = scb->sg_list;
1616 struct scatterlist *cur_seg;
1617 int i;
1618
1619 scb->platform_data->xfer_len = 0;
1620
1621 scsi_for_each_sg(cmd, cur_seg, nseg, i) {
1622 dma_addr_t addr;
1623 bus_size_t len;
1624
1625 addr = sg_dma_address(cur_seg);
1626 len = sg_dma_len(cur_seg);
1627 scb->platform_data->xfer_len += len;
1628 sg = ahd_sg_setup(ahd, scb, sg, addr, len,
1629 i == (nseg - 1));
1630 }
1631 }
1632
1633 LIST_INSERT_HEAD(&ahd->pending_scbs, scb, pending_links);
1634 dev->openings--;
1635 dev->active++;
1636 dev->commands_issued++;
1637
1638 if ((dev->flags & AHD_DEV_PERIODIC_OTAG) != 0)
1639 dev->commands_since_idle_or_otag++;
1640 scb->flags |= SCB_ACTIVE;
1641 ahd_queue_scb(ahd, scb);
1642
1643 ahd_unlock(ahd, &flags);
1644
1645 return 0;
1646 }
1647
1648
1649
1650
1651 irqreturn_t
1652 ahd_linux_isr(int irq, void *dev_id)
1653 {
1654 struct ahd_softc *ahd;
1655 u_long flags;
1656 int ours;
1657
1658 ahd = (struct ahd_softc *) dev_id;
1659 ahd_lock(ahd, &flags);
1660 ours = ahd_intr(ahd);
1661 ahd_unlock(ahd, &flags);
1662 return IRQ_RETVAL(ours);
1663 }
1664
1665 void
1666 ahd_send_async(struct ahd_softc *ahd, char channel,
1667 u_int target, u_int lun, ac_code code)
1668 {
1669 switch (code) {
1670 case AC_TRANSFER_NEG:
1671 {
1672 struct scsi_target *starget;
1673 struct ahd_initiator_tinfo *tinfo;
1674 struct ahd_tmode_tstate *tstate;
1675 unsigned int target_ppr_options;
1676
1677 BUG_ON(target == CAM_TARGET_WILDCARD);
1678
1679 tinfo = ahd_fetch_transinfo(ahd, channel, ahd->our_id,
1680 target, &tstate);
1681
1682
1683
1684
1685
1686 if (tinfo->curr.period != tinfo->goal.period
1687 || tinfo->curr.width != tinfo->goal.width
1688 || tinfo->curr.offset != tinfo->goal.offset
1689 || tinfo->curr.ppr_options != tinfo->goal.ppr_options)
1690 if (bootverbose == 0)
1691 break;
1692
1693
1694
1695
1696
1697 starget = ahd->platform_data->starget[target];
1698 if (starget == NULL)
1699 break;
1700
1701 target_ppr_options =
1702 (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0)
1703 + (spi_qas(starget) ? MSG_EXT_PPR_QAS_REQ : 0)
1704 + (spi_iu(starget) ? MSG_EXT_PPR_IU_REQ : 0)
1705 + (spi_rd_strm(starget) ? MSG_EXT_PPR_RD_STRM : 0)
1706 + (spi_pcomp_en(starget) ? MSG_EXT_PPR_PCOMP_EN : 0)
1707 + (spi_rti(starget) ? MSG_EXT_PPR_RTI : 0)
1708 + (spi_wr_flow(starget) ? MSG_EXT_PPR_WR_FLOW : 0)
1709 + (spi_hold_mcs(starget) ? MSG_EXT_PPR_HOLD_MCS : 0);
1710
1711 if (tinfo->curr.period == spi_period(starget)
1712 && tinfo->curr.width == spi_width(starget)
1713 && tinfo->curr.offset == spi_offset(starget)
1714 && tinfo->curr.ppr_options == target_ppr_options)
1715 if (bootverbose == 0)
1716 break;
1717
1718 spi_period(starget) = tinfo->curr.period;
1719 spi_width(starget) = tinfo->curr.width;
1720 spi_offset(starget) = tinfo->curr.offset;
1721 spi_dt(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_DT_REQ ? 1 : 0;
1722 spi_qas(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_QAS_REQ ? 1 : 0;
1723 spi_iu(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_IU_REQ ? 1 : 0;
1724 spi_rd_strm(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_RD_STRM ? 1 : 0;
1725 spi_pcomp_en(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_PCOMP_EN ? 1 : 0;
1726 spi_rti(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_RTI ? 1 : 0;
1727 spi_wr_flow(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_WR_FLOW ? 1 : 0;
1728 spi_hold_mcs(starget) = tinfo->curr.ppr_options & MSG_EXT_PPR_HOLD_MCS ? 1 : 0;
1729 spi_display_xfer_agreement(starget);
1730 break;
1731 }
1732 case AC_SENT_BDR:
1733 {
1734 WARN_ON(lun != CAM_LUN_WILDCARD);
1735 scsi_report_device_reset(ahd->platform_data->host,
1736 channel - 'A', target);
1737 break;
1738 }
1739 case AC_BUS_RESET:
1740 if (ahd->platform_data->host != NULL) {
1741 scsi_report_bus_reset(ahd->platform_data->host,
1742 channel - 'A');
1743 }
1744 break;
1745 default:
1746 panic("ahd_send_async: Unexpected async event");
1747 }
1748 }
1749
1750
1751
1752
1753 void
1754 ahd_done(struct ahd_softc *ahd, struct scb *scb)
1755 {
1756 struct scsi_cmnd *cmd;
1757 struct ahd_linux_device *dev;
1758
1759 if ((scb->flags & SCB_ACTIVE) == 0) {
1760 printk("SCB %d done'd twice\n", SCB_GET_TAG(scb));
1761 ahd_dump_card_state(ahd);
1762 panic("Stopping for safety");
1763 }
1764 LIST_REMOVE(scb, pending_links);
1765 cmd = scb->io_ctx;
1766 dev = scb->platform_data->dev;
1767 dev->active--;
1768 dev->openings++;
1769 if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
1770 cmd->result &= ~(CAM_DEV_QFRZN << 16);
1771 dev->qfrozen--;
1772 }
1773 ahd_linux_unmap_scb(ahd, scb);
1774
1775
1776
1777
1778
1779
1780
1781 cmd->sense_buffer[0] = 0;
1782 if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) {
1783 #ifdef AHD_REPORT_UNDERFLOWS
1784 uint32_t amount_xferred;
1785
1786 amount_xferred =
1787 ahd_get_transfer_length(scb) - ahd_get_residual(scb);
1788 #endif
1789 if ((scb->flags & SCB_TRANSMISSION_ERROR) != 0) {
1790 #ifdef AHD_DEBUG
1791 if ((ahd_debug & AHD_SHOW_MISC) != 0) {
1792 ahd_print_path(ahd, scb);
1793 printk("Set CAM_UNCOR_PARITY\n");
1794 }
1795 #endif
1796 ahd_set_transaction_status(scb, CAM_UNCOR_PARITY);
1797 #ifdef AHD_REPORT_UNDERFLOWS
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807 } else if (amount_xferred < scb->io_ctx->underflow) {
1808 u_int i;
1809
1810 ahd_print_path(ahd, scb);
1811 printk("CDB:");
1812 for (i = 0; i < scb->io_ctx->cmd_len; i++)
1813 printk(" 0x%x", scb->io_ctx->cmnd[i]);
1814 printk("\n");
1815 ahd_print_path(ahd, scb);
1816 printk("Saw underflow (%ld of %ld bytes). "
1817 "Treated as error\n",
1818 ahd_get_residual(scb),
1819 ahd_get_transfer_length(scb));
1820 ahd_set_transaction_status(scb, CAM_DATA_RUN_ERR);
1821 #endif
1822 } else {
1823 ahd_set_transaction_status(scb, CAM_REQ_CMP);
1824 }
1825 } else if (ahd_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) {
1826 ahd_linux_handle_scsi_status(ahd, cmd->device, scb);
1827 }
1828
1829 if (dev->openings == 1
1830 && ahd_get_transaction_status(scb) == CAM_REQ_CMP
1831 && ahd_get_scsi_status(scb) != SAM_STAT_TASK_SET_FULL)
1832 dev->tag_success_count++;
1833
1834
1835
1836
1837
1838
1839 if ((dev->openings + dev->active) < dev->maxtags
1840 && dev->tag_success_count > AHD_TAG_SUCCESS_INTERVAL) {
1841 dev->tag_success_count = 0;
1842 dev->openings++;
1843 }
1844
1845 if (dev->active == 0)
1846 dev->commands_since_idle_or_otag = 0;
1847
1848 if ((scb->flags & SCB_RECOVERY_SCB) != 0) {
1849 printk("Recovery SCB completes\n");
1850 if (ahd_get_transaction_status(scb) == CAM_BDR_SENT
1851 || ahd_get_transaction_status(scb) == CAM_REQ_ABORTED)
1852 ahd_set_transaction_status(scb, CAM_CMD_TIMEOUT);
1853
1854 if (ahd->platform_data->eh_done)
1855 complete(ahd->platform_data->eh_done);
1856 }
1857
1858 ahd_free_scb(ahd, scb);
1859 ahd_linux_queue_cmd_complete(ahd, cmd);
1860 }
1861
1862 static void
1863 ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
1864 struct scsi_device *sdev, struct scb *scb)
1865 {
1866 struct ahd_devinfo devinfo;
1867 struct ahd_linux_device *dev = scsi_transport_device_data(sdev);
1868
1869 ahd_compile_devinfo(&devinfo,
1870 ahd->our_id,
1871 sdev->sdev_target->id, sdev->lun,
1872 sdev->sdev_target->channel == 0 ? 'A' : 'B',
1873 ROLE_INITIATOR);
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885 switch (ahd_get_scsi_status(scb)) {
1886 default:
1887 break;
1888 case SAM_STAT_CHECK_CONDITION:
1889 case SAM_STAT_COMMAND_TERMINATED:
1890 {
1891 struct scsi_cmnd *cmd;
1892
1893
1894
1895
1896
1897 cmd = scb->io_ctx;
1898 if ((scb->flags & (SCB_SENSE|SCB_PKT_SENSE)) != 0) {
1899 struct scsi_status_iu_header *siu;
1900 u_int sense_size;
1901 u_int sense_offset;
1902
1903 if (scb->flags & SCB_SENSE) {
1904 sense_size = min(sizeof(struct scsi_sense_data)
1905 - ahd_get_sense_residual(scb),
1906 (u_long)SCSI_SENSE_BUFFERSIZE);
1907 sense_offset = 0;
1908 } else {
1909
1910
1911
1912
1913 siu = (struct scsi_status_iu_header *)
1914 scb->sense_data;
1915 sense_size = min_t(size_t,
1916 scsi_4btoul(siu->sense_length),
1917 SCSI_SENSE_BUFFERSIZE);
1918 sense_offset = SIU_SENSE_OFFSET(siu);
1919 }
1920
1921 memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
1922 memcpy(cmd->sense_buffer,
1923 ahd_get_sense_buf(ahd, scb)
1924 + sense_offset, sense_size);
1925 set_status_byte(cmd, SAM_STAT_CHECK_CONDITION);
1926
1927 #ifdef AHD_DEBUG
1928 if (ahd_debug & AHD_SHOW_SENSE) {
1929 int i;
1930
1931 printk("Copied %d bytes of sense data at %d:",
1932 sense_size, sense_offset);
1933 for (i = 0; i < sense_size; i++) {
1934 if ((i & 0xF) == 0)
1935 printk("\n");
1936 printk("0x%x ", cmd->sense_buffer[i]);
1937 }
1938 printk("\n");
1939 }
1940 #endif
1941 }
1942 break;
1943 }
1944 case SAM_STAT_TASK_SET_FULL:
1945
1946
1947
1948
1949
1950
1951
1952
1953 dev->tag_success_count = 0;
1954 if (dev->active != 0) {
1955
1956
1957
1958
1959 dev->openings = 0;
1960 #ifdef AHD_DEBUG
1961 if ((ahd_debug & AHD_SHOW_QFULL) != 0) {
1962 ahd_print_path(ahd, scb);
1963 printk("Dropping tag count to %d\n",
1964 dev->active);
1965 }
1966 #endif
1967 if (dev->active == dev->tags_on_last_queuefull) {
1968
1969 dev->last_queuefull_same_count++;
1970
1971
1972
1973
1974
1975
1976
1977
1978 if (dev->last_queuefull_same_count
1979 == AHD_LOCK_TAGS_COUNT) {
1980 dev->maxtags = dev->active;
1981 ahd_print_path(ahd, scb);
1982 printk("Locking max tag count at %d\n",
1983 dev->active);
1984 }
1985 } else {
1986 dev->tags_on_last_queuefull = dev->active;
1987 dev->last_queuefull_same_count = 0;
1988 }
1989 ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
1990 ahd_set_scsi_status(scb, SAM_STAT_GOOD);
1991 ahd_platform_set_tags(ahd, sdev, &devinfo,
1992 (dev->flags & AHD_DEV_Q_BASIC)
1993 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
1994 break;
1995 }
1996
1997
1998
1999
2000 dev->openings = 1;
2001 ahd_platform_set_tags(ahd, sdev, &devinfo,
2002 (dev->flags & AHD_DEV_Q_BASIC)
2003 ? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
2004 ahd_set_scsi_status(scb, SAM_STAT_BUSY);
2005 }
2006 }
2007
2008 static void
2009 ahd_linux_queue_cmd_complete(struct ahd_softc *ahd, struct scsi_cmnd *cmd)
2010 {
2011 int status;
2012 int new_status = DID_OK;
2013 int do_fallback = 0;
2014 int scsi_status;
2015 struct scsi_sense_data *sense;
2016
2017
2018
2019
2020
2021
2022
2023
2024 status = ahd_cmd_get_transaction_status(cmd);
2025 switch (status) {
2026 case CAM_REQ_INPROG:
2027 case CAM_REQ_CMP:
2028 new_status = DID_OK;
2029 break;
2030 case CAM_AUTOSENSE_FAIL:
2031 new_status = DID_ERROR;
2032 fallthrough;
2033 case CAM_SCSI_STATUS_ERROR:
2034 scsi_status = ahd_cmd_get_scsi_status(cmd);
2035
2036 switch(scsi_status) {
2037 case SAM_STAT_COMMAND_TERMINATED:
2038 case SAM_STAT_CHECK_CONDITION:
2039 sense = (struct scsi_sense_data *)
2040 cmd->sense_buffer;
2041 if (sense->extra_len >= 5 &&
2042 (sense->add_sense_code == 0x47
2043 || sense->add_sense_code == 0x48))
2044 do_fallback = 1;
2045 break;
2046 default:
2047 break;
2048 }
2049 break;
2050 case CAM_REQ_ABORTED:
2051 new_status = DID_ABORT;
2052 break;
2053 case CAM_BUSY:
2054 new_status = DID_BUS_BUSY;
2055 break;
2056 case CAM_REQ_INVALID:
2057 case CAM_PATH_INVALID:
2058 new_status = DID_BAD_TARGET;
2059 break;
2060 case CAM_SEL_TIMEOUT:
2061 new_status = DID_NO_CONNECT;
2062 break;
2063 case CAM_SCSI_BUS_RESET:
2064 case CAM_BDR_SENT:
2065 new_status = DID_RESET;
2066 break;
2067 case CAM_UNCOR_PARITY:
2068 new_status = DID_PARITY;
2069 do_fallback = 1;
2070 break;
2071 case CAM_CMD_TIMEOUT:
2072 new_status = DID_TIME_OUT;
2073 do_fallback = 1;
2074 break;
2075 case CAM_REQ_CMP_ERR:
2076 case CAM_UNEXP_BUSFREE:
2077 case CAM_DATA_RUN_ERR:
2078 new_status = DID_ERROR;
2079 do_fallback = 1;
2080 break;
2081 case CAM_UA_ABORT:
2082 case CAM_NO_HBA:
2083 case CAM_SEQUENCE_FAIL:
2084 case CAM_CCB_LEN_ERR:
2085 case CAM_PROVIDE_FAIL:
2086 case CAM_REQ_TERMIO:
2087 case CAM_UNREC_HBA_ERROR:
2088 case CAM_REQ_TOO_BIG:
2089 new_status = DID_ERROR;
2090 break;
2091 case CAM_REQUEUE_REQ:
2092 new_status = DID_REQUEUE;
2093 break;
2094 default:
2095
2096 new_status = DID_ERROR;
2097 break;
2098 }
2099
2100 if (do_fallback) {
2101 printk("%s: device overrun (status %x) on %d:%d:%d\n",
2102 ahd_name(ahd), status, cmd->device->channel,
2103 cmd->device->id, (u8)cmd->device->lun);
2104 }
2105
2106 ahd_cmd_set_transaction_status(cmd, new_status);
2107
2108 scsi_done(cmd);
2109 }
2110
2111 static void
2112 ahd_freeze_simq(struct ahd_softc *ahd)
2113 {
2114 scsi_block_requests(ahd->platform_data->host);
2115 }
2116
2117 static void
2118 ahd_release_simq(struct ahd_softc *ahd)
2119 {
2120 scsi_unblock_requests(ahd->platform_data->host);
2121 }
2122
2123 static int
2124 ahd_linux_queue_abort_cmd(struct scsi_cmnd *cmd)
2125 {
2126 struct ahd_softc *ahd;
2127 struct ahd_linux_device *dev;
2128 struct scb *pending_scb;
2129 u_int saved_scbptr;
2130 u_int active_scbptr;
2131 u_int last_phase;
2132 u_int cdb_byte;
2133 int retval = SUCCESS;
2134 int was_paused;
2135 int paused;
2136 int wait;
2137 int disconnected;
2138 ahd_mode_state saved_modes;
2139 unsigned long flags;
2140
2141 pending_scb = NULL;
2142 paused = FALSE;
2143 wait = FALSE;
2144 ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
2145
2146 scmd_printk(KERN_INFO, cmd,
2147 "Attempting to queue an ABORT message:");
2148
2149 printk("CDB:");
2150 for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
2151 printk(" 0x%x", cmd->cmnd[cdb_byte]);
2152 printk("\n");
2153
2154 ahd_lock(ahd, &flags);
2155
2156
2157
2158
2159
2160
2161
2162
2163 dev = scsi_transport_device_data(cmd->device);
2164
2165 if (dev == NULL) {
2166
2167
2168
2169
2170 scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
2171 goto done;
2172 }
2173
2174
2175
2176
2177 LIST_FOREACH(pending_scb, &ahd->pending_scbs, pending_links) {
2178 if (pending_scb->io_ctx == cmd)
2179 break;
2180 }
2181
2182 if (pending_scb == NULL) {
2183 scmd_printk(KERN_INFO, cmd, "Command not found\n");
2184 goto done;
2185 }
2186
2187 if ((pending_scb->flags & SCB_RECOVERY_SCB) != 0) {
2188
2189
2190
2191 retval = FAILED;
2192 goto done;
2193 }
2194
2195
2196
2197
2198
2199
2200
2201 was_paused = ahd_is_paused(ahd);
2202 ahd_pause_and_flushwork(ahd);
2203 paused = TRUE;
2204
2205 if ((pending_scb->flags & SCB_ACTIVE) == 0) {
2206 scmd_printk(KERN_INFO, cmd, "Command already completed\n");
2207 goto done;
2208 }
2209
2210 printk("%s: At time of recovery, card was %spaused\n",
2211 ahd_name(ahd), was_paused ? "" : "not ");
2212 ahd_dump_card_state(ahd);
2213
2214 disconnected = TRUE;
2215 if (ahd_search_qinfifo(ahd, cmd->device->id,
2216 cmd->device->channel + 'A',
2217 cmd->device->lun,
2218 pending_scb->hscb->tag,
2219 ROLE_INITIATOR, CAM_REQ_ABORTED,
2220 SEARCH_COMPLETE) > 0) {
2221 printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
2222 ahd_name(ahd), cmd->device->channel,
2223 cmd->device->id, (u8)cmd->device->lun);
2224 goto done;
2225 }
2226
2227 saved_modes = ahd_save_modes(ahd);
2228 ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
2229 last_phase = ahd_inb(ahd, LASTPHASE);
2230 saved_scbptr = ahd_get_scbptr(ahd);
2231 active_scbptr = saved_scbptr;
2232 if (disconnected && (ahd_inb(ahd, SEQ_FLAGS) & NOT_IDENTIFIED) == 0) {
2233 struct scb *bus_scb;
2234
2235 bus_scb = ahd_lookup_scb(ahd, active_scbptr);
2236 if (bus_scb == pending_scb)
2237 disconnected = FALSE;
2238 }
2239
2240
2241
2242
2243
2244
2245 ahd_inb(ahd, SAVED_SCSIID);
2246 if (last_phase != P_BUSFREE
2247 && SCB_GET_TAG(pending_scb) == active_scbptr) {
2248
2249
2250
2251
2252
2253 pending_scb = ahd_lookup_scb(ahd, active_scbptr);
2254 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
2255 ahd_outb(ahd, MSG_OUT, HOST_MSG);
2256 ahd_outb(ahd, SCSISIGO, last_phase|ATNO);
2257 scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
2258 wait = TRUE;
2259 } else if (disconnected) {
2260
2261
2262
2263
2264
2265 pending_scb->flags |= SCB_RECOVERY_SCB|SCB_ABORT;
2266 ahd_set_scbptr(ahd, SCB_GET_TAG(pending_scb));
2267 pending_scb->hscb->cdb_len = 0;
2268 pending_scb->hscb->task_attribute = 0;
2269 pending_scb->hscb->task_management = SIU_TASKMGMT_ABORT_TASK;
2270
2271 if ((pending_scb->flags & SCB_PACKETIZED) != 0) {
2272
2273
2274
2275
2276
2277
2278
2279 ahd_outb(ahd, SCB_TASK_MANAGEMENT,
2280 pending_scb->hscb->task_management);
2281 } else {
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291 pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
2292
2293
2294
2295
2296
2297
2298
2299 ahd_outb(ahd, SCB_CONTROL,
2300 ahd_inb(ahd, SCB_CONTROL)|MK_MESSAGE);
2301 }
2302
2303
2304
2305
2306
2307
2308 ahd_search_qinfifo(ahd, cmd->device->id,
2309 cmd->device->channel + 'A', cmd->device->lun,
2310 SCB_LIST_NULL, ROLE_INITIATOR,
2311 CAM_REQUEUE_REQ, SEARCH_COMPLETE);
2312 ahd_qinfifo_requeue_tail(ahd, pending_scb);
2313 ahd_set_scbptr(ahd, saved_scbptr);
2314 ahd_print_path(ahd, pending_scb);
2315 printk("Device is disconnected, re-queuing SCB\n");
2316 wait = TRUE;
2317 } else {
2318 scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
2319 retval = FAILED;
2320 }
2321
2322
2323 ahd_restore_modes(ahd, saved_modes);
2324 done:
2325 if (paused)
2326 ahd_unpause(ahd);
2327 if (wait) {
2328 DECLARE_COMPLETION_ONSTACK(done);
2329
2330 ahd->platform_data->eh_done = &done;
2331 ahd_unlock(ahd, &flags);
2332
2333 printk("%s: Recovery code sleeping\n", ahd_name(ahd));
2334 if (!wait_for_completion_timeout(&done, 5 * HZ)) {
2335 ahd_lock(ahd, &flags);
2336 ahd->platform_data->eh_done = NULL;
2337 ahd_unlock(ahd, &flags);
2338 printk("%s: Timer Expired (active %d)\n",
2339 ahd_name(ahd), dev->active);
2340 retval = FAILED;
2341 }
2342 printk("Recovery code awake\n");
2343 } else
2344 ahd_unlock(ahd, &flags);
2345
2346 if (retval != SUCCESS)
2347 printk("%s: Command abort returning 0x%x\n",
2348 ahd_name(ahd), retval);
2349
2350 return retval;
2351 }
2352
2353 static void ahd_linux_set_width(struct scsi_target *starget, int width)
2354 {
2355 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2356 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2357 struct ahd_devinfo devinfo;
2358 unsigned long flags;
2359
2360 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2361 starget->channel + 'A', ROLE_INITIATOR);
2362 ahd_lock(ahd, &flags);
2363 ahd_set_width(ahd, &devinfo, width, AHD_TRANS_GOAL, FALSE);
2364 ahd_unlock(ahd, &flags);
2365 }
2366
2367 static void ahd_linux_set_period(struct scsi_target *starget, int period)
2368 {
2369 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2370 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2371 struct ahd_tmode_tstate *tstate;
2372 struct ahd_initiator_tinfo *tinfo
2373 = ahd_fetch_transinfo(ahd,
2374 starget->channel + 'A',
2375 shost->this_id, starget->id, &tstate);
2376 struct ahd_devinfo devinfo;
2377 unsigned int ppr_options = tinfo->goal.ppr_options;
2378 unsigned int dt;
2379 unsigned long flags;
2380 unsigned long offset = tinfo->goal.offset;
2381
2382 #ifdef AHD_DEBUG
2383 if ((ahd_debug & AHD_SHOW_DV) != 0)
2384 printk("%s: set period to %d\n", ahd_name(ahd), period);
2385 #endif
2386 if (offset == 0)
2387 offset = MAX_OFFSET;
2388
2389 if (period < 8)
2390 period = 8;
2391 if (period < 10) {
2392 if (spi_max_width(starget)) {
2393 ppr_options |= MSG_EXT_PPR_DT_REQ;
2394 if (period == 8)
2395 ppr_options |= MSG_EXT_PPR_IU_REQ;
2396 } else
2397 period = 10;
2398 }
2399
2400 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2401
2402 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2403 starget->channel + 'A', ROLE_INITIATOR);
2404
2405
2406 if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) {
2407 if (spi_width(starget) == 0)
2408 ppr_options &= MSG_EXT_PPR_QAS_REQ;
2409 }
2410
2411 ahd_find_syncrate(ahd, &period, &ppr_options,
2412 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2413
2414 ahd_lock(ahd, &flags);
2415 ahd_set_syncrate(ahd, &devinfo, period, offset,
2416 ppr_options, AHD_TRANS_GOAL, FALSE);
2417 ahd_unlock(ahd, &flags);
2418 }
2419
2420 static void ahd_linux_set_offset(struct scsi_target *starget, int offset)
2421 {
2422 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2423 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2424 struct ahd_tmode_tstate *tstate;
2425 struct ahd_initiator_tinfo *tinfo
2426 = ahd_fetch_transinfo(ahd,
2427 starget->channel + 'A',
2428 shost->this_id, starget->id, &tstate);
2429 struct ahd_devinfo devinfo;
2430 unsigned int ppr_options = 0;
2431 unsigned int period = 0;
2432 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2433 unsigned long flags;
2434
2435 #ifdef AHD_DEBUG
2436 if ((ahd_debug & AHD_SHOW_DV) != 0)
2437 printk("%s: set offset to %d\n", ahd_name(ahd), offset);
2438 #endif
2439
2440 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2441 starget->channel + 'A', ROLE_INITIATOR);
2442 if (offset != 0) {
2443 period = tinfo->goal.period;
2444 ppr_options = tinfo->goal.ppr_options;
2445 ahd_find_syncrate(ahd, &period, &ppr_options,
2446 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2447 }
2448
2449 ahd_lock(ahd, &flags);
2450 ahd_set_syncrate(ahd, &devinfo, period, offset, ppr_options,
2451 AHD_TRANS_GOAL, FALSE);
2452 ahd_unlock(ahd, &flags);
2453 }
2454
2455 static void ahd_linux_set_dt(struct scsi_target *starget, int dt)
2456 {
2457 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2458 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2459 struct ahd_tmode_tstate *tstate;
2460 struct ahd_initiator_tinfo *tinfo
2461 = ahd_fetch_transinfo(ahd,
2462 starget->channel + 'A',
2463 shost->this_id, starget->id, &tstate);
2464 struct ahd_devinfo devinfo;
2465 unsigned int ppr_options = tinfo->goal.ppr_options
2466 & ~MSG_EXT_PPR_DT_REQ;
2467 unsigned int period = tinfo->goal.period;
2468 unsigned int width = tinfo->goal.width;
2469 unsigned long flags;
2470
2471 #ifdef AHD_DEBUG
2472 if ((ahd_debug & AHD_SHOW_DV) != 0)
2473 printk("%s: %s DT\n", ahd_name(ahd),
2474 dt ? "enabling" : "disabling");
2475 #endif
2476 if (dt && spi_max_width(starget)) {
2477 ppr_options |= MSG_EXT_PPR_DT_REQ;
2478 if (!width)
2479 ahd_linux_set_width(starget, 1);
2480 } else {
2481 if (period <= 9)
2482 period = 10;
2483
2484 ppr_options &= ~MSG_EXT_PPR_IU_REQ;
2485 }
2486 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2487 starget->channel + 'A', ROLE_INITIATOR);
2488 ahd_find_syncrate(ahd, &period, &ppr_options,
2489 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2490
2491 ahd_lock(ahd, &flags);
2492 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2493 ppr_options, AHD_TRANS_GOAL, FALSE);
2494 ahd_unlock(ahd, &flags);
2495 }
2496
2497 static void ahd_linux_set_qas(struct scsi_target *starget, int qas)
2498 {
2499 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2500 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2501 struct ahd_tmode_tstate *tstate;
2502 struct ahd_initiator_tinfo *tinfo
2503 = ahd_fetch_transinfo(ahd,
2504 starget->channel + 'A',
2505 shost->this_id, starget->id, &tstate);
2506 struct ahd_devinfo devinfo;
2507 unsigned int ppr_options = tinfo->goal.ppr_options
2508 & ~MSG_EXT_PPR_QAS_REQ;
2509 unsigned int period = tinfo->goal.period;
2510 unsigned int dt;
2511 unsigned long flags;
2512
2513 #ifdef AHD_DEBUG
2514 if ((ahd_debug & AHD_SHOW_DV) != 0)
2515 printk("%s: %s QAS\n", ahd_name(ahd),
2516 qas ? "enabling" : "disabling");
2517 #endif
2518
2519 if (qas) {
2520 ppr_options |= MSG_EXT_PPR_QAS_REQ;
2521 }
2522
2523 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2524
2525 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2526 starget->channel + 'A', ROLE_INITIATOR);
2527 ahd_find_syncrate(ahd, &period, &ppr_options,
2528 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2529
2530 ahd_lock(ahd, &flags);
2531 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2532 ppr_options, AHD_TRANS_GOAL, FALSE);
2533 ahd_unlock(ahd, &flags);
2534 }
2535
2536 static void ahd_linux_set_iu(struct scsi_target *starget, int iu)
2537 {
2538 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2539 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2540 struct ahd_tmode_tstate *tstate;
2541 struct ahd_initiator_tinfo *tinfo
2542 = ahd_fetch_transinfo(ahd,
2543 starget->channel + 'A',
2544 shost->this_id, starget->id, &tstate);
2545 struct ahd_devinfo devinfo;
2546 unsigned int ppr_options = tinfo->goal.ppr_options
2547 & ~MSG_EXT_PPR_IU_REQ;
2548 unsigned int period = tinfo->goal.period;
2549 unsigned int dt;
2550 unsigned long flags;
2551
2552 #ifdef AHD_DEBUG
2553 if ((ahd_debug & AHD_SHOW_DV) != 0)
2554 printk("%s: %s IU\n", ahd_name(ahd),
2555 iu ? "enabling" : "disabling");
2556 #endif
2557
2558 if (iu && spi_max_width(starget)) {
2559 ppr_options |= MSG_EXT_PPR_IU_REQ;
2560 ppr_options |= MSG_EXT_PPR_DT_REQ;
2561 }
2562
2563 dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2564
2565 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2566 starget->channel + 'A', ROLE_INITIATOR);
2567 ahd_find_syncrate(ahd, &period, &ppr_options,
2568 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2569
2570 ahd_lock(ahd, &flags);
2571 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2572 ppr_options, AHD_TRANS_GOAL, FALSE);
2573 ahd_unlock(ahd, &flags);
2574 }
2575
2576 static void ahd_linux_set_rd_strm(struct scsi_target *starget, int rdstrm)
2577 {
2578 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2579 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2580 struct ahd_tmode_tstate *tstate;
2581 struct ahd_initiator_tinfo *tinfo
2582 = ahd_fetch_transinfo(ahd,
2583 starget->channel + 'A',
2584 shost->this_id, starget->id, &tstate);
2585 struct ahd_devinfo devinfo;
2586 unsigned int ppr_options = tinfo->goal.ppr_options
2587 & ~MSG_EXT_PPR_RD_STRM;
2588 unsigned int period = tinfo->goal.period;
2589 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2590 unsigned long flags;
2591
2592 #ifdef AHD_DEBUG
2593 if ((ahd_debug & AHD_SHOW_DV) != 0)
2594 printk("%s: %s Read Streaming\n", ahd_name(ahd),
2595 rdstrm ? "enabling" : "disabling");
2596 #endif
2597
2598 if (rdstrm && spi_max_width(starget))
2599 ppr_options |= MSG_EXT_PPR_RD_STRM;
2600
2601 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2602 starget->channel + 'A', ROLE_INITIATOR);
2603 ahd_find_syncrate(ahd, &period, &ppr_options,
2604 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2605
2606 ahd_lock(ahd, &flags);
2607 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2608 ppr_options, AHD_TRANS_GOAL, FALSE);
2609 ahd_unlock(ahd, &flags);
2610 }
2611
2612 static void ahd_linux_set_wr_flow(struct scsi_target *starget, int wrflow)
2613 {
2614 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2615 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2616 struct ahd_tmode_tstate *tstate;
2617 struct ahd_initiator_tinfo *tinfo
2618 = ahd_fetch_transinfo(ahd,
2619 starget->channel + 'A',
2620 shost->this_id, starget->id, &tstate);
2621 struct ahd_devinfo devinfo;
2622 unsigned int ppr_options = tinfo->goal.ppr_options
2623 & ~MSG_EXT_PPR_WR_FLOW;
2624 unsigned int period = tinfo->goal.period;
2625 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2626 unsigned long flags;
2627
2628 #ifdef AHD_DEBUG
2629 if ((ahd_debug & AHD_SHOW_DV) != 0)
2630 printk("%s: %s Write Flow Control\n", ahd_name(ahd),
2631 wrflow ? "enabling" : "disabling");
2632 #endif
2633
2634 if (wrflow && spi_max_width(starget))
2635 ppr_options |= MSG_EXT_PPR_WR_FLOW;
2636
2637 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2638 starget->channel + 'A', ROLE_INITIATOR);
2639 ahd_find_syncrate(ahd, &period, &ppr_options,
2640 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2641
2642 ahd_lock(ahd, &flags);
2643 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2644 ppr_options, AHD_TRANS_GOAL, FALSE);
2645 ahd_unlock(ahd, &flags);
2646 }
2647
2648 static void ahd_linux_set_rti(struct scsi_target *starget, int rti)
2649 {
2650 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2651 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2652 struct ahd_tmode_tstate *tstate;
2653 struct ahd_initiator_tinfo *tinfo
2654 = ahd_fetch_transinfo(ahd,
2655 starget->channel + 'A',
2656 shost->this_id, starget->id, &tstate);
2657 struct ahd_devinfo devinfo;
2658 unsigned int ppr_options = tinfo->goal.ppr_options
2659 & ~MSG_EXT_PPR_RTI;
2660 unsigned int period = tinfo->goal.period;
2661 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2662 unsigned long flags;
2663
2664 if ((ahd->features & AHD_RTI) == 0) {
2665 #ifdef AHD_DEBUG
2666 if ((ahd_debug & AHD_SHOW_DV) != 0)
2667 printk("%s: RTI not available\n", ahd_name(ahd));
2668 #endif
2669 return;
2670 }
2671
2672 #ifdef AHD_DEBUG
2673 if ((ahd_debug & AHD_SHOW_DV) != 0)
2674 printk("%s: %s RTI\n", ahd_name(ahd),
2675 rti ? "enabling" : "disabling");
2676 #endif
2677
2678 if (rti && spi_max_width(starget))
2679 ppr_options |= MSG_EXT_PPR_RTI;
2680
2681 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2682 starget->channel + 'A', ROLE_INITIATOR);
2683 ahd_find_syncrate(ahd, &period, &ppr_options,
2684 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2685
2686 ahd_lock(ahd, &flags);
2687 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2688 ppr_options, AHD_TRANS_GOAL, FALSE);
2689 ahd_unlock(ahd, &flags);
2690 }
2691
2692 static void ahd_linux_set_pcomp_en(struct scsi_target *starget, int pcomp)
2693 {
2694 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2695 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2696 struct ahd_tmode_tstate *tstate;
2697 struct ahd_initiator_tinfo *tinfo
2698 = ahd_fetch_transinfo(ahd,
2699 starget->channel + 'A',
2700 shost->this_id, starget->id, &tstate);
2701 struct ahd_devinfo devinfo;
2702 unsigned int ppr_options = tinfo->goal.ppr_options
2703 & ~MSG_EXT_PPR_PCOMP_EN;
2704 unsigned int period = tinfo->goal.period;
2705 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2706 unsigned long flags;
2707
2708 #ifdef AHD_DEBUG
2709 if ((ahd_debug & AHD_SHOW_DV) != 0)
2710 printk("%s: %s Precompensation\n", ahd_name(ahd),
2711 pcomp ? "Enable" : "Disable");
2712 #endif
2713
2714 if (pcomp && spi_max_width(starget)) {
2715 uint8_t precomp;
2716
2717 if (ahd->unit < ARRAY_SIZE(aic79xx_iocell_info)) {
2718 const struct ahd_linux_iocell_opts *iocell_opts;
2719
2720 iocell_opts = &aic79xx_iocell_info[ahd->unit];
2721 precomp = iocell_opts->precomp;
2722 } else {
2723 precomp = AIC79XX_DEFAULT_PRECOMP;
2724 }
2725 ppr_options |= MSG_EXT_PPR_PCOMP_EN;
2726 AHD_SET_PRECOMP(ahd, precomp);
2727 } else {
2728 AHD_SET_PRECOMP(ahd, 0);
2729 }
2730
2731 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2732 starget->channel + 'A', ROLE_INITIATOR);
2733 ahd_find_syncrate(ahd, &period, &ppr_options,
2734 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2735
2736 ahd_lock(ahd, &flags);
2737 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2738 ppr_options, AHD_TRANS_GOAL, FALSE);
2739 ahd_unlock(ahd, &flags);
2740 }
2741
2742 static void ahd_linux_set_hold_mcs(struct scsi_target *starget, int hold)
2743 {
2744 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
2745 struct ahd_softc *ahd = *((struct ahd_softc **)shost->hostdata);
2746 struct ahd_tmode_tstate *tstate;
2747 struct ahd_initiator_tinfo *tinfo
2748 = ahd_fetch_transinfo(ahd,
2749 starget->channel + 'A',
2750 shost->this_id, starget->id, &tstate);
2751 struct ahd_devinfo devinfo;
2752 unsigned int ppr_options = tinfo->goal.ppr_options
2753 & ~MSG_EXT_PPR_HOLD_MCS;
2754 unsigned int period = tinfo->goal.period;
2755 unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ;
2756 unsigned long flags;
2757
2758 if (hold && spi_max_width(starget))
2759 ppr_options |= MSG_EXT_PPR_HOLD_MCS;
2760
2761 ahd_compile_devinfo(&devinfo, shost->this_id, starget->id, 0,
2762 starget->channel + 'A', ROLE_INITIATOR);
2763 ahd_find_syncrate(ahd, &period, &ppr_options,
2764 dt ? AHD_SYNCRATE_MAX : AHD_SYNCRATE_ULTRA2);
2765
2766 ahd_lock(ahd, &flags);
2767 ahd_set_syncrate(ahd, &devinfo, period, tinfo->goal.offset,
2768 ppr_options, AHD_TRANS_GOAL, FALSE);
2769 ahd_unlock(ahd, &flags);
2770 }
2771
2772 static void ahd_linux_get_signalling(struct Scsi_Host *shost)
2773 {
2774 struct ahd_softc *ahd = *(struct ahd_softc **)shost->hostdata;
2775 unsigned long flags;
2776 u8 mode;
2777
2778 ahd_lock(ahd, &flags);
2779 ahd_pause(ahd);
2780 mode = ahd_inb(ahd, SBLKCTL);
2781 ahd_unpause(ahd);
2782 ahd_unlock(ahd, &flags);
2783
2784 if (mode & ENAB40)
2785 spi_signalling(shost) = SPI_SIGNAL_LVD;
2786 else if (mode & ENAB20)
2787 spi_signalling(shost) = SPI_SIGNAL_SE;
2788 else
2789 spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
2790 }
2791
2792 static struct spi_function_template ahd_linux_transport_functions = {
2793 .set_offset = ahd_linux_set_offset,
2794 .show_offset = 1,
2795 .set_period = ahd_linux_set_period,
2796 .show_period = 1,
2797 .set_width = ahd_linux_set_width,
2798 .show_width = 1,
2799 .set_dt = ahd_linux_set_dt,
2800 .show_dt = 1,
2801 .set_iu = ahd_linux_set_iu,
2802 .show_iu = 1,
2803 .set_qas = ahd_linux_set_qas,
2804 .show_qas = 1,
2805 .set_rd_strm = ahd_linux_set_rd_strm,
2806 .show_rd_strm = 1,
2807 .set_wr_flow = ahd_linux_set_wr_flow,
2808 .show_wr_flow = 1,
2809 .set_rti = ahd_linux_set_rti,
2810 .show_rti = 1,
2811 .set_pcomp_en = ahd_linux_set_pcomp_en,
2812 .show_pcomp_en = 1,
2813 .set_hold_mcs = ahd_linux_set_hold_mcs,
2814 .show_hold_mcs = 1,
2815 .get_signalling = ahd_linux_get_signalling,
2816 };
2817
2818 static int __init
2819 ahd_linux_init(void)
2820 {
2821 int error = 0;
2822
2823
2824
2825
2826 if (aic79xx)
2827 aic79xx_setup(aic79xx);
2828
2829 ahd_linux_transport_template =
2830 spi_attach_transport(&ahd_linux_transport_functions);
2831 if (!ahd_linux_transport_template)
2832 return -ENODEV;
2833
2834 scsi_transport_reserve_device(ahd_linux_transport_template,
2835 sizeof(struct ahd_linux_device));
2836
2837 error = ahd_linux_pci_init();
2838 if (error)
2839 spi_release_transport(ahd_linux_transport_template);
2840 return error;
2841 }
2842
2843 static void __exit
2844 ahd_linux_exit(void)
2845 {
2846 ahd_linux_pci_exit();
2847 spi_release_transport(ahd_linux_transport_template);
2848 }
2849
2850 module_init(ahd_linux_init);
2851 module_exit(ahd_linux_exit);