2111 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family 4 * of PCI-SCSI IO processors.5 *6 * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr>7 * Copyright (c) 2003-2005 Matthew Wilcox <matthew@wil.cx>8 *9 * This driver is derived from the Linux sym53c8xx driver.10 * Copyright (C) 1998-2000 Gerard Roudier11 *12 * The sym53c8xx driver is derived from the ncr53c8xx driver that had been 13 * a port of the FreeBSD ncr driver to Linux-1.2.13.14 *15 * The original ncr driver has been written for 386bsd and FreeBSD by16 * Wolfgang Stanglmeier <wolf@cologne.de>17 * Stefan Esser <se@mi.Uni-Koeln.de>18 * Copyright (C) 1994 Wolfgang Stanglmeier19 *20 * Other major contributions:21 *22 * NVRAM detection and reading.23 * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk>24 *25 *-----------------------------------------------------------------------------26 */27#include <linux/ctype.h>28#include <linux/init.h>29#include <linux/module.h>30#include <linux/moduleparam.h>31#include <linux/spinlock.h>32#include <scsi/scsi.h>33#include <scsi/scsi_tcq.h>34#include <scsi/scsi_device.h>35#include <scsi/scsi_transport.h>36 37#include "sym_glue.h"38#include "sym_nvram.h"39 40#define NAME53C "sym53c"41#define NAME53C8XX "sym53c8xx"42 43struct sym_driver_setup sym_driver_setup = SYM_LINUX_DRIVER_SETUP;44unsigned int sym_debug_flags = 0;45 46static char *excl_string;47static char *safe_string;48module_param_named(cmd_per_lun, sym_driver_setup.max_tag, ushort, 0);49module_param_named(burst, sym_driver_setup.burst_order, byte, 0);50module_param_named(led, sym_driver_setup.scsi_led, byte, 0);51module_param_named(diff, sym_driver_setup.scsi_diff, byte, 0);52module_param_named(irqm, sym_driver_setup.irq_mode, byte, 0);53module_param_named(buschk, sym_driver_setup.scsi_bus_check, byte, 0);54module_param_named(hostid, sym_driver_setup.host_id, byte, 0);55module_param_named(verb, sym_driver_setup.verbose, byte, 0);56module_param_named(debug, sym_debug_flags, uint, 0);57module_param_named(settle, sym_driver_setup.settle_delay, byte, 0);58module_param_named(nvram, sym_driver_setup.use_nvram, byte, 0);59module_param_named(excl, excl_string, charp, 0);60module_param_named(safe, safe_string, charp, 0);61 62MODULE_PARM_DESC(cmd_per_lun, "The maximum number of tags to use by default");63MODULE_PARM_DESC(burst, "Maximum burst. 0 to disable, 255 to read from registers");64MODULE_PARM_DESC(led, "Set to 1 to enable LED support");65MODULE_PARM_DESC(diff, "0 for no differential mode, 1 for BIOS, 2 for always, 3 for not GPIO3");66MODULE_PARM_DESC(irqm, "0 for open drain, 1 to leave alone, 2 for totem pole");67MODULE_PARM_DESC(buschk, "0 to not check, 1 for detach on error, 2 for warn on error");68MODULE_PARM_DESC(hostid, "The SCSI ID to use for the host adapters");69MODULE_PARM_DESC(verb, "0 for minimal verbosity, 1 for normal, 2 for excessive");70MODULE_PARM_DESC(debug, "Set bits to enable debugging");71MODULE_PARM_DESC(settle, "Settle delay in seconds. Default 3");72MODULE_PARM_DESC(nvram, "Option currently not used");73MODULE_PARM_DESC(excl, "List ioport addresses here to prevent controllers from being attached");74MODULE_PARM_DESC(safe, "Set other settings to a \"safe mode\"");75 76MODULE_LICENSE("GPL");77MODULE_VERSION(SYM_VERSION);78MODULE_AUTHOR("Matthew Wilcox <matthew@wil.cx>");79MODULE_DESCRIPTION("NCR, Symbios and LSI 8xx and 1010 PCI SCSI adapters");80 81static void sym2_setup_params(void)82{83 char *p = excl_string;84 int xi = 0;85 86 while (p && (xi < 8)) {87 char *next_p;88 int val = (int) simple_strtoul(p, &next_p, 0);89 sym_driver_setup.excludes[xi++] = val;90 p = next_p;91 }92 93 if (safe_string) {94 if (*safe_string == 'y') {95 sym_driver_setup.max_tag = 0;96 sym_driver_setup.burst_order = 0;97 sym_driver_setup.scsi_led = 0;98 sym_driver_setup.scsi_diff = 1;99 sym_driver_setup.irq_mode = 0;100 sym_driver_setup.scsi_bus_check = 2;101 sym_driver_setup.host_id = 7;102 sym_driver_setup.verbose = 2;103 sym_driver_setup.settle_delay = 10;104 sym_driver_setup.use_nvram = 1;105 } else if (*safe_string != 'n') {106 printk(KERN_WARNING NAME53C8XX "Ignoring parameter %s"107 " passed to safe option", safe_string);108 }109 }110}111 112static struct scsi_transport_template *sym2_transport_template = NULL;113 114/*115 * Driver private area in the SCSI command structure.116 */117struct sym_ucmd { /* Override the SCSI pointer structure */118 struct completion *eh_done; /* SCSI error handling */119};120 121#define SYM_UCMD_PTR(cmd) ((struct sym_ucmd *)scsi_cmd_priv(cmd))122#define SYM_SOFTC_PTR(cmd) sym_get_hcb(cmd->device->host)123 124/*125 * Complete a pending CAM CCB.126 */127void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *cmd)128{129 struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd);130 131 if (ucmd->eh_done)132 complete(ucmd->eh_done);133 134 scsi_dma_unmap(cmd);135 scsi_done(cmd);136}137 138/*139 * Tell the SCSI layer about a BUS RESET.140 */141void sym_xpt_async_bus_reset(struct sym_hcb *np)142{143 printf_notice("%s: SCSI BUS has been reset.\n", sym_name(np));144 np->s.settle_time = jiffies + sym_driver_setup.settle_delay * HZ;145 np->s.settle_time_valid = 1;146 if (sym_verbose >= 2)147 printf_info("%s: command processing suspended for %d seconds\n",148 sym_name(np), sym_driver_setup.settle_delay);149}150 151/*152 * Choose the more appropriate CAM status if 153 * the IO encountered an extended error.154 */155static int sym_xerr_cam_status(int cam_status, int x_status)156{157 if (x_status) {158 if (x_status & XE_PARITY_ERR)159 cam_status = DID_PARITY;160 else161 cam_status = DID_ERROR;162 }163 return cam_status;164}165 166/*167 * Build CAM result for a failed or auto-sensed IO.168 */169void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid)170{171 struct scsi_cmnd *cmd = cp->cmd;172 u_int cam_status, scsi_status;173 174 cam_status = DID_OK;175 scsi_status = cp->ssss_status;176 177 if (cp->host_flags & HF_SENSE) {178 scsi_status = cp->sv_scsi_status;179 resid = cp->sv_resid;180 if (sym_verbose && cp->sv_xerr_status)181 sym_print_xerr(cmd, cp->sv_xerr_status);182 if (cp->host_status == HS_COMPLETE &&183 cp->ssss_status == S_GOOD &&184 cp->xerr_status == 0) {185 cam_status = sym_xerr_cam_status(DID_OK,186 cp->sv_xerr_status);187 /*188 * Bounce back the sense data to user.189 */190 memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);191 memcpy(cmd->sense_buffer, cp->sns_bbuf,192 min(SCSI_SENSE_BUFFERSIZE, SYM_SNS_BBUF_LEN));193#if 0194 /*195 * If the device reports a UNIT ATTENTION condition 196 * due to a RESET condition, we should consider all 197 * disconnect CCBs for this unit as aborted.198 */199 if (1) {200 u_char *p;201 p = (u_char *) cmd->sense_data;202 if (p[0]==0x70 && p[2]==0x6 && p[12]==0x29)203 sym_clear_tasks(np, DID_ABORT,204 cp->target,cp->lun, -1);205 }206#endif207 } else {208 /*209 * Error return from our internal request sense. This210 * is bad: we must clear the contingent allegiance211 * condition otherwise the device will always return212 * BUSY. Use a big stick.213 */214 sym_reset_scsi_target(np, cmd->device->id);215 cam_status = DID_ERROR;216 }217 } else if (cp->host_status == HS_COMPLETE) /* Bad SCSI status */218 cam_status = DID_OK;219 else if (cp->host_status == HS_SEL_TIMEOUT) /* Selection timeout */220 cam_status = DID_NO_CONNECT;221 else if (cp->host_status == HS_UNEXPECTED) /* Unexpected BUS FREE*/222 cam_status = DID_ERROR;223 else { /* Extended error */224 if (sym_verbose) {225 sym_print_addr(cmd, "COMMAND FAILED (%x %x %x).\n",226 cp->host_status, cp->ssss_status,227 cp->xerr_status);228 }229 /*230 * Set the most appropriate value for CAM status.231 */232 cam_status = sym_xerr_cam_status(DID_ERROR, cp->xerr_status);233 }234 scsi_set_resid(cmd, resid);235 cmd->result = (cam_status << 16) | scsi_status;236}237 238static int sym_scatter(struct sym_hcb *np, struct sym_ccb *cp, struct scsi_cmnd *cmd)239{240 int segment;241 int use_sg;242 243 cp->data_len = 0;244 245 use_sg = scsi_dma_map(cmd);246 if (use_sg > 0) {247 struct scatterlist *sg;248 struct sym_tcb *tp = &np->target[cp->target];249 struct sym_tblmove *data;250 251 if (use_sg > SYM_CONF_MAX_SG) {252 scsi_dma_unmap(cmd);253 return -1;254 }255 256 data = &cp->phys.data[SYM_CONF_MAX_SG - use_sg];257 258 scsi_for_each_sg(cmd, sg, use_sg, segment) {259 dma_addr_t baddr = sg_dma_address(sg);260 unsigned int len = sg_dma_len(sg);261 262 if ((len & 1) && (tp->head.wval & EWS)) {263 len++;264 cp->odd_byte_adjustment++;265 }266 267 sym_build_sge(np, &data[segment], baddr, len);268 cp->data_len += len;269 }270 } else {271 segment = -2;272 }273 274 return segment;275}276 277/*278 * Queue a SCSI command.279 */280static int sym_queue_command(struct sym_hcb *np, struct scsi_cmnd *cmd)281{282 struct scsi_device *sdev = cmd->device;283 struct sym_tcb *tp;284 struct sym_lcb *lp;285 struct sym_ccb *cp;286 int order;287 288 /*289 * Retrieve the target descriptor.290 */291 tp = &np->target[sdev->id];292 293 /*294 * Select tagged/untagged.295 */296 lp = sym_lp(tp, sdev->lun);297 order = (lp && lp->s.reqtags) ? M_SIMPLE_TAG : 0;298 299 /*300 * Queue the SCSI IO.301 */302 cp = sym_get_ccb(np, cmd, order);303 if (!cp)304 return 1; /* Means resource shortage */305 sym_queue_scsiio(np, cmd, cp);306 return 0;307}308 309/*310 * Setup buffers and pointers that address the CDB.311 */312static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)313{314 memcpy(cp->cdb_buf, cmd->cmnd, cmd->cmd_len);315 316 cp->phys.cmd.addr = CCB_BA(cp, cdb_buf[0]);317 cp->phys.cmd.size = cpu_to_scr(cmd->cmd_len);318 319 return 0;320}321 322/*323 * Setup pointers that address the data and start the I/O.324 */325int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp)326{327 u32 lastp, goalp;328 int dir;329 330 /*331 * Build the CDB.332 */333 if (sym_setup_cdb(np, cmd, cp))334 goto out_abort;335 336 /*337 * No direction means no data.338 */339 dir = cmd->sc_data_direction;340 if (dir != DMA_NONE) {341 cp->segments = sym_scatter(np, cp, cmd);342 if (cp->segments < 0) {343 sym_set_cam_status(cmd, DID_ERROR);344 goto out_abort;345 }346 347 /*348 * No segments means no data.349 */350 if (!cp->segments)351 dir = DMA_NONE;352 } else {353 cp->data_len = 0;354 cp->segments = 0;355 }356 357 /*358 * Set the data pointer.359 */360 switch (dir) {361 case DMA_BIDIRECTIONAL:362 scmd_printk(KERN_INFO, cmd, "got DMA_BIDIRECTIONAL command");363 sym_set_cam_status(cmd, DID_ERROR);364 goto out_abort;365 case DMA_TO_DEVICE:366 goalp = SCRIPTA_BA(np, data_out2) + 8;367 lastp = goalp - 8 - (cp->segments * (2*4));368 break;369 case DMA_FROM_DEVICE:370 cp->host_flags |= HF_DATA_IN;371 goalp = SCRIPTA_BA(np, data_in2) + 8;372 lastp = goalp - 8 - (cp->segments * (2*4));373 break;374 case DMA_NONE:375 default:376 lastp = goalp = SCRIPTB_BA(np, no_data);377 break;378 }379 380 /*381 * Set all pointers values needed by SCRIPTS.382 */383 cp->phys.head.lastp = cpu_to_scr(lastp);384 cp->phys.head.savep = cpu_to_scr(lastp);385 cp->startp = cp->phys.head.savep;386 cp->goalp = cpu_to_scr(goalp);387 388 /*389 * When `#ifed 1', the code below makes the driver 390 * panic on the first attempt to write to a SCSI device.391 * It is the first test we want to do after a driver 392 * change that does not seem obviously safe. :)393 */394#if 0395 switch (cp->cdb_buf[0]) {396 case 0x0A: case 0x2A: case 0xAA:397 panic("XXXXXXXXXXXXX WRITE NOT YET ALLOWED XXXXXXXXXXXXXX\n");398 break;399 default:400 break;401 }402#endif403 404 /*405 * activate this job.406 */407 sym_put_start_queue(np, cp);408 return 0;409 410out_abort:411 sym_free_ccb(np, cp);412 sym_xpt_done(np, cmd);413 return 0;414}415 416 417/*418 * timer daemon.419 *420 * Misused to keep the driver running when421 * interrupts are not configured correctly.422 */423static void sym_timer(struct sym_hcb *np)424{425 unsigned long thistime = jiffies;426 427 /*428 * Restart the timer.429 */430 np->s.timer.expires = thistime + SYM_CONF_TIMER_INTERVAL;431 add_timer(&np->s.timer);432 433 /*434 * If we are resetting the ncr, wait for settle_time before 435 * clearing it. Then command processing will be resumed.436 */437 if (np->s.settle_time_valid) {438 if (time_before_eq(np->s.settle_time, thistime)) {439 if (sym_verbose >= 2 )440 printk("%s: command processing resumed\n",441 sym_name(np));442 np->s.settle_time_valid = 0;443 }444 return;445 }446 447 /*448 * Nothing to do for now, but that may come.449 */450 if (np->s.lasttime + 4*HZ < thistime) {451 np->s.lasttime = thistime;452 }453 454#ifdef SYM_CONF_PCIQ_MAY_MISS_COMPLETIONS455 /*456 * Some way-broken PCI bridges may lead to 457 * completions being lost when the clearing 458 * of the INTFLY flag by the CPU occurs 459 * concurrently with the chip raising this flag.460 * If this ever happen, lost completions will 461 * be reaped here.462 */463 sym_wakeup_done(np);464#endif465}466 467 468/*469 * PCI BUS error handler.470 */471void sym_log_bus_error(struct Scsi_Host *shost)472{473 struct sym_data *sym_data = shost_priv(shost);474 struct pci_dev *pdev = sym_data->pdev;475 unsigned short pci_sts;476 pci_read_config_word(pdev, PCI_STATUS, &pci_sts);477 if (pci_sts & 0xf900) {478 pci_write_config_word(pdev, PCI_STATUS, pci_sts);479 shost_printk(KERN_WARNING, shost,480 "PCI bus error: status = 0x%04x\n", pci_sts & 0xf900);481 }482}483 484/*485 * queuecommand method. Entered with the host adapter lock held and486 * interrupts disabled.487 */488static int sym53c8xx_queue_command_lck(struct scsi_cmnd *cmd)489{490 struct sym_hcb *np = SYM_SOFTC_PTR(cmd);491 struct sym_ucmd *ucp = SYM_UCMD_PTR(cmd);492 int sts = 0;493 494 memset(ucp, 0, sizeof(*ucp));495 496 /*497 * Shorten our settle_time if needed for 498 * this command not to time out.499 */500 if (np->s.settle_time_valid && scsi_cmd_to_rq(cmd)->timeout) {501 unsigned long tlimit = jiffies + scsi_cmd_to_rq(cmd)->timeout;502 tlimit -= SYM_CONF_TIMER_INTERVAL*2;503 if (time_after(np->s.settle_time, tlimit)) {504 np->s.settle_time = tlimit;505 }506 }507 508 if (np->s.settle_time_valid)509 return SCSI_MLQUEUE_HOST_BUSY;510 511 sts = sym_queue_command(np, cmd);512 if (sts)513 return SCSI_MLQUEUE_HOST_BUSY;514 return 0;515}516 517static DEF_SCSI_QCMD(sym53c8xx_queue_command)518 519/*520 * Linux entry point of the interrupt handler.521 */522static irqreturn_t sym53c8xx_intr(int irq, void *dev_id)523{524 struct Scsi_Host *shost = dev_id;525 struct sym_data *sym_data = shost_priv(shost);526 irqreturn_t result;527 528 /* Avoid spinloop trying to handle interrupts on frozen device */529 if (pci_channel_offline(sym_data->pdev))530 return IRQ_NONE;531 532 if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("[");533 534 spin_lock(shost->host_lock);535 result = sym_interrupt(shost);536 spin_unlock(shost->host_lock);537 538 if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("]\n");539 540 return result;541}542 543/*544 * Linux entry point of the timer handler545 */546static void sym53c8xx_timer(struct timer_list *t)547{548 struct sym_hcb *np = from_timer(np, t, s.timer);549 unsigned long flags;550 551 spin_lock_irqsave(np->s.host->host_lock, flags);552 sym_timer(np);553 spin_unlock_irqrestore(np->s.host->host_lock, flags);554}555 556 557/*558 * What the eh thread wants us to perform.559 */560#define SYM_EH_ABORT 0561#define SYM_EH_DEVICE_RESET 1562 563/*564 * Generic method for our eh processing.565 * The 'op' argument tells what we have to do.566 */567/*568 * Error handlers called from the eh thread (one thread per HBA).569 */570static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd)571{572 struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd);573 struct Scsi_Host *shost = cmd->device->host;574 struct sym_data *sym_data = shost_priv(shost);575 struct pci_dev *pdev = sym_data->pdev;576 struct sym_hcb *np = sym_data->ncb;577 SYM_QUEHEAD *qp;578 int cmd_queued = 0;579 int sts = -1;580 struct completion eh_done;581 582 scmd_printk(KERN_WARNING, cmd, "ABORT operation started\n");583 584 /*585 * Escalate to host reset if the PCI bus went down586 */587 if (pci_channel_offline(pdev))588 return SCSI_FAILED;589 590 spin_lock_irq(shost->host_lock);591 /* This one is queued in some place -> to wait for completion */592 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {593 struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq);594 if (cp->cmd == cmd) {595 cmd_queued = 1;596 break;597 }598 }599 600 sts = sym_abort_scsiio(np, cmd, 1);601 /* On error, restore everything and cross fingers :) */602 if (sts)603 cmd_queued = 0;604 605 if (cmd_queued) {606 init_completion(&eh_done);607 ucmd->eh_done = &eh_done;608 spin_unlock_irq(shost->host_lock);609 if (!wait_for_completion_timeout(&eh_done, 5*HZ)) {610 ucmd->eh_done = NULL;611 sts = -2;612 }613 } else {614 spin_unlock_irq(shost->host_lock);615 }616 617 dev_warn(&cmd->device->sdev_gendev, "ABORT operation %s.\n",618 sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed");619 return sts ? SCSI_FAILED : SCSI_SUCCESS;620}621 622static int sym53c8xx_eh_target_reset_handler(struct scsi_cmnd *cmd)623{624 struct scsi_target *starget = scsi_target(cmd->device);625 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);626 struct sym_data *sym_data = shost_priv(shost);627 struct pci_dev *pdev = sym_data->pdev;628 struct sym_hcb *np = sym_data->ncb;629 SYM_QUEHEAD *qp;630 int sts;631 struct completion eh_done;632 633 starget_printk(KERN_WARNING, starget,634 "TARGET RESET operation started\n");635 636 /*637 * Escalate to host reset if the PCI bus went down638 */639 if (pci_channel_offline(pdev))640 return SCSI_FAILED;641 642 spin_lock_irq(shost->host_lock);643 sts = sym_reset_scsi_target(np, starget->id);644 if (!sts) {645 FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {646 struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb,647 link_ccbq);648 struct scsi_cmnd *cmd = cp->cmd;649 struct sym_ucmd *ucmd;650 651 if (!cmd || cmd->device->channel != starget->channel ||652 cmd->device->id != starget->id)653 continue;654 655 ucmd = SYM_UCMD_PTR(cmd);656 init_completion(&eh_done);657 ucmd->eh_done = &eh_done;658 spin_unlock_irq(shost->host_lock);659 if (!wait_for_completion_timeout(&eh_done, 5*HZ)) {660 ucmd->eh_done = NULL;661 sts = -2;662 }663 spin_lock_irq(shost->host_lock);664 }665 }666 spin_unlock_irq(shost->host_lock);667 668 starget_printk(KERN_WARNING, starget, "TARGET RESET operation %s.\n",669 sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed");670 return SCSI_SUCCESS;671}672 673static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)674{675 struct Scsi_Host *shost = cmd->device->host;676 struct sym_data *sym_data = shost_priv(shost);677 struct pci_dev *pdev = sym_data->pdev;678 struct sym_hcb *np = sym_data->ncb;679 680 scmd_printk(KERN_WARNING, cmd, "BUS RESET operation started\n");681 682 /*683 * Escalate to host reset if the PCI bus went down684 */685 if (pci_channel_offline(pdev))686 return SCSI_FAILED;687 688 spin_lock_irq(shost->host_lock);689 sym_reset_scsi_bus(np, 1);690 spin_unlock_irq(shost->host_lock);691 692 dev_warn(&cmd->device->sdev_gendev, "BUS RESET operation complete.\n");693 return SCSI_SUCCESS;694}695 696static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd)697{698 struct Scsi_Host *shost = cmd->device->host;699 struct sym_data *sym_data = shost_priv(shost);700 struct pci_dev *pdev = sym_data->pdev;701 struct sym_hcb *np = sym_data->ncb;702 struct completion eh_done;703 int finished_reset = 1;704 705 shost_printk(KERN_WARNING, shost, "HOST RESET operation started\n");706 707 /* We may be in an error condition because the PCI bus708 * went down. In this case, we need to wait until the709 * PCI bus is reset, the card is reset, and only then710 * proceed with the scsi error recovery. There's no711 * point in hurrying; take a leisurely wait.712 */713#define WAIT_FOR_PCI_RECOVERY 35714 if (pci_channel_offline(pdev)) {715 init_completion(&eh_done);716 spin_lock_irq(shost->host_lock);717 /* Make sure we didn't race */718 if (pci_channel_offline(pdev)) {719 BUG_ON(sym_data->io_reset);720 sym_data->io_reset = &eh_done;721 finished_reset = 0;722 }723 spin_unlock_irq(shost->host_lock);724 if (!finished_reset)725 finished_reset = wait_for_completion_timeout726 (sym_data->io_reset,727 WAIT_FOR_PCI_RECOVERY*HZ);728 spin_lock_irq(shost->host_lock);729 sym_data->io_reset = NULL;730 spin_unlock_irq(shost->host_lock);731 }732 733 if (finished_reset) {734 sym_reset_scsi_bus(np, 0);735 sym_start_up(shost, 1);736 }737 738 shost_printk(KERN_WARNING, shost, "HOST RESET operation %s.\n",739 finished_reset==1 ? "complete" : "failed");740 return finished_reset ? SCSI_SUCCESS : SCSI_FAILED;741}742 743/*744 * Tune device queuing depth, according to various limits.745 */746static void sym_tune_dev_queuing(struct sym_tcb *tp, int lun, u_short reqtags)747{748 struct sym_lcb *lp = sym_lp(tp, lun);749 u_short oldtags;750 751 if (!lp)752 return;753 754 oldtags = lp->s.reqtags;755 756 if (reqtags > lp->s.scdev_depth)757 reqtags = lp->s.scdev_depth;758 759 lp->s.reqtags = reqtags;760 761 if (reqtags != oldtags) {762 dev_info(&tp->starget->dev,763 "tagged command queuing %s, command queue depth %d.\n",764 lp->s.reqtags ? "enabled" : "disabled", reqtags);765 }766}767 768static int sym53c8xx_slave_alloc(struct scsi_device *sdev)769{770 struct sym_hcb *np = sym_get_hcb(sdev->host);771 struct sym_tcb *tp = &np->target[sdev->id];772 struct sym_lcb *lp;773 unsigned long flags;774 int error;775 776 if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN)777 return -ENXIO;778 779 spin_lock_irqsave(np->s.host->host_lock, flags);780 781 /*782 * Fail the device init if the device is flagged NOSCAN at BOOT in783 * the NVRAM. This may speed up boot and maintain coherency with784 * BIOS device numbering. Clearing the flag allows the user to785 * rescan skipped devices later. We also return an error for786 * devices not flagged for SCAN LUNS in the NVRAM since some single787 * lun devices behave badly when asked for a non zero LUN.788 */789 790 if (tp->usrflags & SYM_SCAN_BOOT_DISABLED) {791 tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED;792 starget_printk(KERN_INFO, sdev->sdev_target,793 "Scan at boot disabled in NVRAM\n");794 error = -ENXIO;795 goto out;796 }797 798 if (tp->usrflags & SYM_SCAN_LUNS_DISABLED) {799 if (sdev->lun != 0) {800 error = -ENXIO;801 goto out;802 }803 starget_printk(KERN_INFO, sdev->sdev_target,804 "Multiple LUNs disabled in NVRAM\n");805 }806 807 lp = sym_alloc_lcb(np, sdev->id, sdev->lun);808 if (!lp) {809 error = -ENOMEM;810 goto out;811 }812 if (tp->nlcb == 1)813 tp->starget = sdev->sdev_target;814 815 spi_min_period(tp->starget) = tp->usr_period;816 spi_max_width(tp->starget) = tp->usr_width;817 818 error = 0;819out:820 spin_unlock_irqrestore(np->s.host->host_lock, flags);821 822 return error;823}824 825/*826 * Linux entry point for device queue sizing.827 */828static int sym53c8xx_slave_configure(struct scsi_device *sdev)829{830 struct sym_hcb *np = sym_get_hcb(sdev->host);831 struct sym_tcb *tp = &np->target[sdev->id];832 struct sym_lcb *lp = sym_lp(tp, sdev->lun);833 int reqtags, depth_to_use;834 835 /*836 * Get user flags.837 */838 lp->curr_flags = lp->user_flags;839 840 /*841 * Select queue depth from driver setup.842 * Do not use more than configured by user.843 * Use at least 1.844 * Do not use more than our maximum.845 */846 reqtags = sym_driver_setup.max_tag;847 if (reqtags > tp->usrtags)848 reqtags = tp->usrtags;849 if (!sdev->tagged_supported)850 reqtags = 0;851 if (reqtags > SYM_CONF_MAX_TAG)852 reqtags = SYM_CONF_MAX_TAG;853 depth_to_use = reqtags ? reqtags : 1;854 scsi_change_queue_depth(sdev, depth_to_use);855 lp->s.scdev_depth = depth_to_use;856 sym_tune_dev_queuing(tp, sdev->lun, reqtags);857 858 if (!spi_initial_dv(sdev->sdev_target))859 spi_dv_device(sdev);860 861 return 0;862}863 864static void sym53c8xx_slave_destroy(struct scsi_device *sdev)865{866 struct sym_hcb *np = sym_get_hcb(sdev->host);867 struct sym_tcb *tp = &np->target[sdev->id];868 struct sym_lcb *lp = sym_lp(tp, sdev->lun);869 unsigned long flags;870 871 /* if slave_alloc returned before allocating a sym_lcb, return */872 if (!lp)873 return;874 875 spin_lock_irqsave(np->s.host->host_lock, flags);876 877 if (lp->busy_itlq || lp->busy_itl) {878 /*879 * This really shouldn't happen, but we can't return an error880 * so let's try to stop all on-going I/O.881 */882 starget_printk(KERN_WARNING, tp->starget,883 "Removing busy LCB (%d)\n", (u8)sdev->lun);884 sym_reset_scsi_bus(np, 1);885 }886 887 if (sym_free_lcb(np, sdev->id, sdev->lun) == 0) {888 /*889 * It was the last unit for this target.890 */891 tp->head.sval = 0;892 tp->head.wval = np->rv_scntl3;893 tp->head.uval = 0;894 tp->tgoal.check_nego = 1;895 tp->starget = NULL;896 }897 898 spin_unlock_irqrestore(np->s.host->host_lock, flags);899}900 901/*902 * Linux entry point for info() function903 */904static const char *sym53c8xx_info (struct Scsi_Host *host)905{906 return SYM_DRIVER_NAME;907}908 909 910#ifdef SYM_LINUX_PROC_INFO_SUPPORT911/*912 * Proc file system stuff913 *914 * A read operation returns adapter information.915 * A write operation is a control command.916 * The string is parsed in the driver code and the command is passed 917 * to the sym_usercmd() function.918 */919 920#ifdef SYM_LINUX_USER_COMMAND_SUPPORT921 922struct sym_usrcmd {923 u_long target;924 u_long lun;925 u_long data;926 u_long cmd;927};928 929#define UC_SETSYNC 10930#define UC_SETTAGS 11931#define UC_SETDEBUG 12932#define UC_SETWIDE 14933#define UC_SETFLAG 15934#define UC_SETVERBOSE 17935#define UC_RESETDEV 18936#define UC_CLEARDEV 19937 938static void sym_exec_user_command (struct sym_hcb *np, struct sym_usrcmd *uc)939{940 struct sym_tcb *tp;941 int t, l;942 943 switch (uc->cmd) {944 case 0: return;945 946#ifdef SYM_LINUX_DEBUG_CONTROL_SUPPORT947 case UC_SETDEBUG:948 sym_debug_flags = uc->data;949 break;950#endif951 case UC_SETVERBOSE:952 np->verbose = uc->data;953 break;954 default:955 /*956 * We assume that other commands apply to targets.957 * This should always be the case and avoid the below 958 * 4 lines to be repeated 6 times.959 */960 for (t = 0; t < SYM_CONF_MAX_TARGET; t++) {961 if (!((uc->target >> t) & 1))962 continue;963 tp = &np->target[t];964 if (!tp->nlcb)965 continue;966 967 switch (uc->cmd) {968 969 case UC_SETSYNC:970 if (!uc->data || uc->data >= 255) {971 tp->tgoal.iu = tp->tgoal.dt =972 tp->tgoal.qas = 0;973 tp->tgoal.offset = 0;974 } else if (uc->data <= 9 && np->minsync_dt) {975 if (uc->data < np->minsync_dt)976 uc->data = np->minsync_dt;977 tp->tgoal.iu = tp->tgoal.dt =978 tp->tgoal.qas = 1;979 tp->tgoal.width = 1;980 tp->tgoal.period = uc->data;981 tp->tgoal.offset = np->maxoffs_dt;982 } else {983 if (uc->data < np->minsync)984 uc->data = np->minsync;985 tp->tgoal.iu = tp->tgoal.dt =986 tp->tgoal.qas = 0;987 tp->tgoal.period = uc->data;988 tp->tgoal.offset = np->maxoffs;989 }990 tp->tgoal.check_nego = 1;991 break;992 case UC_SETWIDE:993 tp->tgoal.width = uc->data ? 1 : 0;994 tp->tgoal.check_nego = 1;995 break;996 case UC_SETTAGS:997 for (l = 0; l < SYM_CONF_MAX_LUN; l++)998 sym_tune_dev_queuing(tp, l, uc->data);999 break;1000 case UC_RESETDEV:1001 tp->to_reset = 1;1002 np->istat_sem = SEM;1003 OUTB(np, nc_istat, SIGP|SEM);1004 break;1005 case UC_CLEARDEV:1006 for (l = 0; l < SYM_CONF_MAX_LUN; l++) {1007 struct sym_lcb *lp = sym_lp(tp, l);1008 if (lp) lp->to_clear = 1;1009 }1010 np->istat_sem = SEM;1011 OUTB(np, nc_istat, SIGP|SEM);1012 break;1013 case UC_SETFLAG:1014 tp->usrflags = uc->data;1015 break;1016 }1017 }1018 break;1019 }1020}1021 1022static int sym_skip_spaces(char *ptr, int len)1023{1024 int cnt, c;1025 1026 for (cnt = len; cnt > 0 && (c = *ptr++) && isspace(c); cnt--);1027 1028 return (len - cnt);1029}1030 1031static int get_int_arg(char *ptr, int len, u_long *pv)1032{1033 char *end;1034 1035 *pv = simple_strtoul(ptr, &end, 10);1036 return (end - ptr);1037}1038 1039static int is_keyword(char *ptr, int len, char *verb)1040{1041 int verb_len = strlen(verb);1042 1043 if (len >= verb_len && !memcmp(verb, ptr, verb_len))1044 return verb_len;1045 else1046 return 0;1047}1048 1049#define SKIP_SPACES(ptr, len) \1050 if ((arg_len = sym_skip_spaces(ptr, len)) < 1) \1051 return -EINVAL; \1052 ptr += arg_len; len -= arg_len;1053 1054#define GET_INT_ARG(ptr, len, v) \1055 if (!(arg_len = get_int_arg(ptr, len, &(v)))) \1056 return -EINVAL; \1057 ptr += arg_len; len -= arg_len;1058 1059 1060/*1061 * Parse a control command1062 */1063 1064static int sym_user_command(struct Scsi_Host *shost, char *buffer, int length)1065{1066 struct sym_hcb *np = sym_get_hcb(shost);1067 char *ptr = buffer;1068 int len = length;1069 struct sym_usrcmd cmd, *uc = &cmd;1070 int arg_len;1071 u_long target;1072 1073 memset(uc, 0, sizeof(*uc));1074 1075 if (len > 0 && ptr[len-1] == '\n')1076 --len;1077 1078 if ((arg_len = is_keyword(ptr, len, "setsync")) != 0)1079 uc->cmd = UC_SETSYNC;1080 else if ((arg_len = is_keyword(ptr, len, "settags")) != 0)1081 uc->cmd = UC_SETTAGS;1082 else if ((arg_len = is_keyword(ptr, len, "setverbose")) != 0)1083 uc->cmd = UC_SETVERBOSE;1084 else if ((arg_len = is_keyword(ptr, len, "setwide")) != 0)1085 uc->cmd = UC_SETWIDE;1086#ifdef SYM_LINUX_DEBUG_CONTROL_SUPPORT1087 else if ((arg_len = is_keyword(ptr, len, "setdebug")) != 0)1088 uc->cmd = UC_SETDEBUG;1089#endif1090 else if ((arg_len = is_keyword(ptr, len, "setflag")) != 0)1091 uc->cmd = UC_SETFLAG;1092 else if ((arg_len = is_keyword(ptr, len, "resetdev")) != 0)1093 uc->cmd = UC_RESETDEV;1094 else if ((arg_len = is_keyword(ptr, len, "cleardev")) != 0)1095 uc->cmd = UC_CLEARDEV;1096 else1097 arg_len = 0;1098 1099#ifdef DEBUG_PROC_INFO1100printk("sym_user_command: arg_len=%d, cmd=%ld\n", arg_len, uc->cmd);1101#endif1102 1103 if (!arg_len)1104 return -EINVAL;1105 ptr += arg_len; len -= arg_len;1106 1107 switch(uc->cmd) {1108 case UC_SETSYNC:1109 case UC_SETTAGS:1110 case UC_SETWIDE:1111 case UC_SETFLAG:1112 case UC_RESETDEV:1113 case UC_CLEARDEV:1114 SKIP_SPACES(ptr, len);1115 if ((arg_len = is_keyword(ptr, len, "all")) != 0) {1116 ptr += arg_len; len -= arg_len;1117 uc->target = ~0;1118 } else {1119 GET_INT_ARG(ptr, len, target);1120 uc->target = (1<<target);1121#ifdef DEBUG_PROC_INFO1122printk("sym_user_command: target=%ld\n", target);1123#endif1124 }1125 break;1126 }1127 1128 switch(uc->cmd) {1129 case UC_SETVERBOSE:1130 case UC_SETSYNC:1131 case UC_SETTAGS:1132 case UC_SETWIDE:1133 SKIP_SPACES(ptr, len);1134 GET_INT_ARG(ptr, len, uc->data);1135#ifdef DEBUG_PROC_INFO1136printk("sym_user_command: data=%ld\n", uc->data);1137#endif1138 break;1139#ifdef SYM_LINUX_DEBUG_CONTROL_SUPPORT1140 case UC_SETDEBUG:1141 while (len > 0) {1142 SKIP_SPACES(ptr, len);1143 if ((arg_len = is_keyword(ptr, len, "alloc")))1144 uc->data |= DEBUG_ALLOC;1145 else if ((arg_len = is_keyword(ptr, len, "phase")))1146 uc->data |= DEBUG_PHASE;1147 else if ((arg_len = is_keyword(ptr, len, "queue")))1148 uc->data |= DEBUG_QUEUE;1149 else if ((arg_len = is_keyword(ptr, len, "result")))1150 uc->data |= DEBUG_RESULT;1151 else if ((arg_len = is_keyword(ptr, len, "scatter")))1152 uc->data |= DEBUG_SCATTER;1153 else if ((arg_len = is_keyword(ptr, len, "script")))1154 uc->data |= DEBUG_SCRIPT;1155 else if ((arg_len = is_keyword(ptr, len, "tiny")))1156 uc->data |= DEBUG_TINY;1157 else if ((arg_len = is_keyword(ptr, len, "timing")))1158 uc->data |= DEBUG_TIMING;1159 else if ((arg_len = is_keyword(ptr, len, "nego")))1160 uc->data |= DEBUG_NEGO;1161 else if ((arg_len = is_keyword(ptr, len, "tags")))1162 uc->data |= DEBUG_TAGS;1163 else if ((arg_len = is_keyword(ptr, len, "pointer")))1164 uc->data |= DEBUG_POINTER;1165 else1166 return -EINVAL;1167 ptr += arg_len; len -= arg_len;1168 }1169#ifdef DEBUG_PROC_INFO1170printk("sym_user_command: data=%ld\n", uc->data);1171#endif1172 break;1173#endif /* SYM_LINUX_DEBUG_CONTROL_SUPPORT */1174 case UC_SETFLAG:1175 while (len > 0) {1176 SKIP_SPACES(ptr, len);1177 if ((arg_len = is_keyword(ptr, len, "no_disc")))1178 uc->data &= ~SYM_DISC_ENABLED;1179 else1180 return -EINVAL;1181 ptr += arg_len; len -= arg_len;1182 }1183 break;1184 default:1185 break;1186 }1187 1188 if (len)1189 return -EINVAL;1190 else {1191 unsigned long flags;1192 1193 spin_lock_irqsave(shost->host_lock, flags);1194 sym_exec_user_command(np, uc);1195 spin_unlock_irqrestore(shost->host_lock, flags);1196 }1197 return length;1198}1199 1200#endif /* SYM_LINUX_USER_COMMAND_SUPPORT */1201 1202 1203/*1204 * Copy formatted information into the input buffer.1205 */1206static int sym_show_info(struct seq_file *m, struct Scsi_Host *shost)1207{1208#ifdef SYM_LINUX_USER_INFO_SUPPORT1209 struct sym_data *sym_data = shost_priv(shost);1210 struct pci_dev *pdev = sym_data->pdev;1211 struct sym_hcb *np = sym_data->ncb;1212 1213 seq_printf(m, "Chip " NAME53C "%s, device id 0x%x, "1214 "revision id 0x%x\n", np->s.chip_name,1215 pdev->device, pdev->revision);1216 seq_printf(m, "At PCI address %s, IRQ %u\n",1217 pci_name(pdev), pdev->irq);1218 seq_printf(m, "Min. period factor %d, %s SCSI BUS%s\n",1219 (int) (np->minsync_dt ? np->minsync_dt : np->minsync),1220 np->maxwide ? "Wide" : "Narrow",1221 np->minsync_dt ? ", DT capable" : "");1222 1223 seq_printf(m, "Max. started commands %d, "1224 "max. commands per LUN %d\n",1225 SYM_CONF_MAX_START, SYM_CONF_MAX_TAG);1226 1227 return 0;1228#else1229 return -EINVAL;1230#endif /* SYM_LINUX_USER_INFO_SUPPORT */1231}1232 1233#endif /* SYM_LINUX_PROC_INFO_SUPPORT */1234 1235/*1236 * Free resources claimed by sym_iomap_device(). Note that1237 * sym_free_resources() should be used instead of this function after calling1238 * sym_attach().1239 */1240static void sym_iounmap_device(struct sym_device *device)1241{1242 if (device->s.ioaddr)1243 pci_iounmap(device->pdev, device->s.ioaddr);1244 if (device->s.ramaddr)1245 pci_iounmap(device->pdev, device->s.ramaddr);1246}1247 1248/*1249 * Free controller resources.1250 */1251static void sym_free_resources(struct sym_hcb *np, struct pci_dev *pdev,1252 int do_free_irq)1253{1254 /*1255 * Free O/S specific resources.1256 */1257 if (do_free_irq)1258 free_irq(pdev->irq, np->s.host);1259 if (np->s.ioaddr)1260 pci_iounmap(pdev, np->s.ioaddr);1261 if (np->s.ramaddr)1262 pci_iounmap(pdev, np->s.ramaddr);1263 /*1264 * Free O/S independent resources.1265 */1266 sym_hcb_free(np);1267 1268 sym_mfree_dma(np, sizeof(*np), "HCB");1269}1270 1271/*1272 * Host attach and initialisations.1273 *1274 * Allocate host data and ncb structure.1275 * Remap MMIO region.1276 * Do chip initialization.1277 * If all is OK, install interrupt handling and1278 * start the timer daemon.1279 */1280static struct Scsi_Host *sym_attach(const struct scsi_host_template *tpnt, int unit,1281 struct sym_device *dev)1282{1283 struct sym_data *sym_data;1284 struct sym_hcb *np = NULL;1285 struct Scsi_Host *shost = NULL;1286 struct pci_dev *pdev = dev->pdev;1287 unsigned long flags;1288 struct sym_fw *fw;1289 int do_free_irq = 0;1290 1291 printk(KERN_INFO "sym%d: <%s> rev 0x%x at pci %s irq %u\n",1292 unit, dev->chip.name, pdev->revision, pci_name(pdev),1293 pdev->irq);1294 1295 /*1296 * Get the firmware for this chip.1297 */1298 fw = sym_find_firmware(&dev->chip);1299 if (!fw)1300 goto attach_failed;1301 1302 shost = scsi_host_alloc(tpnt, sizeof(*sym_data));1303 if (!shost)1304 goto attach_failed;1305 sym_data = shost_priv(shost);1306 1307 /*1308 * Allocate immediately the host control block, 1309 * since we are only expecting to succeed. :)1310 * We keep track in the HCB of all the resources that 1311 * are to be released on error.1312 */1313 np = __sym_calloc_dma(&pdev->dev, sizeof(*np), "HCB");1314 if (!np)1315 goto attach_failed;1316 np->bus_dmat = &pdev->dev; /* Result in 1 DMA pool per HBA */1317 sym_data->ncb = np;1318 sym_data->pdev = pdev;1319 np->s.host = shost;1320 1321 pci_set_drvdata(pdev, shost);1322 1323 /*1324 * Copy some useful infos to the HCB.1325 */1326 np->hcb_ba = vtobus(np);1327 np->verbose = sym_driver_setup.verbose;1328 np->s.unit = unit;1329 np->features = dev->chip.features;1330 np->clock_divn = dev->chip.nr_divisor;1331 np->maxoffs = dev->chip.offset_max;1332 np->maxburst = dev->chip.burst_max;1333 np->myaddr = dev->host_id;1334 np->mmio_ba = (u32)dev->mmio_base;1335 np->ram_ba = (u32)dev->ram_base;1336 np->s.ioaddr = dev->s.ioaddr;1337 np->s.ramaddr = dev->s.ramaddr;1338 1339 /*1340 * Edit its name.1341 */1342 strscpy(np->s.chip_name, dev->chip.name, sizeof(np->s.chip_name));1343 sprintf(np->s.inst_name, "sym%d", np->s.unit);1344 1345 if ((SYM_CONF_DMA_ADDRESSING_MODE > 0) && (np->features & FE_DAC) &&1346 !dma_set_mask(&pdev->dev, DMA_DAC_MASK)) {1347 set_dac(np);1348 } else if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {1349 printf_warning("%s: No suitable DMA available\n", sym_name(np));1350 goto attach_failed;1351 }1352 1353 if (sym_hcb_attach(shost, fw, dev->nvram))1354 goto attach_failed;1355 1356 /*1357 * Install the interrupt handler.1358 * If we synchonize the C code with SCRIPTS on interrupt, 1359 * we do not want to share the INTR line at all.1360 */1361 if (request_irq(pdev->irq, sym53c8xx_intr, IRQF_SHARED, NAME53C8XX,1362 shost)) {1363 printf_err("%s: request irq %u failure\n",1364 sym_name(np), pdev->irq);1365 goto attach_failed;1366 }1367 do_free_irq = 1;1368 1369 /*1370 * After SCSI devices have been opened, we cannot1371 * reset the bus safely, so we do it here.1372 */1373 spin_lock_irqsave(shost->host_lock, flags);1374 if (sym_reset_scsi_bus(np, 0))1375 goto reset_failed;1376 1377 /*1378 * Start the SCRIPTS.1379 */1380 sym_start_up(shost, 1);1381 1382 /*1383 * Start the timer daemon1384 */1385 timer_setup(&np->s.timer, sym53c8xx_timer, 0);1386 np->s.lasttime=0;1387 sym_timer (np);1388 1389 /*1390 * Fill Linux host instance structure1391 * and return success.1392 */1393 shost->max_channel = 0;1394 shost->this_id = np->myaddr;1395 shost->max_id = np->maxwide ? 16 : 8;1396 shost->max_lun = SYM_CONF_MAX_LUN;1397 shost->unique_id = pci_resource_start(pdev, 0);1398 shost->cmd_per_lun = SYM_CONF_MAX_TAG;1399 shost->can_queue = (SYM_CONF_MAX_START-2);1400 shost->sg_tablesize = SYM_CONF_MAX_SG;1401 shost->max_cmd_len = 16;1402 BUG_ON(sym2_transport_template == NULL);1403 shost->transportt = sym2_transport_template;1404 1405 /* 53c896 rev 1 errata: DMA may not cross 16MB boundary */1406 if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && pdev->revision < 2)1407 shost->dma_boundary = 0xFFFFFF;1408 1409 spin_unlock_irqrestore(shost->host_lock, flags);1410 1411 return shost;1412 1413 reset_failed:1414 printf_err("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, "1415 "TERMINATION, DEVICE POWER etc.!\n", sym_name(np));1416 spin_unlock_irqrestore(shost->host_lock, flags);1417 attach_failed:1418 printf_info("sym%d: giving up ...\n", unit);1419 if (np)1420 sym_free_resources(np, pdev, do_free_irq);1421 else1422 sym_iounmap_device(dev);1423 if (shost)1424 scsi_host_put(shost);1425 1426 return NULL;1427}1428 1429 1430/*1431 * Detect and try to read SYMBIOS and TEKRAM NVRAM.1432 */1433#if SYM_CONF_NVRAM_SUPPORT1434static void sym_get_nvram(struct sym_device *devp, struct sym_nvram *nvp)1435{1436 devp->nvram = nvp;1437 nvp->type = 0;1438 1439 sym_read_nvram(devp, nvp);1440}1441#else1442static inline void sym_get_nvram(struct sym_device *devp, struct sym_nvram *nvp)1443{1444}1445#endif /* SYM_CONF_NVRAM_SUPPORT */1446 1447static int sym_check_supported(struct sym_device *device)1448{1449 struct sym_chip *chip;1450 struct pci_dev *pdev = device->pdev;1451 unsigned long io_port = pci_resource_start(pdev, 0);1452 int i;1453 1454 /*1455 * If user excluded this chip, do not initialize it.1456 * I hate this code so much. Must kill it.1457 */1458 if (io_port) {1459 for (i = 0 ; i < 8 ; i++) {1460 if (sym_driver_setup.excludes[i] == io_port)1461 return -ENODEV;1462 }1463 }1464 1465 /*1466 * Check if the chip is supported. Then copy the chip description1467 * to our device structure so we can make it match the actual device1468 * and options.1469 */1470 chip = sym_lookup_chip_table(pdev->device, pdev->revision);1471 if (!chip) {1472 dev_info(&pdev->dev, "device not supported\n");1473 return -ENODEV;1474 }1475 memcpy(&device->chip, chip, sizeof(device->chip));1476 1477 return 0;1478}1479 1480/*1481 * Ignore Symbios chips controlled by various RAID controllers.1482 * These controllers set value 0x52414944 at RAM end - 16.1483 */1484static int sym_check_raid(struct sym_device *device)1485{1486 unsigned int ram_size, ram_val;1487 1488 if (!device->s.ramaddr)1489 return 0;1490 1491 if (device->chip.features & FE_RAM8K)1492 ram_size = 8192;1493 else1494 ram_size = 4096;1495 1496 ram_val = readl(device->s.ramaddr + ram_size - 16);1497 if (ram_val != 0x52414944)1498 return 0;1499 1500 dev_info(&device->pdev->dev,1501 "not initializing, driven by RAID controller.\n");1502 return -ENODEV;1503}1504 1505static int sym_set_workarounds(struct sym_device *device)1506{1507 struct sym_chip *chip = &device->chip;1508 struct pci_dev *pdev = device->pdev;1509 u_short status_reg;1510 1511 /*1512 * (ITEM 12 of a DEL about the 896 I haven't yet).1513 * We must ensure the chip will use WRITE AND INVALIDATE.1514 * The revision number limit is for now arbitrary.1515 */1516 if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && pdev->revision < 0x4) {1517 chip->features |= (FE_WRIE | FE_CLSE);1518 }1519 1520 /* If the chip can do Memory Write Invalidate, enable it */1521 if (chip->features & FE_WRIE) {1522 if (pci_set_mwi(pdev))1523 return -ENODEV;1524 }1525 1526 /*1527 * Work around for errant bit in 895A. The 66Mhz1528 * capable bit is set erroneously. Clear this bit.1529 * (Item 1 DEL 533)1530 *1531 * Make sure Config space and Features agree.1532 *1533 * Recall: writes are not normal to status register -1534 * write a 1 to clear and a 0 to leave unchanged.1535 * Can only reset bits.1536 */1537 pci_read_config_word(pdev, PCI_STATUS, &status_reg);1538 if (chip->features & FE_66MHZ) {1539 if (!(status_reg & PCI_STATUS_66MHZ))1540 chip->features &= ~FE_66MHZ;1541 } else {1542 if (status_reg & PCI_STATUS_66MHZ) {1543 status_reg = PCI_STATUS_66MHZ;1544 pci_write_config_word(pdev, PCI_STATUS, status_reg);1545 pci_read_config_word(pdev, PCI_STATUS, &status_reg);1546 }1547 }1548 1549 return 0;1550}1551 1552/*1553 * Map HBA registers and on-chip SRAM (if present).1554 */1555static int sym_iomap_device(struct sym_device *device)1556{1557 struct pci_dev *pdev = device->pdev;1558 struct pci_bus_region bus_addr;1559 int i = 2;1560 1561 pcibios_resource_to_bus(pdev->bus, &bus_addr, &pdev->resource[1]);1562 device->mmio_base = bus_addr.start;1563 1564 if (device->chip.features & FE_RAM) {1565 /*1566 * If the BAR is 64-bit, resource 2 will be occupied by the1567 * upper 32 bits1568 */1569 if (!pdev->resource[i].flags)1570 i++;1571 pcibios_resource_to_bus(pdev->bus, &bus_addr,1572 &pdev->resource[i]);1573 device->ram_base = bus_addr.start;1574 }1575 1576#ifdef CONFIG_SCSI_SYM53C8XX_MMIO1577 if (device->mmio_base)1578 device->s.ioaddr = pci_iomap(pdev, 1,1579 pci_resource_len(pdev, 1));1580#endif1581 if (!device->s.ioaddr)1582 device->s.ioaddr = pci_iomap(pdev, 0,1583 pci_resource_len(pdev, 0));1584 if (!device->s.ioaddr) {1585 dev_err(&pdev->dev, "could not map registers; giving up.\n");1586 return -EIO;1587 }1588 if (device->ram_base) {1589 device->s.ramaddr = pci_iomap(pdev, i,1590 pci_resource_len(pdev, i));1591 if (!device->s.ramaddr) {1592 dev_warn(&pdev->dev,1593 "could not map SRAM; continuing anyway.\n");1594 device->ram_base = 0;1595 }1596 }1597 1598 return 0;1599}1600 1601/*1602 * The NCR PQS and PDS cards are constructed as a DEC bridge1603 * behind which sits a proprietary NCR memory controller and1604 * either four or two 53c875s as separate devices. We can tell1605 * if an 875 is part of a PQS/PDS or not since if it is, it will1606 * be on the same bus as the memory controller. In its usual1607 * mode of operation, the 875s are slaved to the memory1608 * controller for all transfers. To operate with the Linux1609 * driver, the memory controller is disabled and the 875s1610 * freed to function independently. The only wrinkle is that1611 * the preset SCSI ID (which may be zero) must be read in from1612 * a special configuration space register of the 875.1613 */1614static void sym_config_pqs(struct pci_dev *pdev, struct sym_device *sym_dev)1615{1616 int slot;1617 u8 tmp;1618 1619 for (slot = 0; slot < 256; slot++) {1620 struct pci_dev *memc = pci_get_slot(pdev->bus, slot);1621 1622 if (!memc || memc->vendor != 0x101a || memc->device == 0x0009) {1623 pci_dev_put(memc);1624 continue;1625 }1626 1627 /* bit 1: allow individual 875 configuration */1628 pci_read_config_byte(memc, 0x44, &tmp);1629 if ((tmp & 0x2) == 0) {1630 tmp |= 0x2;1631 pci_write_config_byte(memc, 0x44, tmp);1632 }1633 1634 /* bit 2: drive individual 875 interrupts to the bus */1635 pci_read_config_byte(memc, 0x45, &tmp);1636 if ((tmp & 0x4) == 0) {1637 tmp |= 0x4;1638 pci_write_config_byte(memc, 0x45, tmp);1639 }1640 1641 pci_dev_put(memc);1642 break;1643 }1644 1645 pci_read_config_byte(pdev, 0x84, &tmp);1646 sym_dev->host_id = tmp;1647}1648 1649/*1650 * Called before unloading the module.1651 * Detach the host.1652 * We have to free resources and halt the NCR chip.1653 */1654static int sym_detach(struct Scsi_Host *shost, struct pci_dev *pdev)1655{1656 struct sym_hcb *np = sym_get_hcb(shost);1657 printk("%s: detaching ...\n", sym_name(np));1658 1659 del_timer_sync(&np->s.timer);1660 1661 /*1662 * Reset NCR chip.1663 * We should use sym_soft_reset(), but we don't want to do 1664 * so, since we may not be safe if interrupts occur.1665 */1666 printk("%s: resetting chip\n", sym_name(np));1667 OUTB(np, nc_istat, SRST);1668 INB(np, nc_mbox1);1669 udelay(10);1670 OUTB(np, nc_istat, 0);1671 1672 sym_free_resources(np, pdev, 1);1673 scsi_host_put(shost);1674 1675 return 1;1676}1677 1678/*1679 * Driver host template.1680 */1681static const struct scsi_host_template sym2_template = {1682 .module = THIS_MODULE,1683 .name = "sym53c8xx",1684 .info = sym53c8xx_info, 1685 .cmd_size = sizeof(struct sym_ucmd),1686 .queuecommand = sym53c8xx_queue_command,1687 .slave_alloc = sym53c8xx_slave_alloc,1688 .slave_configure = sym53c8xx_slave_configure,1689 .slave_destroy = sym53c8xx_slave_destroy,1690 .eh_abort_handler = sym53c8xx_eh_abort_handler,1691 .eh_target_reset_handler = sym53c8xx_eh_target_reset_handler,1692 .eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler,1693 .eh_host_reset_handler = sym53c8xx_eh_host_reset_handler,1694 .this_id = 7,1695 .max_sectors = 0xFFFF,1696#ifdef SYM_LINUX_PROC_INFO_SUPPORT1697 .show_info = sym_show_info,1698#ifdef SYM_LINUX_USER_COMMAND_SUPPORT1699 .write_info = sym_user_command,1700#endif1701 .proc_name = NAME53C8XX,1702#endif1703};1704 1705static int attach_count;1706 1707static int sym2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)1708{1709 struct sym_device sym_dev;1710 struct sym_nvram nvram;1711 struct Scsi_Host *shost;1712 int do_iounmap = 0;1713 int do_disable_device = 1;1714 1715 memset(&sym_dev, 0, sizeof(sym_dev));1716 memset(&nvram, 0, sizeof(nvram));1717 sym_dev.pdev = pdev;1718 sym_dev.host_id = SYM_SETUP_HOST_ID;1719 1720 if (pci_enable_device(pdev))1721 goto leave;1722 1723 pci_set_master(pdev);1724 1725 if (pci_request_regions(pdev, NAME53C8XX))1726 goto disable;1727 1728 if (sym_check_supported(&sym_dev))1729 goto free;1730 1731 if (sym_iomap_device(&sym_dev))1732 goto free;1733 do_iounmap = 1;1734 1735 if (sym_check_raid(&sym_dev)) {1736 do_disable_device = 0; /* Don't disable the device */1737 goto free;1738 }1739 1740 if (sym_set_workarounds(&sym_dev))1741 goto free;1742 1743 sym_config_pqs(pdev, &sym_dev);1744 1745 sym_get_nvram(&sym_dev, &nvram);1746 1747 do_iounmap = 0; /* Don't sym_iounmap_device() after sym_attach(). */1748 shost = sym_attach(&sym2_template, attach_count, &sym_dev);1749 if (!shost)1750 goto free;1751 1752 if (scsi_add_host(shost, &pdev->dev))1753 goto detach;1754 scsi_scan_host(shost);1755 1756 attach_count++;1757 1758 return 0;1759 1760 detach:1761 sym_detach(pci_get_drvdata(pdev), pdev);1762 free:1763 if (do_iounmap)1764 sym_iounmap_device(&sym_dev);1765 pci_release_regions(pdev);1766 disable:1767 if (do_disable_device)1768 pci_disable_device(pdev);1769 leave:1770 return -ENODEV;1771}1772 1773static void sym2_remove(struct pci_dev *pdev)1774{1775 struct Scsi_Host *shost = pci_get_drvdata(pdev);1776 1777 scsi_remove_host(shost);1778 sym_detach(shost, pdev);1779 pci_release_regions(pdev);1780 pci_disable_device(pdev);1781 1782 attach_count--;1783}1784 1785/**1786 * sym2_io_error_detected() - called when PCI error is detected1787 * @pdev: pointer to PCI device1788 * @state: current state of the PCI slot1789 */1790static pci_ers_result_t sym2_io_error_detected(struct pci_dev *pdev,1791 pci_channel_state_t state)1792{1793 /* If slot is permanently frozen, turn everything off */1794 if (state == pci_channel_io_perm_failure) {1795 sym2_remove(pdev);1796 return PCI_ERS_RESULT_DISCONNECT;1797 }1798 1799 disable_irq(pdev->irq);1800 pci_disable_device(pdev);1801 1802 /* Request that MMIO be enabled, so register dump can be taken. */1803 return PCI_ERS_RESULT_CAN_RECOVER;1804}1805 1806/**1807 * sym2_io_slot_dump - Enable MMIO and dump debug registers1808 * @pdev: pointer to PCI device1809 */1810static pci_ers_result_t sym2_io_slot_dump(struct pci_dev *pdev)1811{1812 struct Scsi_Host *shost = pci_get_drvdata(pdev);1813 1814 sym_dump_registers(shost);1815 1816 /* Request a slot reset. */1817 return PCI_ERS_RESULT_NEED_RESET;1818}1819 1820/**1821 * sym2_reset_workarounds - hardware-specific work-arounds1822 * @pdev: pointer to PCI device1823 *1824 * This routine is similar to sym_set_workarounds(), except1825 * that, at this point, we already know that the device was1826 * successfully initialized at least once before, and so most1827 * of the steps taken there are un-needed here.1828 */1829static void sym2_reset_workarounds(struct pci_dev *pdev)1830{1831 u_short status_reg;1832 struct sym_chip *chip;1833 1834 chip = sym_lookup_chip_table(pdev->device, pdev->revision);1835 1836 /* Work around for errant bit in 895A, in a fashion1837 * similar to what is done in sym_set_workarounds().1838 */1839 pci_read_config_word(pdev, PCI_STATUS, &status_reg);1840 if (!(chip->features & FE_66MHZ) && (status_reg & PCI_STATUS_66MHZ)) {1841 status_reg = PCI_STATUS_66MHZ;1842 pci_write_config_word(pdev, PCI_STATUS, status_reg);1843 pci_read_config_word(pdev, PCI_STATUS, &status_reg);1844 }1845}1846 1847/**1848 * sym2_io_slot_reset() - called when the pci bus has been reset.1849 * @pdev: pointer to PCI device1850 *1851 * Restart the card from scratch.1852 */1853static pci_ers_result_t sym2_io_slot_reset(struct pci_dev *pdev)1854{1855 struct Scsi_Host *shost = pci_get_drvdata(pdev);1856 struct sym_hcb *np = sym_get_hcb(shost);1857 1858 printk(KERN_INFO "%s: recovering from a PCI slot reset\n",1859 sym_name(np));1860 1861 if (pci_enable_device(pdev)) {1862 printk(KERN_ERR "%s: Unable to enable after PCI reset\n",1863 sym_name(np));1864 return PCI_ERS_RESULT_DISCONNECT;1865 }1866 1867 pci_set_master(pdev);1868 enable_irq(pdev->irq);1869 1870 /* If the chip can do Memory Write Invalidate, enable it */1871 if (np->features & FE_WRIE) {1872 if (pci_set_mwi(pdev))1873 return PCI_ERS_RESULT_DISCONNECT;1874 }1875 1876 /* Perform work-arounds, analogous to sym_set_workarounds() */1877 sym2_reset_workarounds(pdev);1878 1879 /* Perform host reset only on one instance of the card */1880 if (PCI_FUNC(pdev->devfn) == 0) {1881 if (sym_reset_scsi_bus(np, 0)) {1882 printk(KERN_ERR "%s: Unable to reset scsi host\n",1883 sym_name(np));1884 return PCI_ERS_RESULT_DISCONNECT;1885 }1886 sym_start_up(shost, 1);1887 }1888 1889 return PCI_ERS_RESULT_RECOVERED;1890}1891 1892/**1893 * sym2_io_resume() - resume normal ops after PCI reset1894 * @pdev: pointer to PCI device1895 *1896 * Called when the error recovery driver tells us that its1897 * OK to resume normal operation. Use completion to allow1898 * halted scsi ops to resume.1899 */1900static void sym2_io_resume(struct pci_dev *pdev)1901{1902 struct Scsi_Host *shost = pci_get_drvdata(pdev);1903 struct sym_data *sym_data = shost_priv(shost);1904 1905 spin_lock_irq(shost->host_lock);1906 if (sym_data->io_reset)1907 complete(sym_data->io_reset);1908 spin_unlock_irq(shost->host_lock);1909}1910 1911static void sym2_get_signalling(struct Scsi_Host *shost)1912{1913 struct sym_hcb *np = sym_get_hcb(shost);1914 enum spi_signal_type type;1915 1916 switch (np->scsi_mode) {1917 case SMODE_SE:1918 type = SPI_SIGNAL_SE;1919 break;1920 case SMODE_LVD:1921 type = SPI_SIGNAL_LVD;1922 break;1923 case SMODE_HVD:1924 type = SPI_SIGNAL_HVD;1925 break;1926 default:1927 type = SPI_SIGNAL_UNKNOWN;1928 break;1929 }1930 spi_signalling(shost) = type;1931}1932 1933static void sym2_set_offset(struct scsi_target *starget, int offset)1934{1935 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);1936 struct sym_hcb *np = sym_get_hcb(shost);1937 struct sym_tcb *tp = &np->target[starget->id];1938 1939 tp->tgoal.offset = offset;1940 tp->tgoal.check_nego = 1;1941}1942 1943static void sym2_set_period(struct scsi_target *starget, int period)1944{1945 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);1946 struct sym_hcb *np = sym_get_hcb(shost);1947 struct sym_tcb *tp = &np->target[starget->id];1948 1949 /* have to have DT for these transfers, but DT will also1950 * set width, so check that this is allowed */1951 if (period <= np->minsync && spi_width(starget))1952 tp->tgoal.dt = 1;1953 1954 tp->tgoal.period = period;1955 tp->tgoal.check_nego = 1;1956}1957 1958static void sym2_set_width(struct scsi_target *starget, int width)1959{1960 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);1961 struct sym_hcb *np = sym_get_hcb(shost);1962 struct sym_tcb *tp = &np->target[starget->id];1963 1964 /* It is illegal to have DT set on narrow transfers. If DT is1965 * clear, we must also clear IU and QAS. */1966 if (width == 0)1967 tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0;1968 1969 tp->tgoal.width = width;1970 tp->tgoal.check_nego = 1;1971}1972 1973static void sym2_set_dt(struct scsi_target *starget, int dt)1974{1975 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);1976 struct sym_hcb *np = sym_get_hcb(shost);1977 struct sym_tcb *tp = &np->target[starget->id];1978 1979 /* We must clear QAS and IU if DT is clear */1980 if (dt)1981 tp->tgoal.dt = 1;1982 else1983 tp->tgoal.iu = tp->tgoal.dt = tp->tgoal.qas = 0;1984 tp->tgoal.check_nego = 1;1985}1986 1987#if 01988static void sym2_set_iu(struct scsi_target *starget, int iu)1989{1990 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);1991 struct sym_hcb *np = sym_get_hcb(shost);1992 struct sym_tcb *tp = &np->target[starget->id];1993 1994 if (iu)1995 tp->tgoal.iu = tp->tgoal.dt = 1;1996 else1997 tp->tgoal.iu = 0;1998 tp->tgoal.check_nego = 1;1999}2000 2001static void sym2_set_qas(struct scsi_target *starget, int qas)2002{2003 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);2004 struct sym_hcb *np = sym_get_hcb(shost);2005 struct sym_tcb *tp = &np->target[starget->id];2006 2007 if (qas)2008 tp->tgoal.dt = tp->tgoal.qas = 1;2009 else2010 tp->tgoal.qas = 0;2011 tp->tgoal.check_nego = 1;2012}2013#endif2014 2015static struct spi_function_template sym2_transport_functions = {2016 .set_offset = sym2_set_offset,2017 .show_offset = 1,2018 .set_period = sym2_set_period,2019 .show_period = 1,2020 .set_width = sym2_set_width,2021 .show_width = 1,2022 .set_dt = sym2_set_dt,2023 .show_dt = 1,2024#if 02025 .set_iu = sym2_set_iu,2026 .show_iu = 1,2027 .set_qas = sym2_set_qas,2028 .show_qas = 1,2029#endif2030 .get_signalling = sym2_get_signalling,2031};2032 2033static struct pci_device_id sym2_id_table[] = {2034 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C810,2035 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2036 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C820,2037 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, /* new */2038 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C825,2039 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2040 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C815,2041 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2042 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C810AP,2043 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, /* new */2044 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C860,2045 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2046 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1510,2047 PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_SCSI<<8, 0xffff00, 0UL },2048 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C896,2049 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2050 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C895,2051 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2052 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C885,2053 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2054 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C875,2055 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2056 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C1510,2057 PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_SCSI<<8, 0xffff00, 0UL }, /* new */2058 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C895A,2059 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2060 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C875A,2061 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2062 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1010_33,2063 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2064 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1010_66,2065 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2066 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_NCR_53C875J,2067 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },2068 { 0, }2069};2070 2071MODULE_DEVICE_TABLE(pci, sym2_id_table);2072 2073static const struct pci_error_handlers sym2_err_handler = {2074 .error_detected = sym2_io_error_detected,2075 .mmio_enabled = sym2_io_slot_dump,2076 .slot_reset = sym2_io_slot_reset,2077 .resume = sym2_io_resume,2078};2079 2080static struct pci_driver sym2_driver = {2081 .name = NAME53C8XX,2082 .id_table = sym2_id_table,2083 .probe = sym2_probe,2084 .remove = sym2_remove,2085 .err_handler = &sym2_err_handler,2086};2087 2088static int __init sym2_init(void)2089{2090 int error;2091 2092 sym2_setup_params();2093 sym2_transport_template = spi_attach_transport(&sym2_transport_functions);2094 if (!sym2_transport_template)2095 return -ENODEV;2096 2097 error = pci_register_driver(&sym2_driver);2098 if (error)2099 spi_release_transport(sym2_transport_template);2100 return error;2101}2102 2103static void __exit sym2_exit(void)2104{2105 pci_unregister_driver(&sym2_driver);2106 spi_release_transport(sym2_transport_template);2107}2108 2109module_init(sym2_init);2110module_exit(sym2_exit);2111