cregit-Linux how code gets into the kernel

Release 4.11 drivers/scsi/gdth.c

Directory: drivers/scsi
/************************************************************************
 * Linux driver for                                                     *  
 * ICP vortex GmbH:    GDT ISA/EISA/PCI Disk Array Controllers          *
 * Intel Corporation:  Storage RAID Controllers                         *
 *                                                                      *
 * gdth.c                                                               *
 * Copyright (C) 1995-06 ICP vortex GmbH, Achim Leubner                 *
 * Copyright (C) 2002-04 Intel Corporation                              *
 * Copyright (C) 2003-06 Adaptec Inc.                                   *
 * <achim_leubner@adaptec.com>                                          *
 *                                                                      *
 * Additions/Fixes:                                                     *
 * Boji Tony Kannanthanam <boji.t.kannanthanam@intel.com>               *
 * Johannes Dinner <johannes_dinner@adaptec.com>                        *
 *                                                                      *
 * This program is free software; you can redistribute it and/or modify *
 * it under the terms of the GNU General Public License as published    *
 * by the Free Software Foundation; either version 2 of the License,    *
 * or (at your option) any later version.                               *
 *                                                                      *
 * This program is distributed in the hope that it will be useful,      *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the         *
 * GNU General Public License for more details.                         *
 *                                                                      *
 * You should have received a copy of the GNU General Public License    *
 * along with this kernel; if not, write to the Free Software           *
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.            *
 *                                                                      *
 * Linux kernel 2.6.x supported                                         *
 *                                                                      *
 ************************************************************************/

/* All GDT Disk Array Controllers are fully supported by this driver.
 * This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the
 * PCI Fibre Channel Disk Array Controllers. See gdth.h for a complete
 * list of all controller types.
 * 
 * If you have one or more GDT3000/3020 EISA controllers with 
 * controller BIOS disabled, you have to set the IRQ values with the 
 * command line option "gdth=irq1,irq2,...", where the irq1,irq2,... are
 * the IRQ values for the EISA controllers.
 * 
 * After the optional list of IRQ values, other possible 
 * command line options are:
 * disable:Y                    disable driver
 * disable:N                    enable driver
 * reserve_mode:0               reserve no drives for the raw service
 * reserve_mode:1               reserve all not init., removable drives
 * reserve_mode:2               reserve all not init. drives
 * reserve_list:h,b,t,l,h,b,t,l,...     reserve particular drive(s) with 
 *                              h- controller no., b- channel no., 
 *                              t- target ID, l- LUN
 * reverse_scan:Y               reverse scan order for PCI controllers         
 * reverse_scan:N               scan PCI controllers like BIOS
 * max_ids:x                    x - target ID count per channel (1..MAXID)
 * rescan:Y                     rescan all channels/IDs 
 * rescan:N                     use all devices found until now
 * hdr_channel:x                x - number of virtual bus for host drives
 * shared_access:Y              disable driver reserve/release protocol to 
 *                              access a shared resource from several nodes, 
 *                              appropriate controller firmware required
 * shared_access:N              enable driver reserve/release protocol
 * probe_eisa_isa:Y             scan for EISA/ISA controllers
 * probe_eisa_isa:N             do not scan for EISA/ISA controllers
 * force_dma32:Y                use only 32 bit DMA mode
 * force_dma32:N                use 64 bit DMA mode, if supported
 *
 * The default values are: "gdth=disable:N,reserve_mode:1,reverse_scan:N,
 *                          max_ids:127,rescan:N,hdr_channel:0,
 *                          shared_access:Y,probe_eisa_isa:N,force_dma32:N".
 * Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y".
 * 
 * When loading the gdth driver as a module, the same options are available. 
 * You can set the IRQs with "IRQ=...". However, the syntax to specify the
 * options changes slightly. You must replace all ',' between options 
 * with ' ' and all ':' with '=' and you must use 
 * '1' in place of 'Y' and '0' in place of 'N'.
 * 
 * Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0
 *           max_ids=127 rescan=0 hdr_channel=0 shared_access=0
 *           probe_eisa_isa=0 force_dma32=0"
 * The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1".
 */

