cregit-Linux how code gets into the kernel

Release 4.11 drivers/scsi/aha152x.c

Directory: drivers/scsi
/* aha152x.c -- Adaptec AHA-152x driver
 * Author: Jürgen E. Fischer, fischer@norbit.de
 * Copyright 1993-2004 Jürgen E. Fischer
 *
 * 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, 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.
 *
 *
 * $Id: aha152x.c,v 2.7 2004/01/24 11:42:59 fischer Exp $
 *
 * $Log: aha152x.c,v $
 * Revision 2.7  2004/01/24 11:42:59  fischer
 * - gather code that is not used by PCMCIA at the end
 * - move request_region for !PCMCIA case to detection
 * - migration to new scsi host api (remove legacy code)
 * - free host scribble before scsi_done
 * - fix error handling
 * - one isapnp device added to id_table
 *
 * Revision 2.6  2003/10/30 20:52:47  fischer
 * - interfaces changes for kernel 2.6
 * - aha152x_probe_one introduced for pcmcia stub
 * - fixed pnpdev handling
 * - instead of allocation a new one, reuse command for request sense after check condition and reset
 * - fixes race in is_complete
 *
 * Revision 2.5  2002/04/14 11:24:53  fischer
 * - isapnp support
 * - abort fixed
 * - 2.5 support
 *
 * Revision 2.4  2000/12/16 12:53:56  fischer
 * - allow REQUEST SENSE to be queued
 * - handle shared PCI interrupts
 *
 * Revision 2.3  2000/11/04 16:40:26  fischer
 * - handle data overruns
 * - extend timeout for data phases
 *
 * Revision 2.2  2000/08/08 19:54:53  fischer
 * - minor changes
 *
 * Revision 2.1  2000/05/17 16:23:17  fischer
 * - signature update
 * - fix for data out w/o scatter gather
 *
 * Revision 2.0  1999/12/25 15:07:32  fischer
 * - interrupt routine completly reworked
 * - basic support for new eh code
 *
 * Revision 1.21  1999/11/10 23:46:36  fischer
 * - default to synchronous operation
 * - synchronous negotiation fixed
 * - added timeout to loops
 * - debugging output can be controlled through procfs
 *
 * Revision 1.20  1999/11/07 18:37:31  fischer
 * - synchronous operation works
 * - resid support for sg driver
 *
 * Revision 1.19  1999/11/02 22:39:59  fischer
 * - moved leading comments to README.aha152x
 * - new additional module parameters
 * - updates for 2.3
 * - support for the Tripace TC1550 controller
 * - interrupt handling changed
 *
 * Revision 1.18  1996/09/07 20:10:40  fischer
 * - fixed can_queue handling (multiple outstanding commands working again)
 *
 * Revision 1.17  1996/08/17 16:05:14  fischer
 * - biosparam improved
 * - interrupt verification
 * - updated documentation
 * - cleanups
 *
 * Revision 1.16  1996/06/09 00:04:56  root
 * - added configuration symbols for insmod (aha152x/aha152x1)
 *
 * Revision 1.15  1996/04/30 14:52:06  fischer
 * - proc info fixed
 * - support for extended translation for >1GB disks
 *
 * Revision 1.14  1996/01/17  15:11:20  fischer
 * - fixed lockup in MESSAGE IN phase after reconnection
 *
 * Revision 1.13  1996/01/09  02:15:53  fischer
 * - some cleanups
 * - moved request_irq behind controller initialization
 *   (to avoid spurious interrupts)
 *
 * Revision 1.12  1995/12/16  12:26:07  fischer
 * - barrier()s added
 * - configurable RESET delay added
 *
 * Revision 1.11  1995/12/06  21:18:35  fischer
 * - some minor updates
 *
 * Revision 1.10  1995/07/22  19:18:45  fischer
 * - support for 2 controllers
 * - started synchronous data transfers (not working yet)
 *
 * Revision 1.9  1995/03/18  09:20:24  root
 * - patches for PCMCIA and modules
 *
 * Revision 1.8  1995/01/21  22:07:19  root
 * - snarf_region => request_region
 * - aha152x_intr interface change
 *
 * Revision 1.7  1995/01/02  23:19:36  root
 * - updated COMMAND_SIZE to cmd_len
 * - changed sti() to restore_flags()
 * - fixed some #ifdef which generated warnings
 *
 * Revision 1.6  1994/11/24  20:35:27  root
 * - problem with odd number of bytes in fifo fixed
 *
 * Revision 1.5  1994/10/30  14:39:56  root
 * - abort code fixed
 * - debugging improved
 *
 * Revision 1.4  1994/09/12  11:33:01  root
 * - irqaction to request_irq
 * - abortion updated
 *
 * Revision 1.3  1994/08/04  13:53:05  root
 * - updates for mid-level-driver changes
 * - accept unexpected BUSFREE phase as error condition
 * - parity check now configurable
 *
 * Revision 1.2  1994/07/03  12:56:36  root
 * - cleaned up debugging code
 * - more tweaking on reset delays
 * - updated abort/reset code (pretty untested...)
 *
 * Revision 1.1  1994/05/28  21:18:49  root
 * - update for mid-level interface change (abort-reset)
 * - delays after resets adjusted for some slow devices
 *
 * Revision 1.0  1994/03/25  12:52:00  root
 * - Fixed "more data than expected" problem
 * - added new BIOS signatures
 *
 * Revision 0.102  1994/01/31  20:44:12  root
 * - minor changes in insw/outsw handling
 *
 * Revision 0.101  1993/12/13  01:16:27  root
 * - fixed STATUS phase (non-GOOD stati were dropped sometimes;
 *   fixes problems with CD-ROM sector size detection & media change)
 *
 * Revision 0.100  1993/12/10  16:58:47  root
 * - fix for unsuccessful selections in case of non-continuous id assignments
 *   on the scsi bus.
 *
 * Revision 0.99  1993/10/24  16:19:59  root
 * - fixed DATA IN (rare read errors gone)
 *
 * Revision 0.98  1993/10/17  12:54:44  root
 * - fixed some recent fixes (shame on me)
 * - moved initialization of scratch area to aha152x_queue
 *
 * Revision 0.97  1993/10/09  18:53:53  root
 * - DATA IN fixed. Rarely left data in the fifo.
 *
 * Revision 0.96  1993/10/03  00:53:59  root
 * - minor changes on DATA IN
 *
 * Revision 0.95  1993/09/24  10:36:01  root
 * - change handling of MSGI after reselection
 * - fixed sti/cli
 * - minor changes
 *
 * Revision 0.94  1993/09/18  14:08:22  root
 * - fixed bug in multiple outstanding command code
 * - changed detection
 * - support for kernel command line configuration
 * - reset corrected
 * - changed message handling
 *
 * Revision 0.93  1993/09/15  20:41:19  root
 * - fixed bugs with multiple outstanding commands
 *
 * Revision 0.92  1993/09/13  02:46:33  root
 * - multiple outstanding commands work (no problems with IBM drive)
 *
 * Revision 0.91  1993/09/12  20:51:46  root
 * added multiple outstanding commands
 * (some problem with this $%&? IBM device remain)
 *
 * Revision 0.9  1993/09/12  11:11:22  root
 * - corrected auto-configuration
 * - changed the auto-configuration (added some '#define's)
 * - added support for dis-/reconnection
 *
 * Revision 0.8  1993/09/06  23:09:39  root
 * - added support for the drive activity light
 * - minor changes
 *
 * Revision 0.7  1993/09/05  14:30:15  root
 * - improved phase detection
 * - now using the new snarf_region code of 0.99pl13
 *
 * Revision 0.6  1993/09/02  11:01:38  root
 * first public release; added some signatures and biosparam()
 *
 * Revision 0.5  1993/08/30  10:23:30  root
 * fixed timing problems with my IBM drive
 *
 * Revision 0.4  1993/08/29  14:06:52  root
 * fixed some problems with timeouts due incomplete commands
 *
 * Revision 0.3  1993/08/28  15:55:03  root
 * writing data works too.  mounted and worked on a dos partition
 *
 * Revision 0.2  1993/08/27  22:42:07  root
 * reading data works.  Mounted a msdos partition.
 *
 * Revision 0.1  1993/08/25  13:38:30  root
 * first "damn thing doesn't work" version
 *
 * Revision 0.0  1993/08/14  19:54:25  root
 * empty function bodies; detect() works.
 *
 *
 **************************************************************************

 see Documentation/scsi/aha152x.txt for configuration details

 **************************************************************************/

