Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Linux driver attachment glue for aic7770 based controllers.
0003  *
0004  * Copyright (c) 2000-2003 Adaptec Inc.
0005  * All rights reserved.
0006  *
0007  * Redistribution and use in source and binary forms, with or without
0008  * modification, are permitted provided that the following conditions
0009  * are met:
0010  * 1. Redistributions of source code must retain the above copyright
0011  *    notice, this list of conditions, and the following disclaimer,
0012  *    without modification.
0013  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0014  *    substantially similar to the "NO WARRANTY" disclaimer below
0015  *    ("Disclaimer") and any redistribution must be conditioned upon
0016  *    including a substantially similar Disclaimer requirement for further
0017  *    binary redistribution.
0018  * 3. Neither the names of the above-listed copyright holders nor the names
0019  *    of any contributors may be used to endorse or promote products derived
0020  *    from this software without specific prior written permission.
0021  *
0022  * Alternatively, this software may be distributed under the terms of the
0023  * GNU General Public License ("GPL") version 2 as published by the Free
0024  * Software Foundation.
0025  *
0026  * NO WARRANTY
0027  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0028  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0029  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
0030  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0031  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0032  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0033  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0034  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
0035  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
0036  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0037  * POSSIBILITY OF SUCH DAMAGES.
0038  *
0039  * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7770_osm.c#14 $
0040  */
0041 
0042 #include "aic7xxx_osm.h"
0043 
0044 #include <linux/device.h>
0045 #include <linux/eisa.h>
0046 
0047 int
0048 aic7770_map_registers(struct ahc_softc *ahc, u_int port)
0049 {
0050     /*
0051      * Lock out other contenders for our i/o space.
0052      */
0053     if (!request_region(port, AHC_EISA_IOSIZE, "aic7xxx"))
0054         return (ENOMEM);
0055     ahc->tag = BUS_SPACE_PIO;
0056     ahc->bsh.ioport = port;
0057     return (0);
0058 }
0059 
0060 int
0061 aic7770_map_int(struct ahc_softc *ahc, u_int irq)
0062 {
0063     int error;
0064     int shared;
0065 
0066     shared = 0;
0067     if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
0068         shared = IRQF_SHARED;
0069 
0070     error = request_irq(irq, ahc_linux_isr, shared, "aic7xxx", ahc);
0071     if (error == 0)
0072         ahc->platform_data->irq = irq;
0073     
0074     return (-error);
0075 }
0076 
0077 static int
0078 aic7770_probe(struct device *dev)
0079 {
0080     struct eisa_device *edev = to_eisa_device(dev);
0081     u_int eisaBase = edev->base_addr+AHC_EISA_SLOT_OFFSET;
0082     struct  ahc_softc *ahc;
0083     char    buf[80];
0084     char   *name;
0085     int error;
0086 
0087     sprintf(buf, "ahc_eisa:%d", eisaBase >> 12);
0088     name = kstrdup(buf, GFP_ATOMIC);
0089     if (name == NULL)
0090         return (ENOMEM);
0091     ahc = ahc_alloc(&aic7xxx_driver_template, name);
0092     if (ahc == NULL)
0093         return (ENOMEM);
0094     ahc->dev = dev;
0095     error = aic7770_config(ahc, aic7770_ident_table + edev->id.driver_data,
0096                    eisaBase);
0097     if (error != 0) {
0098         ahc->bsh.ioport = 0;
0099         ahc_free(ahc);
0100         return (error);
0101     }
0102 
0103     dev_set_drvdata(dev, ahc);
0104 
0105     error = ahc_linux_register_host(ahc, &aic7xxx_driver_template);
0106     return (error);
0107 }
0108 
0109 static int
0110 aic7770_remove(struct device *dev)
0111 {
0112     struct ahc_softc *ahc = dev_get_drvdata(dev);
0113     u_long s;
0114 
0115     if (ahc->platform_data && ahc->platform_data->host)
0116             scsi_remove_host(ahc->platform_data->host);
0117 
0118     ahc_lock(ahc, &s);
0119     ahc_intr_enable(ahc, FALSE);
0120     ahc_unlock(ahc, &s);
0121 
0122     ahc_free(ahc);
0123     return 0;
0124 }
0125  
0126 static struct eisa_device_id aic7770_ids[] = {
0127     { "ADP7771", 0 }, /* AHA 274x */
0128     { "ADP7756", 1 }, /* AHA 284x BIOS enabled */
0129     { "ADP7757", 2 }, /* AHA 284x BIOS disabled */
0130     { "ADP7782", 3 }, /* AHA 274x Olivetti OEM */
0131     { "ADP7783", 4 }, /* AHA 274x Olivetti OEM (Differential) */
0132     { "ADP7770", 5 }, /* AIC7770 generic */
0133     { "" }
0134 };
0135 MODULE_DEVICE_TABLE(eisa, aic7770_ids);
0136 
0137 static struct eisa_driver aic7770_driver = {
0138     .id_table   = aic7770_ids,
0139     .driver = {
0140         .name   = "aic7xxx",
0141         .probe  = aic7770_probe,
0142         .remove = aic7770_remove,
0143     }
0144 };
0145   
0146 int
0147 ahc_linux_eisa_init(void)
0148 {
0149     return eisa_driver_register(&aic7770_driver);
0150 }
0151   
0152 void
0153 ahc_linux_eisa_exit(void)
0154 {
0155     eisa_driver_unregister(&aic7770_driver);
0156 }