#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"
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) */
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;
u8 sel_timeout;
- u8 irq_level;
+ unsigned int irq_level;
u8 tag_max_num;
u8 acb_flag;
u8 gmode2;
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);
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,
* 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)
{
* 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;
* 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 };
*
* @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];
}
*
* @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)
*
* @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;
/* 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;
/* 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);
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;
* 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;
* @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;
* @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,
}
+#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.
{
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;
}
dprintkl(KERN_ERR, "sg_update_list: sg_to_virt failed\n");
- srb->virt_addr = 0;
+ srb->virt_addr = NULL;
}
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)
}
-/* 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)
{
/* 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",
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);
/* 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 ");
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);
} 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;
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);
*
* @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);
* @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;
* @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;
* @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;
*
* 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;
* @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;
* @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;
*
* @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,
/*
* 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;
*
* @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;
*
* @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;
*
* @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;
*
* @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;
* 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 */
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 */
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);
}
-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,
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();
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);
/* 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;
}
scsi_remove_host(scsi_host);
adapter_uninit(acb);
+ pci_disable_device(dev);
scsi_host_put(scsi_host);
pci_set_drvdata(dev, NULL);
}