#include <linux/module.h>
#include <asm/irq.h>
#include <linux/io.h>
#include <linux/blkdev.h>
#include <linux/completion.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/isapnp.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <scsi/scsicam.h>

#include "scsi.h"
#include <scsi/scsi_dbg.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_spi.h>
#include <scsi/scsi_eh.h>
#include "aha152x.h"

static LIST_HEAD(aha152x_host_list);


/* DEFINES */

/* For PCMCIA cards, always use AUTOCONF */
#if defined(PCMCIA) || defined(MODULE)
#if !defined(AUTOCONF)

#define AUTOCONF
#endif
#endif

#if !defined(AUTOCONF) && !defined(SETUP0)
#error define AUTOCONF or SETUP0
#endif


#define	DO_LOCK(flags)		spin_lock_irqsave(&QLOCK,flags)

#define	DO_UNLOCK(flags)	spin_unlock_irqrestore(&QLOCK,flags)


#define LEAD		"(scsi%d:%d:%d) "

#define INFO_LEAD	KERN_INFO       LEAD

#define CMDINFO(cmd) \
			(cmd) ? ((cmd)->device->host->host_no) : -1, \
                        (cmd) ? ((cmd)->device->id & 0x0f) : -1, \
                        (cmd) ? ((u8)(cmd)->device->lun & 0x07) : -1


