vserver 1.9.5.x5
[linux-2.6.git] / drivers / scsi / dc395x.c
index 2a062f1..8738e20 100644 (file)
 #include <linux/delay.h>
 #include <linux/ctype.h>
 #include <linux/blkdev.h>
-#include <asm/io.h>
-#include "scsi.h"
-#include "hosts.h"
-#include "dc395x.h"
-#include <scsi/scsicam.h>      /* needed for scsicam_bios_param */
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <linux/list.h>
+#include <asm/io.h>
+
+#include <scsi/scsi.h>
+#include <scsi/scsicam.h>      /* needed for scsicam_bios_param */
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_host.h>
+
+#include "dc395x.h"
 
 #define DC395X_NAME    "dc395x"
 #define DC395X_BANNER  "Tekram DC395(U/UW/F), DC315(U) - ASIC TRM-S1040"
@@ -222,7 +226,7 @@ struct NvRamType {
 struct ScsiReqBlk {
        struct list_head list;          /* next/prev ptrs for srb lists */
        struct DeviceCtlBlk *dcb;
-       Scsi_Cmnd *cmd;
+       struct scsi_cmnd *cmd;
 
        struct SGentry *segment_x;      /* Linear array of hw sg entries (up to 64 entries) */
        u32 sg_bus_addr;                /* Bus address of sg list (ie, of segment_x) */
@@ -291,8 +295,8 @@ struct DeviceCtlBlk {
 struct AdapterCtlBlk {
        struct Scsi_Host *scsi_host;
 
-       u16 io_port_base;
-       u16 io_port_len;
+       unsigned long io_port_base;
+       unsigned long io_port_len;
 
        struct list_head dcb_list;              /* head of going dcb list */
        struct DeviceCtlBlk *dcb_run_robin;
@@ -307,7 +311,7 @@ struct AdapterCtlBlk {
 
        u8 sel_timeout;
 
-       u8 irq_level;
+       unsigned int irq_level;
        u8 tag_max_num;
        u8 acb_flag;
        u8 gmode2;
@@ -372,21 +376,21 @@ static void disconnect(struct AdapterCtlBlk *acb);
 static void reselect(struct AdapterCtlBlk *acb);
 static u8 start_scsi(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
                struct ScsiReqBlk *srb);
-static void build_srb(Scsi_Cmnd *cmd, struct DeviceCtlBlk *dcb,
+static inline void enable_msgout_abort(struct AdapterCtlBlk *acb,
+               struct ScsiReqBlk *srb);
+static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
                struct ScsiReqBlk *srb);
 static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_code,
-               Scsi_Cmnd *cmd, u8 force);
+               struct scsi_cmnd *cmd, u8 force);
 static void scsi_reset_detect(struct AdapterCtlBlk *acb);
 static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb);
 static void pci_unmap_srb_sense(struct AdapterCtlBlk *acb,
                struct ScsiReqBlk *srb);
-static inline void enable_msgout_abort(struct AdapterCtlBlk *acb,
-               struct ScsiReqBlk *srb);
 static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
                struct ScsiReqBlk *srb);
 static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
                struct ScsiReqBlk *srb);