/* The meaning of the Scsi_Pointer members in this driver is as follows:
 * ptr:                     Chaining
 * this_residual:           unused
 * buffer:                  unused
 * dma_handle:              unused
 * buffers_residual:        unused
 * Status:                  unused
 * Message:                 unused
 * have_data_in:            unused
 * sent_command:            unused
 * phase:                   unused
 */


/* interrupt coalescing */
/* #define INT_COAL */

/* statistics */

#define GDTH_STATISTICS

#include <linux/module.h>

#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/proc_fs.h>
#include <linux/time.h>
#include <linux/timer.h>
#include <linux/dma-mapping.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/slab.h>

#ifdef GDTH_RTC
#include <linux/mc146818rtc.h>
#endif
#include <linux/reboot.h>

#include <asm/dma.h>
#include <asm/io.h>
#include <linux/uaccess.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/scatterlist.h>

#include "scsi.h"
#include <scsi/scsi_host.h>
#include "gdth.h"

static DEFINE_MUTEX(gdth_mutex);
static void gdth_delay(int milliseconds);
static void gdth_eval_mapping(u32 size, u32 *cyls, int *heads, int *secs);
static irqreturn_t gdth_interrupt(int irq, void *dev_id);
static irqreturn_t __gdth_interrupt(gdth_ha_str *ha,
                                    int gdth_from_wait, int* pIndex);
static int gdth_sync_event(gdth_ha_str *ha, int service, u8 index,
                                                               Scsi_Cmnd *scp);
static int gdth_async_event(gdth_ha_str *ha);
static void gdth_log_event(gdth_evt_data *dvr, char *buffer);

static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, u8 priority);
static void gdth_next(gdth_ha_str *ha);
static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, u8 b);
static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp);
static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, u16 source,
                                      u16 idx, gdth_evt_data *evt);
static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr);
static void gdth_readapp_event(gdth_ha_str *ha, u8 application, 
                               gdth_evt_str *estr);
static void gdth_clear_events(void);

static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
                                    char *buffer, u16 count);
static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp);
static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, u16 hdrive);

static void gdth_enable_int(gdth_ha_str *ha);
static int gdth_test_busy(gdth_ha_str *ha);
static int gdth_get_cmd_index(gdth_ha_str *ha);
static void gdth_release_event(gdth_ha_str *ha);
static int gdth_wait(gdth_ha_str *ha, int index,u32 time);
static int gdth_internal_cmd(gdth_ha_str *ha, u8 service, u16 opcode,
                                             u32 p1, u64 p2,u64 p3);
static int gdth_search_drives(gdth_ha_str *ha);
static int gdth_analyse_hdrive(gdth_ha_str *ha, u16 hdrive);

static const char *gdth_ctr_name(gdth_ha_str *ha);

static int gdth_open(struct inode *inode, struct file *filep);
static int gdth_close(struct inode *inode, struct file *filep);
static long gdth_unlocked_ioctl(struct file *filep, unsigned int cmd,
			        unsigned long arg);

static void gdth_flush(gdth_ha_str *ha);
static int gdth_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp,
				struct gdth_cmndinfo *cmndinfo);
static void gdth_scsi_done(struct scsi_cmnd *scp);

#ifdef DEBUG_GDTH

static u8   DebugState = DEBUG_GDTH;

#ifdef __SERIAL__

#define MAX_SERBUF 160
static void ser_init(void);
static void ser_puts(char *str);
static void ser_putc(char c);
static int  ser_printk(const char *fmt, ...);

static char strbuf[MAX_SERBUF+1];
#ifdef __COM2__

#define COM_BASE 0x2f8
#else

#define COM_BASE 0x3f8
#endif

static void ser_init() { unsigned port=COM_BASE; outb(0x80,port+3); outb(0,port+1); /* 19200 Baud, if 9600: outb(12,port) */ outb(6, port); outb(3,port+3); outb(0,port+1); /* ser_putc('I'); ser_putc(' '); */ }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)56100.00%1100.00%
Total56100.00%1100.00%


static void ser_puts(char *str) { char *ptr; ser_init(); for (ptr=str;*ptr;++ptr) ser_putc(*ptr); }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)35100.00%1100.00%
Total35100.00%1100.00%


static void ser_putc(char c) { unsigned port=COM_BASE; while ((inb(port+5) & 0x20)==0); outb(c,port); if (c==0x0a) { while ((inb(port+5) & 0x20)==0); outb(0x0d,port); } }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)68100.00%1100.00%
Total68100.00%1100.00%


