aic7770_linux.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
- /*
- * Linux driver attachment glue for aic7770 based controllers.
- *
- * Copyright (c) 2000-2001 Adaptec Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions, and the following disclaimer,
- * without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- * substantially similar to the "NO WARRANTY" disclaimer below
- * ("Disclaimer") and any redistribution must be conditioned upon
- * including a substantially similar Disclaimer requirement for further
- * binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- * of any contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- *
- * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_linux.c#9 $
- */
- #include "aic7xxx_osm.h"
- #define MINSLOT 1
- #define NUMSLOTS 16
- #define IDOFFSET 0x80
- int
- aic7770_linux_probe(Scsi_Host_Template *template)
- {
- #if defined(__i386__) || defined(__alpha__)
- struct aic7770_identity *entry;
- struct ahc_softc *ahc;
- int i, slot;
- int eisaBase;
- int found;
- if (aic7xxx_no_probe)
- return (0);
- eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
- found = 0;
- for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
- uint32_t eisa_id;
- size_t id_size;
- if (check_region(eisaBase, AHC_EISA_IOSIZE) != 0)
- continue;
- eisa_id = 0;
- id_size = sizeof(eisa_id);
- for (i = 0; i < 4; i++) {
- /* VLcards require priming*/
- outb(0x80 + i, eisaBase + IDOFFSET);
- eisa_id |= inb(eisaBase + IDOFFSET + i)
- << ((id_size-i-1) * 8);
- }
- if (eisa_id & 0x80000000)
- continue; /* no EISA card in slot */
- entry = aic7770_find_device(eisa_id);
- if (entry != NULL) {
- char buf[80];
- char *name;
- int error;
- /*
- * Allocate a softc for this card and
- * set it up for attachment by our
- * common detect routine.
- */
- sprintf(buf, "ahc_eisa:%d", slot);
- name = malloc(strlen(buf) + 1, M_DEVBUF, M_NOWAIT);
- if (name == NULL)
- break;
- strcpy(name, buf);
- ahc = ahc_alloc(template, name);
- if (ahc == NULL) {
- /*
- * If we can't allocate this one,
- * chances are we won't be able to
- * allocate future card structures.
- */
- break;
- }
- ahc->tag = BUS_SPACE_PIO;
- ahc->bsh.ioport = eisaBase;
- error = aic7770_config(ahc, entry);
- if (error != 0) {
- ahc_free(ahc);
- continue;
- }
- found++;
- }
- }
- return (found);
- #else
- return (0);
- #endif
- }
- int
- aic7770_map_registers(struct ahc_softc *ahc)
- {
- /*
- * Lock out other contenders for our i/o space.
- */
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
- request_region(ahc->bsh.ioport, AHC_EISA_IOSIZE, "aic7xxx");
- #else
- if (request_region(ahc->bsh.ioport, AHC_EISA_IOSIZE, "aic7xxx") == 0)
- return (ENOMEM);
- #endif
- return (0);
- }
- int
- aic7770_map_int(struct ahc_softc *ahc, u_int irq)
- {
- int error;
- int shared;
- shared = 0;
- if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
- shared = SA_SHIRQ;
- ahc->platform_data->irq = irq;
- error = request_irq(ahc->platform_data->irq, ahc_linux_isr,
- shared, "aic7xxx", ahc);
-
- return (-error);
- }