static inline void CMD_INC_RESID(struct scsi_cmnd *cmd, int inc) { scsi_set_resid(cmd, scsi_get_resid(cmd) + inc); }

Contributors

PersonTokensPropCommitsCommitProp
Boaz Harrosh27100.00%1100.00%
Total27100.00%1100.00%

#define DELAY_DEFAULT 1000 #if defined(PCMCIA) #define IRQ_MIN 0 #define IRQ_MAX 16 #else #define IRQ_MIN 9 #if defined(__PPC) #define IRQ_MAX (nr_irqs-1) #else #define IRQ_MAX 12 #endif #endif enum { not_issued = 0x0001, /* command not yet issued */ selecting = 0x0002, /* target is being selected */ identified = 0x0004, /* IDENTIFY was sent */ disconnected = 0x0008, /* target disconnected */ completed = 0x0010, /* target sent COMMAND COMPLETE */ aborted = 0x0020, /* ABORT was sent */ resetted = 0x0040, /* BUS DEVICE RESET was sent */ spiordy = 0x0080, /* waiting for SPIORDY to raise */ syncneg = 0x0100, /* synchronous negotiation in progress */ aborting = 0x0200, /* ABORT is pending */ resetting = 0x0400, /* BUS DEVICE RESET is pending */ check_condition = 0x0800, /* requesting sense after CHECK CONDITION */ }; MODULE_AUTHOR("Jürgen Fischer"); MODULE_DESCRIPTION(AHA152X_REVID); MODULE_LICENSE("GPL"); #if !defined(PCMCIA) #if defined(MODULE) static int io[] = {0, 0}; module_param_array(io, int, NULL, 0); MODULE_PARM_DESC(io,"base io address of controller"); static int irq[] = {0, 0}; module_param_array(irq, int, NULL, 0); MODULE_PARM_DESC(irq,"interrupt for controller"); static int scsiid[] = {7, 7}; module_param_array(scsiid, int, NULL, 0); MODULE_PARM_DESC(scsiid,"scsi id of controller"); static int reconnect[] = {1, 1}; module_param_array(reconnect, int, NULL, 0); MODULE_PARM_DESC(reconnect,"allow targets to disconnect"); static int parity[] = {1, 1}; module_param_array(parity, int, NULL, 0); MODULE_PARM_DESC(parity,"use scsi parity"); static int sync[] = {1, 1}; module_param_array(sync, int, NULL, 0); MODULE_PARM_DESC(sync,"use synchronous transfers"); static int delay[] = {DELAY_DEFAULT, DELAY_DEFAULT}; module_param_array(delay, int, NULL, 0); MODULE_PARM_DESC(delay,"scsi reset delay"); static int exttrans[] = {0, 0}; module_param_array(exttrans, int, NULL, 0); MODULE_PARM_DESC(exttrans,"use extended translation"); static int aha152x[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0}; module_param_array(aha152x, int, NULL, 0); MODULE_PARM_DESC(aha152x, "parameters for first controller"); static int aha152x1[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0}; module_param_array(aha152x1, int, NULL, 0); MODULE_PARM_DESC(aha152x1, "parameters for second controller"); #endif /* MODULE */ #ifdef __ISAPNP__ static struct isapnp_device_id id_table[] = { { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1502), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1505), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1510), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1515), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1520), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x2015), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1522), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x2215), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1530), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x3015), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1532), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x3215), 0 }, { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x6360), 0 }, { ISAPNP_DEVICE_SINGLE_END, } }; MODULE_DEVICE_TABLE(isapnp, id_table); #endif /* ISAPNP */ #endif /* !PCMCIA */ static struct scsi_host_template aha152x_driver_template; /* * internal states of the host * */ enum aha152x_state { idle=0, unknown, seldo, seldi, selto, busfree, msgo, cmd, msgi, status, datai, datao, parerr, rsti, maxstate }; /* * current state information of the host * */ struct aha152x_hostdata { Scsi_Cmnd *issue_SC; /* pending commands to issue */ Scsi_Cmnd *current_SC; /* current command on the bus */ Scsi_Cmnd *disconnected_SC; /* commands that disconnected */ Scsi_Cmnd *done_SC; /* command that was completed */ spinlock_t lock; /* host lock */ #if defined(AHA152X_STAT) int total_commands; int disconnections; int busfree_without_any_action; int busfree_without_old_command; int busfree_without_new_command; int busfree_without_done_command; int busfree_with_check_condition; int count[maxstate]; int count_trans[maxstate]; unsigned long time[maxstate]; #endif int commands; /* current number of commands */ int reconnect; /* disconnection allowed */ int parity; /* parity checking enabled */ int synchronous; /* synchronous transferes enabled */ int delay; /* reset out delay */ int ext_trans; /* extended translation enabled */ int swint; /* software-interrupt was fired during detect() */ int service; /* bh needs to be run */ int in_intr; /* bh is running */ /* current state, previous state, last state different from current state */ enum aha152x_state state, prevstate, laststate; int target; /* reconnecting target */ unsigned char syncrate[8]; /* current synchronous transfer agreements */ unsigned char syncneg[8]; /* 0: no negotiation; * 1: negotiation in progress; * 2: negotiation completed */ int cmd_i; /* number of sent bytes of current command */ int msgi_len; /* number of received message bytes */ unsigned char msgi[256]; /* received message bytes */ int msgo_i, msgo_len; /* number of sent bytes and length of current messages */ unsigned char msgo[256]; /* pending messages */ int data_len; /* number of sent/received bytes in dataphase */ unsigned long io_port0; unsigned long io_port1; #ifdef __ISAPNP__ struct pnp_dev *pnpdev; #endif struct list_head host_list; }; /* * host specific command extension * */ struct aha152x_scdata { Scsi_Cmnd *next; /* next sc in queue */ struct completion *done;/* semaphore to block on */ struct scsi_eh_save ses; }; /* access macros for hostdata */ #define HOSTDATA(shpnt) ((struct aha152x_hostdata *) &shpnt->hostdata) #define HOSTNO ((shpnt)->host_no) #define CURRENT_SC (HOSTDATA(shpnt)->current_SC) #define DONE_SC (HOSTDATA(shpnt)->done_SC) #define ISSUE_SC (HOSTDATA(shpnt)->issue_SC) #define DISCONNECTED_SC (HOSTDATA(shpnt)->disconnected_SC) #define QLOCK (HOSTDATA(shpnt)->lock) #define QLOCKER (HOSTDATA(shpnt)->locker) #define QLOCKERL (HOSTDATA(shpnt)->lockerl) #define STATE (HOSTDATA(shpnt)->state) #define PREVSTATE (HOSTDATA(shpnt)->prevstate) #define LASTSTATE (HOSTDATA(shpnt)->laststate) #define RECONN_TARGET (HOSTDATA(shpnt)->target) #define CMD_I (HOSTDATA(shpnt)->cmd_i) #define MSGO(i) (HOSTDATA(shpnt)->msgo[i]) #define MSGO_I (HOSTDATA(shpnt)->msgo_i) #define MSGOLEN (HOSTDATA(shpnt)->msgo_len) #define ADDMSGO(x) (MSGOLEN<256 ? (void)(MSGO(MSGOLEN++)=x) : aha152x_error(shpnt,"MSGO overflow")) #define MSGI(i) (HOSTDATA(shpnt)->msgi[i]) #define MSGILEN (HOSTDATA(shpnt)->msgi_len) #define ADDMSGI(x) (MSGILEN<256 ? (void)(MSGI(MSGILEN++)=x) : aha152x_error(shpnt,"MSGI overflow")) #define DATA_LEN (HOSTDATA(shpnt)->data_len) #define SYNCRATE (HOSTDATA(shpnt)->syncrate[CURRENT_SC->device->id]) #define SYNCNEG (HOSTDATA(shpnt)->syncneg[CURRENT_SC->device->id]) #define DELAY (HOSTDATA(shpnt)->delay) #define EXT_TRANS (HOSTDATA(shpnt)->ext_trans) #define TC1550 (HOSTDATA(shpnt)->tc1550) #define RECONNECT (HOSTDATA(shpnt)->reconnect) #define PARITY (HOSTDATA(shpnt)->parity) #define SYNCHRONOUS (HOSTDATA(shpnt)->synchronous) #define HOSTIOPORT0 (HOSTDATA(shpnt)->io_port0) #define HOSTIOPORT1 (HOSTDATA(shpnt)->io_port1) #define SCDATA(SCpnt) ((struct aha152x_scdata *) (SCpnt)->host_scribble) #define SCNEXT(SCpnt) SCDATA(SCpnt)->next #define SCSEM(SCpnt) SCDATA(SCpnt)->done #define SG_ADDRESS(buffer) ((char *) sg_virt((buffer))) /* state handling */ static void seldi_run(struct Scsi_Host *shpnt); static void seldo_run(struct Scsi_Host *shpnt); static void selto_run(struct Scsi_Host *shpnt); static void busfree_run(struct Scsi_Host *shpnt); static void msgo_init(struct Scsi_Host *shpnt); static void msgo_run(struct Scsi_Host *shpnt); static void msgo_end(struct Scsi_Host *shpnt); static void cmd_init(struct Scsi_Host *shpnt); static void cmd_run(struct Scsi_Host *shpnt); static void cmd_end(struct Scsi_Host *shpnt); static void datai_init(struct Scsi_Host *shpnt); static void datai_run(struct Scsi_Host *shpnt); static void datai_end(struct Scsi_Host *shpnt); static void datao_init(struct Scsi_Host *shpnt); static void datao_run(struct Scsi_Host *shpnt); static void datao_end(struct Scsi_Host *shpnt); static void status_run(struct Scsi_Host *shpnt); static void msgi_run(struct Scsi_Host *shpnt); static void msgi_end(struct Scsi_Host *shpnt); static void parerr_run(struct Scsi_Host *shpnt); static void rsti_run(struct Scsi_Host *shpnt); static void is_complete(struct Scsi_Host *shpnt); /* * driver states * */ static struct { char *name; void (*init)(struct Scsi_Host *); void (*run)(struct Scsi_Host *); void (*end)(struct Scsi_Host *); int spio; } states[] = { { "idle", NULL, NULL, NULL, 0}, { "unknown", NULL, NULL, NULL, 0}, { "seldo", NULL, seldo_run, NULL, 0}, { "seldi", NULL, seldi_run, NULL, 0}, { "selto", NULL, selto_run, NULL, 0}, { "busfree", NULL, busfree_run, NULL, 0}, { "msgo", msgo_init, msgo_run, msgo_end, 1}, { "cmd", cmd_init, cmd_run, cmd_end, 1}, { "msgi", NULL, msgi_run, msgi_end, 1}, { "status", NULL, status_run, NULL, 1}, { "datai", datai_init, datai_run, datai_end, 0}, { "datao", datao_init, datao_run, datao_end, 0}, { "parerr", NULL, parerr_run, NULL, 0}, { "rsti", NULL, rsti_run, NULL, 0}, }; /* setup & interrupt */ static irqreturn_t intr(int irq, void *dev_id); static void reset_ports(struct Scsi_Host *shpnt); static void aha152x_error(struct Scsi_Host *shpnt, char *msg); static void done(struct Scsi_Host *shpnt, int error); /* diagnostics */ static void show_command(Scsi_Cmnd * ptr); static void show_queues(struct Scsi_Host *shpnt); static void disp_enintr(struct Scsi_Host *shpnt); /* * queue services: * */
static inline void append_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC) { Scsi_Cmnd *end; SCNEXT(new_SC) = NULL; if (!*SC) *SC = new_SC; else { for (end = *SC; SCNEXT(end); end = SCNEXT(end)) ; SCNEXT(end) = new_SC; } }