static int ser_printk(const char *fmt, ...) { va_list args; int i; va_start(args,fmt); i = vsprintf(strbuf,fmt,args); ser_puts(strbuf); va_end(args); return i; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)50100.00%1100.00%
Total50100.00%1100.00%

#define TRACE(a) {if (DebugState==1) {ser_printk a;}} #define TRACE2(a) {if (DebugState==1 || DebugState==2) {ser_printk a;}} #define TRACE3(a) {if (DebugState!=0) {ser_printk a;}} #else /* !__SERIAL__ */ #define TRACE(a) {if (DebugState==1) {printk a;}} #define TRACE2(a) {if (DebugState==1 || DebugState==2) {printk a;}} #define TRACE3(a) {if (DebugState!=0) {printk a;}} #endif #else /* !DEBUG */ #define TRACE(a) #define TRACE2(a) #define TRACE3(a) #endif #ifdef GDTH_STATISTICS static u32 max_rq=0, max_index=0, max_sg=0; #ifdef INT_COAL static u32 max_int_coal=0; #endif static u32 act_ints=0, act_ios=0, act_stats=0, act_rq=0; static struct timer_list gdth_timer; #endif #define PTR2USHORT(a) (u16)(unsigned long)(a) #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) #define INDEX_OK(i,t) ((i)<ARRAY_SIZE(t)) #define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b)) #ifdef CONFIG_ISA static u8 gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ #endif #if defined(CONFIG_EISA) || defined(CONFIG_ISA) static u8 gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ #endif static u8 gdth_polling; /* polling if TRUE */ static int gdth_ctr_count = 0; /* controller count */ static LIST_HEAD(gdth_instances); /* controller list */ static u8 gdth_write_through = FALSE; /* write through */ static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ static int elastidx; static int eoldidx; static int major; #define DIN 1 /* IN data direction */ #define DOU 2 /* OUT data direction */ #define DNO DIN /* no data transfer */ #define DUN DIN /* unknown data direction */ static u8 gdth_direction_tab[0x100] = { DNO,DNO,DIN,DIN,DOU,DIN,DIN,DOU,DIN,DUN,DOU,DOU,DUN,DUN,DUN,DIN, DNO,DIN,DIN,DOU,DIN,DOU,DNO,DNO,DOU,DNO,DIN,DNO,DIN,DOU,DNO,DUN, DIN,DUN,DIN,DUN,DOU,DIN,DUN,DUN,DIN,DIN,DOU,DNO,DUN,DIN,DOU,DOU, DOU,DOU,DOU,DNO,DIN,DNO,DNO,DIN,DOU,DOU,DOU,DOU,DIN,DOU,DIN,DOU, DOU,DOU,DIN,DIN,DIN,DNO,DUN,DNO,DNO,DNO,DUN,DNO,DOU,DIN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DIN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DIN,DUN,DOU,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DIN,DUN, DUN,DUN,DUN,DUN,DUN,DNO,DNO,DUN,DIN,DNO,DOU,DUN,DNO,DUN,DOU,DOU, DOU,DOU,DOU,DNO,DUN,DIN,DOU,DIN,DIN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DOU,DUN,DUN,DUN,DUN,DUN, DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN,DUN }; /* LILO and modprobe/insmod parameters */ /* IRQ list for GDT3000/3020 EISA controllers */ static int irq[MAXHA] __initdata = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; /* disable driver flag */ static int disable __initdata = 0; /* reserve flag */ static int reserve_mode = 1; /* reserve list */ static int reserve_list[MAX_RES_ARGS] = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; /* scan order for PCI controllers */ static int reverse_scan = 0; /* virtual channel for the host drives */ static int hdr_channel = 0; /* max. IDs per channel */ static int max_ids = MAXID; /* rescan all IDs */ static int rescan = 0; /* shared access */ static int shared_access = 1; /* enable support for EISA and ISA controllers */ static int probe_eisa_isa = 0; /* 64 bit DMA mode, support for drives > 2 TB, if force_dma32 = 0 */ static int force_dma32 = 0; /* parameters for modprobe/insmod */ module_param_array(irq, int, NULL, 0); module_param(disable, int, 0); module_param(reserve_mode, int, 0); module_param_array(reserve_list, int, NULL, 0); module_param(reverse_scan, int, 0); module_param(hdr_channel, int, 0); module_param(max_ids, int, 0); module_param(rescan, int, 0); module_param(shared_access, int, 0); module_param(probe_eisa_isa, int, 0); module_param(force_dma32, int, 0); MODULE_AUTHOR("Achim Leubner"); MODULE_LICENSE("GPL"); /* ioctl interface */ static const struct file_operations gdth_fops = { .unlocked_ioctl = gdth_unlocked_ioctl, .open = gdth_open, .release = gdth_close, .llseek = noop_llseek, }; #include "gdth_proc.h" #include "gdth_proc.c"
static gdth_ha_str *gdth_find_ha(int hanum) { gdth_ha_str *ha; list_for_each_entry(ha, &gdth_instances, list) if (hanum == ha->hanum) return ha; return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Boaz Harrosh36100.00%1100.00%
Total36100.00%1100.00%


static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha) { struct gdth_cmndinfo *priv = NULL; unsigned long flags; int i; spin_lock_irqsave(&ha->smp_lock, flags); for (i=0; i<GDTH_MAXCMDS; ++i) { if (ha->cmndinfo[i].index == 0) { priv = &ha->cmndinfo[i]; memset(priv, 0, sizeof(*priv)); priv->index = i+1; break; } } spin_unlock_irqrestore(&ha->smp_lock, flags); return priv; }

