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);