Contributors

PersonTokensPropCommitsCommitProp
Jürgen E. Fischer6291.18%133.33%
Linus Torvalds (pre-git)68.82%266.67%
Total68100.00%3100.00%


static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd ** SC) { Scsi_Cmnd *ptr; ptr = *SC; if (ptr) { *SC = SCNEXT(*SC); SCNEXT(ptr)=NULL; } return ptr; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)2655.32%480.00%
Jürgen E. Fischer2144.68%120.00%
Total47100.00%5100.00%


static inline Scsi_Cmnd *remove_lun_SC(Scsi_Cmnd ** SC, int target, int lun) { Scsi_Cmnd *ptr, *prev; for (ptr = *SC, prev = NULL; ptr && ((ptr->device->id != target) || (ptr->device->lun != lun)); prev = ptr, ptr = SCNEXT(ptr)) ; if (ptr) { if (prev) SCNEXT(prev) = SCNEXT(ptr); else *SC = SCNEXT(ptr); SCNEXT(ptr)=NULL; } return ptr; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)10795.54%375.00%
Randy Dunlap54.46%125.00%
Total112100.00%4100.00%


static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, Scsi_Cmnd *SCp) { Scsi_Cmnd *ptr, *prev; for (ptr = *SC, prev = NULL; ptr && SCp!=ptr; prev = ptr, ptr = SCNEXT(ptr)) ; if (ptr) { if (prev) SCNEXT(prev) = SCNEXT(ptr); else *SC = SCNEXT(ptr); SCNEXT(ptr)=NULL; } return ptr; }