Contributors

PersonTokensPropCommitsCommitProp
Boaz Harrosh10998.20%266.67%
Dave Jones21.80%133.33%
Total111100.00%3100.00%


static void gdth_put_cmndinfo(struct gdth_cmndinfo *priv) { BUG_ON(!priv); priv->index = 0; }

Contributors

PersonTokensPropCommitsCommitProp
Boaz Harrosh23100.00%1100.00%
Total23100.00%1100.00%


static void gdth_delay(int milliseconds) { if (milliseconds == 0) { udelay(1); } else { mdelay(milliseconds); } }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2893.33%150.00%
Linus Torvalds26.67%150.00%
Total30100.00%2100.00%


static void gdth_scsi_done(struct scsi_cmnd *scp) { struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); int internal_command = cmndinfo->internal_command; TRACE2(("gdth_scsi_done()\n")); gdth_put_cmndinfo(cmndinfo); scp->host_scribble = NULL; if (internal_command) complete((struct completion *)scp->request); else scp->scsi_done(scp); }

Contributors

PersonTokensPropCommitsCommitProp
Boaz Harrosh2941.43%116.67%
Achim Leubner2738.57%116.67%
Matthew Wilcox1014.29%233.33%
Linus Torvalds (pre-git)34.29%116.67%
Christoph Hellwig11.43%116.67%
Total70100.00%6100.00%


int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, int timeout, u32 *info) { gdth_ha_str *ha = shost_priv(sdev->host); Scsi_Cmnd *scp; struct gdth_cmndinfo cmndinfo; DECLARE_COMPLETION_ONSTACK(wait); int rval; scp = kzalloc(sizeof(*scp), GFP_KERNEL); if (!scp) return -ENOMEM; scp->sense_buffer = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); if (!scp->sense_buffer) { kfree(scp); return -ENOMEM; } scp->device = sdev; memset(&cmndinfo, 0, sizeof(cmndinfo)); /* use request field to save the ptr. to completion struct. */ scp->request = (struct request *)&wait; scp->cmd_len = 12; scp->cmnd = cmnd; cmndinfo.priority = IOCTL_PRI; cmndinfo.internal_cmd_str = gdtcmd; cmndinfo.internal_command = 1; TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); __gdth_queuecommand(ha, scp, &cmndinfo); wait_for_completion(&wait); rval = cmndinfo.status; if (info) *info = cmndinfo.info; kfree(scp->sense_buffer); kfree(scp); return rval; }

Contributors

PersonTokensPropCommitsCommitProp
Achim Leubner9441.41%110.00%
Boaz Harrosh6327.75%440.00%
Sven Schnelle3615.86%110.00%
Linus Torvalds (pre-git)2912.78%110.00%
Christoph Hellwig31.32%110.00%
Mariusz Kozlowski10.44%110.00%
Peter Zijlstra10.44%110.00%
Total227100.00%10100.00%