-static inline void set_xfer_rate(struct AdapterCtlBlk *acb,
+static void set_xfer_rate(struct AdapterCtlBlk *acb,
                struct DeviceCtlBlk *dcb);
 static void waiting_timeout(unsigned long ptr);
 
@@ -484,7 +488,7 @@ struct ParameterData {
        int def;                /* default value */
        int safe;               /* safe value */
 };
-static struct ParameterData __initdata cfg_data[] = {
+static struct ParameterData __devinitdata cfg_data[] = {
        { /* adapter id */
                CFG_PARAM_UNSET,
                0,
@@ -569,7 +573,7 @@ MODULE_PARM_DESC(reset_delay, "Reset delay in seconds. Default 1 (0-180)");
  * set_safe_settings - if the use_safe_settings option is set then
  * set all values to the safe and slow values.
  **/
-static void __init set_safe_settings(void)
+static void __devinit set_safe_settings(void)
 {
        if (use_safe_settings)
        {
@@ -588,7 +592,7 @@ static void __init set_safe_settings(void)
  * fix_settings - reset any boot parameters which are out of range
  * back to the default values.
  **/
-static void __init fix_settings(void)
+static void __devinit fix_settings(void)
 {
        int i;
 
@@ -615,7 +619,7 @@ static void __init fix_settings(void)
  * Mapping from the eeprom delay index value (index into this array)
  * to the the number of actual seconds that the delay should be for.
  */
-static char __initdata eeprom_index_to_delay_map[] = 
+static char __devinitdata eeprom_index_to_delay_map[] = 
        { 1, 3, 5, 10, 16, 30, 60, 120 };
 
 
@@ -625,7 +629,7 @@ static char __initdata eeprom_index_to_delay_map[] =
  *
  * @eeprom: The eeprom structure in which we find the delay index to map.
  **/
-static void __init eeprom_index_to_delay(struct NvRamType *eeprom)
+static void __devinit eeprom_index_to_delay(struct NvRamType *eeprom)
 {
        eeprom->delay_time = eeprom_index_to_delay_map[eeprom->delay_time];
 }
@@ -638,7 +642,7 @@ static void __init eeprom_index_to_delay(struct NvRamType *eeprom)
  *
  * @delay: The delay, in seconds, to find the eeprom index for.
  **/
-static int __init delay_to_eeprom_index(int delay)
+static int __devinit delay_to_eeprom_index(int delay)
 {
        u8 idx = 0;
        while (idx < 7 && eeprom_index_to_delay_map[idx] < delay)
@@ -654,7 +658,7 @@ static int __init delay_to_eeprom_index(int delay)
  *
  * @eeprom: The eeprom data to override with command line options.
  **/
-static void __init eeprom_override(struct NvRamType *eeprom)
+static void __devinit eeprom_override(struct NvRamType *eeprom)
 {
        u8 id;
 
@@ -738,7 +742,7 @@ static void free_tag(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
 
 
 /* Find cmd in SRB list */
-inline static struct ScsiReqBlk *find_cmd(Scsi_Cmnd *cmd, 
+inline static struct ScsiReqBlk *find_cmd(struct scsi_cmnd *cmd, 
                struct list_head *head)
 {
        struct ScsiReqBlk *i;
@@ -973,10 +977,10 @@ static void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
 
 
 /* Prepare SRB for being sent to Device DCB w/ command *cmd */
-static void build_srb(Scsi_Cmnd *cmd, struct DeviceCtlBlk *dcb,
+static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb,
                struct ScsiReqBlk *srb)
 {
-       int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+       enum dma_data_direction dir = cmd->sc_data_direction;
        dprintkdbg(DBG_0, "build_srb: (pid#%li) <%02i-%i>\n",
                cmd->pid, dcb->target_id, dcb->target_lun);
 
@@ -985,7 +989,7 @@ static void build_srb(Scsi_Cmnd *cmd, struct DeviceCtlBlk *dcb,
        srb->sg_count = 0;
        srb->total_xfer_length = 0;
        srb->sg_bus_addr = 0;
-       srb->virt_addr = 0;
+       srb->virt_addr = NULL;
        srb->sg_index = 0;
        srb->adapter_status = 0;
        srb->target_status = 0;
@@ -1089,7 +1093,7 @@ static void build_srb(Scsi_Cmnd *cmd, struct DeviceCtlBlk *dcb,
  *        and is expected to be held on return.
  *
  **/
-static int dc395x_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
        struct DeviceCtlBlk *dcb;
        struct ScsiReqBlk *srb;
@@ -1304,7 +1308,7 @@ static void reset_dev_param(struct AdapterCtlBlk *acb)
  * @cmd - some command for this host (for fetching hooks)
  * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
  */
-static int dc395x_eh_bus_reset(Scsi_Cmnd *cmd)
+static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
 {
        struct AdapterCtlBlk *acb =
                (struct AdapterCtlBlk *)cmd->device->host->hostdata;
@@ -1356,7 +1360,7 @@ static int dc395x_eh_bus_reset(Scsi_Cmnd *cmd)
  * @cmd - command to be aborted
  * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
  */
-static int dc395x_eh_abort(Scsi_Cmnd *cmd)
+static int dc395x_eh_abort(struct scsi_cmnd *cmd)
 {
        /*
         * Look into our command queues: If it has not been sent already,
@@ -1672,6 +1676,23 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb,
 }
 
 
+#define DC395x_ENABLE_MSGOUT \
+ DC395x_write16 (acb, TRM_S1040_SCSI_CONTROL, DO_SETATN); \
+ srb->state |= SRB_MSGOUT
+
+
+/* abort command */
+static inline void enable_msgout_abort(struct AdapterCtlBlk *acb,
+               struct ScsiReqBlk *srb)
+{
+       srb->msgout_buf[0] = ABORT;
+       srb->msg_count = 1;
+       DC395x_ENABLE_MSGOUT;
+       srb->state &= ~SRB_MSGIN;
+       srb->state |= SRB_MSGOUT;
+}
+
+
 /**
  * dc395x_handle_interrupt - Handle an interrupt that has been confirmed to
  *                           have been triggered for this card.
@@ -1939,7 +1960,7 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
 {
        u8 idx;
        struct scatterlist *sg;
-       Scsi_Cmnd *cmd = srb->cmd;
+       struct scsi_cmnd *cmd = srb->cmd;
        int segment = cmd->use_sg;
        u32 xferred = srb->total_xfer_length - left; /* bytes transfered */
        struct SGentry *psge = srb->segment_x + srb->sg_index;
@@ -1995,7 +2016,7 @@ static void sg_update_list(struct ScsiReqBlk *srb, u32 left)
        }
 
        dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n");
-       srb->virt_addr = 0;
+       srb->virt_addr = NULL;
 }
 
 
@@ -2579,11 +2600,6 @@ static inline u8 msgin_completed(u8 * msgbuf, u32 len)
        return 1;
 }
 
-#define DC395x_ENABLE_MSGOUT \
- DC395x_write16 (acb, TRM_S1040_SCSI_CONTROL, DO_SETATN); \
- srb->state |= SRB_MSGOUT
-
-
 /* reject_msg */
 static inline void msgin_reject(struct AdapterCtlBlk *acb,
                struct ScsiReqBlk *srb)
@@ -2599,18 +2615,6 @@ static inline void msgin_reject(struct AdapterCtlBlk *acb,
 }
 
 
-/* abort command */
-static inline void enable_msgout_abort(struct AdapterCtlBlk *acb,
-               struct ScsiReqBlk *srb)
-{
-       srb->msgout_buf[0] = ABORT;
-       srb->msg_count = 1;
-       DC395x_ENABLE_MSGOUT;
-       srb->state &= ~SRB_MSGIN;
-       srb->state |= SRB_MSGOUT;
-}
-
-
 static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
                struct DeviceCtlBlk *dcb, u8 tag)
 {
@@ -3249,8 +3253,8 @@ static void add_dev(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
 /* unmap mapped pci regions from SRB */
 static void pci_unmap_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
 {
-       Scsi_Cmnd *cmd = srb->cmd;
-       int dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
+       struct scsi_cmnd *cmd = srb->cmd;
+       enum dma_data_direction dir = cmd->sc_data_direction;
        if (cmd->use_sg && dir != PCI_DMA_NONE) {
                /* unmap DC395x SG list */
                dprintkdbg(DBG_SG, "pci_unmap_srb: list=%08x(%05x)\n",
@@ -3301,11 +3305,10 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
                struct ScsiReqBlk *srb)
 {
        u8 tempcnt, status;
-       Scsi_Cmnd *cmd = srb->cmd;
+       struct scsi_cmnd *cmd = srb->cmd;
        struct ScsiInqData *ptr;
-       int dir;
+       enum dma_data_direction dir = cmd->sc_data_direction;
 
-       dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);
        if (cmd->use_sg) {
                struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer;
                ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset);
@@ -3510,7 +3513,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
 
 /* abort all cmds in our queues */
 static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
-               Scsi_Cmnd *cmd, u8 force)
+               struct scsi_cmnd *cmd, u8 force)
 {
        struct DeviceCtlBlk *dcb;
        dprintkl(KERN_INFO, "doing_srb_done: pids ");
@@ -3518,14 +3521,14 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
        list_for_each_entry(dcb, &acb->dcb_list, list) {
                struct ScsiReqBlk *srb;
                struct ScsiReqBlk *tmp;
-               Scsi_Cmnd *p;
+               struct scsi_cmnd *p;
 
                list_for_each_entry_safe(srb, tmp, &dcb->srb_going_list, list) {
+                       enum dma_data_direction dir;
                        int result;
-                       int dir;
 
                        p = srb->cmd;
-                       dir = scsi_to_pci_dma_dir(p->sc_data_direction);
+                       dir = p->sc_data_direction;
                        result = MK_RES(0, did_flag, 0, 0);
                        printk("G:%li(%02i-%i) ", p->pid,
                               p->device->id, p->device->lun);
@@ -3653,7 +3656,7 @@ static void scsi_reset_detect(struct AdapterCtlBlk *acb)
        } else {
                acb->acb_flag |= RESET_DETECT;
                reset_dev_param(acb);
-               doing_srb_done(acb, DID_RESET, 0, 1);
+               doing_srb_done(acb, DID_RESET, NULL, 1);
                /*DC395x_RecoverSRB( acb ); */
                acb->active_dcb = NULL;
                acb->acb_flag = 0;
@@ -3665,7 +3668,7 @@ static void scsi_reset_detect(struct AdapterCtlBlk *acb)
 static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
                struct ScsiReqBlk *srb)
 {
-       Scsi_Cmnd *cmd = srb->cmd;
+       struct scsi_cmnd *cmd = srb->cmd;
        dprintkdbg(DBG_1, "request_sense: (pid#%li) <%02i-%i>\n",
                cmd->pid, cmd->device->id, cmd->device->lun);
 
@@ -3928,7 +3931,7 @@ static void dc395x_slave_destroy(struct scsi_device *scsi_device)
  *
  * @io_port: base I/O address
  **/
-static void __init trms1040_wait_30us(u16 io_port)
+static void __devinit trms1040_wait_30us(unsigned long io_port)
 {
        /* ScsiPortStallExecution(30); wait 30 us */
        outb(5, io_port + TRM_S1040_GEN_TIMER);
@@ -3945,7 +3948,7 @@ static void __init trms1040_wait_30us(u16 io_port)
  * @cmd:       SB + op code (command) to send
  * @addr:      address to send
  **/
-static void __init trms1040_write_cmd(u16 io_port, u8 cmd, u8 addr)
+static void __devinit trms1040_write_cmd(unsigned long io_port, u8 cmd, u8 addr)
 {
        int i;
        u8 send_data;
@@ -3990,7 +3993,7 @@ static void __init trms1040_write_cmd(u16 io_port, u8 cmd, u8 addr)
  * @addr:      offset into EEPROM
  * @byte:      bytes to write
  **/
-static void __init trms1040_set_data(u16 io_port, u8 addr, u8 byte)
+static void __devinit trms1040_set_data(unsigned long io_port, u8 addr, u8 byte)
 {
        int i;
        u8 send_data;
@@ -4044,7 +4047,7 @@ static void __init trms1040_set_data(u16 io_port, u8 addr, u8 byte)
  * @eeprom:    the data to write
  * @io_port:   the base io port
  **/
-static void __init trms1040_write_all(struct NvRamType *eeprom, u16 io_port)
+static void __devinit trms1040_write_all(struct NvRamType *eeprom, unsigned long io_port)
 {
        u8 *b_eeprom = (u8 *)eeprom;
        u8 addr;
@@ -4084,7 +4087,7 @@ static void __init trms1040_write_all(struct NvRamType *eeprom, u16 io_port)
  *
  * Returns the the byte read.
  **/
-static u8 __init trms1040_get_data(u16 io_port, u8 addr)
+static u8 __devinit trms1040_get_data(unsigned long io_port, u8 addr)
 {
        int i;
        u8 read_byte;
@@ -4122,7 +4125,7 @@ static u8 __init trms1040_get_data(u16 io_port, u8 addr)
  * @eeprom:    where to store the data
  * @io_port:   the base io port
  **/
-static void __init trms1040_read_all(struct NvRamType *eeprom, u16 io_port)
+static void __devinit trms1040_read_all(struct NvRamType *eeprom, unsigned long io_port)
 {
        u8 *b_eeprom = (u8 *)eeprom;
        u8 addr;
@@ -4152,7 +4155,7 @@ static void __init trms1040_read_all(struct NvRamType *eeprom, u16 io_port)
  * @eeprom:    caller allocated strcuture to read the eeprom data into
  * @io_port:   io port to read from
  **/
-static void __init check_eeprom(struct NvRamType *eeprom, u16 io_port)
+static void __devinit check_eeprom(struct NvRamType *eeprom, unsigned long io_port)
 {
        u16 *w_eeprom = (u16 *)eeprom;
        u16 w_addr;
@@ -4222,7 +4225,7 @@ static void __init check_eeprom(struct NvRamType *eeprom, u16 io_port)
  *
  * @eeprom: The eeprom data strucutre to show details for.
  **/
-static void __init print_eeprom_settings(struct NvRamType *eeprom)
+static void __devinit print_eeprom_settings(struct NvRamType *eeprom)
 {
        dprintkl(KERN_INFO, "Used settings: AdapterID=%02i, Speed=%i(%02i.%01iMHz), dev_mode=0x%02x\n",
                eeprom->scsi_id,
@@ -4251,7 +4254,7 @@ static void adapter_sg_tables_free(struct AdapterCtlBlk *acb)
 /*
  * Allocate SG tables; as we have to pci_map them, an SG list (struct SGentry*)
  * should never cross a page boundary */
-static int __init adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
+static int __devinit adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
 {
        const unsigned mem_needed = (DC395x_MAX_SRB_CNT+1)
                                    *SEGMENTX_LEN;
@@ -4297,7 +4300,7 @@ static int __init adapter_sg_tables_alloc(struct AdapterCtlBlk *acb)
  *
  * @acb: The adapter to print the information for.
  **/
-static void __init adapter_print_config(struct AdapterCtlBlk *acb)
+static void __devinit adapter_print_config(struct AdapterCtlBlk *acb)
 {
        u8 bval;
 
@@ -4341,7 +4344,7 @@ static void __init adapter_print_config(struct AdapterCtlBlk *acb)
  *
  * @acb: The adapter to initialize.
  **/
-static void __init adapter_init_params(struct AdapterCtlBlk *acb)
+static void __devinit adapter_init_params(struct AdapterCtlBlk *acb)
 {
        struct NvRamType *eeprom = &acb->eeprom;
        int i;
@@ -4403,7 +4406,7 @@ static void __init adapter_init_params(struct AdapterCtlBlk *acb)
  *
  * @host: The scsi host instance to fill in the values for.
  **/
-static void __init adapter_init_scsi_host(struct Scsi_Host *host)
+static void __devinit adapter_init_scsi_host(struct Scsi_Host *host)
 {
         struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
        struct NvRamType *eeprom = &acb->eeprom;
@@ -4444,7 +4447,7 @@ static void __init adapter_init_scsi_host(struct Scsi_Host *host)
  *
  * @acb: The adapter which we are to init.
  **/
-void __init adapter_init_chip(struct AdapterCtlBlk *acb)
+static void __devinit adapter_init_chip(struct AdapterCtlBlk *acb)
 {
         struct NvRamType *eeprom = &acb->eeprom;
         
@@ -4497,11 +4500,11 @@ void __init adapter_init_chip(struct AdapterCtlBlk *acb)
  * Returns 0 if the initialization succeeds, any other value on
  * failure.
  **/
-static int __init adapter_init(struct AdapterCtlBlk *acb, u32 io_port,
-               u32 io_port_len, u8 irq)
+static int __devinit adapter_init(struct AdapterCtlBlk *acb,
+       unsigned long io_port, u32 io_port_len, unsigned int irq)
 {
        if (!request_region(io_port, io_port_len, DC395X_NAME)) {
-               dprintkl(KERN_ERR, "Failed to reserve IO region 0x%x\n", io_port);
+               dprintkl(KERN_ERR, "Failed to reserve IO region 0x%lx\n", io_port);
                goto failed;
        }
        /* store port base to indicate we have registered it */
@@ -4517,7 +4520,7 @@ static int __init adapter_init(struct AdapterCtlBlk *acb, u32 io_port,
        acb->irq_level = irq;
 
        /* get eeprom configuration information and command line settings etc */
-       check_eeprom(&acb->eeprom, (u16)io_port);
+       check_eeprom(&acb->eeprom, io_port);
        print_eeprom_settings(&acb->eeprom);
 
        /* setup adapter control block */       
@@ -4635,8 +4638,8 @@ static int dc395x_proc_info(struct Scsi_Host *host, char *buffer,
        SPRINTF("SCSI Host Nr %i, ", host->host_no);
        SPRINTF("DC395U/UW/F DC315/U %s\n",
                (acb->config & HCC_WIDE_CARD) ? "Wide" : "");
-       SPRINTF("io_port_base 0x%04x, ", acb->io_port_base);
-       SPRINTF("irq_level 0x%02x, ", acb->irq_level);
+       SPRINTF("io_port_base 0x%04lx, ", acb->io_port_base);
+       SPRINTF("irq_level 0x%04x, ", acb->irq_level);
        SPRINTF(" SelTimeout %ims\n", (1638 * acb->sel_timeout) / 1000);
 
        SPRINTF("MaxID %i, MaxLUN %i, ", host->max_id, host->max_lun);
@@ -4738,7 +4741,7 @@ static int dc395x_proc_info(struct Scsi_Host *host, char *buffer,
 }
 
 
-static Scsi_Host_Template dc395x_driver_template = {
+static struct scsi_host_template dc395x_driver_template = {
        .module                 = THIS_MODULE,
        .proc_name              = DC395X_NAME,
        .proc_info              = dc395x_proc_info,
@@ -4789,11 +4792,11 @@ static void banner_display(void)
 static int __devinit dc395x_init_one(struct pci_dev *dev,
                const struct pci_device_id *id)
 {
-       struct Scsi_Host *scsi_host;
-       struct AdapterCtlBlk *acb;
-       unsigned int io_port_base;
+       struct Scsi_Host *scsi_host = NULL;
+       struct AdapterCtlBlk *acb = NULL;
+       unsigned long io_port_base;
        unsigned int io_port_len;
-       u8 irq;
+       unsigned int irq;
        
        dprintkdbg(DBG_0, "Init one instance (%s)\n", pci_name(dev));
        banner_display();
@@ -4806,23 +4809,23 @@ static int __devinit dc395x_init_one(struct pci_dev *dev,
        io_port_base = pci_resource_start(dev, 0) & PCI_BASE_ADDRESS_IO_MASK;
        io_port_len = pci_resource_len(dev, 0);
        irq = dev->irq;
-       dprintkdbg(DBG_0, "IO_PORT=%04x, IRQ=%x\n", io_port_base, dev->irq);
+       dprintkdbg(DBG_0, "IO_PORT=0x%04lx, IRQ=0x%x\n", io_port_base, dev->irq);
 
        /* allocate scsi host information (includes out adapter) */
        scsi_host = scsi_host_alloc(&dc395x_driver_template,
                                    sizeof(struct AdapterCtlBlk));
        if (!scsi_host) {
                dprintkl(KERN_INFO, "scsi_host_alloc failed\n");
-               return -ENOMEM;
+               goto fail;
        }
        acb = (struct AdapterCtlBlk*)scsi_host->hostdata;
        acb->scsi_host = scsi_host;
+       acb->dev = dev;
 
        /* initialise the adapter and everything we need */
        if (adapter_init(acb, io_port_base, io_port_len, irq)) {
                dprintkl(KERN_INFO, "adapter init failed\n");
-               scsi_host_put(scsi_host);
-               return -ENODEV;
+               goto fail;
        }
 
        pci_set_master(dev);
@@ -4830,14 +4833,20 @@ static int __devinit dc395x_init_one(struct pci_dev *dev,
        /* get the scsi mid level to scan for new devices on the bus */
        if (scsi_add_host(scsi_host, &dev->dev)) {
                dprintkl(KERN_ERR, "scsi_add_host failed\n");
-               adapter_uninit(acb);
-               scsi_host_put(scsi_host);
-               return -ENODEV;
+               goto fail;
        }
        pci_set_drvdata(dev, scsi_host);
        scsi_scan_host(scsi_host);
                
        return 0;
+
+fail:
+       if (acb != NULL)
+               adapter_uninit(acb);
+       if (scsi_host != NULL)
+               scsi_host_put(scsi_host);
+       pci_disable_device(dev);
+       return -ENODEV;
 }
 
 
@@ -4856,6 +4865,7 @@ static void __devexit dc395x_remove_one(struct pci_dev *dev)
 
        scsi_remove_host(scsi_host);
        adapter_uninit(acb);
+       pci_disable_device(dev);
        scsi_host_put(scsi_host);
        pci_set_drvdata(dev, NULL);
 }