Contributors

PersonTokensPropCommitsCommitProp
Linus Torvalds (pre-git)92100.00%3100.00%
Total92100.00%3100.00%


static irqreturn_t swintr(int irqno, void *dev_id) { struct Scsi_Host *shpnt = dev_id; HOSTDATA(shpnt)->swint++; SETPORT(DMACNTRL0, INTEN); return IRQ_HANDLED; }

Contributors

PersonTokensPropCommitsCommitProp
Jürgen E. Fischer3694.74%133.33%
Linus Torvalds (pre-git)12.63%133.33%
James Bottomley12.63%133.33%
Total38100.00%3100.00%


struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup) { struct Scsi_Host *shpnt; shpnt = scsi_host_alloc(&aha152x_driver_template, sizeof(struct aha152x_hostdata)); if (!shpnt) { printk(KERN_ERR "aha152x: scsi_host_alloc failed\n"); return NULL; } memset(HOSTDATA(shpnt), 0, sizeof *HOSTDATA(shpnt)); INIT_LIST_HEAD(&HOSTDATA(shpnt)->host_list); /* need to have host registered before triggering any interrupt */ list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list); shpnt->io_port = setup->io_port; shpnt->n_io_port = IO_RANGE; shpnt->irq = setup->irq; if (!setup->tc1550) { HOSTIOPORT0 = setup->io_port; HOSTIOPORT1 = setup->io_port; } else { HOSTIOPORT0 = setup->io_port+0x10; HOSTIOPORT1 = setup->io_port-0x10; } spin_lock_init(&QLOCK); RECONNECT = setup->reconnect; SYNCHRONOUS = setup->synchronous; PARITY = setup->parity; DELAY = setup->delay; EXT_TRANS = setup->ext_trans; SETPORT(SCSIID, setup->scsiid << 4); shpnt->this_id = setup->scsiid; if (setup->reconnect) shpnt->can_queue = AHA152X_MAXQUEUE; /* RESET OUT */ printk("aha152x: resetting bus...\n"); SETPORT(SCSISEQ, SCSIRSTO); mdelay(256); SETPORT(SCSISEQ, 0); mdelay(DELAY); reset_ports(shpnt); printk(KERN_INFO "aha152x%d%s: " "vital data: rev=%x, " "io=0x%03lx (0x%03lx/0x%03lx), " "irq=%d, " "scsiid=%d, " "reconnect=%s, " "parity=%s, " "synchronous=%s, " "delay=%d, " "extended translation=%s\n", shpnt->host_no, setup->tc1550 ? " (tc1550 mode)" : "", GETPORT(REV) & 0x7, shpnt->io_port, HOSTIOPORT0, HOSTIOPORT1, shpnt->irq, shpnt->this_id, RECONNECT ? "enabled" : "disabled", PARITY ? "enabled" : "disabled", SYNCHRONOUS ? "enabled" : "disabled", DELAY, EXT_TRANS ? "enabled" : "disabled"); /* not expecting any interrupts */ SETPORT(SIMODE0, 0); SETPORT(SIMODE1, 0); if (request_irq(shpnt->irq, swintr, IRQF_SHARED, "aha152x", shpnt)) { printk(KERN_ERR "aha152x%d: irq %d busy.\n", shpnt->host_no, shpnt->irq); goto out_host_put; } HOSTDATA(shpnt)->swint = 0; printk(KERN_INFO "aha152x%d: trying software interrupt, ", shpnt->host_no); mb(); SETPORT(DMACNTRL0, SWINT|INTEN); mdelay(1000); free_irq(shpnt->irq, shpnt); if (!HOSTDATA(shpnt)->swint) { if (TESTHI(DMASTAT, INTSTAT)) { printk("lost.\n"); } else { printk("failed.\n"); } SETPORT(DMACNTRL0, INTEN); printk(KERN_ERR "aha152x%d: irq %d possibly wrong. " "Please verify.\n", shpnt->host_no, shpnt->irq); goto out_host_put; } printk("ok.\n"); /* clear interrupts */ SETPORT(SSTAT0, 0x7f); SETPORT(SSTAT1, 0xef); if (request_irq(shpnt->irq, intr, IRQF_SHARED, "aha152x", shpnt)) { printk(KERN_ERR "aha152x%d: failed to reassign irq %d.\n", shpnt->host_no, shpnt->irq); goto out_host_put; } if( scsi_add_host(shpnt, NULL) ) { free_irq(shpnt->irq, shpnt); printk(KERN_ERR "aha152x%d: failed to add host.\n", shpnt->host_no); goto out_host_put; } scsi_scan_host(shpnt); return shpnt; out_host_put: list_del(&HOSTDATA(shpnt)->host_list); scsi_host_put(shpnt); return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Jürgen E. Fischer45074.38%330.00%
Linus Torvalds (pre-git)11218.51%330.00%
James Bottomley365.95%110.00%
Hannes Reinecke30.50%110.00%
Thomas Gleixner20.33%110.00%
Al Viro20.33%110.00%
Total605100.00%10100.00%