int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, int timeout, u32 *info) { struct scsi_device *sdev = scsi_get_host_dev(shost); int rval = __gdth_execute(sdev, gdtcmd, cmnd, timeout, info); scsi_free_host_dev(sdev); return rval; }

Contributors

PersonTokensPropCommitsCommitProp
Achim Leubner59100.00%1100.00%
Total59100.00%1100.00%


static void gdth_eval_mapping(u32 size, u32 *cyls, int *heads, int *secs) { *cyls = size /HEADS/SECS; if (*cyls <= MAXCYLS) { *heads = HEADS; *secs = SECS; } else { /* too high for 64*32 */ *cyls = size /MEDHEADS/MEDSECS; if (*cyls <= MAXCYLS) { *heads = MEDHEADS; *secs = MEDSECS; } else { /* too high for 127*63 */ *cyls = size /BIGHEADS/BIGSECS; *heads = BIGHEADS; *secs = BIGSECS; } } }

Contributors

PersonTokensPropCommitsCommitProp
Achim Leubner10298.08%150.00%
Dave Jones21.92%150.00%
Total104100.00%2100.00%

/* controller search and initialization functions */ #ifdef CONFIG_EISA
static int __init gdth_search_eisa(u16 eisa_adr) { u32 id; TRACE(("gdth_search_eisa() adr. %x\n",eisa_adr)); id = inl(eisa_adr+ID0REG); if (id == GDT3A_ID || id == GDT3B_ID) { /* GDT3000A or GDT3000B */ if ((inb(eisa_adr+EISAREG) & 8) == 0) return 0; /* not EISA configured */ return 1; } if (id == GDT3_ID) /* GDT3000 */ return 1; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Achim Leubner7797.47%150.00%
Dave Jones22.53%150.00%
Total79100.00%2100.00%

#endif /* CONFIG_EISA */ #ifdef CONFIG_ISA
static int __init gdth_search_isa(u32 bios_adr) { void __iomem *addr; u32 id; TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr)); if ((addr = ioremap(bios_adr+BIOS_ID_OFFS, sizeof(u32))) != NULL) { id = readl(addr); iounmap(addr); if (id == GDT2_ID) /* GDT2000 */ return 1; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)6081.08%225.00%
Achim Leubner56.76%112.50%
Dave Jones34.05%112.50%
James Bottomley22.70%112.50%
Christoph Hellwig22.70%112.50%
Jeff Garzik11.35%112.50%
Linus Torvalds11.35%112.50%
Total74100.00%8100.00%

#endif /* CONFIG_ISA */ #ifdef CONFIG_PCI
static bool gdth_search_vortex(u16 device) { if (device <= PCI_DEVICE_ID_VORTEX_GDT6555) return true; if (device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP && device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP) return true; if (device == PCI_DEVICE_ID_VORTEX_GDTNEWRX || device == PCI_DEVICE_ID_VORTEX_GDTNEWRX2) return true; return false; }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Garzik2961.70%120.00%
Linus Torvalds1429.79%120.00%
Christoph Hellwig24.26%120.00%
Dave Jones12.13%120.00%
James Bottomley12.13%120.00%
Total47100.00%5100.00%

static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out); static int gdth_pci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static void gdth_pci_remove_one(struct pci_dev *pdev); static void gdth_remove_one(gdth_ha_str *ha); /* Vortex only makes RAID controllers. * We do not really want to specify all 550 ids here, so wildcard match. */ static const struct pci_device_id gdthtable[] = { { PCI_VDEVICE(VORTEX, PCI_ANY_ID) }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC) }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC_XSCALE) }, { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, gdthtable); static struct pci_driver gdth_pci_driver = { .name = "gdth", .id_table = gdthtable, .probe = gdth_pci_init_one, .remove = gdth_pci_remove_one, };
static void gdth_pci_remove_one(struct pci_dev *pdev) { gdth_ha_str *ha = pci_get_drvdata(pdev); list_del(&ha->list); gdth_remove_one(ha); pci_disable_device(pdev); }

Contributors

PersonTokensPropCommitsCommitProp
Jeff Garzik3386.84%150.00%
Christoph Hellwig513.16%150.00%
Total38100.00%2100.00%


static int gdth_pci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { u16 vendor = pdev->vendor; u16 device = pdev->device; unsigned long base0, base1, base2