void aha152x_release(struct Scsi_Host *shpnt) { if (!shpnt) return; scsi_remove_host(shpnt); if (shpnt->irq) free_irq(shpnt->irq, shpnt); #if !defined(PCMCIA) if (shpnt->io_port) release_region(shpnt->io_port, IO_RANGE); #endif #ifdef __ISAPNP__ if (HOSTDATA(shpnt)->pnpdev) pnp_device_detach(HOSTDATA(shpnt)->pnpdev); #endif list_del(&HOSTDATA(shpnt)->host_list); scsi_host_put(shpnt); }

Contributors

PersonTokensPropCommitsCommitProp
Jürgen E. Fischer6868.00%125.00%
Linus Torvalds (pre-git)1616.00%125.00%
James Bottomley1111.00%125.00%
Matthew Wilcox55.00%125.00%
Total100100.00%4100.00%

/* * setup controller to generate interrupts depending * on current state (lock has to be acquired) * */
static int setup_expected_interrupts(struct Scsi_Host *shpnt) { if(CURRENT_SC) { CURRENT_SC->SCp.phase |= 1 << 16; if(CURRENT_SC->SCp.phase & selecting) { SETPORT(SSTAT1, SELTO); SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0)); SETPORT(SIMODE1, ENSELTIMO); } else { SETPORT(SIMODE0, (CURRENT_SC->SCp.phase & spiordy) ? ENSPIORDY : 0); SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE); } } else if(STATE==seldi) { SETPORT(SIMODE0, 0); SETPORT(