summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Bottomley <jejb@raven.il.steeleye.com>2003-08-17 11:42:19 -0500
committerJames Bottomley <jejb@raven.il.steeleye.com>2003-08-17 11:42:19 -0500
commitbede2c884fff085be98964e664d2f807065f6d8b (patch)
tree4d7991bc8363e949dd7310fde2620aae5c7068d4
parentdb82f17d8a71a073f8c3f049bcac4fa668f68088 (diff)
parent4277ddc2fcee546c3dff59ac3964471498498b07 (diff)
Merge raven.il.steeleye.com:/home/jejb/BK/scsi-misc-2.5
into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.6
-rw-r--r--drivers/scsi/dc395x.c717
-rw-r--r--drivers/scsi/hosts.c85
-rw-r--r--drivers/scsi/ips.c9985
-rw-r--r--drivers/scsi/ips.h80
-rw-r--r--drivers/scsi/lasi700.c10
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c10
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c11
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c27
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c11
-rw-r--r--drivers/scsi/ppa.c1
-rw-r--r--drivers/scsi/qla1280.c30
-rw-r--r--drivers/scsi/qla1280.h6
-rw-r--r--drivers/scsi/scsi.c8
-rw-r--r--drivers/scsi/scsi_error.c7
-rw-r--r--drivers/scsi/scsi_lib.c22
-rw-r--r--drivers/scsi/scsi_priv.h17
-rw-r--r--drivers/scsi/scsi_proc.c16
-rw-r--r--drivers/scsi/scsi_scan.c126
-rw-r--r--drivers/scsi/scsi_sysfs.c174
-rw-r--r--drivers/scsi/sd.c8
-rw-r--r--drivers/scsi/sr.c31
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c7
-rw-r--r--drivers/scsi/zalon.c6
-rw-r--r--include/scsi/scsi.h2
25 files changed, 5885 insertions, 5514 deletions
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 0714ea4b8736..33fc1b077942 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -60,6 +60,7 @@
#include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/pci.h>
+#include <linux/list.h>
/*---------------------------------------------------------------------------
Features
@@ -306,7 +307,7 @@ struct NvRamType {
SCSI Request Block
-----------------------------------------------------------------------*/
struct ScsiReqBlk {
- struct ScsiReqBlk *next;
+ struct list_head list; /* next/prev ptrs for srb lists */
struct DeviceCtlBlk *dcb;
/* HW scatter list (up to 64 entries) */
@@ -350,22 +351,16 @@ struct ScsiReqBlk {
Device Control Block
-----------------------------------------------------------------------*/
struct DeviceCtlBlk {
- struct DeviceCtlBlk *next;
+ struct list_head list; /* next/prev ptrs for the dcb list */
struct AdapterCtlBlk *acb;
-
- struct ScsiReqBlk *going_srb;
- struct ScsiReqBlk *going_last;
-
- struct ScsiReqBlk *waiting_srb;
- struct ScsiReqBlk *wait_list;
+ struct list_head srb_going_list; /* head of going srb list */
+ struct list_head srb_waiting_list; /* head of waiting srb list */
struct ScsiReqBlk *active_srb;
u32 tag_mask;
u16 max_command;
- u16 going_srb_count;
- u16 waiting_srb_count;
u8 target_id; /* SCSI Target ID (SCSI Only) */
u8 target_lun; /* SCSI Log. Unit (SCSI Only) */
u8 identify_msg;
@@ -390,20 +385,17 @@ struct AdapterCtlBlk {
u16 IOPortBase;
- struct DeviceCtlBlk *link_dcb;
- struct DeviceCtlBlk *last_dcb;
+ struct list_head dcb_list; /* head of going dcb list */
struct DeviceCtlBlk *dcb_run_robin;
-
struct DeviceCtlBlk *active_dcb;
- struct ScsiReqBlk *free_srb;
+ struct list_head srb_free_list; /* head of free srb list */
struct ScsiReqBlk *tmp_srb;
struct timer_list waiting_timer;
struct timer_list selto_timer;
u16 srb_count;
- u8 dcb_count;
u8 sel_timeout;
u8 irq_level;
@@ -824,6 +816,60 @@ void __init eeprom_override(struct NvRamType *eeprom)
/*---------------------------------------------------------------------------
---------------------------------------------------------------------------*/
+/**
+ * list_size - Returns the size (in number of entries) of the
+ * supplied list.
+ *
+ * @head: The pointer to the head of the list to count the items in.
+ **/
+unsigned int list_size(struct list_head *head)
+{
+ unsigned int count = 0;
+ struct list_head *pos;
+ list_for_each(pos, head)
+ count++;
+ return count;
+}
+
+
+/**
+ * dcb_get_next - Given a dcb return the next dcb in the list of
+ * dcb's, wrapping back to the start of the dcb list if required.
+ * Returns the supplied dcb if there is only one dcb in the list.
+ *
+ * @head: The pointer to the head of the list to count the items in.
+ * @pos: The pointer the dcb for which we are searching for the
+ * following dcb.
+ **/
+struct DeviceCtlBlk *dcb_get_next(
+ struct list_head *head,
+ struct DeviceCtlBlk *pos)
+{
+ int use_next = 0;
+ struct DeviceCtlBlk* next = NULL;
+ struct DeviceCtlBlk* i;
+
+ if (list_empty(head))
+ return NULL;
+
+ /* find supplied dcb and then select the next one */
+ list_for_each_entry(i, head, list)
+ if (use_next) {
+ next = i;
+ break;
+ } else if (i == pos) {
+ use_next = 1;
+ }
+ /* if no next one take the head one (ie, wraparound) */
+ if (!next)
+ list_for_each_entry(i, head, list) {
+ next = i;
+ break;
+ }
+
+ return next;
+}
+
/*
* Queueing philosphy:
@@ -851,200 +897,153 @@ void free_tag(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
/* Find cmd in SRB list */
inline static
-struct ScsiReqBlk *find_cmd(Scsi_Cmnd * cmd,
- struct ScsiReqBlk *start)
+struct ScsiReqBlk *find_cmd(Scsi_Cmnd *cmd,
+ struct list_head *head)
{
- struct ScsiReqBlk *psrb = start;
- if (!start)
- return 0;
- do {
- if (psrb->cmd == cmd)
- return psrb;
- psrb = psrb->next;
- } while (psrb && psrb != start);
- return 0;
+ struct ScsiReqBlk *i;
+ list_for_each_entry(i, head, list)
+ if (i->cmd == cmd)
+ return i;
+ return NULL;
}
-/* Return next free SRB */
-static inline
-struct ScsiReqBlk *get_srb_free(struct AdapterCtlBlk *acb)
+/*
+ * srb_get_free - Return a free srb from the list of free SRBs that
+ * is stored with the acb.
+ */
+static
+struct ScsiReqBlk *srb_get_free(struct AdapterCtlBlk *acb)
{
+ struct list_head *head = &acb->srb_free_list;
struct ScsiReqBlk *srb;
- /*DC395x_Free_integrity (acb); */
- srb = acb->free_srb;
- if (!srb)
+ if (!list_empty(head)) {
+ srb = list_entry(head->next, struct ScsiReqBlk, list);
+ list_del(head->next);
+ dprintkdbg(DBG_0, "srb_get_free: got srb %p\n", srb);
+ } else {
+ srb = NULL;
dprintkl(KERN_ERR, "Out of Free SRBs :-(\n");
- if (srb) {
- acb->free_srb = srb->next;
- srb->next = NULL;
}
-
return srb;
}
-/* Insert SRB oin top of free list */
-static inline
-void insert_srb_free(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
+/*
+ * srb_free_insert - Insert an srb to the head of the free list
+ * stored in the acb.
+ */
+static
+void srb_free_insert(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
{
- dprintkdbg(DBG_0, "Free SRB %p\n", srb);
- srb->next = acb->free_srb;
- acb->free_srb = srb;
+ dprintkdbg(DBG_0, "srb_free_insert: put srb %p\n", srb);
+ list_add_tail(&srb->list, &acb->srb_free_list);
}
-/* Inserts a SRB to the top of the Waiting list */
-static inline
-void insert_srb_waiting(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
+/*
+ * srb_waiting_insert - Insert an srb to the head of the wiating list
+ * stored in the dcb.
+ */
+static
+void srb_waiting_insert(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
{
- dprintkdbg(DBG_0, "Insert srb %p cmd %li to Waiting\n", srb, srb->cmd->pid);
- srb->next = dcb->waiting_srb;
- if (!dcb->waiting_srb)
- dcb->wait_list = srb;
- dcb->waiting_srb = srb;
- dcb->waiting_srb_count++;
+ dprintkdbg(DBG_0, "srb_waiting_insert: srb %p cmd %li\n", srb, srb->cmd->pid);
+ list_add(&srb->list, &dcb->srb_waiting_list);
}
-/* Queue SRB to waiting list */
+/*
+ * srb_waiting_append - Append an srb to the tail of the waiting list
+ * stored in the dcb.
+ */
static inline
-void append_srb_waiting(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
+void srb_waiting_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
{
- dprintkdbg(DBG_0, "Append srb %p cmd %li to Waiting\n", srb, srb->cmd->pid);
- if (dcb->waiting_srb)
- dcb->wait_list->next = srb;
- else
- dcb->waiting_srb = srb;
-
- dcb->wait_list = srb;
- /* No next one in waiting list */
- srb->next = NULL;
- dcb->waiting_srb_count++;
+ dprintkdbg(DBG_0, "srb_waiting_append: srb %p cmd %li\n", srb, srb->cmd->pid);
+ list_add_tail(&srb->list, &dcb->srb_waiting_list);
}
+/*
+ * srb_going_append - Append an srb to the tail of the going list
+ * stored in the dcb.
+ */
static inline
-void append_srb_going(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
-{
- dprintkdbg(DBG_0, "Append SRB %p to Going\n", srb);
- /* Append to the list of Going commands */
- if (dcb->going_srb)
- dcb->going_last->next = srb;
- else
- dcb->going_srb = srb;
-
- dcb->going_last = srb;
- /* No next one in sent list */
- srb->next = NULL;
- dcb->going_srb_count++;
-}
-
-
-/* Find predecessor SRB */
-inline static
-struct ScsiReqBlk *find_srb_prev(struct ScsiReqBlk *srb,
- struct ScsiReqBlk *start)
+void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
{
- struct ScsiReqBlk *p = start;
- if (!start)
- return 0;
- do {
- if (p->next == srb)
- return p;
- p = p->next;
- } while (p && p != start);
- return 0;
+ dprintkdbg(DBG_0, "srb_going_append: srb %p\n", srb);
+ list_add_tail(&srb->list, &dcb->srb_going_list);
}
-/* Remove SRB from SRB queue */
-inline static
-struct ScsiReqBlk *remove_srb(struct ScsiReqBlk *srb,
- struct ScsiReqBlk *pre)
-{
- if (pre->next != srb)
- pre = find_srb_prev(srb, pre);
- if (!pre) {
- dprintkl(KERN_ERR, "Internal ERROR: SRB to rmv not found in Q!\n");
- return 0;
- }
- pre->next = srb->next;
- /*srb->next = NULL; */
- return pre;
-}
-
-/* Remove SRB from Going queue */
+/*
+ * srb_going_remove - Remove an srb from the going list stored in the
+ * dcb.
+ */
static
-void remove_srb_going(struct DeviceCtlBlk *dcb,
- struct ScsiReqBlk *srb,
- struct ScsiReqBlk *hint)
+void srb_going_remove(struct DeviceCtlBlk *dcb,
+ struct ScsiReqBlk *srb)
{
- struct ScsiReqBlk *pre = NULL;
- dprintkdbg(DBG_0, "Remove SRB %p from Going\n", srb);
- if (!srb)
- dprintkl(KERN_ERR, "Going_remove %p!\n", srb);
- if (srb == dcb->going_srb)
- dcb->going_srb = srb->next;
- else if (hint && hint->next == srb)
- pre = remove_srb(srb, hint);
- else
- pre = remove_srb(srb, dcb->going_srb);
- if (srb == dcb->going_last)
- dcb->going_last = pre;
- dcb->going_srb_count--;
+ struct ScsiReqBlk *i;
+ struct ScsiReqBlk *tmp;
+ dprintkdbg(DBG_0, "srb_going_remove: srb %p\n", srb);
+
+ list_for_each_entry_safe(i, tmp, &dcb->srb_going_list, list)
+ if (i == srb) {
+ list_del(&srb->list);
+ break;
+ }
}
-/* Remove SRB from Waiting queue */
+/*
+ * srb_waiting_remove - Remove an srb from the waiting list stored in the
+ * dcb.
+ */
static
-void remove_srb_waiting(struct DeviceCtlBlk *dcb,
- struct ScsiReqBlk *srb,
- struct ScsiReqBlk *hint)
+void srb_waiting_remove(struct DeviceCtlBlk *dcb,
+ struct ScsiReqBlk *srb)
{
- struct ScsiReqBlk *pre = NULL;
- dprintkdbg(DBG_0, "Remove SRB %p from Waiting\n", srb);
- if (!srb)
- dprintkl(KERN_ERR, "Waiting_remove %p!\n", srb);
- if (srb == dcb->waiting_srb)
- dcb->waiting_srb = srb->next;
- else if (hint && hint->next == srb)
- pre = remove_srb(srb, hint);
- else
- pre = remove_srb(srb, dcb->waiting_srb);
- if (srb == dcb->wait_list)
- dcb->wait_list = pre;
- dcb->waiting_srb_count--;
+ struct ScsiReqBlk *i;
+ struct ScsiReqBlk *tmp;
+ dprintkdbg(DBG_0, "srb_waiting_remove: srb %p\n", srb);
+
+ list_for_each_entry_safe(i, tmp, &dcb->srb_waiting_list, list)
+ if (i == srb) {
+ list_del(&srb->list);
+ break;
+ }
}
-/* Moves SRB from Going list to the top of Waiting list */
+/*
+ * srb_going_to_waiting_move - Remove an srb from the going list in
+ * the dcb and insert it at the head of the waiting list in the dcb.
+ */
static
-void move_srb_going_to_waiting(struct DeviceCtlBlk *dcb,
+void srb_going_to_waiting_move(struct DeviceCtlBlk *dcb,
struct ScsiReqBlk *srb)
{
- dprintkdbg(DBG_0, "Going_to_Waiting (SRB %p) pid = %li\n", srb, srb->cmd->pid);
- /* Remove SRB from Going */
- remove_srb_going(dcb, srb, 0);
- TRACEPRINTF("GtW *");
- /* Insert on top of Waiting */
- insert_srb_waiting(dcb, srb);
- /* Tag Mask must be freed elsewhere ! (KG, 99/06/18) */
+ dprintkdbg(DBG_0, "srb_going_waiting_move: srb %p, pid = %li\n", srb, srb->cmd->pid);
+ list_move(&srb->list, &dcb->srb_waiting_list);
}
-/* Moves first SRB from Waiting list to Going list */
-static inline
-void move_srb_waiting_to_going(struct DeviceCtlBlk *dcb,
+/*
+ * srb_waiting_to_going_move - Remove an srb from the waiting list in
+ * the dcb and insert it at the head of the going list in the dcb.
+ */
+static
+void srb_waiting_to_going_move(struct DeviceCtlBlk *dcb,
struct ScsiReqBlk *srb)
{
/* Remove from waiting list */
- dprintkdbg(DBG_0, "Remove SRB %p from head of Waiting\n", srb);
- remove_srb_waiting(dcb, srb, 0);
+ dprintkdbg(DBG_0, "srb_waiting_to_going: srb %p\n", srb);
TRACEPRINTF("WtG *");
- append_srb_going(dcb, srb);
+ list_move(&srb->list, &dcb->srb_going_list);
}
@@ -1070,39 +1069,66 @@ void waiting_set_timer(struct AdapterCtlBlk *acb, unsigned long to)
static
void waiting_process_next(struct AdapterCtlBlk *acb)
{
- struct DeviceCtlBlk *ptr;
- struct DeviceCtlBlk *ptr1;
+ struct DeviceCtlBlk *start = NULL;
+ struct DeviceCtlBlk *pos;
+ struct DeviceCtlBlk *dcb;
struct ScsiReqBlk *srb;
+ struct list_head *dcb_list_head = &acb->dcb_list;
if ((acb->active_dcb)
|| (acb->acb_flag & (RESET_DETECT + RESET_DONE + RESET_DEV)))
return;
+
if (timer_pending(&acb->waiting_timer))
del_timer(&acb->waiting_timer);
- ptr = acb->dcb_run_robin;
- if (!ptr) { /* This can happen! */
- ptr = acb->link_dcb;
- acb->dcb_run_robin = ptr;
- }
- ptr1 = ptr;
- if (!ptr1)
+
+ if (list_empty(dcb_list_head))
return;
+
+ /*
+ * Find the starting dcb. Need to find it again in the list
+ * since the list may have changed since we set the ptr to it
+ */
+ list_for_each_entry(dcb, dcb_list_head, list)
+ if (dcb == acb->dcb_run_robin) {
+ start = dcb;
+ break;
+ }
+ if (!start) {
+ /* This can happen! */
+ start = list_entry(dcb_list_head->next, typeof(*start), list);
+ acb->dcb_run_robin = start;
+ }
+
+
+ /*
+ * Loop over the dcb, but we start somewhere (potentially) in
+ * the middle of the loop so we need to manully do this.
+ */
+ pos = start;
do {
+ struct list_head *waiting_list_head = &pos->srb_waiting_list;
+
/* Make sure, the next another device gets scheduled ... */
- acb->dcb_run_robin = ptr1->next;
- if (!(srb = ptr1->waiting_srb)
- || (ptr1->max_command <= ptr1->going_srb_count))
- ptr1 = ptr1->next;
- else {
+ acb->dcb_run_robin = dcb_get_next(dcb_list_head,
+ acb->dcb_run_robin);
+
+ if (list_empty(waiting_list_head) ||
+ pos->max_command <= list_size(&pos->srb_going_list)) {
+ /* move to next dcb */
+ pos = dcb_get_next(dcb_list_head, pos);
+ } else {
+ srb = list_entry(waiting_list_head->next,
+ struct ScsiReqBlk, list);
+
/* Try to send to the bus */
- if (!start_scsi(acb, ptr1, srb))
- move_srb_waiting_to_going(ptr1, srb);
+ if (!start_scsi(acb, pos, srb))
+ srb_waiting_to_going_move(pos, srb);
else
- waiting_set_timer(acb, HZ / 50);
+ waiting_set_timer(acb, HZ/50);
break;
}
- } while (ptr1 != ptr);
- return;
+ } while (pos != start);
}
@@ -1141,30 +1167,18 @@ void send_srb(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb)
struct DeviceCtlBlk *dcb;
dcb = srb->dcb;
- if ((dcb->max_command <= dcb->going_srb_count) ||
- (acb->active_dcb) ||
+ if (dcb->max_command <= list_size(&dcb->srb_going_list) ||
+ acb->active_dcb ||
(acb->acb_flag & (RESET_DETECT + RESET_DONE + RESET_DEV))) {
- append_srb_waiting(dcb, srb);
+ srb_waiting_append(dcb, srb);
waiting_process_next(acb);
return;
}
-#if 0
- if (dcb->waiting_srb) {
- append_srb_waiting(dcb, srb);
- /* srb = waiting_srb_get(dcb); *//* non-existent */
- srb = dcb->waiting_srb;
- /* Remove from waiting list */
- dcb->waiting_srb = srb->next;
- srb->next = NULL;
- if (!dcb->waiting_srb)
- dcb->wait_list = NULL;
- }
-#endif
- if (!start_scsi(acb, dcb, srb))
- append_srb_going(dcb, srb);
- else {
- insert_srb_waiting(dcb, srb);
+ if (!start_scsi(acb, dcb, srb)) {
+ srb_going_append(dcb, srb);
+ } else {
+ srb_waiting_insert(dcb, srb);
waiting_set_timer(acb, HZ / 50);
}
}
@@ -1391,7 +1405,7 @@ dc395x_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
cmd->result = 0;
/* get a free SRB */
- srb = get_srb_free(acb);
+ srb = srb_get_free(acb);
if (!srb)
{
/*
@@ -1405,9 +1419,9 @@ dc395x_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
/* build srb for the command */
build_srb(cmd, dcb, srb);
- if (dcb->waiting_srb) {
+ if (!list_empty(&dcb->srb_waiting_list)) {
/* append to waiting queue */
- append_srb_waiting(dcb, srb);
+ srb_waiting_append(dcb, srb);
waiting_process_next(acb);
} else {
/* process immediately */
@@ -1609,17 +1623,13 @@ static inline void clear_fifo(struct AdapterCtlBlk *acb, char *txt)
*/
static void reset_dev_param(struct AdapterCtlBlk *acb)
{
- struct DeviceCtlBlk *dcb = acb->link_dcb;
- struct DeviceCtlBlk *dcb_temp;
+ struct DeviceCtlBlk *dcb;
struct NvRamType *eeprom = &acb->eeprom;
- u8 period_index;
dprintkdbg(DBG_0, "reset_dev_param..............\n");
- if (dcb == NULL)
- return;
+ list_for_each_entry(dcb, &acb->dcb_list, list) {
+ u8 period_index;
- dcb_temp = dcb;
- do {
dcb->sync_mode &= ~(SYNC_NEGO_DONE + WIDE_NEGO_DONE);
dcb->sync_period = 0;
dcb->sync_offset = 0;
@@ -1631,10 +1641,7 @@ static void reset_dev_param(struct AdapterCtlBlk *acb)
if (!(dcb->dev_mode & NTC_DO_WIDE_NEGO)
|| !(acb->config & HCC_WIDE_CARD))
dcb->sync_mode &= ~WIDE_NEGO_ENABLE;
-
- dcb = dcb->next;
}
- while (dcb_temp != dcb && dcb != NULL);
}
@@ -1729,18 +1736,18 @@ static int dc395x_eh_abort(Scsi_Cmnd * cmd)
return FAILED;
}
- srb = find_cmd(cmd, dcb->waiting_srb);
+ srb = find_cmd(cmd, &dcb->srb_waiting_list);
if (srb) {
- remove_srb_waiting(dcb, srb, 0);
+ srb_waiting_remove(dcb, srb);
pci_unmap_srb_sense(acb, srb);
pci_unmap_srb(acb, srb);
free_tag(dcb, srb);
- insert_srb_free(acb, srb);
+ srb_free_insert(acb, srb);
dprintkl(KERN_DEBUG, "abort - command found in waiting commands queue");
cmd->result = DID_ABORT << 16;
return SUCCESS;
}
- srb = find_cmd(cmd, dcb->going_srb);
+ srb = find_cmd(cmd, &dcb->srb_going_list);
if (srb) {
dprintkl(KERN_DEBUG, "abort - command currently in progress");
/* XXX: Should abort the command here */
@@ -3322,23 +3329,27 @@ struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
struct DeviceCtlBlk *dcb,
u8 tag)
{
- struct ScsiReqBlk *last_srb = dcb->going_last;
- struct ScsiReqBlk *srb = dcb->going_srb;
+ struct ScsiReqBlk *srb = NULL;
+ struct ScsiReqBlk *i;
+
+
dprintkdbg(DBG_0, "QTag Msg (SRB %p): %i\n", srb, tag);
if (!(dcb->tag_mask & (1 << tag)))
dprintkl(KERN_DEBUG,
"MsgIn_QTag: tag_mask (%08x) does not reserve tag %i!\n",
dcb->tag_mask, tag);
- if (!srb)
+ if (list_empty(&dcb->srb_going_list))
goto mingx0;
- while (srb) {
- if (srb->tag_number == tag)
+ list_for_each_entry(i, &dcb->srb_going_list, list) {
+ if (i->tag_number == tag) {
+ srb = i;
break;
- if (srb == last_srb)
- goto mingx0;
- srb = srb->next;
+ }
}
+ if (!srb)
+ goto mingx0;
+
dprintkdbg(DBG_0, "pid %li (%i-%i)\n", srb->cmd->pid,
srb->dcb->target_id, srb->dcb->target_lun);
if (dcb->flag & ABORT_DEV_) {
@@ -3350,13 +3361,18 @@ struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb,
goto mingx0;
/* Tag found */
- TRACEPRINTF("[%s]*", dcb->active_srb->debugtrace);
- TRACEPRINTF("RTag*");
- /* Just for debugging ... */
- last_srb = srb;
- srb = dcb->active_srb;
- TRACEPRINTF("Found.*");
- srb = last_srb;
+ {
+ struct ScsiReqBlk *last_srb;
+
+ TRACEPRINTF("[%s]*", dcb->active_srb->debugtrace);
+ TRACEPRINTF("RTag*");
+ /* Just for debugging ... */
+
+ last_srb = srb;
+ srb = dcb->active_srb;
+ TRACEPRINTF("Found.*");
+ srb = last_srb;
+ }
memcpy(srb->msgin_buf, dcb->active_srb->msgin_buf, acb->msg_len);
srb->state |= dcb->active_srb->state;
@@ -3774,36 +3790,26 @@ void nop1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
static
void set_xfer_rate(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
{
- u8 bval;
- u16 cnt, i;
- struct DeviceCtlBlk *dcb_temp;
+ struct DeviceCtlBlk *i;
/*
- ** set all lun device's period , offset
+ * set all lun device's period , offset
*/
- if (!(dcb->identify_msg & 0x07)) {
- if (acb->scan_devices)
- current_sync_offset = dcb->sync_offset;
- else {
- dcb_temp = acb->link_dcb;
- cnt = acb->dcb_count;
- bval = dcb->target_id;
- for (i = 0; i < cnt; i++) {
- if (dcb_temp->target_id == bval) {
- dcb_temp->sync_period =
- dcb->sync_period;
- dcb_temp->sync_offset =
- dcb->sync_offset;
- dcb_temp->sync_mode =
- dcb->sync_mode;
- dcb_temp->min_nego_period =
- dcb->min_nego_period;
- }
- dcb_temp = dcb_temp->next;
- }
- }
+ if (dcb->identify_msg & 0x07)
+ return;
+
+ if (acb->scan_devices) {
+ current_sync_offset = dcb->sync_offset;
+ return;
}
- return;
+
+ list_for_each_entry(i, &acb->dcb_list, list)
+ if (i->target_id == dcb->target_id) {
+ i->sync_period = dcb->sync_period;
+ i->sync_offset = dcb->sync_offset;
+ i->sync_mode = dcb->sync_mode;
+ i->min_nego_period = dcb->min_nego_period;
+ }
}
@@ -3882,7 +3888,7 @@ static void disconnect(struct AdapterCtlBlk *acb)
goto disc1;
}
free_tag(dcb, srb);
- move_srb_going_to_waiting(dcb, srb);
+ srb_going_to_waiting_move(dcb, srb);
dprintkdbg(DBG_KG, "Retry pid %li ...\n",
srb->cmd->pid);
waiting_set_timer(acb, HZ / 20);
@@ -3964,7 +3970,7 @@ static void reselect(struct AdapterCtlBlk *acb)
srb->state = SRB_READY;
free_tag(dcb, srb);
- move_srb_going_to_waiting(dcb, srb);
+ srb_going_to_waiting_move(dcb, srb);
waiting_set_timer(acb, HZ / 20);
/* return; */
@@ -4049,43 +4055,32 @@ static void reselect(struct AdapterCtlBlk *acb)
static
void remove_dev(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb)
{
- struct DeviceCtlBlk *pPrevDCB = acb->link_dcb;
+ struct DeviceCtlBlk *i;
+ struct DeviceCtlBlk *tmp;
dprintkdbg(DBG_0, "remove_dev\n");
- if (dcb->going_srb_count > 1) {
+ if (list_size(&dcb->srb_going_list) > 1) {
dprintkdbg(DBG_DCB, "Driver won't free DCB (ID %i, LUN %i): 0x%08x because of SRBCnt %i\n",
dcb->target_id, dcb->target_lun, (int) dcb,
- dcb->going_srb_count);
+ list_size(&dcb->srb_going_list));
return;
}
acb->dcb_map[dcb->target_id] &= ~(1 << dcb->target_lun);
acb->children[dcb->target_id][dcb->target_lun] = NULL;
- /* The first one */
- if (dcb == acb->link_dcb) {
- /* The last one */
- if (acb->last_dcb == dcb) {
- dcb->next = NULL;
- acb->last_dcb = NULL;
+ list_for_each_entry_safe(i, tmp, &acb->dcb_list, list) {
+ if (dcb == i) {
+ list_del(&i->list);
+ break;
}
- acb->link_dcb = dcb->next;
- } else {
- while (pPrevDCB->next != dcb)
- pPrevDCB = pPrevDCB->next;
- pPrevDCB->next = dcb->next;
- if (dcb == acb->last_dcb)
- acb->last_dcb = pPrevDCB;
- }
+ }
dprintkdbg(DBG_DCB, "Driver about to free DCB (ID %i, LUN %i): %p\n",
dcb->target_id, dcb->target_lun, dcb);
if (dcb == acb->active_dcb)
acb->active_dcb = NULL;
- if (dcb == acb->link_dcb)
- acb->link_dcb = dcb->next;
if (dcb == acb->dcb_run_robin)
- acb->dcb_run_robin = dcb->next;
- acb->dcb_count--;
+ acb->dcb_run_robin = dcb_get_next(&acb->dcb_list, dcb);
dc395x_kfree(dcb);
}
@@ -4320,7 +4315,7 @@ void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
request_sense(acb, dcb, srb);
return;
} else if (status_byte(status) == QUEUE_FULL) {
- tempcnt = (u8) dcb->going_srb_count;
+ tempcnt = (u8)list_size(&dcb->srb_going_list);
printk
("\nDC395x: QUEUE_FULL for dev %02i-%i with %i cmnds\n",
dcb->target_id, dcb->target_lun, tempcnt);
@@ -4328,7 +4323,7 @@ void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
tempcnt--;
dcb->max_command = tempcnt;
free_tag(dcb, srb);
- move_srb_going_to_waiting(dcb, srb);
+ srb_going_to_waiting_move(dcb, srb);
waiting_set_timer(acb, HZ / 20);
srb->adapter_status = 0;
srb->target_status = 0;
@@ -4409,12 +4404,12 @@ void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
cmd->device->lun, srb->total_xfer_length);
}
- remove_srb_going(dcb, srb, 0);
+ srb_going_remove(dcb, srb);
/* Add to free list */
if (srb == acb->tmp_srb)
dprintkl(KERN_ERR, "ERROR! Completed Cmnd with tmp_srb!\n");
else
- insert_srb_free(acb, srb);
+ srb_free_insert(acb, srb);
dprintkdbg(DBG_0, "SRBdone: done pid %li\n", cmd->pid);
if (debug_enabled(DBG_KG)) {
@@ -4444,30 +4439,21 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
Scsi_Cmnd * cmd, u8 force)
{
struct DeviceCtlBlk *dcb;
- struct ScsiReqBlk *srb;
- struct ScsiReqBlk *srb_temp;
- u16 cnt;
- Scsi_Cmnd *p;
- dcb = acb->link_dcb;
- if (!dcb)
- return;
dprintkl(KERN_INFO, "doing_srb_done: pids ");
- do {
- /* As the ML may queue cmnds again, cache old values */
- struct ScsiReqBlk *waiting_srb = dcb->waiting_srb;
- /*struct ScsiReqBlk* wait_list = dcb->wait_list; */
- u16 waiting_srb_count = dcb->waiting_srb_count;
- /* Going queue */
- cnt = dcb->going_srb_count;
- srb = dcb->going_srb;
- while (cnt--) {
+ list_for_each_entry(dcb, &acb->dcb_list, list) {
+ struct ScsiReqBlk *srb;
+ struct ScsiReqBlk *tmp;
+ Scsi_Cmnd *p;
+
+ list_for_each_entry_safe(srb, tmp, &dcb->srb_going_list, list) {
int result;
int dir;
- srb_temp = srb->next;
+
p = srb->cmd;
dir = scsi_to_pci_dma_dir(p->sc_data_direction);
result = MK_RES(0, did_flag, 0, 0);
+
/*result = MK_RES(0,DID_RESET,0,0); */
TRACEPRINTF("Reset(%li):%08x*", jiffies, result);
printk(" (G)");
@@ -4476,12 +4462,10 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
p->device->id, p->device->lun);
#endif
TRACEOUT("%s\n", srb->debugtrace);
- dcb->going_srb = srb_temp;
- dcb->going_srb_count--;
- if (!srb_temp)
- dcb->going_last = NULL;
+
+ srb_going_remove(dcb, srb);
free_tag(dcb, srb);
- insert_srb_free(acb, srb);
+ srb_free_insert(acb, srb);
p->result = result;
pci_unmap_srb_sense(acb, srb);
pci_unmap_srb(acb, srb);
@@ -4490,9 +4474,8 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
* as they all complete or all time out */
p->scsi_done(p);
}
- srb = srb_temp;
}
- if (dcb->going_srb)
+ if (!list_empty(&dcb->srb_going_list))
dprintkl(KERN_DEBUG,
"How could the ML send cmnds to the Going queue? (%02i-%i)!!\n",
dcb->target_id, dcb->target_lun);
@@ -4501,16 +4484,12 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
"tag_mask for %02i-%i should be empty, is %08x!\n",
dcb->target_id, dcb->target_lun,
dcb->tag_mask);
- /*dcb->going_srb_count = 0;; */
- /*dcb->going_srb = NULL; dcb->going_last = NULL; */
/* Waiting queue */
- cnt = waiting_srb_count;
- srb = waiting_srb;
- while (cnt--) {
+ list_for_each_entry_safe(srb, tmp, &dcb->srb_waiting_list, list) {
int result;
- srb_temp = srb->next;
p = srb->cmd;
+
result = MK_RES(0, did_flag, 0, 0);
TRACEPRINTF("Reset(%li):%08x*", jiffies, result);
printk(" (W)");
@@ -4519,11 +4498,8 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
p->device->lun);
#endif
TRACEOUT("%s\n", srb->debugtrace);
- dcb->waiting_srb = srb_temp;
- dcb->waiting_srb_count--;
- if (!srb_temp)
- dcb->wait_list = NULL;
- insert_srb_free(acb, srb);
+ srb_waiting_remove(dcb, srb);
+ srb_free_insert(acb, srb);
p->result = result;
pci_unmap_srb_sense(acb, srb);
@@ -4532,21 +4508,16 @@ void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
/* For new EH, we normally don't need to give commands back,
* as they all complete or all time out */
cmd->scsi_done(cmd);
- srb = srb_temp;
}
}
- if (dcb->waiting_srb_count)
+ if (!list_empty(&dcb->srb_waiting_list))
printk
("\nDC395x: Debug: ML queued %i cmnds again to %02i-%i\n",
- dcb->waiting_srb_count, dcb->target_id,
+ list_size(&dcb->srb_waiting_list), dcb->target_id,
dcb->target_lun);
- /* The ML could have queued the cmnds again! */
- /*dcb->waiting_srb_count = 0;; */
- /*dcb->waiting_srb = NULL; dcb->wait_list = NULL; */
+
dcb->flag &= ~ABORT_DEV_;
- dcb = dcb->next;
}
- while (dcb != acb->link_dcb && dcb);
printk("\n");
}
@@ -4703,7 +4674,7 @@ void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
"Request Sense failed for pid %li (%02i-%i)!\n",
srb->cmd->pid, dcb->target_id, dcb->target_lun);
TRACEPRINTF("?*");
- move_srb_going_to_waiting(dcb, srb);
+ srb_going_to_waiting_move(dcb, srb);
waiting_set_timer(acb, HZ / 100);
}
TRACEPRINTF(".*");
@@ -4736,26 +4707,17 @@ void init_dcb(struct AdapterCtlBlk *acb, struct DeviceCtlBlk **pdcb,
if (!dcb)
return;
- if (acb->dcb_count == 0) {
- acb->link_dcb = dcb;
+ INIT_LIST_HEAD(&dcb->srb_waiting_list);
+ INIT_LIST_HEAD(&dcb->srb_going_list);
+ if (list_empty(&acb->dcb_list))
acb->dcb_run_robin = dcb;
- } else {
- acb->last_dcb->next = dcb;
- }
-
- acb->dcb_count++;
- dcb->next = acb->link_dcb;
- acb->last_dcb = dcb;
+ list_add_tail(&dcb->list, &acb->dcb_list);
/* $$$$$$$ */
dcb->acb = acb;
dcb->target_id = target;
dcb->target_lun = lun;
/* $$$$$$$ */
- dcb->waiting_srb = NULL;
- dcb->going_srb = NULL;
- dcb->going_srb_count = 0;
- dcb->waiting_srb_count = 0;
dcb->active_srb = NULL;
/* $$$$$$$ */
dcb->tag_mask = 0;
@@ -4792,9 +4754,10 @@ void init_dcb(struct AdapterCtlBlk *acb, struct DeviceCtlBlk **pdcb,
/* $$$$$$$ */
if (dcb->target_lun != 0) {
/* Copy settings */
- struct DeviceCtlBlk *prevDCB = acb->link_dcb;
- while (prevDCB->target_id != dcb->target_id)
- prevDCB = prevDCB->next;
+ struct DeviceCtlBlk *prevDCB;
+ list_for_each_entry(prevDCB, &acb->dcb_list, list)
+ if (prevDCB->target_id == dcb->target_id)
+ break;
dprintkdbg(DBG_KG,
"Copy settings from %02i-%02i to %02i-%02i\n",
prevDCB->target_id, prevDCB->target_lun,
@@ -4924,9 +4887,7 @@ static void __init link_srb(struct AdapterCtlBlk *acb)
int i;
for (i = 0; i < acb->srb_count - 1; i++)
- acb->srb_array[i].next = &acb->srb_array[i + 1];
- acb->srb_array[i].next = NULL;
- /*DC395x_Free_integrity (acb); */
+ srb_free_insert(acb, &acb->srb_array[i]);
}
@@ -4974,14 +4935,12 @@ int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq)
*/
acb->scsi_host = host;
acb->IOPortBase = (u16) io_port;
- acb->link_dcb = NULL;
acb->dcb_run_robin = NULL;
acb->active_dcb = NULL;
acb->srb_count = DC395x_MAX_SRB_CNT;
acb->scsi_host->this_id = eeprom->scsi_id;
acb->hostid_bit = (1 << acb->scsi_host->this_id);
/*acb->scsi_host->this_lun = 0; */
- acb->dcb_count = 0;
acb->irq_level = irq;
acb->tag_max_num = 1 << eeprom->max_tag;
if (acb->tag_max_num > 30)
@@ -5006,14 +4965,14 @@ int __init init_acb(struct Scsi_Host *host, u32 io_port, u8 irq)
return 1;
}
#endif
+ INIT_LIST_HEAD(&acb->dcb_list);
+ INIT_LIST_HEAD(&acb->srb_free_list);
link_srb(acb);
- acb->free_srb = acb->srb_array;
+
/*
* temp SRB for Q tag used or abort command used
*/
acb->tmp_srb = &acb->srb;
- acb->srb.dcb = NULL;
- acb->srb.next = NULL;
init_timer(&acb->waiting_timer);
for (i = 0; i < DC395x_MAX_SCSI_ID; i++)
@@ -5550,10 +5509,11 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
int inout)
{
struct AdapterCtlBlk *acb = (struct AdapterCtlBlk *)host->hostdata;
- int dev, spd, spd1;
+ int spd, spd1;
char *pos = buffer;
struct DeviceCtlBlk *dcb;
unsigned long flags;
+ int dev;
if (inout) /* Has data been written to the file ? */
return -EPERM;
@@ -5580,7 +5540,7 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
SPRINTF(", DelayReset %is\n", acb->eeprom.delay_time);
/*SPRINTF("\n"); */
- SPRINTF("Nr of DCBs: %i\n", acb->dcb_count);
+ SPRINTF("Nr of DCBs: %i\n", list_size(&acb->dcb_list));
SPRINTF
("Map of attached LUNs: %02x %02x %02x %02x %02x %02x %02x %02x\n",
acb->dcb_map[0], acb->dcb_map[1], acb->dcb_map[2],
@@ -5595,8 +5555,8 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
SPRINTF
("Un ID LUN Prty Sync Wide DsCn SndS TagQ nego_period SyncFreq SyncOffs MaxCmd\n");
- dcb = acb->link_dcb;
- for (dev = 0; dev < acb->dcb_count; dev++) {
+ dev = 0;
+ list_for_each_entry(dcb, &acb->dcb_list, list) {
int nego_period;
SPRINTF("%02i %02i %02i ", dev, dcb->target_id,
dcb->target_lun);
@@ -5606,8 +5566,7 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
YESNO(dcb->dev_mode & NTC_DO_DISCONNECT);
YESNO(dcb->dev_mode & NTC_DO_SEND_START);
YESNO(dcb->sync_mode & EN_TAG_QUEUEING);
- nego_period =
- clock_period[dcb->sync_period & 0x07] << 2;
+ nego_period = clock_period[dcb->sync_period & 0x07] << 2;
if (dcb->sync_offset)
SPRINTF(" %03i ns ", nego_period);
else
@@ -5624,45 +5583,42 @@ int dc395x_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t o
/* Add more info ... */
SPRINTF(" %02i\n", dcb->max_command);
- dcb = dcb->next;
+ dev++;
}
if (timer_pending(&acb->waiting_timer))
SPRINTF("Waiting queue timer running\n");
else
SPRINTF("\n");
- dcb = acb->link_dcb;
- for (dev = 0; dev < acb->dcb_count; dev++) {
+ list_for_each_entry(dcb, &acb->dcb_list, list) {
struct ScsiReqBlk *srb;
- if (dcb->waiting_srb_count)
+ if (!list_empty(&dcb->srb_waiting_list))
SPRINTF("DCB (%02i-%i): Waiting: %i:",
dcb->target_id, dcb->target_lun,
- dcb->waiting_srb_count);
- for (srb = dcb->waiting_srb; srb; srb = srb->next)
+ list_size(&dcb->srb_waiting_list));
+ list_for_each_entry(srb, &dcb->srb_waiting_list, list)
SPRINTF(" %li", srb->cmd->pid);
- if (dcb->going_srb_count)
+ if (!list_empty(&dcb->srb_going_list))
SPRINTF("\nDCB (%02i-%i): Going : %i:",
dcb->target_id, dcb->target_lun,
- dcb->going_srb_count);
- for (srb = dcb->going_srb; srb; srb = srb->next)
+ list_size(&dcb->srb_going_list));
+ list_for_each_entry(srb, &dcb->srb_going_list, list)
#if debug_enabled(DBG_TRACE|DBG_TRACEALL)
SPRINTF("\n %s", srb->debugtrace);
#else
SPRINTF(" %li", srb->cmd->pid);
#endif
- if (dcb->waiting_srb_count || dcb->going_srb_count)
+ if (!list_empty(&dcb->srb_waiting_list) || !list_empty(&dcb->srb_going_list))
SPRINTF("\n");
- dcb = dcb->next;
}
if (debug_enabled(DBG_DCB)) {
SPRINTF("DCB list for ACB %p:\n", acb);
- dcb = acb->link_dcb;
- SPRINTF("%p", dcb);
- for (dev = 0; dev < acb->dcb_count; dev++, dcb = dcb->next)
- SPRINTF("->%p", dcb->next);
- SPRINTF("\n");
+ list_for_each_entry(dcb, &acb->dcb_list, list) {
+ SPRINTF("%p -> ", dcb);
+ }
+ SPRINTF("END\n");
}
*start = buffer + offset;
@@ -5721,19 +5677,13 @@ static
void free_dcbs(struct AdapterCtlBlk* acb)
{
struct DeviceCtlBlk *dcb;
- struct DeviceCtlBlk *dcb_next;
+ struct DeviceCtlBlk *tmp;
- dprintkdbg(DBG_DCB, "Free %i DCBs\n", acb->dcb_count);
+ dprintkdbg(DBG_DCB, "Free %i DCBs\n", list_size(&acb->dcb_list));
- for (dcb = acb->link_dcb; dcb != NULL; dcb = dcb_next)
- {
- dcb_next = dcb->next;
+ list_for_each_entry_safe(dcb, tmp, &acb->dcb_list, list) {
dprintkdbg(DBG_DCB, "Free DCB (ID %i, LUN %i): %p\n",
dcb->target_id, dcb->target_lun, dcb);
- /*
- * Free the DCB. This removes the entry from the
- * link_dcb list and decrements the count in dcb_count
- */
remove_dev(acb, dcb);
}
}
@@ -5862,14 +5812,7 @@ static void __devexit dc395x_remove_one(struct pci_dev *dev)
struct Scsi_Host *host = pci_get_drvdata(dev);
dprintkdbg(DBG_0, "Removing instance\n");
- if (!host) {
- dprintkl(KERN_ERR, "no host allocated\n");
- return;
- }
- if (scsi_remove_host(host)) {
- dprintkl(KERN_ERR, "scsi_remove_host failed\n");
- return;
- }
+ scsi_remove_host(host);
host_release(host);
scsi_host_put(host);
pci_set_drvdata(dev, NULL);
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 642c398d294a..5d04835fec83 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -40,6 +40,16 @@
static int scsi_host_next_hn; /* host_no for next new host */
+static void scsi_host_cls_release(struct class_device *class_dev)
+{
+ put_device(&class_to_shost(class_dev)->shost_gendev);
+}
+
+static struct class shost_class = {
+ .name = "scsi_host",
+ .release = scsi_host_cls_release,
+};
+
/**
* scsi_host_cancel - cancel outstanding IO to this host
* @shost: pointer to struct Scsi_Host
@@ -64,10 +74,18 @@ void scsi_host_cancel(struct Scsi_Host *shost, int recovery)
**/
void scsi_remove_host(struct Scsi_Host *shost)
{
+ unsigned long flags;
+
scsi_host_cancel(shost, 0);
scsi_proc_host_rm(shost);
scsi_forget_host(shost);
- scsi_sysfs_remove_host(shost);
+
+ spin_lock_irqsave(shost->host_lock, flags);
+ set_bit(SHOST_DEL, &shost->shost_state);
+ spin_unlock_irqrestore(shost->host_lock, flags);
+
+ class_device_unregister(&shost->shost_classdev);
+ device_del(&shost->shost_gendev);
}
/**
@@ -89,21 +107,45 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
if (!shost->can_queue) {
printk(KERN_ERR "%s: can_queue = 0 no longer supported\n",
sht->name);
- error = -EINVAL;
+ return -EINVAL;
}
- error = scsi_sysfs_add_host(shost, dev);
- if (!error)
- scsi_proc_host_add(shost);
+ if (!shost->shost_gendev.parent)
+ shost->shost_gendev.parent = dev ? dev : &legacy_bus;
+
+ error = device_add(&shost->shost_gendev);
+ if (error)
+ goto out;
+
+ set_bit(SHOST_ADD, &shost->shost_state);
+ get_device(shost->shost_gendev.parent);
+
+ error = class_device_add(&shost->shost_classdev);
+ if (error)
+ goto out_del_gendev;
+
+ get_device(&shost->shost_gendev);
+
+ error = scsi_sysfs_add_host(shost);
+ if (error)
+ goto out_del_classdev;
+
+ scsi_proc_host_add(shost);
+ return error;
+
+ out_del_classdev:
+ class_device_del(&shost->shost_classdev);
+ out_del_gendev:
+ device_del(&shost->shost_gendev);
+ out:
return error;
}
-/**
- * scsi_free_sdev - free a scsi hosts resources
- * @shost: scsi host to free
- **/
-void scsi_free_shost(struct Scsi_Host *shost)
+static void scsi_host_dev_release(struct device *dev)
{
+ struct Scsi_Host *shost = dev_to_shost(dev);
+ struct device *parent = dev->parent;
+
if (shost->ehandler) {
DECLARE_COMPLETION(sem);
shost->eh_notify = &sem;
@@ -115,6 +157,8 @@ void scsi_free_shost(struct Scsi_Host *shost)
scsi_proc_hostdir_rm(shost->hostt);
scsi_destroy_command_freelist(shost);
+
+ put_device(parent);
kfree(shost);
}
@@ -214,7 +258,16 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
if (rval)
goto fail;
- scsi_sysfs_init_host(shost);
+ device_initialize(&shost->shost_gendev);
+ snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d",
+ shost->host_no);
+ shost->shost_gendev.release = scsi_host_dev_release;
+
+ class_device_initialize(&shost->shost_classdev);
+ shost->shost_classdev.dev = &shost->shost_gendev;
+ shost->shost_classdev.class = &shost_class;
+ snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d",
+ shost->host_no);
shost->eh_notify = &complete;
/* XXX(hch): handle error return */
@@ -299,3 +352,13 @@ void scsi_host_put(struct Scsi_Host *shost)
{
put_device(&shost->shost_gendev);
}
+
+int scsi_init_hosts(void)
+{
+ return class_register(&shost_class);
+}
+
+void scsi_exit_hosts(void)
+{
+ class_unregister(&shost_class);
+}
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index e7c504d6a53e..46b0069406e9 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -5,8 +5,8 @@
/* Jack Hammer, Adaptec, Inc. */
/* David Jeffery, Adaptec, Inc. */
/* */
-/* Copyright (C) 2000 IBM Corporation */
-/* Copyright (C) 2002,2003 Adaptec, Inc. */
+/* Copyright (C) 2000 IBM Corporation */
+/* Copyright (C) 2002,2003 Adaptec, Inc. */
/* */
/* 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 */
@@ -130,6 +130,7 @@
/* 5.10.15 - remove unused code (sem, macros, etc.) */
/* 5.30.00 - use __devexit_p() */
/* 6.00.00 - Add 6x Adapters and Battery Flash */
+/* 6.10.00 - Remove 1G Addressing Limitations */
/*****************************************************************************/
/*
@@ -150,7 +151,7 @@
* nommap - Don't use memory mapped I/O
* ioctlsize - Initial size of the IOCTL buffer
*/
-
+
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/page.h>
@@ -187,34 +188,34 @@
#include <linux/smp.h>
#ifdef MODULE
- static char *ips = NULL;
- MODULE_PARM(ips, "s");
+static char *ips = NULL;
+MODULE_PARM(ips, "s");
#endif
/*
* DRIVER_VER
*/
-#define IPS_VERSION_HIGH "5.99"
-#define IPS_VERSION_LOW ".01-BETA"
-
+#define IPS_VERSION_HIGH "6.10"
+#define IPS_VERSION_LOW ".90-BETA"
-#if !defined(__i386__) && !defined(__ia64__)
- #error "This driver has only been tested on the x86/ia64 platforms"
+#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
+#error "This driver has only been tested on the x86/ia64/x86_64 platforms"
#endif
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
- #include "sd.h"
- #define IPS_SG_ADDRESS(sg) ((sg)->address)
- #define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)
- #define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags)
- #ifndef __devexit_p
- #define __devexit_p(x) x
- #endif
+#include <linux/blk.h>
+#include "sd.h"
+#define IPS_SG_ADDRESS(sg) ((sg)->address)
+#define IPS_LOCK_SAVE(lock,flags) spin_lock_irqsave(&io_request_lock,flags)
+#define IPS_UNLOCK_RESTORE(lock,flags) spin_unlock_irqrestore(&io_request_lock,flags)
+#ifndef __devexit_p
+#define __devexit_p(x) x
+#endif
#else
- #define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \
+#define IPS_SG_ADDRESS(sg) (page_address((sg)->page) ? \
page_address((sg)->page)+(sg)->offset : 0)
- #define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0)
- #define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0)
+#define IPS_LOCK_SAVE(lock,flags) do{spin_lock(lock);(void)flags;}while(0)
+#define IPS_UNLOCK_RESTORE(lock,flags) do{spin_unlock(lock);(void)flags;}while(0)
#endif
#define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
@@ -223,34 +224,35 @@
scsi_to_pci_dma_dir(scb->scsi_cmd->sc_data_direction))
#ifdef IPS_DEBUG
- #define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
- #define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n");
- #define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
+#define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
+#define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n");
+#define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
#else
- #define METHOD_TRACE(s, i)
- #define DEBUG(i, s)
- #define DEBUG_VAR(i, s, v...)
+#define METHOD_TRACE(s, i)
+#define DEBUG(i, s)
+#define DEBUG_VAR(i, s, v...)
#endif
/*
* global variables
*/
-static const char ips_name[] = "ips";
-static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */
-static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */
+static const char ips_name[] = "ips";
+static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS]; /* Array of host controller structures */
+static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS]; /* Array of HA structures */
static unsigned int ips_next_controller;
static unsigned int ips_num_controllers;
static unsigned int ips_released_controllers;
-static int ips_hotplug;
-static int ips_cmd_timeout = 60;
-static int ips_reset_timeout = 60 * 5;
-static int ips_force_memio = 1; /* Always use Memory Mapped I/O */
-static int ips_force_i2o = 1; /* Always use I2O command delivery */
-static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */
-static int ips_cd_boot; /* Booting from Manager CD */
-static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */
-static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */
-static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */
+static int ips_hotplug;
+static int ips_cmd_timeout = 60;
+static int ips_reset_timeout = 60 * 5;
+static int ips_force_memio = 1; /* Always use Memory Mapped I/O */
+static int ips_force_i2o = 1; /* Always use I2O command delivery */
+static int ips_ioctlsize = IPS_IOCTL_SIZE; /* Size of the ioctl buffer */
+static int ips_cd_boot; /* Booting from Manager CD */
+static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */
+static dma_addr_t ips_flashbusaddr;
+static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */
+static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */
static Scsi_Host_Template ips_driver_template = {
.detect = ips_detect,
.release = ips_release,
@@ -258,9 +260,12 @@ static Scsi_Host_Template ips_driver_template = {
.queuecommand = ips_queue,
.eh_abort_handler = ips_eh_abort,
.eh_host_reset_handler = ips_eh_reset,
+ .proc_name = "ips",
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+ .proc_info = ips_proc_info,
.slave_configure = ips_slave_configure,
#else
+ .proc_info = ips_proc24_info,
.select_queue_depths = ips_select_queue_depth,
#endif
.bios_param = ips_biosparam,
@@ -273,30 +278,30 @@ static Scsi_Host_Template ips_driver_template = {
#endif
};
-IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */
+IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */
- /* This table describes all ServeRAID Adapters */
- static struct pci_device_id ips_pci_table[] = {
- { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
- { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
- { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
- { 0, }
- };
+/* This table describes all ServeRAID Adapters */
+static struct pci_device_id ips_pci_table[] = {
+ { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+ { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+ { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+ { 0, }
+};
- MODULE_DEVICE_TABLE( pci, ips_pci_table );
+MODULE_DEVICE_TABLE( pci, ips_pci_table );
- static char ips_hot_plug_name[] = "ips";
+static char ips_hot_plug_name[] = "ips";
- static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
- static void __devexit ips_remove_device(struct pci_dev *pci_dev);
+static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
+static void __devexit ips_remove_device(struct pci_dev *pci_dev);
- struct pci_driver ips_pci_driver = {
- .name = ips_hot_plug_name,
- .id_table = ips_pci_table,
- .probe = ips_insert_device,
- .remove = __devexit_p(ips_remove_device),
- };
+struct pci_driver ips_pci_driver = {
+ .name = ips_hot_plug_name,
+ .id_table = ips_pci_table,
+ .probe = ips_insert_device,
+ .remove = __devexit_p(ips_remove_device),
+};
/*
@@ -307,83 +312,82 @@ static int ips_halt(struct notifier_block *nb, ulong event, void *buf);
#define MAX_ADAPTER_NAME 15
static char ips_adapter_name[][30] = {
- "ServeRAID",
- "ServeRAID II",
- "ServeRAID on motherboard",
- "ServeRAID on motherboard",
- "ServeRAID 3H",
- "ServeRAID 3L",
- "ServeRAID 4H",
- "ServeRAID 4M",
- "ServeRAID 4L",
- "ServeRAID 4Mx",
- "ServeRAID 4Lx",
- "ServeRAID 5i",
- "ServeRAID 5i",
- "ServeRAID 00",
- "ServeRAID 00"
+ "ServeRAID",
+ "ServeRAID II",
+ "ServeRAID on motherboard",
+ "ServeRAID on motherboard",
+ "ServeRAID 3H",
+ "ServeRAID 3L",
+ "ServeRAID 4H",
+ "ServeRAID 4M",
+ "ServeRAID 4L",
+ "ServeRAID 4Mx",
+ "ServeRAID 4Lx",
+ "ServeRAID 5i",
+ "ServeRAID 5i",
+ "ServeRAID 6M",
+ "ServeRAID 6i"
};
-
static struct notifier_block ips_notifier = {
- ips_halt, NULL, 0
+ ips_halt, NULL, 0
};
/*
* Direction table
*/
static char ips_command_direction[] = {
-IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
-IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK,
-IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
-IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
-IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
-IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN,
-IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK,
-IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
-IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE,
-IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
-IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT,
-IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE,
-IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
-IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE,
-IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT,
-IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE,
-IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
-IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK
+ IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
+ IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK,
+ IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
+ IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
+ IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
+ IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN,
+ IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK,
+ IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
+ IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE,
+ IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
+ IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT,
+ IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE,
+ IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
+ IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE,
+ IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT,
+ IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE,
+ IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
+ IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK
};
/*
@@ -393,8 +397,8 @@ int ips_detect(Scsi_Host_Template *);
int ips_release(struct Scsi_Host *);
int ips_eh_abort(Scsi_Cmnd *);
int ips_eh_reset(Scsi_Cmnd *);
-int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));
-const char * ips_info(struct Scsi_Host *);
+int ips_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
+const char *ips_info(struct Scsi_Host *);
irqreturn_t do_ipsintr(int, void *, struct pt_regs *);
static int ips_hainit(ips_ha_t *);
static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
@@ -439,7 +443,7 @@ static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
-static void ips_free_flash_copperhead(ips_ha_t *ha);
+static void ips_free_flash_copperhead(ips_ha_t * ha);
static void ips_get_bios_version(ips_ha_t *, int);
static void ips_identify_controller(ips_ha_t *);
static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);
@@ -464,37 +468,42 @@ static void ips_ffdc_time(ips_ha_t *);
static uint32_t ips_statupd_copperhead(ips_ha_t *);
static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
static uint32_t ips_statupd_morpheus(ips_ha_t *);
-static ips_scb_t * ips_getscb(ips_ha_t *);
+static ips_scb_t *ips_getscb(ips_ha_t *);
static inline void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
static inline void ips_putq_scb_tail(ips_scb_queue_t *, ips_scb_t *);
static inline void ips_putq_wait_head(ips_wait_queue_t *, Scsi_Cmnd *);
static inline void ips_putq_wait_tail(ips_wait_queue_t *, Scsi_Cmnd *);
-static inline void ips_putq_copp_head(ips_copp_queue_t *, ips_copp_wait_item_t *);
-static inline void ips_putq_copp_tail(ips_copp_queue_t *, ips_copp_wait_item_t *);
-static inline ips_scb_t * ips_removeq_scb_head(ips_scb_queue_t *);
-static inline ips_scb_t * ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
-static inline Scsi_Cmnd * ips_removeq_wait_head(ips_wait_queue_t *);
-static inline Scsi_Cmnd * ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);
-static inline ips_copp_wait_item_t * ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *);
-static inline ips_copp_wait_item_t * ips_removeq_copp_head(ips_copp_queue_t *);
+static inline void ips_putq_copp_head(ips_copp_queue_t *,
+ ips_copp_wait_item_t *);
+static inline void ips_putq_copp_tail(ips_copp_queue_t *,
+ ips_copp_wait_item_t *);
+static inline ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *);
+static inline ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
+static inline Scsi_Cmnd *ips_removeq_wait_head(ips_wait_queue_t *);
+static inline Scsi_Cmnd *ips_removeq_wait(ips_wait_queue_t *, Scsi_Cmnd *);
+static inline ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *,
+ ips_copp_wait_item_t *);
+static inline ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *);
static int ips_is_passthru(Scsi_Cmnd *);
static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);
static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
-static void ips_scmd_buf_write(Scsi_Cmnd *scmd, void *data, unsigned int count);
-static void ips_scmd_buf_read(Scsi_Cmnd *scmd, void *data, unsigned int count);
+static void ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data,
+ unsigned int count);
+static void ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned int count);
-int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
+int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
static int ips_host_info(ips_ha_t *, char *, off_t, int);
static void copy_mem_info(IPS_INFOSTR *, char *, int);
static int copy_info(IPS_INFOSTR *, char *, ...);
-static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr );
-static void ips_version_check(ips_ha_t *ha, int intr);
-static int ips_abort_init(ips_ha_t *ha, int index);
-static int ips_init_phase2( int index );
+static int ips_get_version_info(ips_ha_t * ha, IPS_VERSION_DATA * Buffer,
+ int intr);
+static void ips_version_check(ips_ha_t * ha, int intr);
+static int ips_abort_init(ips_ha_t * ha, int index);
+static int ips_init_phase2(int index);
-static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr );
+static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr);
static int ips_register_scsi(int index);
/*--------------------------------------------------------------------------*/
/* Exported Functions */
@@ -510,43 +519,48 @@ static int ips_register_scsi(int index);
/* */
/****************************************************************************/
static int
-ips_setup(char *ips_str) {
-
- int i;
- char *key;
- char *value;
- IPS_OPTION options[] = {
- {"noi2o", &ips_force_i2o, 0},
- {"nommap", &ips_force_memio, 0},
- {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
- {"cdboot", &ips_cd_boot, 0},
- {"maxcmds", &MaxLiteCmds, 32},
- };
-
- /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
- /* Search for value */
- while ((key = strsep(&ips_str, ",."))) {
- if (!*key)
- continue;
- value = strchr(key, ':');
- if (value)
- *value++ = '\0';
- /*
- * We now have key/value pairs.
- * Update the variables
- */
- for (i = 0; i < (sizeof(options) / sizeof(options[0])); i++) {
- if (strnicmp(key, options[i].option_name, strlen(options[i].option_name)) == 0) {
- if (value)
- *options[i].option_flag = simple_strtoul(value, NULL, 0);
- else
- *options[i].option_flag = options[i].option_value;
- break;
- }
- }
- }
-
- return (1);
+ips_setup(char *ips_str)
+{
+
+ int i;
+ char *key;
+ char *value;
+ IPS_OPTION options[] = {
+ {"noi2o", &ips_force_i2o, 0},
+ {"nommap", &ips_force_memio, 0},
+ {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
+ {"cdboot", &ips_cd_boot, 0},
+ {"maxcmds", &MaxLiteCmds, 32},
+ };
+
+ /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
+ /* Search for value */
+ while ((key = strsep(&ips_str, ",."))) {
+ if (!*key)
+ continue;
+ value = strchr(key, ':');
+ if (value)
+ *value++ = '\0';
+ /*
+ * We now have key/value pairs.
+ * Update the variables
+ */
+ for (i = 0; i < (sizeof (options) / sizeof (options[0])); i++) {
+ if (strnicmp
+ (key, options[i].option_name,
+ strlen(options[i].option_name)) == 0) {
+ if (value)
+ *options[i].option_flag =
+ simple_strtoul(value, NULL, 0);
+ else
+ *options[i].option_flag =
+ options[i].option_value;
+ break;
+ }
+ }
+ }
+
+ return (1);
}
__setup("ips=", ips_setup);
@@ -563,94 +577,83 @@ __setup("ips=", ips_setup);
/* */
/****************************************************************************/
int
-ips_detect(Scsi_Host_Template *SHT) {
- int i;
+ips_detect(Scsi_Host_Template * SHT)
+{
+ int i;
- METHOD_TRACE("ips_detect", 1);
+ METHOD_TRACE("ips_detect", 1);
#ifdef MODULE
- if (ips)
- ips_setup(ips);
+ if (ips)
+ ips_setup(ips);
#endif
- /* If Booting from the Manager CD, Allocate a large Flash */
- /* Buffer ( so we won't need to allocate one for each adapter ). */
- if ( ips_cd_boot ) {
- ips_FlashData = ( char * ) __get_free_pages( IPS_INIT_GFP, 7 );
- if (ips_FlashData == NULL) {
- /* The validity of this pointer is checked in ips_make_passthru() before it is used */
- printk( KERN_WARNING "ERROR: Can't Allocate Large Buffer for Flashing\n" );
- }
- }
-
- SHT->proc_info = ips_proc_info;
- SHT->proc_name = "ips";
-
- for(i = 0; i < ips_num_controllers; i++){
- if ( ips_register_scsi(i) )
- ips_free(ips_ha[i]);
- ips_released_controllers++;
- }
- ips_hotplug = 1;
- return (ips_num_controllers);
+ for (i = 0; i < ips_num_controllers; i++) {
+ if (ips_register_scsi(i))
+ ips_free(ips_ha[i]);
+ ips_released_controllers++;
+ }
+ ips_hotplug = 1;
+ return (ips_num_controllers);
}
-
/****************************************************************************/
/* configure the function pointers to use the functions that will work */
/* with the found version of the adapter */
/****************************************************************************/
-static void ips_setup_funclist(ips_ha_t *ha){
-
- /*
- * Setup Functions
- */
- if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) {
- /* morpheus / marco / sebring */
- ha->func.isintr = ips_isintr_morpheus;
- ha->func.isinit = ips_isinit_morpheus;
- ha->func.issue = ips_issue_i2o_memio;
- ha->func.init = ips_init_morpheus;
- ha->func.statupd = ips_statupd_morpheus;
- ha->func.reset = ips_reset_morpheus;
- ha->func.intr = ips_intr_morpheus;
- ha->func.enableint = ips_enable_int_morpheus;
- } else if (IPS_USE_MEMIO(ha)) {
- /* copperhead w/MEMIO */
- ha->func.isintr = ips_isintr_copperhead_memio;
- ha->func.isinit = ips_isinit_copperhead_memio;
- ha->func.init = ips_init_copperhead_memio;
- ha->func.statupd = ips_statupd_copperhead_memio;
- ha->func.statinit = ips_statinit_memio;
- ha->func.reset = ips_reset_copperhead_memio;
- ha->func.intr = ips_intr_copperhead;
- ha->func.erasebios = ips_erase_bios_memio;
- ha->func.programbios = ips_program_bios_memio;
- ha->func.verifybios = ips_verify_bios_memio;
- ha->func.enableint = ips_enable_int_copperhead_memio;
- if (IPS_USE_I2O_DELIVER(ha))
- ha->func.issue = ips_issue_i2o_memio;
- else
- ha->func.issue = ips_issue_copperhead_memio;
- } else {
- /* copperhead */
- ha->func.isintr = ips_isintr_copperhead;
- ha->func.isinit = ips_isinit_copperhead;
- ha->func.init = ips_init_copperhead;
- ha->func.statupd = ips_statupd_copperhead;
- ha->func.statinit = ips_statinit;
- ha->func.reset = ips_reset_copperhead;
- ha->func.intr = ips_intr_copperhead;
- ha->func.erasebios = ips_erase_bios;
- ha->func.programbios = ips_program_bios;
- ha->func.verifybios = ips_verify_bios;
- ha->func.enableint = ips_enable_int_copperhead;
-
- if (IPS_USE_I2O_DELIVER(ha))
- ha->func.issue = ips_issue_i2o;
- else
- ha->func.issue = ips_issue_copperhead;
- }
+static void
+ips_setup_funclist(ips_ha_t * ha)
+{
+
+ /*
+ * Setup Functions
+ */
+ if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) {
+ /* morpheus / marco / sebring */
+ ha->func.isintr = ips_isintr_morpheus;
+ ha->func.isinit = ips_isinit_morpheus;
+ ha->func.issue = ips_issue_i2o_memio;
+ ha->func.init = ips_init_morpheus;
+ ha->func.statupd = ips_statupd_morpheus;
+ ha->func.reset = ips_reset_morpheus;
+ ha->func.intr = ips_intr_morpheus;
+ ha->func.enableint = ips_enable_int_morpheus;
+ } else if (IPS_USE_MEMIO(ha)) {
+ /* copperhead w/MEMIO */
+ ha->func.isintr = ips_isintr_copperhead_memio;
+ ha->func.isinit = ips_isinit_copperhead_memio;
+ ha->func.init = ips_init_copperhead_memio;
+ ha->func.statupd = ips_statupd_copperhead_memio;
+ ha->func.statinit = ips_statinit_memio;
+ ha->func.reset = ips_reset_copperhead_memio;
+ ha->func.intr = ips_intr_copperhead;
+ ha->func.erasebios = ips_erase_bios_memio;
+ ha->func.programbios = ips_program_bios_memio;
+ ha->func.verifybios = ips_verify_bios_memio;
+ ha->func.enableint = ips_enable_int_copperhead_memio;
+ if (IPS_USE_I2O_DELIVER(ha))
+ ha->func.issue = ips_issue_i2o_memio;
+ else
+ ha->func.issue = ips_issue_copperhead_memio;
+ } else {
+ /* copperhead */
+ ha->func.isintr = ips_isintr_copperhead;
+ ha->func.isinit = ips_isinit_copperhead;
+ ha->func.init = ips_init_copperhead;
+ ha->func.statupd = ips_statupd_copperhead;
+ ha->func.statinit = ips_statinit;
+ ha->func.reset = ips_reset_copperhead;
+ ha->func.intr = ips_intr_copperhead;
+ ha->func.erasebios = ips_erase_bios;
+ ha->func.programbios = ips_program_bios;
+ ha->func.verifybios = ips_verify_bios;
+ ha->func.enableint = ips_enable_int_copperhead;
+
+ if (IPS_USE_I2O_DELIVER(ha))
+ ha->func.issue = ips_issue_i2o;
+ else
+ ha->func.issue = ips_issue_copperhead;
+ }
}
/****************************************************************************/
@@ -663,70 +666,71 @@ static void ips_setup_funclist(ips_ha_t *ha){
/* */
/****************************************************************************/
int
-ips_release(struct Scsi_Host *sh) {
- ips_scb_t *scb;
- ips_ha_t *ha;
- int i;
+ips_release(struct Scsi_Host *sh)
+{
+ ips_scb_t *scb;
+ ips_ha_t *ha;
+ int i;
- METHOD_TRACE("ips_release", 1);
+ METHOD_TRACE("ips_release", 1);
- for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++);
+ for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ;
- if (i == IPS_MAX_ADAPTERS) {
- printk(KERN_WARNING "(%s) release, invalid Scsi_Host pointer.\n",
- ips_name);
- BUG();
- return (FALSE);
- }
+ if (i == IPS_MAX_ADAPTERS) {
+ printk(KERN_WARNING
+ "(%s) release, invalid Scsi_Host pointer.\n", ips_name);
+ BUG();
+ return (FALSE);
+ }
- ha = IPS_HA(sh);
+ ha = IPS_HA(sh);
- if (!ha)
- return (FALSE);
+ if (!ha)
+ return (FALSE);
- /* flush the cache on the controller */
- scb = &ha->scbs[ha->max_cmds-1];
+ /* flush the cache on the controller */
+ scb = &ha->scbs[ha->max_cmds - 1];
- ips_init_scb(ha, scb);
+ ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_FLUSH;
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_FLUSH;
- scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
- scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.flush_cache.state = IPS_NORM_STATE;
- scb->cmd.flush_cache.reserved = 0;
- scb->cmd.flush_cache.reserved2 = 0;
- scb->cmd.flush_cache.reserved3 = 0;
- scb->cmd.flush_cache.reserved4 = 0;
+ scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
+ scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.flush_cache.state = IPS_NORM_STATE;
+ scb->cmd.flush_cache.reserved = 0;
+ scb->cmd.flush_cache.reserved2 = 0;
+ scb->cmd.flush_cache.reserved3 = 0;
+ scb->cmd.flush_cache.reserved4 = 0;
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
+ IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
- /* send command */
- if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n");
+ /* send command */
+ if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
+ IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n");
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n");
+ IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n");
- ips_sh[i] = NULL;
- ips_ha[i] = NULL;
+ ips_sh[i] = NULL;
+ ips_ha[i] = NULL;
- /* free extra memory */
- ips_free(ha);
+ /* free extra memory */
+ ips_free(ha);
- /* Free I/O Region */
- if (ha->io_addr)
- release_region(ha->io_addr, ha->io_len);
+ /* Free I/O Region */
+ if (ha->io_addr)
+ release_region(ha->io_addr, ha->io_len);
- /* free IRQ */
- free_irq(ha->irq, ha);
+ /* free IRQ */
+ free_irq(ha->irq, ha);
- IPS_REMOVE_HOST(sh);
- scsi_host_put(sh);
+ IPS_REMOVE_HOST(sh);
+ scsi_host_put(sh);
- ips_released_controllers++;
+ ips_released_controllers++;
- return (FALSE);
+ return (FALSE);
}
/****************************************************************************/
@@ -739,50 +743,54 @@ ips_release(struct Scsi_Host *sh) {
/* */
/****************************************************************************/
static int
-ips_halt(struct notifier_block *nb, ulong event, void *buf) {
- ips_scb_t *scb;
- ips_ha_t *ha;
- int i;
+ips_halt(struct notifier_block *nb, ulong event, void *buf)
+{
+ ips_scb_t *scb;
+ ips_ha_t *ha;
+ int i;
- if ((event != SYS_RESTART) && (event != SYS_HALT) &&
- (event != SYS_POWER_OFF))
- return (NOTIFY_DONE);
+ if ((event != SYS_RESTART) && (event != SYS_HALT) &&
+ (event != SYS_POWER_OFF))
+ return (NOTIFY_DONE);
- for (i = 0; i < ips_next_controller; i++) {
- ha = (ips_ha_t *) ips_ha[i];
+ for (i = 0; i < ips_next_controller; i++) {
+ ha = (ips_ha_t *) ips_ha[i];
- if (!ha)
- continue;
+ if (!ha)
+ continue;
- if (!ha->active)
- continue;
+ if (!ha->active)
+ continue;
- /* flush the cache on the controller */
- scb = &ha->scbs[ha->max_cmds-1];
+ /* flush the cache on the controller */
+ scb = &ha->scbs[ha->max_cmds - 1];
- ips_init_scb(ha, scb);
+ ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_FLUSH;
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_FLUSH;
- scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
- scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.flush_cache.state = IPS_NORM_STATE;
- scb->cmd.flush_cache.reserved = 0;
- scb->cmd.flush_cache.reserved2 = 0;
- scb->cmd.flush_cache.reserved3 = 0;
- scb->cmd.flush_cache.reserved4 = 0;
+ scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
+ scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.flush_cache.state = IPS_NORM_STATE;
+ scb->cmd.flush_cache.reserved = 0;
+ scb->cmd.flush_cache.reserved2 = 0;
+ scb->cmd.flush_cache.reserved3 = 0;
+ scb->cmd.flush_cache.reserved4 = 0;
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
+ IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
- /* send command */
- if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n");
- else
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n");
- }
+ /* send command */
+ if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) ==
+ IPS_FAILURE)
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Incomplete Flush.\n");
+ else
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Flushing Complete.\n");
+ }
- return (NOTIFY_OK);
+ return (NOTIFY_OK);
}
/****************************************************************************/
@@ -795,50 +803,51 @@ ips_halt(struct notifier_block *nb, ulong event, void *buf) {
/* Note: this routine is called under the io_request_lock */
/****************************************************************************/
int
-ips_eh_abort(Scsi_Cmnd *SC) {
- ips_ha_t *ha;
- ips_copp_wait_item_t *item;
- int ret;
-
- METHOD_TRACE("ips_eh_abort", 1);
-
- if (!SC)
- return (FAILED);
-
- ha = (ips_ha_t *) SC->device->host->hostdata;
-
- if (!ha)
- return (FAILED);
-
- if (!ha->active)
- return (FAILED);
-
- if (SC->serial_number != SC->serial_number_at_timeout) {
- /* HMM, looks like a bogus command */
- DEBUG(1, "Abort called with bogus scsi command");
-
- return (FAILED);
- }
-
- /* See if the command is on the copp queue */
- item = ha->copp_waitlist.head;
- while ((item) && (item->scsi_cmd != SC))
- item = item->next;
-
- if (item) {
- /* Found it */
- ips_removeq_copp(&ha->copp_waitlist, item);
- ret = (SUCCESS);
-
- /* See if the command is on the wait queue */
- } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
- /* command not sent yet */
- ret = (SUCCESS);
- } else {
- /* command must have already been sent */
- ret = (FAILED);
- }
- return ret;
+ips_eh_abort(Scsi_Cmnd * SC)
+{
+ ips_ha_t *ha;
+ ips_copp_wait_item_t *item;
+ int ret;
+
+ METHOD_TRACE("ips_eh_abort", 1);
+
+ if (!SC)
+ return (FAILED);
+
+ ha = (ips_ha_t *) SC->device->host->hostdata;
+
+ if (!ha)
+ return (FAILED);
+
+ if (!ha->active)
+ return (FAILED);
+
+ if (SC->serial_number != SC->serial_number_at_timeout) {
+ /* HMM, looks like a bogus command */
+ DEBUG(1, "Abort called with bogus scsi command");
+
+ return (FAILED);
+ }
+
+ /* See if the command is on the copp queue */
+ item = ha->copp_waitlist.head;
+ while ((item) && (item->scsi_cmd != SC))
+ item = item->next;
+
+ if (item) {
+ /* Found it */
+ ips_removeq_copp(&ha->copp_waitlist, item);
+ ret = (SUCCESS);
+
+ /* See if the command is on the wait queue */
+ } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
+ /* command not sent yet */
+ ret = (SUCCESS);
+ } else {
+ /* command must have already been sent */
+ ret = (FAILED);
+ }
+ return ret;
}
/****************************************************************************/
@@ -853,188 +862,190 @@ ips_eh_abort(Scsi_Cmnd *SC) {
/* */
/****************************************************************************/
int
-ips_eh_reset(Scsi_Cmnd *SC) {
- int ret;
- int i;
- ips_ha_t *ha;
- ips_scb_t *scb;
- ips_copp_wait_item_t *item;
+ips_eh_reset(Scsi_Cmnd * SC)
+{
+ int ret;
+ int i;
+ ips_ha_t *ha;
+ ips_scb_t *scb;
+ ips_copp_wait_item_t *item;
- METHOD_TRACE("ips_eh_reset", 1);
+ METHOD_TRACE("ips_eh_reset", 1);
#ifdef NO_IPS_RESET
- return (FAILED);
+ return (FAILED);
#else
- if (!SC) {
- DEBUG(1, "Reset called with NULL scsi command");
-
- return (FAILED);
- }
-
- ha = (ips_ha_t *) SC->device->host->hostdata;
-
- if (!ha) {
- DEBUG(1, "Reset called with NULL ha struct");
-
- return (FAILED);
- }
-
- if (!ha->active)
- return (FAILED);
-
- /* See if the command is on the copp queue */
- item = ha->copp_waitlist.head;
- while ((item) && (item->scsi_cmd != SC))
- item = item->next;
-
- if (item) {
- /* Found it */
- ips_removeq_copp(&ha->copp_waitlist, item);
- return (SUCCESS);
- }
-
- /* See if the command is on the wait queue */
- if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
- /* command not sent yet */
- return (SUCCESS);
- }
-
- /* An explanation for the casual observer: */
- /* Part of the function of a RAID controller is automatic error */
- /* detection and recovery. As such, the only problem that physically */
- /* resetting an adapter will ever fix is when, for some reason, */
- /* the driver is not successfully communicating with the adapter. */
- /* Therefore, we will attempt to flush this adapter. If that succeeds, */
- /* then there's no real purpose in a physical reset. This will complete */
- /* much faster and avoids any problems that might be caused by a */
- /* physical reset ( such as having to fail all the outstanding I/O's ). */
-
- if (ha->ioctl_reset == 0) { /* IF Not an IOCTL Requested Reset */
- scb = &ha->scbs[ha->max_cmds-1];
-
- ips_init_scb(ha, scb);
-
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_FLUSH;
-
- scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
- scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.flush_cache.state = IPS_NORM_STATE;
- scb->cmd.flush_cache.reserved = 0;
- scb->cmd.flush_cache.reserved2 = 0;
- scb->cmd.flush_cache.reserved3 = 0;
- scb->cmd.flush_cache.reserved4 = 0;
-
- /* Attempt the flush command */
- ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
- if (ret == IPS_SUCCESS) {
- IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Reset Request - Flushed Cache\n");
- return (SUCCESS);
- }
- }
-
- /* Either we can't communicate with the adapter or it's an IOCTL request */
- /* from a utility. A physical reset is needed at this point. */
-
- ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */
-
- /*
- * command must have already been sent
- * reset the controller
- */
- IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Resetting controller.\n");
- ret = (*ha->func.reset)(ha);
-
- if (!ret) {
- Scsi_Cmnd *scsi_cmd;
-
- IPS_PRINTK(KERN_NOTICE, ha->pcidev,
- "Controller reset failed - controller now offline.\n");
-
- /* Now fail all of the active commands */
- DEBUG_VAR(1, "(%s%d) Failing active commands",
- ips_name, ha->host_num);
-
- while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
- scb->scsi_cmd->result = DID_ERROR << 16;
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- ips_freescb(ha, scb);
- }
-
- /* Now fail all of the pending commands */
- DEBUG_VAR(1, "(%s%d) Failing pending commands",
- ips_name, ha->host_num);
-
- while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
- scsi_cmd->result = DID_ERROR;
- scsi_cmd->scsi_done(scsi_cmd);
- }
-
- ha->active = FALSE;
- return (FAILED);
- }
-
- if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
- Scsi_Cmnd *scsi_cmd;
-
- IPS_PRINTK(KERN_NOTICE, ha->pcidev,
- "Controller reset failed - controller now offline.\n");
-
- /* Now fail all of the active commands */
- DEBUG_VAR(1, "(%s%d) Failing active commands",
- ips_name, ha->host_num);
-
- while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
- scb->scsi_cmd->result = DID_ERROR << 16;
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- ips_freescb(ha, scb);
- }
-
- /* Now fail all of the pending commands */
- DEBUG_VAR(1, "(%s%d) Failing pending commands",
- ips_name, ha->host_num);
-
- while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
- scsi_cmd->result = DID_ERROR << 16;
- scsi_cmd->scsi_done(scsi_cmd);
- }
-
- ha->active = FALSE;
- return (FAILED);
- }
-
- /* FFDC */
- if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) {
- struct timeval tv;
-
- do_gettimeofday(&tv);
- ha->last_ffdc = tv.tv_sec;
- ha->reset_count++;
- ips_ffdc_reset(ha, IPS_INTR_IORL);
- }
-
- /* Now fail all of the active commands */
- DEBUG_VAR(1, "(%s%d) Failing active commands",
- ips_name, ha->host_num);
-
- while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
- scb->scsi_cmd->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- ips_freescb(ha, scb);
- }
-
- /* Reset DCDB active command bits */
- for (i = 1; i < ha->nbus; i++)
- ha->dcdb_active[i-1] = 0;
-
- /* Reset the number of active IOCTLs */
- ha->num_ioctl = 0;
+ if (!SC) {
+ DEBUG(1, "Reset called with NULL scsi command");
+
+ return (FAILED);
+ }
+
+ ha = (ips_ha_t *) SC->device->host->hostdata;
+
+ if (!ha) {
+ DEBUG(1, "Reset called with NULL ha struct");
+
+ return (FAILED);
+ }
+
+ if (!ha->active)
+ return (FAILED);
+
+ /* See if the command is on the copp queue */
+ item = ha->copp_waitlist.head;
+ while ((item) && (item->scsi_cmd != SC))
+ item = item->next;
+
+ if (item) {
+ /* Found it */
+ ips_removeq_copp(&ha->copp_waitlist, item);
+ return (SUCCESS);
+ }
+
+ /* See if the command is on the wait queue */
+ if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
+ /* command not sent yet */
+ return (SUCCESS);
+ }
+
+ /* An explanation for the casual observer: */
+ /* Part of the function of a RAID controller is automatic error */
+ /* detection and recovery. As such, the only problem that physically */
+ /* resetting an adapter will ever fix is when, for some reason, */
+ /* the driver is not successfully communicating with the adapter. */
+ /* Therefore, we will attempt to flush this adapter. If that succeeds, */
+ /* then there's no real purpose in a physical reset. This will complete */
+ /* much faster and avoids any problems that might be caused by a */
+ /* physical reset ( such as having to fail all the outstanding I/O's ). */
+
+ if (ha->ioctl_reset == 0) { /* IF Not an IOCTL Requested Reset */
+ scb = &ha->scbs[ha->max_cmds - 1];
+
+ ips_init_scb(ha, scb);
+
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_FLUSH;
+
+ scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
+ scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.flush_cache.state = IPS_NORM_STATE;
+ scb->cmd.flush_cache.reserved = 0;
+ scb->cmd.flush_cache.reserved2 = 0;
+ scb->cmd.flush_cache.reserved3 = 0;
+ scb->cmd.flush_cache.reserved4 = 0;
+
+ /* Attempt the flush command */
+ ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
+ if (ret == IPS_SUCCESS) {
+ IPS_PRINTK(KERN_NOTICE, ha->pcidev,
+ "Reset Request - Flushed Cache\n");
+ return (SUCCESS);
+ }
+ }
+
+ /* Either we can't communicate with the adapter or it's an IOCTL request */
+ /* from a utility. A physical reset is needed at this point. */
+
+ ha->ioctl_reset = 0; /* Reset the IOCTL Requested Reset Flag */
+
+ /*
+ * command must have already been sent
+ * reset the controller
+ */
+ IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Resetting controller.\n");
+ ret = (*ha->func.reset) (ha);
+
+ if (!ret) {
+ Scsi_Cmnd *scsi_cmd;
+
+ IPS_PRINTK(KERN_NOTICE, ha->pcidev,
+ "Controller reset failed - controller now offline.\n");
+
+ /* Now fail all of the active commands */
+ DEBUG_VAR(1, "(%s%d) Failing active commands",
+ ips_name, ha->host_num);
+
+ while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
+ scb->scsi_cmd->result = DID_ERROR << 16;
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ ips_freescb(ha, scb);
+ }
+
+ /* Now fail all of the pending commands */
+ DEBUG_VAR(1, "(%s%d) Failing pending commands",
+ ips_name, ha->host_num);
+
+ while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
+ scsi_cmd->result = DID_ERROR;
+ scsi_cmd->scsi_done(scsi_cmd);
+ }
+
+ ha->active = FALSE;
+ return (FAILED);
+ }
+
+ if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
+ Scsi_Cmnd *scsi_cmd;
+
+ IPS_PRINTK(KERN_NOTICE, ha->pcidev,
+ "Controller reset failed - controller now offline.\n");
+
+ /* Now fail all of the active commands */
+ DEBUG_VAR(1, "(%s%d) Failing active commands",
+ ips_name, ha->host_num);
+
+ while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
+ scb->scsi_cmd->result = DID_ERROR << 16;
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ ips_freescb(ha, scb);
+ }
+
+ /* Now fail all of the pending commands */
+ DEBUG_VAR(1, "(%s%d) Failing pending commands",
+ ips_name, ha->host_num);
+
+ while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
+ scsi_cmd->result = DID_ERROR << 16;
+ scsi_cmd->scsi_done(scsi_cmd);
+ }
+
+ ha->active = FALSE;
+ return (FAILED);
+ }
+
+ /* FFDC */
+ if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) {
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+ ha->last_ffdc = tv.tv_sec;
+ ha->reset_count++;
+ ips_ffdc_reset(ha, IPS_INTR_IORL);
+ }
+
+ /* Now fail all of the active commands */
+ DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num);
+
+ while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
+ scb->scsi_cmd->result =
+ (DID_RESET << 16) | (SUGGEST_RETRY << 24);
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ ips_freescb(ha, scb);
+ }
- ips_next(ha, IPS_INTR_IORL);
+ /* Reset DCDB active command bits */
+ for (i = 1; i < ha->nbus; i++)
+ ha->dcdb_active[i - 1] = 0;
- return (SUCCESS);
-#endif /* NO_IPS_RESET */
+ /* Reset the number of active IOCTLs */
+ ha->num_ioctl = 0;
+
+ ips_next(ha, IPS_INTR_IORL);
+
+ return (SUCCESS);
+#endif /* NO_IPS_RESET */
}
@@ -1051,96 +1062,95 @@ ips_eh_reset(Scsi_Cmnd *SC) {
/* */
/****************************************************************************/
int
-ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
- ips_ha_t *ha;
- ips_passthru_t *pt;
-
- METHOD_TRACE("ips_queue", 1);
-
- ha = (ips_ha_t *) SC->device->host->hostdata;
-
- if (!ha)
- return (1);
-
- if (!ha->active)
- return (DID_ERROR);
-
- if (ips_is_passthru(SC)) {
- if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
- SC->result = DID_BUS_BUSY << 16;
- done(SC);
-
- return (0);
- }
- } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
- SC->result = DID_BUS_BUSY << 16;
- done(SC);
-
- return (0);
- }
-
- SC->scsi_done = done;
-
- DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
- ips_name,
- ha->host_num,
- SC->cmnd[0],
- SC->device->channel,
- SC->device->id,
- SC->device->lun);
-
- /* Check for command to initiator IDs */
- if ((SC->device->channel > 0) && (SC->device->id == ha->ha_id[SC->device->channel])) {
- SC->result = DID_NO_CONNECT << 16;
- done(SC);
-
- return (0);
- }
-
- if (ips_is_passthru(SC)) {
-
- ips_copp_wait_item_t *scratch;
-
- /* A Reset IOCTL is only sent by the ServeRAID boot CD in extreme cases. */
- /* There can never be any system activity ( network or disk ), but check */
- /* anyway just as a good practice. */
- pt = (ips_passthru_t *) SC->request_buffer;
- if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&
- (pt->CoppCP.cmd.reset.adapter_flag == 1)) {
- if (ha->scb_activelist.count != 0) {
- SC->result = DID_BUS_BUSY << 16;
- done(SC);
- return (0);
- }
- ha->ioctl_reset = 1; /* This reset request is from an IOCTL */
- ips_eh_reset(SC);
- SC->result = DID_OK << 16;
- SC->scsi_done(SC);
- return (0);
- }
-
- /* allocate space for the scribble */
- scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_ATOMIC);
-
- if (!scratch) {
- SC->result = DID_ERROR << 16;
- done(SC);
-
- return (0);
- }
-
- scratch->scsi_cmd = SC;
- scratch->next = NULL;
-
- ips_putq_copp_tail(&ha->copp_waitlist, scratch);
- }
- else {
- ips_putq_wait_tail(&ha->scb_waitlist, SC);
- }
-
- ips_next(ha, IPS_INTR_IORL);
-
- return (0);
+ips_queue(Scsi_Cmnd * SC, void (*done) (Scsi_Cmnd *))
+{
+ ips_ha_t *ha;
+ ips_passthru_t *pt;
+
+ METHOD_TRACE("ips_queue", 1);
+
+ ha = (ips_ha_t *) SC->device->host->hostdata;
+
+ if (!ha)
+ return (1);
+
+ if (!ha->active)
+ return (DID_ERROR);
+
+ if (ips_is_passthru(SC)) {
+ if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
+ SC->result = DID_BUS_BUSY << 16;
+ done(SC);
+
+ return (0);
+ }
+ } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
+ SC->result = DID_BUS_BUSY << 16;
+ done(SC);
+
+ return (0);
+ }
+
+ SC->scsi_done = done;
+
+ DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
+ ips_name,
+ ha->host_num,
+ SC->cmnd[0],
+ SC->device->channel, SC->device->id, SC->device->lun);
+
+ /* Check for command to initiator IDs */
+ if ((SC->device->channel > 0)
+ && (SC->device->id == ha->ha_id[SC->device->channel])) {
+ SC->result = DID_NO_CONNECT << 16;
+ done(SC);
+
+ return (0);
+ }
+
+ if (ips_is_passthru(SC)) {
+
+ ips_copp_wait_item_t *scratch;
+
+ /* A Reset IOCTL is only sent by the boot CD in extreme cases. */
+ /* There can never be any system activity ( network or disk ), but check */
+ /* anyway just as a good practice. */
+ pt = (ips_passthru_t *) SC->request_buffer;
+ if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&
+ (pt->CoppCP.cmd.reset.adapter_flag == 1)) {
+ if (ha->scb_activelist.count != 0) {
+ SC->result = DID_BUS_BUSY << 16;
+ done(SC);
+ return (0);
+ }
+ ha->ioctl_reset = 1; /* This reset request is from an IOCTL */
+ ips_eh_reset(SC);
+ SC->result = DID_OK << 16;
+ SC->scsi_done(SC);
+ return (0);
+ }
+
+ /* allocate space for the scribble */
+ scratch = kmalloc(sizeof (ips_copp_wait_item_t), GFP_ATOMIC);
+
+ if (!scratch) {
+ SC->result = DID_ERROR << 16;
+ done(SC);
+
+ return (0);
+ }
+
+ scratch->scsi_cmd = SC;
+ scratch->next = NULL;
+
+ ips_putq_copp_tail(&ha->copp_waitlist, scratch);
+ } else {
+ ips_putq_wait_tail(&ha->scb_waitlist, SC);
+ }
+
+ ips_next(ha, IPS_INTR_IORL);
+
+ return (0);
}
/****************************************************************************/
@@ -1154,52 +1164,72 @@ ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
/****************************************************************************/
static int
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-ips_biosparam(Disk *disk, kdev_t dev, int geom[]) {
- ips_ha_t *ha = (ips_ha_t *) disk->device->host->hostdata;
- unsigned long capacity = disk->capacity;
+ips_biosparam(Disk * disk, kdev_t dev, int geom[])
+{
+ ips_ha_t *ha = (ips_ha_t *) disk->device->host->hostdata;
+ unsigned long capacity = disk->capacity;
#else
ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
- sector_t capacity, int geom[]) {
- ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata;
+ sector_t capacity, int geom[])
+{
+ ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata;
#endif
- int heads;
- int sectors;
- int cylinders;
+ int heads;
+ int sectors;
+ int cylinders;
- METHOD_TRACE("ips_biosparam", 1);
+ METHOD_TRACE("ips_biosparam", 1);
- if (!ha)
- /* ?!?! host adater info invalid */
- return (0);
+ if (!ha)
+ /* ?!?! host adater info invalid */
+ return (0);
- if (!ha->active)
- return (0);
+ if (!ha->active)
+ return (0);
- if (!ips_read_adapter_status(ha, IPS_INTR_ON))
- /* ?!?! Enquiry command failed */
- return (0);
+ if (!ips_read_adapter_status(ha, IPS_INTR_ON))
+ /* ?!?! Enquiry command failed */
+ return (0);
- if ((capacity > 0x400000) &&
- ((ha->enq->ucMiscFlag & 0x8) == 0)) {
- heads = IPS_NORM_HEADS;
- sectors = IPS_NORM_SECTORS;
- } else {
- heads = IPS_COMP_HEADS;
- sectors = IPS_COMP_SECTORS;
- }
+ if ((capacity > 0x400000) && ((ha->enq->ucMiscFlag & 0x8) == 0)) {
+ heads = IPS_NORM_HEADS;
+ sectors = IPS_NORM_SECTORS;
+ } else {
+ heads = IPS_COMP_HEADS;
+ sectors = IPS_COMP_SECTORS;
+ }
- cylinders = (unsigned long)capacity / (heads * sectors);
+ cylinders = (unsigned long) capacity / (heads * sectors);
- DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
- heads, sectors, cylinders);
+ DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
+ heads, sectors, cylinders);
- geom[0] = heads;
- geom[1] = sectors;
- geom[2] = cylinders;
+ geom[0] = heads;
+ geom[1] = sectors;
+ geom[2] = cylinders;
- return (0);
+ return (0);
}
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+
+/* ips_proc24_info is a wrapper around ips_proc_info *
+ * for compatibility with the 2.4 scsi parameters */
+static int
+ips_proc24_info(char *buffer, char **start, off_t offset, int length,
+ int hostno, int func)
+{
+ int i;
+
+ for (i = 0; i < ips_next_controller; i++) {
+ if (ips_sh[i] && ips_sh[i]->host_no == hostno) {
+ return ips_proc_info(ips_sh[i], buffer, start,
+ offset, length, func);
+ }
+ }
+ return -EINVAL;
+}
+
/****************************************************************************/
/* */
/* Routine Name: ips_select_queue_depth */
@@ -1210,37 +1240,38 @@ ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
/* */
/****************************************************************************/
static void
-ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) {
- Scsi_Device *device;
- ips_ha_t *ha;
- int count = 0;
- int min;
-
- ha = IPS_HA(host);
- min = ha->max_cmds / 4;
-
- for (device = scsi_devs; device; device = device->next) {
- if (device->host == host) {
- if ((device->channel == 0) && (device->type == 0))
- count++;
- }
- }
-
- for (device = scsi_devs; device; device = device->next) {
- if (device->host == host) {
- if ((device->channel == 0) && (device->type == 0)) {
- device->queue_depth = ( ha->max_cmds - 1 ) / count;
- if (device->queue_depth < min)
- device->queue_depth = min;
- }
- else {
- device->queue_depth = 2;
- }
-
- if (device->queue_depth < 2)
- device->queue_depth = 2;
- }
- }
+ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device * scsi_devs)
+{
+ Scsi_Device *device;
+ ips_ha_t *ha;
+ int count = 0;
+ int min;
+
+ ha = IPS_HA(host);
+ min = ha->max_cmds / 4;
+
+ for (device = scsi_devs; device; device = device->next) {
+ if (device->host == host) {
+ if ((device->channel == 0) && (device->type == 0))
+ count++;
+ }
+ }
+
+ for (device = scsi_devs; device; device = device->next) {
+ if (device->host == host) {
+ if ((device->channel == 0) && (device->type == 0)) {
+ device->queue_depth =
+ (ha->max_cmds - 1) / count;
+ if (device->queue_depth < min)
+ device->queue_depth = min;
+ } else {
+ device->queue_depth = 2;
+ }
+
+ if (device->queue_depth < 2)
+ device->queue_depth = 2;
+ }
+ }
}
#else
@@ -1254,19 +1285,19 @@ ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) {
/* */
/****************************************************************************/
int
-ips_slave_configure(Scsi_Device *SDptr)
+ips_slave_configure(Scsi_Device * SDptr)
{
- ips_ha_t *ha;
- int min;
-
- ha = IPS_HA(SDptr->host);
- if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) {
- min = ha->max_cmds / 2;
- if (ha->enq->ucLogDriveCount <= 2)
- min = ha->max_cmds - 1;
- scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
- }
- return 0;
+ ips_ha_t *ha;
+ int min;
+
+ ha = IPS_HA(SDptr->host);
+ if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) {
+ min = ha->max_cmds / 2;
+ if (ha->enq->ucLogDriveCount <= 2)
+ min = ha->max_cmds - 1;
+ scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
+ }
+ return 0;
}
#endif
@@ -1280,38 +1311,39 @@ ips_slave_configure(Scsi_Device *SDptr)
/* */
/****************************************************************************/
irqreturn_t
-do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) {
- ips_ha_t *ha;
- unsigned long cpu_flags;
- struct Scsi_Host *host;
- int irqstatus;
-
- METHOD_TRACE("do_ipsintr", 2);
-
- ha = (ips_ha_t *) dev_id;
- if (!ha)
- return IRQ_NONE;
- host = ips_sh[ha->host_num];
- /* interrupt during initialization */
- if(!host){
- (*ha->func.intr)(ha);
- return IRQ_HANDLED;
- }
+do_ipsintr(int irq, void *dev_id, struct pt_regs * regs)
+{
+ ips_ha_t *ha;
+ unsigned long cpu_flags;
+ struct Scsi_Host *host;
+ int irqstatus;
+
+ METHOD_TRACE("do_ipsintr", 2);
+
+ ha = (ips_ha_t *) dev_id;
+ if (!ha)
+ return IRQ_NONE;
+ host = ips_sh[ha->host_num];
+ /* interrupt during initialization */
+ if (!host) {
+ (*ha->func.intr) (ha);
+ return IRQ_HANDLED;
+ }
- IPS_LOCK_SAVE(host->host_lock, cpu_flags);
+ IPS_LOCK_SAVE(host->host_lock, cpu_flags);
- if (!ha->active) {
- IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
- return IRQ_HANDLED;
- }
+ if (!ha->active) {
+ IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
+ return IRQ_HANDLED;
+ }
- irqstatus = (*ha->func.intr)(ha);
+ irqstatus = (*ha->func.intr) (ha);
- IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
+ IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
- /* start the next command */
- ips_next(ha, IPS_INTR_ON);
- return IRQ_RETVAL(irqstatus);
+ /* start the next command */
+ ips_next(ha, IPS_INTR_ON);
+ return IRQ_RETVAL(irqstatus);
}
/****************************************************************************/
@@ -1326,55 +1358,56 @@ do_ipsintr(int irq, void *dev_id, struct pt_regs *regs) {
/* */
/****************************************************************************/
int
-ips_intr_copperhead(ips_ha_t *ha) {
- ips_stat_t *sp;
- ips_scb_t *scb;
- IPS_STATUS cstatus;
- int intrstatus;
+ips_intr_copperhead(ips_ha_t * ha)
+{
+ ips_stat_t *sp;
+ ips_scb_t *scb;
+ IPS_STATUS cstatus;
+ int intrstatus;
- METHOD_TRACE("ips_intr", 2);
+ METHOD_TRACE("ips_intr", 2);
- if (!ha)
- return 0;
+ if (!ha)
+ return 0;
- if (!ha->active)
- return 0;
+ if (!ha->active)
+ return 0;
- intrstatus = (*ha->func.isintr)(ha);
+ intrstatus = (*ha->func.isintr) (ha);
- if (!intrstatus) {
- /*
- * Unexpected/Shared interrupt
- */
+ if (!intrstatus) {
+ /*
+ * Unexpected/Shared interrupt
+ */
- return 0;
- }
+ return 0;
+ }
- while (TRUE) {
- sp = &ha->sp;
+ while (TRUE) {
+ sp = &ha->sp;
- intrstatus = (*ha->func.isintr)(ha);
+ intrstatus = (*ha->func.isintr) (ha);
- if (!intrstatus)
- break;
- else
- cstatus.value = (*ha->func.statupd)(ha);
+ if (!intrstatus)
+ break;
+ else
+ cstatus.value = (*ha->func.statupd) (ha);
- if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
- /* Spurious Interupt ? */
- continue;
- }
+ if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
+ /* Spurious Interupt ? */
+ continue;
+ }
- ips_chkstatus(ha, &cstatus);
- scb = (ips_scb_t *) sp->scb_addr;
+ ips_chkstatus(ha, &cstatus);
+ scb = (ips_scb_t *) sp->scb_addr;
- /*
- * use the callback function to finish things up
- * NOTE: interrupts are OFF for this
- */
- (*scb->callback) (ha, scb);
- } /* end while */
- return 1;
+ /*
+ * use the callback function to finish things up
+ * NOTE: interrupts are OFF for this
+ */
+ (*scb->callback) (ha, scb);
+ } /* end while */
+ return 1;
}
/****************************************************************************/
@@ -1389,60 +1422,62 @@ ips_intr_copperhead(ips_ha_t *ha) {
/* */
/****************************************************************************/
int
-ips_intr_morpheus(ips_ha_t *ha) {
- ips_stat_t *sp;
- ips_scb_t *scb;
- IPS_STATUS cstatus;
- int intrstatus;
+ips_intr_morpheus(ips_ha_t * ha)
+{
+ ips_stat_t *sp;
+ ips_scb_t *scb;
+ IPS_STATUS cstatus;
+ int intrstatus;
- METHOD_TRACE("ips_intr_morpheus", 2);
+ METHOD_TRACE("ips_intr_morpheus", 2);
- if (!ha)
- return 0;
+ if (!ha)
+ return 0;
- if (!ha->active)
- return 0;
+ if (!ha->active)
+ return 0;
- intrstatus = (*ha->func.isintr)(ha);
+ intrstatus = (*ha->func.isintr) (ha);
- if (!intrstatus) {
- /*
- * Unexpected/Shared interrupt
- */
+ if (!intrstatus) {
+ /*
+ * Unexpected/Shared interrupt
+ */
- return 0;
- }
+ return 0;
+ }
- while (TRUE) {
- sp = &ha->sp;
+ while (TRUE) {
+ sp = &ha->sp;
- intrstatus = (*ha->func.isintr)(ha);
+ intrstatus = (*ha->func.isintr) (ha);
- if (!intrstatus)
- break;
- else
- cstatus.value = (*ha->func.statupd)(ha);
+ if (!intrstatus)
+ break;
+ else
+ cstatus.value = (*ha->func.statupd) (ha);
- if (cstatus.value == 0xffffffff)
- /* No more to process */
- break;
+ if (cstatus.value == 0xffffffff)
+ /* No more to process */
+ break;
- if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Spurious interrupt; no ccb.\n");
+ if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Spurious interrupt; no ccb.\n");
- continue;
- }
+ continue;
+ }
- ips_chkstatus(ha, &cstatus);
- scb = (ips_scb_t *) sp->scb_addr;
+ ips_chkstatus(ha, &cstatus);
+ scb = (ips_scb_t *) sp->scb_addr;
- /*
- * use the callback function to finish things up
- * NOTE: interrupts are OFF for this
- */
- (*scb->callback) (ha, scb);
- } /* end while */
- return 1;
+ /*
+ * use the callback function to finish things up
+ * NOTE: interrupts are OFF for this
+ */
+ (*scb->callback) (ha, scb);
+ } /* end while */
+ return 1;
}
/****************************************************************************/
@@ -1455,32 +1490,32 @@ ips_intr_morpheus(ips_ha_t *ha) {
/* */
/****************************************************************************/
const char *
-ips_info(struct Scsi_Host *SH) {
- static char buffer[256];
- char *bp;
- ips_ha_t *ha;
+ips_info(struct Scsi_Host *SH)
+{
+ static char buffer[256];
+ char *bp;
+ ips_ha_t *ha;
- METHOD_TRACE("ips_info", 1);
+ METHOD_TRACE("ips_info", 1);
- ha = IPS_HA(SH);
+ ha = IPS_HA(SH);
- if (!ha)
- return (NULL);
+ if (!ha)
+ return (NULL);
- bp = &buffer[0];
- memset(bp, 0, sizeof(buffer));
+ bp = &buffer[0];
+ memset(bp, 0, sizeof (buffer));
- sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ",
- IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT );
+ sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ",
+ IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT);
- if (ha->ad_type > 0 &&
- ha->ad_type <= MAX_ADAPTER_NAME) {
- strcat(bp, " <");
- strcat(bp, ips_adapter_name[ha->ad_type-1]);
- strcat(bp, ">");
- }
+ if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) {
+ strcat(bp, " <");
+ strcat(bp, ips_adapter_name[ha->ad_type - 1]);
+ strcat(bp, ">");
+ }
- return (bp);
+ return (bp);
}
/****************************************************************************/
@@ -1494,38 +1529,39 @@ ips_info(struct Scsi_Host *SH) {
/****************************************************************************/
int
ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
- int length, int func) {
- int i;
- int ret;
- ips_ha_t *ha = NULL;
-
- METHOD_TRACE("ips_proc_info", 1);
-
- /* Find our host structure */
- for (i = 0; i < ips_next_controller; i++) {
- if (ips_sh[i]) {
- if (ips_sh[i] == host) {
- ha = (ips_ha_t *) ips_sh[i]->hostdata;
- break;
- }
- }
- }
-
- if (!ha)
- return (-EINVAL);
-
- if (func) {
- /* write */
- return (0);
- } else {
- /* read */
- if (start)
- *start = buffer;
-
- ret = ips_host_info(ha, buffer, offset, length);
-
- return (ret);
- }
+ int length, int func)
+{
+ int i;
+ int ret;
+ ips_ha_t *ha = NULL;
+
+ METHOD_TRACE("ips_proc_info", 1);
+
+ /* Find our host structure */
+ for (i = 0; i < ips_next_controller; i++) {
+ if (ips_sh[i]) {
+ if (ips_sh[i] == host) {
+ ha = (ips_ha_t *) ips_sh[i]->hostdata;
+ break;
+ }
+ }
+ }
+
+ if (!ha)
+ return (-EINVAL);
+
+ if (func) {
+ /* write */
+ return (0);
+ } else {
+ /* read */
+ if (start)
+ *start = buffer;
+
+ ret = ips_host_info(ha, buffer, offset, length);
+
+ return (ret);
+ }
}
/*--------------------------------------------------------------------------*/
@@ -1542,32 +1578,32 @@ ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
/* */
/****************************************************************************/
static int
-ips_is_passthru(Scsi_Cmnd *SC) {
- METHOD_TRACE("ips_is_passthru", 1);
-
- if (!SC)
- return (0);
-
- if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
- (SC->device->channel == 0) &&
- (SC->device->id == IPS_ADAPTER_ID) &&
- (SC->device->lun == 0) &&
- SC->request_buffer){
- if((!SC->use_sg) && SC->request_bufflen &&
- (((char *) SC->request_buffer)[0] == 'C') &&
- (((char *) SC->request_buffer)[1] == 'O') &&
- (((char *) SC->request_buffer)[2] == 'P') &&
- (((char *) SC->request_buffer)[3] == 'P'))
- return 1;
- else if(SC->use_sg){
- struct scatterlist *sg = SC->request_buffer;
- char *buffer = IPS_SG_ADDRESS(sg);
- if(buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
- buffer[2] == 'P' && buffer[3] == 'P')
- return 1;
- }
- }
- return 0;
+ips_is_passthru(Scsi_Cmnd * SC)
+{
+ METHOD_TRACE("ips_is_passthru", 1);
+
+ if (!SC)
+ return (0);
+
+ if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
+ (SC->device->channel == 0) &&
+ (SC->device->id == IPS_ADAPTER_ID) &&
+ (SC->device->lun == 0) && SC->request_buffer) {
+ if ((!SC->use_sg) && SC->request_bufflen &&
+ (((char *) SC->request_buffer)[0] == 'C') &&
+ (((char *) SC->request_buffer)[1] == 'O') &&
+ (((char *) SC->request_buffer)[2] == 'P') &&
+ (((char *) SC->request_buffer)[3] == 'P'))
+ return 1;
+ else if (SC->use_sg) {
+ struct scatterlist *sg = SC->request_buffer;
+ char *buffer = IPS_SG_ADDRESS(sg);
+ if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
+ buffer[2] == 'P' && buffer[3] == 'P')
+ return 1;
+ }
+ }
+ return 0;
}
/****************************************************************************/
@@ -1579,24 +1615,23 @@ ips_is_passthru(Scsi_Cmnd *SC) {
/* is too small or doesn't exist */
/****************************************************************************/
static int
-ips_alloc_passthru_buffer(ips_ha_t *ha, int length){
+ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
+{
void *bigger_buf;
- int count;
- int order;
+ dma_addr_t dma_busaddr;
- if(ha->ioctl_data && length <= (PAGE_SIZE << ha->ioctl_order))
+ if (ha->ioctl_data && length <= ha->ioctl_len)
return 0;
/* there is no buffer or it's not big enough, allocate a new one */
- for (count = PAGE_SIZE, order = 0;
- count < length;
- order++, count <<= 1);
- bigger_buf = (void *) __get_free_pages(IPS_ATOMIC_GFP, order);
+ bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr);
if (bigger_buf) {
/* free the old memory */
- free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
+ pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data,
+ ha->ioctl_busaddr);
/* use the new memory */
ha->ioctl_data = (char *) bigger_buf;
- ha->ioctl_order = order;
+ ha->ioctl_len = length;
+ ha->ioctl_busaddr = dma_busaddr;
} else {
return -1;
}
@@ -1613,92 +1648,96 @@ ips_alloc_passthru_buffer(ips_ha_t *ha, int length){
/* */
/****************************************************************************/
static int
-ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) {
- ips_passthru_t *pt;
- int length = 0;
- int ret;
-
- METHOD_TRACE("ips_make_passthru", 1);
-
- if(!SC->use_sg){
- length = SC->request_bufflen;
- }else{
- struct scatterlist *sg = SC->request_buffer;
- int i;
- for(i = 0; i < SC->use_sg; i++)
- length += sg[i].length;
- }
- if (length < sizeof(ips_passthru_t)) {
- /* wrong size */
- DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
- ips_name, ha->host_num);
- return (IPS_FAILURE);
- }
- if(ips_alloc_passthru_buffer(ha, length)){
- /* allocation failure! If ha->ioctl_data exists, use it to return
- some error codes. Return a failed command to the scsi layer. */
- if(ha->ioctl_data){
- pt = (ips_passthru_t *)ha->ioctl_data;
- ips_scmd_buf_read(SC, pt, sizeof(ips_passthru_t));
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- ips_scmd_buf_write(SC, pt, sizeof(ips_passthru_t));
- }
- return IPS_FAILURE;
- }
- ha->ioctl_datasize = length;
-
- ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize);
- pt = (ips_passthru_t *)ha->ioctl_data;
-
- /*
- * Some notes about the passthru interface used
- *
- * IF the scsi op_code == 0x0d then we assume
- * that the data came along with/goes with the
- * packet we received from the sg driver. In this
- * case the CmdBSize field of the pt structure is
- * used for the size of the buffer.
- */
-
- switch (pt->CoppCmd) {
- case IPS_NUMCTRLS:
- memcpy(ha->ioctl_data + sizeof(ips_passthru_t),
- &ips_num_controllers, sizeof(int));
- ips_scmd_buf_write(SC, ha->ioctl_data,
- sizeof(ips_passthru_t) + sizeof(int));
- SC->result = DID_OK << 16;
-
- return (IPS_SUCCESS_IMM);
-
- case IPS_COPPUSRCMD:
- case IPS_COPPIOCCMD:
- if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
- if (length < (sizeof(ips_passthru_t) + pt->CmdBSize)) {
- /* wrong size */
- DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
- ips_name, ha->host_num);
-
- return (IPS_FAILURE);
- }
-
- if(ha->device_id == IPS_DEVICEID_COPPERHEAD &&
- pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) {
- ret = ips_flash_copperhead(ha, pt, scb);
- ips_scmd_buf_write(SC, ha->ioctl_data, sizeof(ips_passthru_t));
- return ret;
- }
- if (ips_usrcmd(ha, pt, scb))
- return (IPS_SUCCESS);
- else
- return (IPS_FAILURE);
- }
-
- break;
-
- } /* end switch */
-
- return (IPS_FAILURE);
+ips_make_passthru(ips_ha_t * ha, Scsi_Cmnd * SC, ips_scb_t * scb, int intr)
+{
+ ips_passthru_t *pt;
+ int length = 0;
+ int ret;
+
+ METHOD_TRACE("ips_make_passthru", 1);
+
+ if (!SC->use_sg) {
+ length = SC->request_bufflen;
+ } else {
+ struct scatterlist *sg = SC->request_buffer;
+ int i;
+ for (i = 0; i < SC->use_sg; i++)
+ length += sg[i].length;
+ }
+ if (length < sizeof (ips_passthru_t)) {
+ /* wrong size */
+ DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
+ ips_name, ha->host_num);
+ return (IPS_FAILURE);
+ }
+ if (ips_alloc_passthru_buffer(ha, length)) {
+ /* allocation failure! If ha->ioctl_data exists, use it to return
+ some error codes. Return a failed command to the scsi layer. */
+ if (ha->ioctl_data) {
+ pt = (ips_passthru_t *) ha->ioctl_data;
+ ips_scmd_buf_read(SC, pt, sizeof (ips_passthru_t));
+ pt->BasicStatus = 0x0B;
+ pt->ExtendedStatus = 0x00;
+ ips_scmd_buf_write(SC, pt, sizeof (ips_passthru_t));
+ }
+ return IPS_FAILURE;
+ }
+ ha->ioctl_datasize = length;
+
+ ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize);
+ pt = (ips_passthru_t *) ha->ioctl_data;
+
+ /*
+ * Some notes about the passthru interface used
+ *
+ * IF the scsi op_code == 0x0d then we assume
+ * that the data came along with/goes with the
+ * packet we received from the sg driver. In this
+ * case the CmdBSize field of the pt structure is
+ * used for the size of the buffer.
+ */
+
+ switch (pt->CoppCmd) {
+ case IPS_NUMCTRLS:
+ memcpy(ha->ioctl_data + sizeof (ips_passthru_t),
+ &ips_num_controllers, sizeof (int));
+ ips_scmd_buf_write(SC, ha->ioctl_data,
+ sizeof (ips_passthru_t) + sizeof (int));
+ SC->result = DID_OK << 16;
+
+ return (IPS_SUCCESS_IMM);
+
+ case IPS_COPPUSRCMD:
+ case IPS_COPPIOCCMD:
+ if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
+ if (length < (sizeof (ips_passthru_t) + pt->CmdBSize)) {
+ /* wrong size */
+ DEBUG_VAR(1,
+ "(%s%d) Passthru structure wrong size",
+ ips_name, ha->host_num);
+
+ return (IPS_FAILURE);
+ }
+
+ if (ha->device_id == IPS_DEVICEID_COPPERHEAD &&
+ pt->CoppCP.cmd.flashfw.op_code ==
+ IPS_CMD_RW_BIOSFW) {
+ ret = ips_flash_copperhead(ha, pt, scb);
+ ips_scmd_buf_write(SC, ha->ioctl_data,
+ sizeof (ips_passthru_t));
+ return ret;
+ }
+ if (ips_usrcmd(ha, pt, scb))
+ return (IPS_SUCCESS);
+ else
+ return (IPS_FAILURE);
+ }
+
+ break;
+
+ } /* end switch */
+
+ return (IPS_FAILURE);
}
/****************************************************************************/
@@ -1707,62 +1746,70 @@ ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) {
/* Flash the BIOS/FW on a Copperhead style controller */
/****************************************************************************/
static int
-ips_flash_copperhead(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb){
- int datasize, count;
-
- /* Trombone is the only copperhead that can do packet flash, but only
- * for firmware. No one said it had to make sence. */
- if(IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE){
- if(ips_usrcmd(ha, pt, scb))
- return IPS_SUCCESS;
- else
- return IPS_FAILURE;
- }
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0;
- scb->scsi_cmd->result = DID_OK <<16;
- /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */
- /* avoid allocating a huge buffer per adapter ( which can fail ). */
- if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
- pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS){
- pt->BasicStatus = 0;
- return ips_flash_bios(ha, pt, scb);
- }else if(pt->CoppCP.cmd.flashfw.packet_num == 0){
- if(ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
- ha->flash_data = ips_FlashData;
- ha->flash_order = 7;
- ha->flash_datasize = 0;
- }else if(!ha->flash_data){
- datasize = pt->CoppCP.cmd.flashfw.total_packets *
- pt->CoppCP.cmd.flashfw.count;
- for (count = PAGE_SIZE, ha->flash_order = 0; count < datasize;
- ha->flash_order++, count <<= 1);
- ha->flash_data = (char *)__get_free_pages(IPS_ATOMIC_GFP, ha->flash_order);
- ha->flash_datasize = 0;
- }else
- return IPS_FAILURE;
- }else{
- if(pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
- (PAGE_SIZE << ha->flash_order)){
- ips_free_flash_copperhead(ha);
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "failed size sanity check\n");
- return IPS_FAILURE;
- }
- }
- if(!ha->flash_data)
- return IPS_FAILURE;
- pt->BasicStatus = 0;
- memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
- pt->CoppCP.cmd.flashfw.count);
- ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
- if(pt->CoppCP.cmd.flashfw.packet_num ==
- pt->CoppCP.cmd.flashfw.total_packets - 1){
- if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
- return ips_flash_bios(ha, pt, scb);
- else if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
- return ips_flash_firmware(ha, pt, scb);
- }
- return IPS_SUCCESS_IMM;
+ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
+{
+ int datasize;
+
+ /* Trombone is the only copperhead that can do packet flash, but only
+ * for firmware. No one said it had to make sence. */
+ if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) {
+ if (ips_usrcmd(ha, pt, scb))
+ return IPS_SUCCESS;
+ else
+ return IPS_FAILURE;
+ }
+ pt->BasicStatus = 0x0B;
+ pt->ExtendedStatus = 0;
+ scb->scsi_cmd->result = DID_OK << 16;
+ /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can */
+ /* avoid allocating a huge buffer per adapter ( which can fail ). */
+ if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
+ pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
+ pt->BasicStatus = 0;
+ return ips_flash_bios(ha, pt, scb);
+ } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) {
+ if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
+ ha->flash_data = ips_FlashData;
+ ha->flash_busaddr = ips_flashbusaddr;
+ ha->flash_len = PAGE_SIZE << 7;
+ ha->flash_datasize = 0;
+ } else if (!ha->flash_data) {
+ datasize = pt->CoppCP.cmd.flashfw.total_packets *
+ pt->CoppCP.cmd.flashfw.count;
+ ha->flash_data = pci_alloc_consistent(ha->pcidev,
+ datasize,
+ &ha->flash_busaddr);
+ if (!ha->flash_data){
+ printk(KERN_WARNING "Unable to allocate a flash buffer\n");
+ return IPS_FAILURE;
+ }
+ ha->flash_datasize = 0;
+ ha->flash_len = datasize;
+ } else
+ return IPS_FAILURE;
+ } else {
+ if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
+ ha->flash_len) {
+ ips_free_flash_copperhead(ha);
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "failed size sanity check\n");
+ return IPS_FAILURE;
+ }
+ }
+ if (!ha->flash_data)
+ return IPS_FAILURE;
+ pt->BasicStatus = 0;
+ memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
+ pt->CoppCP.cmd.flashfw.count);
+ ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
+ if (pt->CoppCP.cmd.flashfw.packet_num ==
+ pt->CoppCP.cmd.flashfw.total_packets - 1) {
+ if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
+ return ips_flash_bios(ha, pt, scb);
+ else if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
+ return ips_flash_firmware(ha, pt, scb);
+ }
+ return IPS_SUCCESS_IMM;
}
/****************************************************************************/
@@ -1771,46 +1818,59 @@ ips_flash_copperhead(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb){
/* flashes the bios of a copperhead adapter */
/****************************************************************************/
static int
-ips_flash_bios(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){
-
- if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
- pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS){
- if ((!ha->func.programbios) || (!ha->func.erasebios) ||
- (!ha->func.verifybios))
- goto error;
- if((*ha->func.erasebios)(ha)){
- DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
- ips_name, ha->host_num);
- goto error;
- }else if ((*ha->func.programbios)(ha, ha->flash_data + IPS_BIOS_HEADER,
- ha->flash_datasize - IPS_BIOS_HEADER, 0 )) {
- DEBUG_VAR(1, "(%s%d) flash bios failed - unable to flash",
- ips_name, ha->host_num);
- goto error;
- }else if ((*ha->func.verifybios)(ha, ha->flash_data + IPS_BIOS_HEADER,
- ha->flash_datasize - IPS_BIOS_HEADER, 0 )) {
- DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash",
- ips_name, ha->host_num);
- goto error;
- }
- ips_free_flash_copperhead(ha);
- return IPS_SUCCESS_IMM;
- }else if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
- pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS){
- if(!ha->func.erasebios)
- goto error;
- if((*ha->func.erasebios)(ha)){
- DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
- ips_name, ha->host_num);
- goto error;
- }
- return IPS_SUCCESS_IMM;
- }
-error:
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- ips_free_flash_copperhead(ha);
- return IPS_FAILURE;
+ips_flash_bios(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
+{
+
+ if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
+ pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS) {
+ if ((!ha->func.programbios) || (!ha->func.erasebios) ||
+ (!ha->func.verifybios))
+ goto error;
+ if ((*ha->func.erasebios) (ha)) {
+ DEBUG_VAR(1,
+ "(%s%d) flash bios failed - unable to erase flash",
+ ips_name, ha->host_num);
+ goto error;
+ } else
+ if ((*ha->func.programbios) (ha,
+ ha->flash_data +
+ IPS_BIOS_HEADER,
+ ha->flash_datasize -
+ IPS_BIOS_HEADER, 0)) {
+ DEBUG_VAR(1,
+ "(%s%d) flash bios failed - unable to flash",
+ ips_name, ha->host_num);
+ goto error;
+ } else
+ if ((*ha->func.verifybios) (ha,
+ ha->flash_data +
+ IPS_BIOS_HEADER,
+ ha->flash_datasize -
+ IPS_BIOS_HEADER, 0)) {
+ DEBUG_VAR(1,
+ "(%s%d) flash bios failed - unable to verify flash",
+ ips_name, ha->host_num);
+ goto error;
+ }
+ ips_free_flash_copperhead(ha);
+ return IPS_SUCCESS_IMM;
+ } else if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
+ pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
+ if (!ha->func.erasebios)
+ goto error;
+ if ((*ha->func.erasebios) (ha)) {
+ DEBUG_VAR(1,
+ "(%s%d) flash bios failed - unable to erase flash",
+ ips_name, ha->host_num);
+ goto error;
+ }
+ return IPS_SUCCESS_IMM;
+ }
+ error:
+ pt->BasicStatus = 0x0B;
+ pt->ExtendedStatus = 0x00;
+ ips_free_flash_copperhead(ha);
+ return IPS_FAILURE;
}
/****************************************************************************/
@@ -1821,38 +1881,37 @@ error:
/* Fill in a single scb sg_list element from an address */
/* return a -1 if a breakup occurred */
/****************************************************************************/
-static inline int ips_fill_scb_sg_single(ips_ha_t *ha, dma_addr_t busaddr,
- ips_scb_t *scb, int indx, unsigned int e_len)
+static inline int
+ips_fill_scb_sg_single(ips_ha_t * ha, dma_addr_t busaddr,
+ ips_scb_t * scb, int indx, unsigned int e_len)
{
- int ret_val = 0;
-
- if ( (scb->data_len + e_len) > ha->max_xfer) {
- e_len = ha->max_xfer - scb->data_len;
- scb->breakup = indx;
- ++scb->sg_break;
- ret_val = -1;
- } else {
- scb->breakup = 0;
- scb->sg_break = 0;
- }
- if (IPS_USE_ENH_SGLIST(ha)) {
- scb->sg_list.enh_list[indx].address_lo =
- cpu_to_le32(pci_dma_lo32(busaddr));
- scb->sg_list.enh_list[indx].address_hi =
- cpu_to_le32(pci_dma_hi32(busaddr));
- scb->sg_list.enh_list[indx].length =
- cpu_to_le32(e_len);
- } else {
- scb->sg_list.std_list[indx].address =
- cpu_to_le32(pci_dma_lo32(busaddr));
- scb->sg_list.std_list[indx].length =
- cpu_to_le32(e_len);
- }
-
- ++scb->sg_len;
- scb->data_len += e_len;
- return ret_val;
+ int ret_val = 0;
+
+ if ((scb->data_len + e_len) > ha->max_xfer) {
+ e_len = ha->max_xfer - scb->data_len;
+ scb->breakup = indx;
+ ++scb->sg_break;
+ ret_val = -1;
+ } else {
+ scb->breakup = 0;
+ scb->sg_break = 0;
+ }
+ if (IPS_USE_ENH_SGLIST(ha)) {
+ scb->sg_list.enh_list[indx].address_lo =
+ cpu_to_le32(pci_dma_lo32(busaddr));
+ scb->sg_list.enh_list[indx].address_hi =
+ cpu_to_le32(pci_dma_hi32(busaddr));
+ scb->sg_list.enh_list[indx].length = cpu_to_le32(e_len);
+ } else {
+ scb->sg_list.std_list[indx].address =
+ cpu_to_le32(pci_dma_lo32(busaddr));
+ scb->sg_list.std_list[indx].length = cpu_to_le32(e_len);
+ }
+
+ ++scb->sg_len;
+ scb->data_len += e_len;
+ return ret_val;
}
/****************************************************************************/
@@ -1861,49 +1920,51 @@ static inline int ips_fill_scb_sg_single(ips_ha_t *ha, dma_addr_t busaddr,
/* flashes the firmware of a copperhead adapter */
/****************************************************************************/
static int
-ips_flash_firmware(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){
- IPS_SG_LIST sg_list;
- uint32_t cmd_busaddr;
-
- if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
- pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW ){
- memset(&pt->CoppCP.cmd, 0, sizeof(IPS_HOST_COMMAND));
- pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
- pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
- }else{
- pt->BasicStatus = 0x0B;
- pt->ExtendedStatus = 0x00;
- ips_free_flash_copperhead(ha);
- return IPS_FAILURE;
- }
- /* Save the S/G list pointer so it doesn't get clobbered */
- sg_list.list = scb->sg_list.list;
- cmd_busaddr = scb->scb_busaddr;
- /* copy in the CP */
- memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
- /* FIX stuff that might be wrong */
- scb->sg_list.list = sg_list.list;
- scb->scb_busaddr = cmd_busaddr;
- scb->bus = scb->scsi_cmd->device->channel;
- scb->target_id = scb->scsi_cmd->device->id;
- scb->lun = scb->scsi_cmd->device->lun;
- scb->sg_len = 0;
- scb->data_len = 0;
- scb->flags = 0;
- scb->op_code = 0;
- scb->callback = ipsintr_done;
- scb->timeout = ips_cmd_timeout;
-
- scb->data_len = ha->flash_datasize;
- scb->data_busaddr = pci_map_single(ha->pcidev, ha->flash_data, scb->data_len,
- IPS_DMA_DIR(scb));
- scb->flags |= IPS_SCB_MAP_SINGLE;
- scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr);
- if (pt->TimeOut)
- scb->timeout = pt->TimeOut;
- scb->scsi_cmd->result = DID_OK <<16;
- return IPS_SUCCESS;
+ips_flash_firmware(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
+{
+ IPS_SG_LIST sg_list;
+ uint32_t cmd_busaddr;
+
+ if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
+ pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW) {
+ memset(&pt->CoppCP.cmd, 0, sizeof (IPS_HOST_COMMAND));
+ pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
+ pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
+ } else {
+ pt->BasicStatus = 0x0B;
+ pt->ExtendedStatus = 0x00;
+ ips_free_flash_copperhead(ha);
+ return IPS_FAILURE;
+ }
+ /* Save the S/G list pointer so it doesn't get clobbered */
+ sg_list.list = scb->sg_list.list;
+ cmd_busaddr = scb->scb_busaddr;
+ /* copy in the CP */
+ memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
+ /* FIX stuff that might be wrong */
+ scb->sg_list.list = sg_list.list;
+ scb->scb_busaddr = cmd_busaddr;
+ scb->bus = scb->scsi_cmd->device->channel;
+ scb->target_id = scb->scsi_cmd->device->id;
+ scb->lun = scb->scsi_cmd->device->lun;
+ scb->sg_len = 0;
+ scb->data_len = 0;
+ scb->flags = 0;
+ scb->op_code = 0;
+ scb->callback = ipsintr_done;
+ scb->timeout = ips_cmd_timeout;
+
+ scb->data_len = ha->flash_datasize;
+ scb->data_busaddr =
+ pci_map_single(ha->pcidev, ha->flash_data, scb->data_len,
+ IPS_DMA_DIR(scb));
+ scb->flags |= IPS_SCB_MAP_SINGLE;
+ scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr);
+ if (pt->TimeOut)
+ scb->timeout = pt->TimeOut;
+ scb->scsi_cmd->result = DID_OK << 16;
+ return IPS_SUCCESS;
}
/****************************************************************************/
@@ -1912,12 +1973,14 @@ ips_flash_firmware(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){
/* release the memory resources used to hold the flash image */
/****************************************************************************/
static void
-ips_free_flash_copperhead(ips_ha_t *ha){
- if(ha->flash_data == ips_FlashData)
- test_and_clear_bit(0, &ips_FlashDataInUse);
- else if(ha->flash_data)
- free_pages((unsigned long)ha->flash_data, ha->flash_order);
- ha->flash_data = NULL;
+ips_free_flash_copperhead(ips_ha_t * ha)
+{
+ if (ha->flash_data == ips_FlashData)
+ test_and_clear_bit(0, &ips_FlashDataInUse);
+ else if (ha->flash_data)
+ pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data,
+ ha->flash_busaddr);
+ ha->flash_data = NULL;
}
/****************************************************************************/
@@ -1930,83 +1993,82 @@ ips_free_flash_copperhead(ips_ha_t *ha){
/* */
/****************************************************************************/
static int
-ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
- IPS_SG_LIST sg_list;
- uint32_t cmd_busaddr;
-
- METHOD_TRACE("ips_usrcmd", 1);
-
- if ((!scb) || (!pt) || (!ha))
- return (0);
-
- /* Save the S/G list pointer so it doesn't get clobbered */
- sg_list.list = scb->sg_list.list;
- cmd_busaddr = scb->scb_busaddr;
- /* copy in the CP */
- memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
- memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE));
-
- /* FIX stuff that might be wrong */
- scb->sg_list.list = sg_list.list;
- scb->scb_busaddr = cmd_busaddr;
- scb->bus = scb->scsi_cmd->device->channel;
- scb->target_id = scb->scsi_cmd->device->id;
- scb->lun = scb->scsi_cmd->device->lun;
- scb->sg_len = 0;
- scb->data_len = 0;
- scb->flags = 0;
- scb->op_code = 0;
- scb->callback = ipsintr_done;
- scb->timeout = ips_cmd_timeout;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
-
- /* we don't support DCDB/READ/WRITE Scatter Gather */
- if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
- (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
- (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
- return (0);
-
- if (pt->CmdBSize) {
- scb->data_len = pt->CmdBSize;
- scb->data_busaddr = pci_map_single(ha->pcidev,
- ha->ioctl_data +
- sizeof(ips_passthru_t),
- pt->CmdBSize,
- IPS_DMA_DIR(scb));
- scb->flags |= IPS_SCB_MAP_SINGLE;
- } else {
- scb->data_busaddr = 0L;
- }
-
- if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
- scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
- (unsigned long)&scb->dcdb -
- (unsigned long)scb);
-
- if (pt->CmdBSize) {
- if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
- scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
- else
- scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
- }
-
- /* set timeouts */
- if (pt->TimeOut) {
- scb->timeout = pt->TimeOut;
-
- if (pt->TimeOut <= 10)
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
- else if (pt->TimeOut <= 60)
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
- else
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
- }
-
- /* assume success */
- scb->scsi_cmd->result = DID_OK << 16;
-
- /* success */
- return (1);
+ips_usrcmd(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
+{
+ IPS_SG_LIST sg_list;
+ uint32_t cmd_busaddr;
+
+ METHOD_TRACE("ips_usrcmd", 1);
+
+ if ((!scb) || (!pt) || (!ha))
+ return (0);
+
+ /* Save the S/G list pointer so it doesn't get clobbered */
+ sg_list.list = scb->sg_list.list;
+ cmd_busaddr = scb->scb_busaddr;
+ /* copy in the CP */
+ memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
+ memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof (IPS_DCDB_TABLE));
+
+ /* FIX stuff that might be wrong */
+ scb->sg_list.list = sg_list.list;
+ scb->scb_busaddr = cmd_busaddr;
+ scb->bus = scb->scsi_cmd->device->channel;
+ scb->target_id = scb->scsi_cmd->device->id;
+ scb->lun = scb->scsi_cmd->device->lun;
+ scb->sg_len = 0;
+ scb->data_len = 0;
+ scb->flags = 0;
+ scb->op_code = 0;
+ scb->callback = ipsintr_done;
+ scb->timeout = ips_cmd_timeout;
+ scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
+
+ /* we don't support DCDB/READ/WRITE Scatter Gather */
+ if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
+ (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
+ (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
+ return (0);
+
+ if (pt->CmdBSize) {
+ scb->data_len = pt->CmdBSize;
+ scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t);
+ } else {
+ scb->data_busaddr = 0L;
+ }
+
+ if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
+ scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
+ (unsigned long) &scb->
+ dcdb -
+ (unsigned long) scb);
+
+ if (pt->CmdBSize) {
+ if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
+ scb->dcdb.buffer_pointer =
+ cpu_to_le32(scb->data_busaddr);
+ else
+ scb->cmd.basic_io.sg_addr =
+ cpu_to_le32(scb->data_busaddr);
+ }
+
+ /* set timeouts */
+ if (pt->TimeOut) {
+ scb->timeout = pt->TimeOut;
+
+ if (pt->TimeOut <= 10)
+ scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
+ else if (pt->TimeOut <= 60)
+ scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
+ else
+ scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
+ }
+
+ /* assume success */
+ scb->scsi_cmd->result = DID_OK << 16;
+
+ /* success */
+ return (1);
}
/****************************************************************************/
@@ -2019,33 +2081,34 @@ ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
/* */
/****************************************************************************/
static void
-ips_cleanup_passthru(ips_ha_t *ha, ips_scb_t *scb) {
- ips_passthru_t *pt;
+ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb)
+{
+ ips_passthru_t *pt;
- METHOD_TRACE("ips_cleanup_passthru", 1);
+ METHOD_TRACE("ips_cleanup_passthru", 1);
- if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) {
- DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
- ips_name, ha->host_num);
+ if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) {
+ DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
+ ips_name, ha->host_num);
- return ;
- }
- pt = (ips_passthru_t *) ha->ioctl_data;
+ return;
+ }
+ pt = (ips_passthru_t *) ha->ioctl_data;
- /* Copy data back to the user */
- if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) /* Copy DCDB Back to Caller's Area */
- memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof(IPS_DCDB_TABLE));
-
- pt->BasicStatus = scb->basic_status;
- pt->ExtendedStatus = scb->extended_status;
- pt->AdapterType = ha->ad_type;
+ /* Copy data back to the user */
+ if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB) /* Copy DCDB Back to Caller's Area */
+ memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof (IPS_DCDB_TABLE));
- if(ha->device_id == IPS_DEVICEID_COPPERHEAD &&
- (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD ||
- scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
- ips_free_flash_copperhead(ha);
+ pt->BasicStatus = scb->basic_status;
+ pt->ExtendedStatus = scb->extended_status;
+ pt->AdapterType = ha->ad_type;
- ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize);
+ if (ha->device_id == IPS_DEVICEID_COPPERHEAD &&
+ (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD ||
+ scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
+ ips_free_flash_copperhead(ha);
+
+ ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize);
}
/****************************************************************************/
@@ -2058,78 +2121,88 @@ ips_cleanup_passthru(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static int
-ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) {
- IPS_INFOSTR info;
-
- METHOD_TRACE("ips_host_info", 1);
-
- info.buffer = ptr;
- info.length = len;
- info.offset = offset;
- info.pos = 0;
- info.localpos = 0;
-
- copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
-
- if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
- (le16_to_cpu(ha->nvram->adapter_type) != 0))
- copy_info(&info, "\tController Type : %s\n", ips_adapter_name[ha->ad_type-1]);
- else
- copy_info(&info, "\tController Type : Unknown\n");
-
- if (ha->io_addr)
- copy_info(&info, "\tIO region : 0x%lx (%d bytes)\n",
- ha->io_addr, ha->io_len);
-
- if (ha->mem_addr) {
- copy_info(&info, "\tMemory region : 0x%lx (%d bytes)\n",
- ha->mem_addr, ha->mem_len);
- copy_info(&info, "\tShared memory address : 0x%lx\n", ha->mem_ptr);
- }
-
- copy_info(&info, "\tIRQ number : %d\n", ha->irq);
-
- if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG)
- copy_info(&info, "\tBIOS Version : %c%c%c%c%c%c%c%c\n",
- ha->nvram->bios_high[0], ha->nvram->bios_high[1],
- ha->nvram->bios_high[2], ha->nvram->bios_high[3],
- ha->nvram->bios_low[0], ha->nvram->bios_low[1],
- ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
-
- copy_info(&info, "\tFirmware Version : %c%c%c%c%c%c%c%c\n",
- ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
- ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
- ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
- ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
-
- copy_info(&info, "\tBoot Block Version : %c%c%c%c%c%c%c%c\n",
- ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
- ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
- ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
- ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
-
- copy_info(&info, "\tDriver Version : %s%s\n",
- IPS_VERSION_HIGH, IPS_VERSION_LOW);
-
- copy_info(&info, "\tDriver Build : %d\n",
- IPS_BUILD_IDENT);
-
- copy_info(&info, "\tMax Physical Devices : %d\n",
- ha->enq->ucMaxPhysicalDevices);
- copy_info(&info, "\tMax Active Commands : %d\n",
- ha->max_cmds);
- copy_info(&info, "\tCurrent Queued Commands : %d\n",
- ha->scb_waitlist.count);
- copy_info(&info, "\tCurrent Active Commands : %d\n",
- ha->scb_activelist.count - ha->num_ioctl);
- copy_info(&info, "\tCurrent Queued PT Commands : %d\n",
- ha->copp_waitlist.count);
- copy_info(&info, "\tCurrent Active PT Commands : %d\n",
- ha->num_ioctl);
-
- copy_info(&info, "\n");
-
- return (info.localpos);
+ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len)
+{
+ IPS_INFOSTR info;
+
+ METHOD_TRACE("ips_host_info", 1);
+
+ info.buffer = ptr;
+ info.length = len;
+ info.offset = offset;
+ info.pos = 0;
+ info.localpos = 0;
+
+ copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
+
+ if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
+ (le16_to_cpu(ha->nvram->adapter_type) != 0))
+ copy_info(&info, "\tController Type : %s\n",
+ ips_adapter_name[ha->ad_type - 1]);
+ else
+ copy_info(&info,
+ "\tController Type : Unknown\n");
+
+ if (ha->io_addr)
+ copy_info(&info,
+ "\tIO region : 0x%lx (%d bytes)\n",
+ ha->io_addr, ha->io_len);
+
+ if (ha->mem_addr) {
+ copy_info(&info,
+ "\tMemory region : 0x%lx (%d bytes)\n",
+ ha->mem_addr, ha->mem_len);
+ copy_info(&info,
+ "\tShared memory address : 0x%lx\n",
+ ha->mem_ptr);
+ }
+
+ copy_info(&info, "\tIRQ number : %d\n", ha->irq);
+
+ if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG)
+ copy_info(&info,
+ "\tBIOS Version : %c%c%c%c%c%c%c%c\n",
+ ha->nvram->bios_high[0], ha->nvram->bios_high[1],
+ ha->nvram->bios_high[2], ha->nvram->bios_high[3],
+ ha->nvram->bios_low[0], ha->nvram->bios_low[1],
+ ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
+
+ copy_info(&info,
+ "\tFirmware Version : %c%c%c%c%c%c%c%c\n",
+ ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
+ ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
+ ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
+ ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
+
+ copy_info(&info,
+ "\tBoot Block Version : %c%c%c%c%c%c%c%c\n",
+ ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
+ ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
+ ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
+ ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
+
+ copy_info(&info, "\tDriver Version : %s%s\n",
+ IPS_VERSION_HIGH, IPS_VERSION_LOW);
+
+ copy_info(&info, "\tDriver Build : %d\n",
+ IPS_BUILD_IDENT);
+
+ copy_info(&info, "\tMax Physical Devices : %d\n",
+ ha->enq->ucMaxPhysicalDevices);
+ copy_info(&info, "\tMax Active Commands : %d\n",
+ ha->max_cmds);
+ copy_info(&info, "\tCurrent Queued Commands : %d\n",
+ ha->scb_waitlist.count);
+ copy_info(&info, "\tCurrent Active Commands : %d\n",
+ ha->scb_activelist.count - ha->num_ioctl);
+ copy_info(&info, "\tCurrent Queued PT Commands : %d\n",
+ ha->copp_waitlist.count);
+ copy_info(&info, "\tCurrent Active PT Commands : %d\n",
+ ha->num_ioctl);
+
+ copy_info(&info, "\n");
+
+ return (info.localpos);
}
/****************************************************************************/
@@ -2142,28 +2215,29 @@ ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) {
/* */
/****************************************************************************/
static void
-copy_mem_info(IPS_INFOSTR *info, char *data, int len) {
- METHOD_TRACE("copy_mem_info", 1);
-
- if (info->pos + len < info->offset) {
- info->pos += len;
- return;
- }
-
- if (info->pos < info->offset) {
- data += (info->offset - info->pos);
- len -= (info->offset - info->pos);
- info->pos += (info->offset - info->pos);
- }
-
- if (info->localpos + len > info->length)
- len = info->length - info->localpos;
-
- if (len > 0) {
- memcpy(info->buffer + info->localpos, data, len);
- info->pos += len;
- info->localpos += len;
- }
+copy_mem_info(IPS_INFOSTR * info, char *data, int len)
+{
+ METHOD_TRACE("copy_mem_info", 1);
+
+ if (info->pos + len < info->offset) {
+ info->pos += len;
+ return;
+ }
+
+ if (info->pos < info->offset) {
+ data += (info->offset - info->pos);
+ len -= (info->offset - info->pos);
+ info->pos += (info->offset - info->pos);
+ }
+
+ if (info->localpos + len > info->length)
+ len = info->length - info->localpos;
+
+ if (len > 0) {
+ memcpy(info->buffer + info->localpos, data, len);
+ info->pos += len;
+ info->localpos += len;
+ }
}
/****************************************************************************/
@@ -2176,20 +2250,21 @@ copy_mem_info(IPS_INFOSTR *info, char *data, int len) {
/* */
/****************************************************************************/
static int
-copy_info(IPS_INFOSTR *info, char *fmt, ...) {
- va_list args;
- char buf[128];
- int len;
+copy_info(IPS_INFOSTR * info, char *fmt, ...)
+{
+ va_list args;
+ char buf[128];
+ int len;
- METHOD_TRACE("copy_info", 1);
+ METHOD_TRACE("copy_info", 1);
- va_start(args, fmt);
- len = vsprintf(buf, fmt, args);
- va_end(args);
+ va_start(args, fmt);
+ len = vsprintf(buf, fmt, args);
+ va_end(args);
- copy_mem_info(info, buf, len);
+ copy_mem_info(info, buf, len);
- return (len);
+ return (len);
}
/****************************************************************************/
@@ -2202,71 +2277,73 @@ copy_info(IPS_INFOSTR *info, char *fmt, ...) {
/* */
/****************************************************************************/
static void
-ips_identify_controller(ips_ha_t *ha) {
- METHOD_TRACE("ips_identify_controller", 1);
-
- switch (ha->device_id) {
- case IPS_DEVICEID_COPPERHEAD:
- if (ha->revision_id <= IPS_REVID_SERVERAID) {
- ha->ad_type = IPS_ADTYPE_SERVERAID;
- } else if (ha->revision_id == IPS_REVID_SERVERAID2) {
- ha->ad_type = IPS_ADTYPE_SERVERAID2;
- } else if (ha->revision_id == IPS_REVID_NAVAJO) {
- ha->ad_type = IPS_ADTYPE_NAVAJO;
- } else if ((ha->revision_id == IPS_REVID_SERVERAID2) && (ha->slot_num == 0)) {
- ha->ad_type = IPS_ADTYPE_KIOWA;
- } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) &&
- (ha->revision_id <= IPS_REVID_CLARINETP3)) {
- if (ha->enq->ucMaxPhysicalDevices == 15)
- ha->ad_type = IPS_ADTYPE_SERVERAID3L;
- else
- ha->ad_type = IPS_ADTYPE_SERVERAID3;
- } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) &&
- (ha->revision_id <= IPS_REVID_TROMBONE64)) {
- ha->ad_type = IPS_ADTYPE_SERVERAID4H;
- }
- break;
-
- case IPS_DEVICEID_MORPHEUS:
- switch (ha->subdevice_id) {
- case IPS_SUBDEVICEID_4L:
- ha->ad_type = IPS_ADTYPE_SERVERAID4L;
- break;
-
- case IPS_SUBDEVICEID_4M:
- ha->ad_type = IPS_ADTYPE_SERVERAID4M;
- break;
-
- case IPS_SUBDEVICEID_4MX:
- ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
- break;
-
- case IPS_SUBDEVICEID_4LX:
- ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
- break;
-
- case IPS_SUBDEVICEID_5I2:
- ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
- break;
-
- case IPS_SUBDEVICEID_5I1:
- ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
- break;
- }
-
- break;
-
- case IPS_DEVICEID_MARCO:
- switch (ha->subdevice_id) {
- case IPS_SUBDEVICEID_6M:
- ha->ad_type = IPS_ADTYPE_SERVERAID6M;
- break;
- case IPS_SUBDEVICEID_6I:
- ha->ad_type = IPS_ADTYPE_SERVERAID6I;
- break;
- }
- break;
- }
+ips_identify_controller(ips_ha_t * ha)
+{
+ METHOD_TRACE("ips_identify_controller", 1);
+
+ switch (ha->device_id) {
+ case IPS_DEVICEID_COPPERHEAD:
+ if (ha->revision_id <= IPS_REVID_SERVERAID) {
+ ha->ad_type = IPS_ADTYPE_SERVERAID;
+ } else if (ha->revision_id == IPS_REVID_SERVERAID2) {
+ ha->ad_type = IPS_ADTYPE_SERVERAID2;
+ } else if (ha->revision_id == IPS_REVID_NAVAJO) {
+ ha->ad_type = IPS_ADTYPE_NAVAJO;
+ } else if ((ha->revision_id == IPS_REVID_SERVERAID2)
+ && (ha->slot_num == 0)) {
+ ha->ad_type = IPS_ADTYPE_KIOWA;
+ } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) &&
+ (ha->revision_id <= IPS_REVID_CLARINETP3)) {
+ if (ha->enq->ucMaxPhysicalDevices == 15)
+ ha->ad_type = IPS_ADTYPE_SERVERAID3L;
+ else
+ ha->ad_type = IPS_ADTYPE_SERVERAID3;
+ } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) &&
+ (ha->revision_id <= IPS_REVID_TROMBONE64)) {
+ ha->ad_type = IPS_ADTYPE_SERVERAID4H;
+ }
+ break;
+
+ case IPS_DEVICEID_MORPHEUS:
+ switch (ha->subdevice_id) {
+ case IPS_SUBDEVICEID_4L:
+ ha->ad_type = IPS_ADTYPE_SERVERAID4L;
+ break;
+
+ case IPS_SUBDEVICEID_4M:
+ ha->ad_type = IPS_ADTYPE_SERVERAID4M;
+ break;
+
+ case IPS_SUBDEVICEID_4MX:
+ ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
+ break;
+
+ case IPS_SUBDEVICEID_4LX:
+ ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
+ break;
+
+ case IPS_SUBDEVICEID_5I2:
+ ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
+ break;
+
+ case IPS_SUBDEVICEID_5I1:
+ ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
+ break;
+ }
+
+ break;
+
+ case IPS_DEVICEID_MARCO:
+ switch (ha->subdevice_id) {
+ case IPS_SUBDEVICEID_6M:
+ ha->ad_type = IPS_ADTYPE_SERVERAID6M;
+ break;
+ case IPS_SUBDEVICEID_6I:
+ ha->ad_type = IPS_ADTYPE_SERVERAID6I;
+ break;
+ }
+ break;
+ }
}
/****************************************************************************/
@@ -2279,159 +2356,155 @@ ips_identify_controller(ips_ha_t *ha) {
/* */
/****************************************************************************/
static void
-ips_get_bios_version(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- int ret;
- uint8_t major;
- uint8_t minor;
- uint8_t subminor;
- uint8_t *buffer;
- char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+ips_get_bios_version(ips_ha_t * ha, int intr)
+{
+ ips_scb_t *scb;
+ int ret;
+ uint8_t major;
+ uint8_t minor;
+ uint8_t subminor;
+ uint8_t *buffer;
+ char hexDigits[] =
+ { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
+ 'D', 'E', 'F' };
+
+ METHOD_TRACE("ips_get_bios_version", 1);
+
+ major = 0;
+ minor = 0;
+
+ strncpy(ha->bios_version, " ?", 8);
+
+ if (ha->device_id == IPS_DEVICEID_COPPERHEAD) {
+ if (IPS_USE_MEMIO(ha)) {
+ /* Memory Mapped I/O */
+
+ /* test 1st byte */
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
+ return;
+
+ writel(1, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
+ return;
+
+ /* Get Major version */
+ writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ major = readb(ha->mem_ptr + IPS_REG_FLDP);
+
+ /* Get Minor version */
+ writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+ minor = readb(ha->mem_ptr + IPS_REG_FLDP);
+
+ /* Get SubMinor version */
+ writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+ subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
+
+ } else {
+ /* Programmed I/O */
+
+ /* test 1st byte */
+ outl(0, ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
+ return;
+
+ outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
+ return;
+
+ /* Get Major version */
+ outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ major = inb(ha->io_addr + IPS_REG_FLDP);
+
+ /* Get Minor version */
+ outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ minor = inb(ha->io_addr + IPS_REG_FLDP);
+
+ /* Get SubMinor version */
+ outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ subminor = inb(ha->io_addr + IPS_REG_FLDP);
+
+ }
+ } else {
+ /* Morpheus Family - Send Command to the card */
+
+ buffer = ha->ioctl_data;
- METHOD_TRACE("ips_get_bios_version", 1);
+ memset(buffer, 0, 0x1000);
- major = 0;
- minor = 0;
+ scb = &ha->scbs[ha->max_cmds - 1];
- strncpy(ha->bios_version, " ?", 8);
+ ips_init_scb(ha, scb);
- if (ha->device_id == IPS_DEVICEID_COPPERHEAD) {
- if (IPS_USE_MEMIO(ha)) {
- /* Memory Mapped I/O */
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_RW_BIOSFW;
- /* test 1st byte */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
+ scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
+ scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.flashfw.type = 1;
+ scb->cmd.flashfw.direction = 0;
+ scb->cmd.flashfw.count = cpu_to_le32(0x800);
+ scb->cmd.flashfw.total_packets = 1;
+ scb->cmd.flashfw.packet_num = 0;
+ scb->data_len = 0x1000;
+ scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr;
- if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
- return;
-
- writel(1, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
- return;
+ /* issue the command */
+ if (((ret =
+ ips_send_wait(ha, scb, ips_cmd_timeout,
+ intr)) == IPS_FAILURE)
+ || (ret == IPS_SUCCESS_IMM)
+ || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
+ /* Error occurred */
- /* Get Major version */
- writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- major = readb(ha->mem_ptr + IPS_REG_FLDP);
-
- /* Get Minor version */
- writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- minor = readb(ha->mem_ptr + IPS_REG_FLDP);
-
- /* Get SubMinor version */
- writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
-
- } else {
- /* Programmed I/O */
-
- /* test 1st byte */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
- return ;
-
- outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
- return ;
-
- /* Get Major version */
- outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- major = inb(ha->io_addr + IPS_REG_FLDP);
-
- /* Get Minor version */
- outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- minor = inb(ha->io_addr + IPS_REG_FLDP);
-
- /* Get SubMinor version */
- outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- subminor = inb(ha->io_addr + IPS_REG_FLDP);
-
- }
- } else {
- /* Morpheus Family - Send Command to the card */
-
- buffer = kmalloc(0x1000, IPS_ATOMIC_GFP);
- if (!buffer)
- return;
-
- memset(buffer, 0, 0x1000);
-
- scb = &ha->scbs[ha->max_cmds-1];
-
- ips_init_scb(ha, scb);
-
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_RW_BIOSFW;
-
- scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
- scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.flashfw.type = 1;
- scb->cmd.flashfw.direction = 0;
- scb->cmd.flashfw.count = cpu_to_le32(0x800);
- scb->cmd.flashfw.total_packets = 1;
- scb->cmd.flashfw.packet_num = 0;
- scb->data_len = 0x1000;
- scb->data_busaddr = pci_map_single(ha->pcidev, buffer, scb->data_len,
- IPS_DMA_DIR(scb));
- scb->cmd.flashfw.buffer_addr = scb->data_busaddr;
- scb->flags |= IPS_SCB_MAP_SINGLE;
-
- /* issue the command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
- /* Error occurred */
- kfree(buffer);
-
- return;
- }
-
- if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
- major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */
- minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */
- subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */
- } else {
- kfree(buffer);
- return;
- }
-
- kfree(buffer);
- }
-
- ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
- ha->bios_version[1] = '.';
- ha->bios_version[2] = hexDigits[major & 0x0F];
- ha->bios_version[3] = hexDigits[subminor];
- ha->bios_version[4] = '.';
- ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4];
- ha->bios_version[6] = hexDigits[minor & 0x0F];
- ha->bios_version[7] = 0;
+ return;
+ }
+
+ if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
+ major = buffer[0x1ff + 0xC0]; /* Offset 0x1ff after the header (0xc0) */
+ minor = buffer[0x1fe + 0xC0]; /* Offset 0x1fe after the header (0xc0) */
+ subminor = buffer[0x1fd + 0xC0]; /* Offset 0x1fd after the header (0xc0) */
+ } else {
+ return;
+ }
+ }
+
+ ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
+ ha->bios_version[1] = '.';
+ ha->bios_version[2] = hexDigits[major & 0x0F];
+ ha->bios_version[3] = hexDigits[subminor];
+ ha->bios_version[4] = '.';
+ ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4];
+ ha->bios_version[6] = hexDigits[minor & 0x0F];
+ ha->bios_version[7] = 0;
}
/****************************************************************************/
@@ -2446,125 +2519,130 @@ ips_get_bios_version(ips_ha_t *ha, int intr) {
/* */
/****************************************************************************/
static int
-ips_hainit(ips_ha_t *ha) {
- int i;
- struct timeval tv;
+ips_hainit(ips_ha_t * ha)
+{
+ int i;
+ struct timeval tv;
- METHOD_TRACE("ips_hainit", 1);
+ METHOD_TRACE("ips_hainit", 1);
- if (!ha)
- return (0);
+ if (!ha)
+ return (0);
- if (ha->func.statinit)
- (*ha->func.statinit)(ha);
+ if (ha->func.statinit)
+ (*ha->func.statinit) (ha);
- if (ha->func.enableint)
- (*ha->func.enableint)(ha);
+ if (ha->func.enableint)
+ (*ha->func.enableint) (ha);
- /* Send FFDC */
- ha->reset_count = 1;
- do_gettimeofday(&tv);
- ha->last_ffdc = tv.tv_sec;
- ips_ffdc_reset(ha, IPS_INTR_IORL);
+ /* Send FFDC */
+ ha->reset_count = 1;
+ do_gettimeofday(&tv);
+ ha->last_ffdc = tv.tv_sec;
+ ips_ffdc_reset(ha, IPS_INTR_IORL);
- if (!ips_read_config(ha, IPS_INTR_IORL)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to read config from controller.\n");
+ if (!ips_read_config(ha, IPS_INTR_IORL)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "unable to read config from controller.\n");
- return (0);
- } /* end if */
+ return (0);
+ }
+ /* end if */
+ if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "unable to read controller status.\n");
- if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to read controller status.\n");
+ return (0);
+ }
- return (0);
- }
+ /* Identify this controller */
+ ips_identify_controller(ha);
- /* Identify this controller */
- ips_identify_controller(ha);
+ if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "unable to read subsystem parameters.\n");
- if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to read subsystem parameters.\n");
+ return (0);
+ }
- return (0);
- }
+ /* write nvram user page 5 */
+ if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "unable to write driver info to controller.\n");
- /* write nvram user page 5 */
- if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to write driver info to controller.\n");
+ return (0);
+ }
- return (0);
- }
+ /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */
+ if ((ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1))
+ ips_clear_adapter(ha, IPS_INTR_IORL);
- /* If there are Logical Drives and a Reset Occurred, then an EraseStripeLock is Needed */
- if ( (ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1) )
- ips_clear_adapter(ha, IPS_INTR_IORL);
-
- /* set limits on SID, LUN, BUS */
- ha->ntargets = IPS_MAX_TARGETS + 1;
- ha->nlun = 1;
- ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
-
- switch (ha->conf->logical_drive[0].ucStripeSize) {
- case 4:
- ha->max_xfer = 0x10000;
- break;
-
- case 5:
- ha->max_xfer = 0x20000;
- break;
-
- case 6:
- ha->max_xfer = 0x40000;
- break;
-
- case 7:
- default:
- ha->max_xfer = 0x80000;
- break;
- }
-
- /* setup max concurrent commands */
- if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
- /* Use the new method */
- ha->max_cmds = ha->enq->ucConcurrentCmdCount;
- } else {
- /* use the old method */
- switch (ha->conf->logical_drive[0].ucStripeSize) {
- case 4:
- ha->max_cmds = 32;
- break;
-
- case 5:
- ha->max_cmds = 16;
- break;
-
- case 6:
- ha->max_cmds = 8;
- break;
-
- case 7:
- default:
- ha->max_cmds = 4;
- break;
- }
- }
-
- /* Limit the Active Commands on a Lite Adapter */
- if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) ||
- (ha->ad_type == IPS_ADTYPE_SERVERAID4L) ||
- (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) {
- if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds))
- ha->max_cmds = MaxLiteCmds;
- }
-
- /* set controller IDs */
- ha->ha_id[0] = IPS_ADAPTER_ID;
- for (i = 1; i < ha->nbus; i++) {
- ha->ha_id[i] = ha->conf->init_id[i-1] & 0x1f;
- ha->dcdb_active[i-1] = 0;
- }
-
- return (1);
+ /* set limits on SID, LUN, BUS */
+ ha->ntargets = IPS_MAX_TARGETS + 1;
+ ha->nlun = 1;
+ ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
+
+ switch (ha->conf->logical_drive[0].ucStripeSize) {
+ case 4:
+ ha->max_xfer = 0x10000;
+ break;
+
+ case 5:
+ ha->max_xfer = 0x20000;
+ break;
+
+ case 6:
+ ha->max_xfer = 0x40000;
+ break;
+
+ case 7:
+ default:
+ ha->max_xfer = 0x80000;
+ break;
+ }
+
+ /* setup max concurrent commands */
+ if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
+ /* Use the new method */
+ ha->max_cmds = ha->enq->ucConcurrentCmdCount;
+ } else {
+ /* use the old method */
+ switch (ha->conf->logical_drive[0].ucStripeSize) {
+ case 4:
+ ha->max_cmds = 32;
+ break;
+
+ case 5:
+ ha->max_cmds = 16;
+ break;
+
+ case 6:
+ ha->max_cmds = 8;
+ break;
+
+ case 7:
+ default:
+ ha->max_cmds = 4;
+ break;
+ }
+ }
+
+ /* Limit the Active Commands on a Lite Adapter */
+ if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) ||
+ (ha->ad_type == IPS_ADTYPE_SERVERAID4L) ||
+ (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) {
+ if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds))
+ ha->max_cmds = MaxLiteCmds;
+ }
+
+ /* set controller IDs */
+ ha->ha_id[0] = IPS_ADAPTER_ID;
+ for (i = 1; i < ha->nbus; i++) {
+ ha->ha_id[i] = ha->conf->init_id[i - 1] & 0x1f;
+ ha->dcdb_active[i - 1] = 0;
+ }
+
+ return (1);
}
/****************************************************************************/
@@ -2577,227 +2655,240 @@ ips_hainit(ips_ha_t *ha) {
/* */
/****************************************************************************/
static void
-ips_next(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- Scsi_Cmnd *SC;
- Scsi_Cmnd *p;
- Scsi_Cmnd *q;
- ips_copp_wait_item_t *item;
- int ret;
- unsigned long cpu_flags = 0;
- struct Scsi_Host *host;
- METHOD_TRACE("ips_next", 1);
-
- if (!ha)
- return ;
- host = ips_sh[ha->host_num];
- /*
- * Block access to the queue function so
- * this command won't time out
- */
- if(intr == IPS_INTR_ON)
- IPS_LOCK_SAVE(host->host_lock, cpu_flags);
-
- if ((ha->subsys->param[3] & 0x300000) && ( ha->scb_activelist.count == 0 )) {
- struct timeval tv;
-
- do_gettimeofday(&tv);
-
- if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
- ha->last_ffdc = tv.tv_sec;
- ips_ffdc_time(ha);
- }
- }
-
- /*
- * Send passthru commands
- * These have priority over normal I/O
- * but shouldn't affect performance too much
- * since we limit the number that can be active
- * on the card at any one time
- */
- while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
- (ha->copp_waitlist.head) &&
- (scb = ips_getscb(ha))) {
-
- item = ips_removeq_copp_head(&ha->copp_waitlist);
- ha->num_ioctl++;
- if(intr == IPS_INTR_ON)
- IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
- scb->scsi_cmd = item->scsi_cmd;
- kfree(item);
-
- ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
-
- if(intr == IPS_INTR_ON)
- IPS_LOCK_SAVE(host->host_lock, cpu_flags);
- switch (ret) {
- case IPS_FAILURE:
- if (scb->scsi_cmd) {
- scb->scsi_cmd->result = DID_ERROR << 16;
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- }
-
- ips_freescb(ha, scb);
- break;
- case IPS_SUCCESS_IMM:
- if (scb->scsi_cmd) {
- scb->scsi_cmd->result = DID_OK << 16;
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- }
-
- ips_freescb(ha, scb);
- break;
- default:
- break;
- } /* end case */
-
- if (ret != IPS_SUCCESS) {
- ha->num_ioctl--;
- continue;
- }
-
- ret = ips_send_cmd(ha, scb);
-
- if (ret == IPS_SUCCESS)
- ips_putq_scb_head(&ha->scb_activelist, scb);
- else
- ha->num_ioctl--;
-
- switch(ret) {
- case IPS_FAILURE:
- if (scb->scsi_cmd) {
- scb->scsi_cmd->result = DID_ERROR << 16;
- }
-
- ips_freescb(ha, scb);
- break;
- case IPS_SUCCESS_IMM:
- ips_freescb(ha, scb);
- break;
- default:
- break;
- } /* end case */
-
- }
-
-
- /*
- * Send "Normal" I/O commands
- */
-
- p = ha->scb_waitlist.head;
- while ((p) && (scb = ips_getscb(ha))) {
- if ((p->device->channel > 0) && (ha->dcdb_active[p->device->channel-1] & (1 << p->device->id))) {
- ips_freescb(ha, scb);
- p = (Scsi_Cmnd *) p->host_scribble;
- continue;
- }
-
- q = p;
- SC = ips_removeq_wait(&ha->scb_waitlist, q);
-
- if(intr == IPS_INTR_ON)
- IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */
-
- SC->result = DID_OK;
- SC->host_scribble = NULL;
-
- memset(SC->sense_buffer, 0, sizeof(SC->sense_buffer));
-
- scb->target_id = SC->device->id;
- scb->lun = SC->device->lun;
- scb->bus = SC->device->channel;
- scb->scsi_cmd = SC;
- scb->breakup = 0;
- scb->data_len = 0;
- scb->callback = ipsintr_done;
- scb->timeout = ips_cmd_timeout;
- memset(&scb->cmd, 0, 16);
-
- /* copy in the CDB */
- memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
-
- /* Now handle the data buffer */
- if (SC->use_sg) {
- struct scatterlist *sg;
- int i;
-
- sg = SC->request_buffer;
- scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg,
- scsi_to_pci_dma_dir(SC->sc_data_direction));
- scb->flags |= IPS_SCB_MAP_SG;
- for (i = 0; i < scb->sg_count; i++) {
- if ( ips_fill_scb_sg_single(ha, sg_dma_address(&sg[i]),
- scb, i, sg_dma_len(&sg[i])) < 0)
- break;
- }
- scb->dcdb.transfer_length = scb->data_len;
- } else {
- if (SC->request_bufflen) {
- scb->data_busaddr = pci_map_single(ha->pcidev, SC->request_buffer,
- SC->request_bufflen,
- scsi_to_pci_dma_dir(SC->sc_data_direction));
- scb->flags |= IPS_SCB_MAP_SINGLE;
- ips_fill_scb_sg_single(ha, scb->data_busaddr, scb, 0, SC->request_bufflen);
- scb->dcdb.transfer_length = scb->data_len;
- } else {
- scb->data_busaddr = 0L;
- scb->sg_len = 0;
- scb->data_len = 0;
- scb->dcdb.transfer_length = 0;
- }
-
- }
-
- scb->dcdb.cmd_attribute = ips_command_direction[scb->scsi_cmd->cmnd[0]];
-
- if (!(scb->dcdb.cmd_attribute & 0x3))
- scb->dcdb.transfer_length = 0;
-
- if (scb->data_len >= IPS_MAX_XFER) {
- scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
- scb->dcdb.transfer_length = 0;
- }
- if(intr == IPS_INTR_ON)
- IPS_LOCK_SAVE(host->host_lock, cpu_flags);
-
- ret = ips_send_cmd(ha, scb);
-
- switch(ret) {
- case IPS_SUCCESS:
- ips_putq_scb_head(&ha->scb_activelist, scb);
- break;
- case IPS_FAILURE:
- if (scb->scsi_cmd) {
- scb->scsi_cmd->result = DID_ERROR << 16;
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- }
-
- if (scb->bus)
- ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
-
- ips_freescb(ha, scb);
- break;
- case IPS_SUCCESS_IMM:
- if (scb->scsi_cmd)
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
-
- if (scb->bus)
- ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
-
- ips_freescb(ha, scb);
- break;
- default:
- break;
- } /* end case */
-
- p = (Scsi_Cmnd *) p->host_scribble;
-
- } /* end while */
-
- if(intr == IPS_INTR_ON)
- IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
+ips_next(ips_ha_t * ha, int intr)
+{
+ ips_scb_t *scb;
+ Scsi_Cmnd *SC;
+ Scsi_Cmnd *p;
+ Scsi_Cmnd *q;
+ ips_copp_wait_item_t *item;
+ int ret;
+ unsigned long cpu_flags = 0;
+ struct Scsi_Host *host;
+ METHOD_TRACE("ips_next", 1);
+
+ if (!ha)
+ return;
+ host = ips_sh[ha->host_num];
+ /*
+ * Block access to the queue function so
+ * this command won't time out
+ */
+ if (intr == IPS_INTR_ON)
+ IPS_LOCK_SAVE(host->host_lock, cpu_flags);
+
+ if ((ha->subsys->param[3] & 0x300000)
+ && (ha->scb_activelist.count == 0)) {
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+
+ if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
+ ha->last_ffdc = tv.tv_sec;
+ ips_ffdc_time(ha);
+ }
+ }
+
+ /*
+ * Send passthru commands
+ * These have priority over normal I/O
+ * but shouldn't affect performance too much
+ * since we limit the number that can be active
+ * on the card at any one time
+ */
+ while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
+ (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) {
+
+ item = ips_removeq_copp_head(&ha->copp_waitlist);
+ ha->num_ioctl++;
+ if (intr == IPS_INTR_ON)
+ IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
+ scb->scsi_cmd = item->scsi_cmd;
+ kfree(item);
+
+ ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
+
+ if (intr == IPS_INTR_ON)
+ IPS_LOCK_SAVE(host->host_lock, cpu_flags);
+ switch (ret) {
+ case IPS_FAILURE:
+ if (scb->scsi_cmd) {
+ scb->scsi_cmd->result = DID_ERROR << 16;
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ }
+
+ ips_freescb(ha, scb);
+ break;
+ case IPS_SUCCESS_IMM:
+ if (scb->scsi_cmd) {
+ scb->scsi_cmd->result = DID_OK << 16;
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ }
+
+ ips_freescb(ha, scb);
+ break;
+ default:
+ break;
+ } /* end case */
+
+ if (ret != IPS_SUCCESS) {
+ ha->num_ioctl--;
+ continue;
+ }
+
+ ret = ips_send_cmd(ha, scb);
+
+ if (ret == IPS_SUCCESS)
+ ips_putq_scb_head(&ha->scb_activelist, scb);
+ else
+ ha->num_ioctl--;
+
+ switch (ret) {
+ case IPS_FAILURE:
+ if (scb->scsi_cmd) {
+ scb->scsi_cmd->result = DID_ERROR << 16;
+ }
+
+ ips_freescb(ha, scb);
+ break;
+ case IPS_SUCCESS_IMM:
+ ips_freescb(ha, scb);
+ break;
+ default:
+ break;
+ } /* end case */
+
+ }
+
+ /*
+ * Send "Normal" I/O commands
+ */
+
+ p = ha->scb_waitlist.head;
+ while ((p) && (scb = ips_getscb(ha))) {
+ if ((p->device->channel > 0)
+ && (ha->
+ dcdb_active[p->device->channel -
+ 1] & (1 << p->device->id))) {
+ ips_freescb(ha, scb);
+ p = (Scsi_Cmnd *) p->host_scribble;
+ continue;
+ }
+
+ q = p;
+ SC = ips_removeq_wait(&ha->scb_waitlist, q);
+
+ if (intr == IPS_INTR_ON)
+ IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags); /* Unlock HA after command is taken off queue */
+
+ SC->result = DID_OK;
+ SC->host_scribble = NULL;
+
+ memset(SC->sense_buffer, 0, sizeof (SC->sense_buffer));
+
+ scb->target_id = SC->device->id;
+ scb->lun = SC->device->lun;
+ scb->bus = SC->device->channel;
+ scb->scsi_cmd = SC;
+ scb->breakup = 0;
+ scb->data_len = 0;
+ scb->callback = ipsintr_done;
+ scb->timeout = ips_cmd_timeout;
+ memset(&scb->cmd, 0, 16);
+
+ /* copy in the CDB */
+ memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
+
+ /* Now handle the data buffer */
+ if (SC->use_sg) {
+ struct scatterlist *sg;
+ int i;
+
+ sg = SC->request_buffer;
+ scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg,
+ scsi_to_pci_dma_dir(SC->
+ sc_data_direction));
+ scb->flags |= IPS_SCB_MAP_SG;
+ for (i = 0; i < scb->sg_count; i++) {
+ if (ips_fill_scb_sg_single
+ (ha, sg_dma_address(&sg[i]), scb, i,
+ sg_dma_len(&sg[i])) < 0)
+ break;
+ }
+ scb->dcdb.transfer_length = scb->data_len;
+ } else {
+ if (SC->request_bufflen) {
+ scb->data_busaddr =
+ pci_map_single(ha->pcidev,
+ SC->request_buffer,
+ SC->request_bufflen,
+ scsi_to_pci_dma_dir(SC->
+ sc_data_direction));
+ scb->flags |= IPS_SCB_MAP_SINGLE;
+ ips_fill_scb_sg_single(ha, scb->data_busaddr,
+ scb, 0,
+ SC->request_bufflen);
+ scb->dcdb.transfer_length = scb->data_len;
+ } else {
+ scb->data_busaddr = 0L;
+ scb->sg_len = 0;
+ scb->data_len = 0;
+ scb->dcdb.transfer_length = 0;
+ }
+
+ }
+
+ scb->dcdb.cmd_attribute =
+ ips_command_direction[scb->scsi_cmd->cmnd[0]];
+
+ if (!(scb->dcdb.cmd_attribute & 0x3))
+ scb->dcdb.transfer_length = 0;
+
+ if (scb->data_len >= IPS_MAX_XFER) {
+ scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
+ scb->dcdb.transfer_length = 0;
+ }
+ if (intr == IPS_INTR_ON)
+ IPS_LOCK_SAVE(host->host_lock, cpu_flags);
+
+ ret = ips_send_cmd(ha, scb);
+
+ switch (ret) {
+ case IPS_SUCCESS:
+ ips_putq_scb_head(&ha->scb_activelist, scb);
+ break;
+ case IPS_FAILURE:
+ if (scb->scsi_cmd) {
+ scb->scsi_cmd->result = DID_ERROR << 16;
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ }
+
+ if (scb->bus)
+ ha->dcdb_active[scb->bus - 1] &=
+ ~(1 << scb->target_id);
+
+ ips_freescb(ha, scb);
+ break;
+ case IPS_SUCCESS_IMM:
+ if (scb->scsi_cmd)
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+
+ if (scb->bus)
+ ha->dcdb_active[scb->bus - 1] &=
+ ~(1 << scb->target_id);
+
+ ips_freescb(ha, scb);
+ break;
+ default:
+ break;
+ } /* end case */
+
+ p = (Scsi_Cmnd *) p->host_scribble;
+
+ } /* end while */
+
+ if (intr == IPS_INTR_ON)
+ IPS_UNLOCK_RESTORE(host->host_lock, cpu_flags);
}
/****************************************************************************/
@@ -2812,19 +2903,20 @@ ips_next(ips_ha_t *ha, int intr) {
/* */
/****************************************************************************/
static inline void
-ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) {
- METHOD_TRACE("ips_putq_scb_head", 1);
+ips_putq_scb_head(ips_scb_queue_t * queue, ips_scb_t * item)
+{
+ METHOD_TRACE("ips_putq_scb_head", 1);
- if (!item)
- return ;
+ if (!item)
+ return;
- item->q_next = queue->head;
- queue->head = item;
+ item->q_next = queue->head;
+ queue->head = item;
- if (!queue->tail)
- queue->tail = item;
+ if (!queue->tail)
+ queue->tail = item;
- queue->count++;
+ queue->count++;
}
/****************************************************************************/
@@ -2839,23 +2931,24 @@ ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) {
/* */
/****************************************************************************/
static inline void
-ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) {
- METHOD_TRACE("ips_putq_scb_tail", 1);
+ips_putq_scb_tail(ips_scb_queue_t * queue, ips_scb_t * item)
+{
+ METHOD_TRACE("ips_putq_scb_tail", 1);
- if (!item)
- return ;
+ if (!item)
+ return;
- item->q_next = NULL;
+ item->q_next = NULL;
- if (queue->tail)
- queue->tail->q_next = item;
+ if (queue->tail)
+ queue->tail->q_next = item;
- queue->tail = item;
+ queue->tail = item;
- if (!queue->head)
- queue->head = item;
+ if (!queue->head)
+ queue->head = item;
- queue->count++;
+ queue->count++;
}
/****************************************************************************/
@@ -2870,26 +2963,27 @@ ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) {
/* */
/****************************************************************************/
static inline ips_scb_t *
-ips_removeq_scb_head(ips_scb_queue_t *queue) {
- ips_scb_t *item;
+ips_removeq_scb_head(ips_scb_queue_t * queue)
+{
+ ips_scb_t *item;
- METHOD_TRACE("ips_removeq_scb_head", 1);
+ METHOD_TRACE("ips_removeq_scb_head", 1);
- item = queue->head;
+ item = queue->head;
- if (!item) {
- return (NULL);
- }
+ if (!item) {
+ return (NULL);
+ }
- queue->head = item->q_next;
- item->q_next = NULL;
+ queue->head = item->q_next;
+ item->q_next = NULL;
- if (queue->tail == item)
- queue->tail = NULL;
+ if (queue->tail == item)
+ queue->tail = NULL;
- queue->count--;
+ queue->count--;
- return (item);
+ return (item);
}
/****************************************************************************/
@@ -2904,37 +2998,38 @@ ips_removeq_scb_head(ips_scb_queue_t *queue) {
/* */
/****************************************************************************/
static inline ips_scb_t *
-ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
- ips_scb_t *p;
+ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item)
+{
+ ips_scb_t *p;
- METHOD_TRACE("ips_removeq_scb", 1);
+ METHOD_TRACE("ips_removeq_scb", 1);
- if (!item)
- return (NULL);
+ if (!item)
+ return (NULL);
- if (item == queue->head) {
- return (ips_removeq_scb_head(queue));
- }
+ if (item == queue->head) {
+ return (ips_removeq_scb_head(queue));
+ }
- p = queue->head;
+ p = queue->head;
- while ((p) && (item != p->q_next))
- p = p->q_next;
+ while ((p) && (item != p->q_next))
+ p = p->q_next;
- if (p) {
- /* found a match */
- p->q_next = item->q_next;
+ if (p) {
+ /* found a match */
+ p->q_next = item->q_next;
- if (!item->q_next)
- queue->tail = p;
+ if (!item->q_next)
+ queue->tail = p;
- item->q_next = NULL;
- queue->count--;
+ item->q_next = NULL;
+ queue->count--;
- return (item);
- }
+ return (item);
+ }
- return (NULL);
+ return (NULL);
}
/****************************************************************************/
@@ -2949,19 +3044,20 @@ ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
/* */
/****************************************************************************/
static inline void
-ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
- METHOD_TRACE("ips_putq_wait_head", 1);
+ips_putq_wait_head(ips_wait_queue_t * queue, Scsi_Cmnd * item)
+{
+ METHOD_TRACE("ips_putq_wait_head", 1);
- if (!item)
- return ;
+ if (!item)
+ return;
- item->host_scribble = (char *) queue->head;
- queue->head = item;
+ item->host_scribble = (char *) queue->head;
+ queue->head = item;
- if (!queue->tail)
- queue->tail = item;
+ if (!queue->tail)
+ queue->tail = item;
- queue->count++;
+ queue->count++;
}
/****************************************************************************/
@@ -2976,23 +3072,24 @@ ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
/* */
/****************************************************************************/
static inline void
-ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
- METHOD_TRACE("ips_putq_wait_tail", 1);
+ips_putq_wait_tail(ips_wait_queue_t * queue, Scsi_Cmnd * item)
+{
+ METHOD_TRACE("ips_putq_wait_tail", 1);
- if (!item)
- return ;
+ if (!item)
+ return;
- item->host_scribble = NULL;
+ item->host_scribble = NULL;
- if (queue->tail)
- queue->tail->host_scribble = (char *)item;
+ if (queue->tail)
+ queue->tail->host_scribble = (char *) item;
- queue->tail = item;
+ queue->tail = item;
- if (!queue->head)
- queue->head = item;
+ if (!queue->head)
+ queue->head = item;
- queue->count++;
+ queue->count++;
}
/****************************************************************************/
@@ -3007,26 +3104,27 @@ ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
/* */
/****************************************************************************/
static inline Scsi_Cmnd *
-ips_removeq_wait_head(ips_wait_queue_t *queue) {
- Scsi_Cmnd *item;
+ips_removeq_wait_head(ips_wait_queue_t * queue)
+{
+ Scsi_Cmnd *item;
- METHOD_TRACE("ips_removeq_wait_head", 1);
+ METHOD_TRACE("ips_removeq_wait_head", 1);
- item = queue->head;
+ item = queue->head;
- if (!item) {
- return (NULL);
- }
+ if (!item) {
+ return (NULL);
+ }
- queue->head = (Scsi_Cmnd *) item->host_scribble;
- item->host_scribble = NULL;
+ queue->head = (Scsi_Cmnd *) item->host_scribble;
+ item->host_scribble = NULL;
- if (queue->tail == item)
- queue->tail = NULL;
+ if (queue->tail == item)
+ queue->tail = NULL;
- queue->count--;
+ queue->count--;
- return (item);
+ return (item);
}
/****************************************************************************/
@@ -3041,37 +3139,38 @@ ips_removeq_wait_head(ips_wait_queue_t *queue) {
/* */
/****************************************************************************/
static inline Scsi_Cmnd *
-ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
- Scsi_Cmnd *p;
+ips_removeq_wait(ips_wait_queue_t * queue, Scsi_Cmnd * item)
+{
+ Scsi_Cmnd *p;
- METHOD_TRACE("ips_removeq_wait", 1);
+ METHOD_TRACE("ips_removeq_wait", 1);
- if (!item)
- return (NULL);
+ if (!item)
+ return (NULL);
- if (item == queue->head) {
- return (ips_removeq_wait_head(queue));
- }
+ if (item == queue->head) {
+ return (ips_removeq_wait_head(queue));
+ }
- p = queue->head;
+ p = queue->head;
- while ((p) && (item != (Scsi_Cmnd *) p->host_scribble))
- p = (Scsi_Cmnd *) p->host_scribble;
+ while ((p) && (item != (Scsi_Cmnd *) p->host_scribble))
+ p = (Scsi_Cmnd *) p->host_scribble;
- if (p) {
- /* found a match */
- p->host_scribble = item->host_scribble;
+ if (p) {
+ /* found a match */
+ p->host_scribble = item->host_scribble;
- if (!item->host_scribble)
- queue->tail = p;
+ if (!item->host_scribble)
+ queue->tail = p;
- item->host_scribble = NULL;
- queue->count--;
+ item->host_scribble = NULL;
+ queue->count--;
- return (item);
- }
+ return (item);
+ }
- return (NULL);
+ return (NULL);
}
/****************************************************************************/
@@ -3086,19 +3185,20 @@ ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
/* */
/****************************************************************************/
static inline void
-ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
- METHOD_TRACE("ips_putq_copp_head", 1);
+ips_putq_copp_head(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
+{
+ METHOD_TRACE("ips_putq_copp_head", 1);
- if (!item)
- return ;
+ if (!item)
+ return;
- item->next = queue->head;
- queue->head = item;
+ item->next = queue->head;
+ queue->head = item;
- if (!queue->tail)
- queue->tail = item;
+ if (!queue->tail)
+ queue->tail = item;
- queue->count++;
+ queue->count++;
}
/****************************************************************************/
@@ -3113,23 +3213,24 @@ ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
/* */
/****************************************************************************/
static inline void
-ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
- METHOD_TRACE("ips_putq_copp_tail", 1);
+ips_putq_copp_tail(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
+{
+ METHOD_TRACE("ips_putq_copp_tail", 1);
- if (!item)
- return ;
+ if (!item)
+ return;
- item->next = NULL;
+ item->next = NULL;
- if (queue->tail)
- queue->tail->next = item;
+ if (queue->tail)
+ queue->tail->next = item;
- queue->tail = item;
+ queue->tail = item;
- if (!queue->head)
- queue->head = item;
+ if (!queue->head)
+ queue->head = item;
- queue->count++;
+ queue->count++;
}
/****************************************************************************/
@@ -3144,26 +3245,27 @@ ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
/* */
/****************************************************************************/
static inline ips_copp_wait_item_t *
-ips_removeq_copp_head(ips_copp_queue_t *queue) {
- ips_copp_wait_item_t *item;
+ips_removeq_copp_head(ips_copp_queue_t * queue)
+{
+ ips_copp_wait_item_t *item;
- METHOD_TRACE("ips_removeq_copp_head", 1);
+ METHOD_TRACE("ips_removeq_copp_head", 1);
- item = queue->head;
+ item = queue->head;
- if (!item) {
- return (NULL);
- }
+ if (!item) {
+ return (NULL);
+ }
- queue->head = item->next;
- item->next = NULL;
+ queue->head = item->next;
+ item->next = NULL;
- if (queue->tail == item)
- queue->tail = NULL;
+ if (queue->tail == item)
+ queue->tail = NULL;
- queue->count--;
+ queue->count--;
- return (item);
+ return (item);
}
/****************************************************************************/
@@ -3178,37 +3280,38 @@ ips_removeq_copp_head(ips_copp_queue_t *queue) {
/* */
/****************************************************************************/
static inline ips_copp_wait_item_t *
-ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
- ips_copp_wait_item_t *p;
+ips_removeq_copp(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
+{
+ ips_copp_wait_item_t *p;
- METHOD_TRACE("ips_removeq_copp", 1);
+ METHOD_TRACE("ips_removeq_copp", 1);
- if (!item)
- return (NULL);
+ if (!item)
+ return (NULL);
- if (item == queue->head) {
- return (ips_removeq_copp_head(queue));
- }
+ if (item == queue->head) {
+ return (ips_removeq_copp_head(queue));
+ }
- p = queue->head;
+ p = queue->head;
- while ((p) && (item != p->next))
- p = p->next;
+ while ((p) && (item != p->next))
+ p = p->next;
- if (p) {
- /* found a match */
- p->next = item->next;
+ if (p) {
+ /* found a match */
+ p->next = item->next;
- if (!item->next)
- queue->tail = p;
+ if (!item->next)
+ queue->tail = p;
- item->next = NULL;
- queue->count--;
+ item->next = NULL;
+ queue->count--;
- return (item);
- }
+ return (item);
+ }
- return (NULL);
+ return (NULL);
}
/****************************************************************************/
@@ -3221,16 +3324,16 @@ ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
/* */
/****************************************************************************/
static void
-ipsintr_blocking(ips_ha_t *ha, ips_scb_t *scb) {
- METHOD_TRACE("ipsintr_blocking", 2);
+ipsintr_blocking(ips_ha_t * ha, ips_scb_t * scb)
+{
+ METHOD_TRACE("ipsintr_blocking", 2);
- ips_freescb(ha, scb);
- if ((ha->waitflag == TRUE) &&
- (ha->cmd_in_progress == scb->cdb[0])) {
- ha->waitflag = FALSE;
+ ips_freescb(ha, scb);
+ if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) {
+ ha->waitflag = FALSE;
- return ;
- }
+ return;
+ }
}
/****************************************************************************/
@@ -3243,23 +3346,26 @@ ipsintr_blocking(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static void
-ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) {
- METHOD_TRACE("ipsintr_done", 2);
+ipsintr_done(ips_ha_t * ha, ips_scb_t * scb)
+{
+ METHOD_TRACE("ipsintr_done", 2);
- if (!scb) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Spurious interrupt; scb NULL.\n");
+ if (!scb) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Spurious interrupt; scb NULL.\n");
- return ;
- }
+ return;
+ }
- if (scb->scsi_cmd == NULL) {
- /* unexpected interrupt */
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Spurious interrupt; scsi_cmd not set.\n");
+ if (scb->scsi_cmd == NULL) {
+ /* unexpected interrupt */
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Spurious interrupt; scsi_cmd not set.\n");
- return;
- }
+ return;
+ }
- ips_done(ha, scb);
+ ips_done(ha, scb);
}
/****************************************************************************/
@@ -3272,104 +3378,118 @@ ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) {
/* ASSUMED to be called form within the request lock */
/****************************************************************************/
static void
-ips_done(ips_ha_t *ha, ips_scb_t *scb) {
- int ret;
-
- METHOD_TRACE("ips_done", 1);
-
- if (!scb)
- return ;
-
- if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
- ips_cleanup_passthru(ha, scb);
- ha->num_ioctl--;
- } else {
- /*
- * Check to see if this command had too much
- * data and had to be broke up. If so, queue
- * the rest of the data and continue.
- */
- if ((scb->breakup) || (scb->sg_break)) {
- /* we had a data breakup */
- scb->data_len = 0;
-
- if (scb->sg_count) {
- /* S/G request */
- struct scatterlist *sg;
- int ips_sg_index = 0;
- int sg_dma_index;
-
- sg = scb->scsi_cmd->request_buffer;
-
- /* Spin forward to last dma chunk */
- sg_dma_index = scb->breakup;
-
- /* Take care of possible partial on last chunk*/
- ips_fill_scb_sg_single(ha, sg_dma_address(&sg[sg_dma_index]),
- scb, ips_sg_index++,
- sg_dma_len(&sg[sg_dma_index]));
-
- for (; sg_dma_index < scb->sg_count; sg_dma_index++) {
- if ( ips_fill_scb_sg_single(ha, sg_dma_address(&sg[sg_dma_index]),
- scb, ips_sg_index++,
- sg_dma_len(&sg[sg_dma_index])) < 0)
- break;
-
- }
-
- } else {
- /* Non S/G Request */
- (void) ips_fill_scb_sg_single(ha,
- scb->data_busaddr + (scb->sg_break * ha->max_xfer),
- scb, 0,
- scb->scsi_cmd->request_bufflen - (scb->sg_break * ha->max_xfer));
- }
-
- scb->dcdb.transfer_length = scb->data_len;
- scb->dcdb.cmd_attribute |= ips_command_direction[scb->scsi_cmd->cmnd[0]];
-
- if (!(scb->dcdb.cmd_attribute & 0x3))
- scb->dcdb.transfer_length = 0;
-
- if (scb->data_len >= IPS_MAX_XFER) {
- scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
- scb->dcdb.transfer_length = 0;
- }
-
- ret = ips_send_cmd(ha, scb);
-
- switch(ret) {
- case IPS_FAILURE:
- if (scb->scsi_cmd) {
- scb->scsi_cmd->result = DID_ERROR << 16;
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- }
-
- ips_freescb(ha, scb);
- break;
- case IPS_SUCCESS_IMM:
- if (scb->scsi_cmd) {
- scb->scsi_cmd->result = DID_ERROR << 16;
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
- }
-
- ips_freescb(ha, scb);
- break;
- default:
- break;
- } /* end case */
-
- return ;
- }
- } /* end if passthru */
-
- if (scb->bus) {
- ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
- }
-
- scb->scsi_cmd->scsi_done(scb->scsi_cmd);
-
- ips_freescb(ha, scb);
+ips_done(ips_ha_t * ha, ips_scb_t * scb)
+{
+ int ret;
+
+ METHOD_TRACE("ips_done", 1);
+
+ if (!scb)
+ return;
+
+ if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
+ ips_cleanup_passthru(ha, scb);
+ ha->num_ioctl--;
+ } else {
+ /*
+ * Check to see if this command had too much
+ * data and had to be broke up. If so, queue
+ * the rest of the data and continue.
+ */
+ if ((scb->breakup) || (scb->sg_break)) {
+ /* we had a data breakup */
+ scb->data_len = 0;
+
+ if (scb->sg_count) {
+ /* S/G request */
+ struct scatterlist *sg;
+ int ips_sg_index = 0;
+ int sg_dma_index;
+
+ sg = scb->scsi_cmd->request_buffer;
+
+ /* Spin forward to last dma chunk */
+ sg_dma_index = scb->breakup;
+
+ /* Take care of possible partial on last chunk */
+ ips_fill_scb_sg_single(ha,
+ sg_dma_address(&sg
+ [sg_dma_index]),
+ scb, ips_sg_index++,
+ sg_dma_len(&sg
+ [sg_dma_index]));
+
+ for (; sg_dma_index < scb->sg_count;
+ sg_dma_index++) {
+ if (ips_fill_scb_sg_single
+ (ha,
+ sg_dma_address(&sg[sg_dma_index]),
+ scb, ips_sg_index++,
+ sg_dma_len(&sg[sg_dma_index])) < 0)
+ break;
+
+ }
+
+ } else {
+ /* Non S/G Request */
+ (void) ips_fill_scb_sg_single(ha,
+ scb->
+ data_busaddr +
+ (scb->sg_break *
+ ha->max_xfer),
+ scb, 0,
+ scb->scsi_cmd->
+ request_bufflen -
+ (scb->sg_break *
+ ha->max_xfer));
+ }
+
+ scb->dcdb.transfer_length = scb->data_len;
+ scb->dcdb.cmd_attribute |=
+ ips_command_direction[scb->scsi_cmd->cmnd[0]];
+
+ if (!(scb->dcdb.cmd_attribute & 0x3))
+ scb->dcdb.transfer_length = 0;
+
+ if (scb->data_len >= IPS_MAX_XFER) {
+ scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
+ scb->dcdb.transfer_length = 0;
+ }
+
+ ret = ips_send_cmd(ha, scb);
+
+ switch (ret) {
+ case IPS_FAILURE:
+ if (scb->scsi_cmd) {
+ scb->scsi_cmd->result = DID_ERROR << 16;
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ }
+
+ ips_freescb(ha, scb);
+ break;
+ case IPS_SUCCESS_IMM:
+ if (scb->scsi_cmd) {
+ scb->scsi_cmd->result = DID_ERROR << 16;
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+ }
+
+ ips_freescb(ha, scb);
+ break;
+ default:
+ break;
+ } /* end case */
+
+ return;
+ }
+ } /* end if passthru */
+
+ if (scb->bus) {
+ ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id);
+ }
+
+ scb->scsi_cmd->scsi_done(scb->scsi_cmd);
+
+ ips_freescb(ha, scb);
}
/****************************************************************************/
@@ -3378,122 +3498,134 @@ ips_done(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/* Routine Description: */
/* */
-/* Map ServeRAID error codes to Linux Error Codes */
+/* Map Controller Error codes to Linux Error Codes */
/* */
/****************************************************************************/
static int
-ips_map_status(ips_ha_t *ha, ips_scb_t *scb, ips_stat_t *sp) {
- int errcode;
- int device_error;
- uint32_t transfer_len;
- IPS_DCDB_TABLE_TAPE *tapeDCDB;
-
- METHOD_TRACE("ips_map_status", 1);
-
- if (scb->bus) {
- DEBUG_VAR(2, "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
- ips_name,
- ha->host_num,
- scb->scsi_cmd->device->channel,
- scb->scsi_cmd->device->id,
- scb->scsi_cmd->device->lun,
- scb->basic_status,
- scb->extended_status,
- scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
- scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
- scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
- }
-
- /* default driver error */
- errcode = DID_ERROR;
- device_error = 0;
-
- switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
- case IPS_CMD_TIMEOUT:
- errcode = DID_TIME_OUT;
- break;
-
- case IPS_INVAL_OPCO:
- case IPS_INVAL_CMD_BLK:
- case IPS_INVAL_PARM_BLK:
- case IPS_LD_ERROR:
- case IPS_CMD_CMPLT_WERROR:
- break;
-
- case IPS_PHYS_DRV_ERROR:
- switch (scb->extended_status) {
- case IPS_ERR_SEL_TO:
- if (scb->bus)
- errcode = DID_NO_CONNECT;
-
- break;
-
- case IPS_ERR_OU_RUN:
- if ( ( scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB ) ||
- ( scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG ) ) {
- tapeDCDB = ( IPS_DCDB_TABLE_TAPE * ) &scb->dcdb;
- transfer_len = tapeDCDB->transfer_length;
- } else {
- transfer_len = ( uint32_t ) scb->dcdb.transfer_length;
- }
-
- if ((scb->bus) && (transfer_len < scb->data_len)) {
- /* Underrun - set default to no error */
- errcode = DID_OK;
-
- /* Restrict access to physical DASD */
- if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
- ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) {
- /* underflow -- no error */
- /* restrict access to physical DASD */
- errcode = DID_TIME_OUT;
- break;
- }
- } else
- errcode = DID_ERROR;
-
- break;
-
- case IPS_ERR_RECOVERY:
- /* don't fail recovered errors */
- if (scb->bus)
- errcode = DID_OK;
-
- break;
-
- case IPS_ERR_HOST_RESET:
- case IPS_ERR_DEV_RESET:
- errcode = DID_RESET;
- break;
-
- case IPS_ERR_CKCOND:
- if (scb->bus) {
- if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) ||
- (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)) {
- tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb;
- memcpy(scb->scsi_cmd->sense_buffer, tapeDCDB->sense_info,
- sizeof(scb->scsi_cmd->sense_buffer));
- } else {
- memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info,
- sizeof(scb->scsi_cmd->sense_buffer));
- }
- device_error = 2; /* check condition */
- }
-
- errcode = DID_OK;
-
- break;
-
- default:
- errcode = DID_ERROR;
- break;
-
- } /* end switch */
- } /* end switch */
-
- scb->scsi_cmd->result = device_error | (errcode << 16);
-
- return (1);
+ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp)
+{
+ int errcode;
+ int device_error;
+ uint32_t transfer_len;
+ IPS_DCDB_TABLE_TAPE *tapeDCDB;
+
+ METHOD_TRACE("ips_map_status", 1);
+
+ if (scb->bus) {
+ DEBUG_VAR(2,
+ "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
+ ips_name, ha->host_num,
+ scb->scsi_cmd->device->channel,
+ scb->scsi_cmd->device->id, scb->scsi_cmd->device->lun,
+ scb->basic_status, scb->extended_status,
+ scb->extended_status ==
+ IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
+ scb->extended_status ==
+ IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
+ scb->extended_status ==
+ IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
+ }
+
+ /* default driver error */
+ errcode = DID_ERROR;
+ device_error = 0;
+
+ switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
+ case IPS_CMD_TIMEOUT:
+ errcode = DID_TIME_OUT;
+ break;
+
+ case IPS_INVAL_OPCO:
+ case IPS_INVAL_CMD_BLK:
+ case IPS_INVAL_PARM_BLK:
+ case IPS_LD_ERROR:
+ case IPS_CMD_CMPLT_WERROR:
+ break;
+
+ case IPS_PHYS_DRV_ERROR:
+ switch (scb->extended_status) {
+ case IPS_ERR_SEL_TO:
+ if (scb->bus)
+ errcode = DID_NO_CONNECT;
+
+ break;
+
+ case IPS_ERR_OU_RUN:
+ if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) ||
+ (scb->cmd.dcdb.op_code ==
+ IPS_CMD_EXTENDED_DCDB_SG)) {
+ tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
+ transfer_len = tapeDCDB->transfer_length;
+ } else {
+ transfer_len =
+ (uint32_t) scb->dcdb.transfer_length;
+ }
+
+ if ((scb->bus) && (transfer_len < scb->data_len)) {
+ /* Underrun - set default to no error */
+ errcode = DID_OK;
+
+ /* Restrict access to physical DASD */
+ if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
+ ((((char *) scb->scsi_cmd->
+ buffer)[0] & 0x1f) == TYPE_DISK)) {
+ /* underflow -- no error */
+ /* restrict access to physical DASD */
+ errcode = DID_TIME_OUT;
+ break;
+ }
+ } else
+ errcode = DID_ERROR;
+
+ break;
+
+ case IPS_ERR_RECOVERY:
+ /* don't fail recovered errors */
+ if (scb->bus)
+ errcode = DID_OK;
+
+ break;
+
+ case IPS_ERR_HOST_RESET:
+ case IPS_ERR_DEV_RESET:
+ errcode = DID_RESET;
+ break;
+
+ case IPS_ERR_CKCOND:
+ if (scb->bus) {
+ if ((scb->cmd.dcdb.op_code ==
+ IPS_CMD_EXTENDED_DCDB)
+ || (scb->cmd.dcdb.op_code ==
+ IPS_CMD_EXTENDED_DCDB_SG)) {
+ tapeDCDB =
+ (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
+ memcpy(scb->scsi_cmd->sense_buffer,
+ tapeDCDB->sense_info,
+ sizeof (scb->scsi_cmd->
+ sense_buffer));
+ } else {
+ memcpy(scb->scsi_cmd->sense_buffer,
+ scb->dcdb.sense_info,
+ sizeof (scb->scsi_cmd->
+ sense_buffer));
+ }
+ device_error = 2; /* check condition */
+ }
+
+ errcode = DID_OK;
+
+ break;
+
+ default:
+ errcode = DID_ERROR;
+ break;
+
+ } /* end switch */
+ } /* end switch */
+
+ scb->scsi_cmd->result = device_error | (errcode << 16);
+
+ return (1);
}
/****************************************************************************/
@@ -3508,25 +3640,26 @@ ips_map_status(ips_ha_t *ha, ips_scb_t *scb, ips_stat_t *sp) {
/* actually need to wait. */
/****************************************************************************/
static int
-ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout, int intr) {
- int ret;
+ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
+{
+ int ret;
- METHOD_TRACE("ips_send_wait", 1);
+ METHOD_TRACE("ips_send_wait", 1);
- if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */
- ha->waitflag = TRUE;
- ha->cmd_in_progress = scb->cdb[0];
- }
- scb->callback = ipsintr_blocking;
- ret = ips_send_cmd(ha, scb);
+ if (intr != IPS_FFDC) { /* Won't be Waiting if this is a Time Stamp */
+ ha->waitflag = TRUE;
+ ha->cmd_in_progress = scb->cdb[0];
+ }
+ scb->callback = ipsintr_blocking;
+ ret = ips_send_cmd(ha, scb);
- if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
- return (ret);
+ if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
+ return (ret);
- if (intr != IPS_FFDC) /* Don't Wait around if this is a Time Stamp */
- ret = ips_wait(ha, timeout, intr);
+ if (intr != IPS_FFDC) /* Don't Wait around if this is a Time Stamp */
+ ret = ips_wait(ha, timeout, intr);
- return (ret);
+ return (ret);
}
/****************************************************************************/
@@ -3536,19 +3669,20 @@ ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout, int intr) {
/* Routine Description: */
/* Write data to Scsi_Cmnd request_buffer at proper offsets */
/****************************************************************************/
-static void ips_scmd_buf_write(Scsi_Cmnd *scmd, void *data, unsigned
- int count)
+static void
+ips_scmd_buf_write(Scsi_Cmnd * scmd, void *data, unsigned
+ int count)
{
if (scmd->use_sg) {
int i;
unsigned int min_cnt, xfer_cnt;
- char *cdata = (char *)data;
+ char *cdata = (char *) data;
struct scatterlist *sg = scmd->request_buffer;
for (i = 0, xfer_cnt = 0;
- (i < scmd->use_sg) && (xfer_cnt < count); i++){
- if(!IPS_SG_ADDRESS(&sg[i]))
+ (i < scmd->use_sg) && (xfer_cnt < count); i++) {
+ if (!IPS_SG_ADDRESS(&sg[i]))
return;
- min_cnt = min( count - xfer_cnt, sg[i].length);
+ min_cnt = min(count - xfer_cnt, sg[i].length);
memcpy(IPS_SG_ADDRESS(&sg[i]), &cdata[xfer_cnt],
min_cnt);
xfer_cnt += min_cnt;
@@ -3567,20 +3701,21 @@ static void ips_scmd_buf_write(Scsi_Cmnd *scmd, void *data, unsigned
/* Routine Description: */
/* Copy data from a Scsi_Cmnd to a new, linear buffer */
/****************************************************************************/
-static void ips_scmd_buf_read(Scsi_Cmnd *scmd, void *data, unsigned
- int count)
+static void
+ips_scmd_buf_read(Scsi_Cmnd * scmd, void *data, unsigned
+ int count)
{
if (scmd->use_sg) {
int i;
unsigned int min_cnt, xfer_cnt;
- char *cdata = (char *)data;
+ char *cdata = (char *) data;
struct scatterlist *sg = scmd->request_buffer;
for (i = 0, xfer_cnt = 0;
- (i < scmd->use_sg) && (xfer_cnt < count); i++){
- if(!IPS_SG_ADDRESS(&sg[i]))
+ (i < scmd->use_sg) && (xfer_cnt < count); i++) {
+ if (!IPS_SG_ADDRESS(&sg[i]))
return;
- min_cnt = min( count - xfer_cnt, sg[i].length);
- memcpy(&cdata[xfer_cnt],IPS_SG_ADDRESS(&sg[i]),
+ min_cnt = min(count - xfer_cnt, sg[i].length);
+ memcpy(&cdata[xfer_cnt], IPS_SG_ADDRESS(&sg[i]),
min_cnt);
xfer_cnt += min_cnt;
}
@@ -3601,338 +3736,395 @@ static void ips_scmd_buf_read(Scsi_Cmnd *scmd, void *data, unsigned
/* */
/****************************************************************************/
static int
-ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
- int ret;
- char *sp;
- int device_error;
- IPS_DCDB_TABLE_TAPE *tapeDCDB;
- int TimeOut;
-
- METHOD_TRACE("ips_send_cmd", 1);
-
- ret = IPS_SUCCESS;
-
- if (!scb->scsi_cmd) {
- /* internal command */
-
- if (scb->bus > 0) {
- /* ServeRAID commands can't be issued */
- /* to real devices -- fail them */
- if ((ha->waitflag == TRUE) &&
- (ha->cmd_in_progress == scb->cdb[0])) {
- ha->waitflag = FALSE;
- }
-
- return (1);
- }
- } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
- /* command to logical bus -- interpret */
- ret = IPS_SUCCESS_IMM;
-
- switch (scb->scsi_cmd->cmnd[0]) {
- case ALLOW_MEDIUM_REMOVAL:
- case REZERO_UNIT:
- case ERASE:
- case WRITE_FILEMARKS:
- case SPACE:
- scb->scsi_cmd->result = DID_ERROR << 16;
- break;
-
- case START_STOP:
- scb->scsi_cmd->result = DID_OK << 16;
-
- case TEST_UNIT_READY:
- case INQUIRY:
- if (scb->target_id == IPS_ADAPTER_ID) {
- /*
- * Either we have a TUR
- * or we have a SCSI inquiry
- */
- if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
- scb->scsi_cmd->result = DID_OK << 16;
-
- if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
- IPS_SCSI_INQ_DATA inquiry;
-
- memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA));
-
- inquiry.DeviceType = IPS_SCSI_INQ_TYPE_PROCESSOR;
- inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
- inquiry.Version = IPS_SCSI_INQ_REV2;
- inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
- inquiry.AdditionalLength = 31;
- inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
- inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync;
- strncpy(inquiry.VendorId, "IBM ", 8);
- strncpy(inquiry.ProductId, "SERVERAID ", 16);
- strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
-
- ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof(inquiry));
-
- scb->scsi_cmd->result = DID_OK << 16;
- }
- } else {
- scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
- scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.logical_info.reserved = 0;
- scb->cmd.logical_info.reserved2 = 0;
- scb->data_len = sizeof(ha->adapt->logical_drive_info);
- scb->data_busaddr = pci_map_single(ha->pcidev,
- &ha->adapt->logical_drive_info,
- scb->data_len, IPS_DMA_DIR(scb));
- scb->flags |= IPS_SCB_MAP_SINGLE;
- scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
- ret = IPS_SUCCESS;
- }
-
- break;
-
- case REQUEST_SENSE:
- ips_reqsen(ha, scb);
- scb->scsi_cmd->result = DID_OK << 16;
- break;
-
- case READ_6:
- case WRITE_6:
- if (!scb->sg_len) {
- scb->cmd.basic_io.op_code =
- (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
- scb->cmd.basic_io.enhanced_sg = 0;
- scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
- } else {
- scb->cmd.basic_io.op_code =
- (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG;
- scb->cmd.basic_io.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
- scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->sg_busaddr);
- }
-
- scb->cmd.basic_io.segment_4G = 0;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.basic_io.log_drv = scb->target_id;
- scb->cmd.basic_io.sg_count = scb->sg_len;
-
- if (scb->cmd.basic_io.lba)
- scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) +
- le16_to_cpu(scb->cmd.basic_io.sector_count));
- else
- scb->cmd.basic_io.lba = (((scb->scsi_cmd->cmnd[1] & 0x1f) << 16) |
- (scb->scsi_cmd->cmnd[2] << 8) |
- (scb->scsi_cmd->cmnd[3]));
-
- scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE);
-
- if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
- scb->cmd.basic_io.sector_count = cpu_to_le16(256);
-
- ret = IPS_SUCCESS;
- break;
-
- case READ_10:
- case WRITE_10:
- if (!scb->sg_len) {
- scb->cmd.basic_io.op_code =
- (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
- scb->cmd.basic_io.enhanced_sg = 0;
- scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
- } else {
- scb->cmd.basic_io.op_code =
- (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG;
- scb->cmd.basic_io.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
- scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->sg_busaddr);
- }
-
- scb->cmd.basic_io.segment_4G = 0;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.basic_io.log_drv = scb->target_id;
- scb->cmd.basic_io.sg_count = scb->sg_len;
-
- if (scb->cmd.basic_io.lba)
- scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) +
- le16_to_cpu(scb->cmd.basic_io.sector_count));
- else
- scb->cmd.basic_io.lba = ((scb->scsi_cmd->cmnd[2] << 24) |
- (scb->scsi_cmd->cmnd[3] << 16) |
- (scb->scsi_cmd->cmnd[4] << 8) |
- scb->scsi_cmd->cmnd[5]);
-
- scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE);
-
-
- if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
- /*
- * This is a null condition
- * we don't have to do anything
- * so just return
- */
- scb->scsi_cmd->result = DID_OK << 16;
- } else
- ret = IPS_SUCCESS;
-
- break;
-
- case RESERVE:
- case RELEASE:
- scb->scsi_cmd->result = DID_OK << 16;
- break;
-
- case MODE_SENSE:
- scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.basic_io.segment_4G = 0;
- scb->cmd.basic_io.enhanced_sg = 0;
- scb->data_len = sizeof(*ha->enq);
- scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq,
- scb->data_len, IPS_DMA_DIR(scb));
- scb->cmd.basic_io.sg_addr = scb->data_busaddr;
- scb->flags |= IPS_SCB_MAP_SINGLE;
- ret = IPS_SUCCESS;
- break;
-
- case READ_CAPACITY:
- scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
- scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.logical_info.reserved = 0;
- scb->cmd.logical_info.reserved2 = 0;
- scb->cmd.logical_info.reserved3 = 0;
- scb->data_len = sizeof(ha->adapt->logical_drive_info);
- scb->data_busaddr = pci_map_single(ha->pcidev,
- &ha->adapt->logical_drive_info,
- scb->data_len, IPS_DMA_DIR(scb));
- scb->flags |= IPS_SCB_MAP_SINGLE;
- scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
- ret = IPS_SUCCESS;
- break;
-
- case SEND_DIAGNOSTIC:
- case REASSIGN_BLOCKS:
- case FORMAT_UNIT:
- case SEEK_10:
- case VERIFY:
- case READ_DEFECT_DATA:
- case READ_BUFFER:
- case WRITE_BUFFER:
- scb->scsi_cmd->result = DID_OK << 16;
- break;
-
- default:
- /* Set the Return Info to appear like the Command was */
- /* attempted, a Check Condition occurred, and Sense */
- /* Data indicating an Invalid CDB OpCode is returned. */
- sp = (char *) scb->scsi_cmd->sense_buffer;
- memset(sp, 0, sizeof(scb->scsi_cmd->sense_buffer));
-
- sp[0] = 0x70; /* Error Code */
- sp[2] = ILLEGAL_REQUEST; /* Sense Key 5 Illegal Req. */
- sp[7] = 0x0A; /* Additional Sense Length */
- sp[12] = 0x20; /* ASC = Invalid OpCode */
- sp[13] = 0x00; /* ASCQ */
-
- device_error = 2; /* Indicate Check Condition */
- scb->scsi_cmd->result = device_error | (DID_OK << 16);
- break;
- } /* end switch */
- } /* end if */
-
- if (ret == IPS_SUCCESS_IMM)
- return (ret);
-
- /* setup DCDB */
- if (scb->bus > 0) {
-
- /* If we already know the Device is Not there, no need to attempt a Command */
- /* This also protects an NT FailOver Controller from getting CDB's sent to it */
- if ( ha->conf->dev[scb->bus-1][scb->target_id].ucState == 0 ) {
- scb->scsi_cmd->result = DID_NO_CONNECT << 16;
- return (IPS_SUCCESS_IMM);
- }
-
- ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id);
- scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
- (unsigned long)&scb->dcdb -
- (unsigned long)scb);
- scb->cmd.dcdb.reserved = 0;
- scb->cmd.dcdb.reserved2 = 0;
- scb->cmd.dcdb.reserved3 = 0;
- scb->cmd.dcdb.segment_4G = 0;
- scb->cmd.dcdb.enhanced_sg = 0;
-
- TimeOut = scb->scsi_cmd->timeout_per_command;
-
- if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */
- if (!scb->sg_len) {
- scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
- } else {
- scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB_SG;
- scb->cmd.dcdb.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
- }
-
- tapeDCDB = (IPS_DCDB_TABLE_TAPE *) &scb->dcdb; /* Use Same Data Area as Old DCDB Struct */
- tapeDCDB->device_address = ((scb->bus - 1) << 4) | scb->target_id;
- tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
- tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */
-
- if (TimeOut) {
- if (TimeOut < ( 10 * HZ ))
- tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
- else if (TimeOut < (60 * HZ))
- tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
- else if (TimeOut < (1200 * HZ))
- tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
- }
-
- tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
- tapeDCDB->reserved_for_LUN = 0;
- tapeDCDB->transfer_length = scb->data_len;
- if(scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)
- tapeDCDB->buffer_pointer = cpu_to_le32(scb->sg_busaddr);
- else
- tapeDCDB->buffer_pointer = cpu_to_le32(scb->data_busaddr);
- tapeDCDB->sg_count = scb->sg_len;
- tapeDCDB->sense_length = sizeof(tapeDCDB->sense_info);
- tapeDCDB->scsi_status = 0;
- tapeDCDB->reserved = 0;
- memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
- } else {
- if (!scb->sg_len) {
- scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
- } else {
- scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
- scb->cmd.dcdb.enhanced_sg = IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
- }
-
- scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id;
- scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
-
- if (TimeOut) {
- if (TimeOut < (10 * HZ))
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
- else if (TimeOut < (60 * HZ))
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
- else if (TimeOut < (1200 * HZ))
- scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
- }
-
- scb->dcdb.transfer_length = scb->data_len;
- if ( scb->dcdb.cmd_attribute & IPS_TRANSFER64K )
- scb->dcdb.transfer_length = 0;
- if(scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG)
- scb->dcdb.buffer_pointer = cpu_to_le32(scb->sg_busaddr);
- else
- scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
- scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
- scb->dcdb.sense_length = sizeof(scb->dcdb.sense_info);
- scb->dcdb.sg_count = scb->sg_len;
- scb->dcdb.reserved = 0;
- memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
- scb->dcdb.scsi_status = 0;
- scb->dcdb.reserved2[0] = 0;
- scb->dcdb.reserved2[1] = 0;
- scb->dcdb.reserved2[2] = 0;
- }
- }
-
- return ((*ha->func.issue)(ha, scb));
+ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
+{
+ int ret;
+ char *sp;
+ int device_error;
+ IPS_DCDB_TABLE_TAPE *tapeDCDB;
+ int TimeOut;
+
+ METHOD_TRACE("ips_send_cmd", 1);
+
+ ret = IPS_SUCCESS;
+
+ if (!scb->scsi_cmd) {
+ /* internal command */
+
+ if (scb->bus > 0) {
+ /* Controller commands can't be issued */
+ /* to real devices -- fail them */
+ if ((ha->waitflag == TRUE) &&
+ (ha->cmd_in_progress == scb->cdb[0])) {
+ ha->waitflag = FALSE;
+ }
+
+ return (1);
+ }
+ } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
+ /* command to logical bus -- interpret */
+ ret = IPS_SUCCESS_IMM;
+
+ switch (scb->scsi_cmd->cmnd[0]) {
+ case ALLOW_MEDIUM_REMOVAL:
+ case REZERO_UNIT:
+ case ERASE:
+ case WRITE_FILEMARKS:
+ case SPACE:
+ scb->scsi_cmd->result = DID_ERROR << 16;
+ break;
+
+ case START_STOP:
+ scb->scsi_cmd->result = DID_OK << 16;
+
+ case TEST_UNIT_READY:
+ case INQUIRY:
+ if (scb->target_id == IPS_ADAPTER_ID) {
+ /*
+ * Either we have a TUR
+ * or we have a SCSI inquiry
+ */
+ if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
+ scb->scsi_cmd->result = DID_OK << 16;
+
+ if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
+ IPS_SCSI_INQ_DATA inquiry;
+
+ memset(&inquiry, 0,
+ sizeof (IPS_SCSI_INQ_DATA));
+
+ inquiry.DeviceType =
+ IPS_SCSI_INQ_TYPE_PROCESSOR;
+ inquiry.DeviceTypeQualifier =
+ IPS_SCSI_INQ_LU_CONNECTED;
+ inquiry.Version = IPS_SCSI_INQ_REV2;
+ inquiry.ResponseDataFormat =
+ IPS_SCSI_INQ_RD_REV2;
+ inquiry.AdditionalLength = 31;
+ inquiry.Flags[0] =
+ IPS_SCSI_INQ_Address16;
+ inquiry.Flags[1] =
+ IPS_SCSI_INQ_WBus16 |
+ IPS_SCSI_INQ_Sync;
+ strncpy(inquiry.VendorId, "IBM ",
+ 8);
+ strncpy(inquiry.ProductId,
+ "SERVERAID ", 16);
+ strncpy(inquiry.ProductRevisionLevel,
+ "1.00", 4);
+
+ ips_scmd_buf_write(scb->scsi_cmd,
+ &inquiry,
+ sizeof (inquiry));
+
+ scb->scsi_cmd->result = DID_OK << 16;
+ }
+ } else {
+ scb->cmd.logical_info.op_code =
+ IPS_CMD_GET_LD_INFO;
+ scb->cmd.logical_info.command_id =
+ IPS_COMMAND_ID(ha, scb);
+ scb->cmd.logical_info.reserved = 0;
+ scb->cmd.logical_info.reserved2 = 0;
+ scb->data_len =
+ sizeof (ha->adapt->logical_drive_info);
+ scb->data_busaddr =
+ pci_map_single(ha->pcidev,
+ &ha->adapt->
+ logical_drive_info,
+ scb->data_len,
+ IPS_DMA_DIR(scb));
+ scb->flags |= IPS_SCB_MAP_SINGLE;
+ scb->cmd.logical_info.buffer_addr =
+ scb->data_busaddr;
+ ret = IPS_SUCCESS;
+ }
+
+ break;
+
+ case REQUEST_SENSE:
+ ips_reqsen(ha, scb);
+ scb->scsi_cmd->result = DID_OK << 16;
+ break;
+
+ case READ_6:
+ case WRITE_6:
+ if (!scb->sg_len) {
+ scb->cmd.basic_io.op_code =
+ (scb->scsi_cmd->cmnd[0] ==
+ READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
+ scb->cmd.basic_io.enhanced_sg = 0;
+ scb->cmd.basic_io.sg_addr =
+ cpu_to_le32(scb->data_busaddr);
+ } else {
+ scb->cmd.basic_io.op_code =
+ (scb->scsi_cmd->cmnd[0] ==
+ READ_6) ? IPS_CMD_READ_SG :
+ IPS_CMD_WRITE_SG;
+ scb->cmd.basic_io.enhanced_sg =
+ IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
+ scb->cmd.basic_io.sg_addr =
+ cpu_to_le32(scb->sg_busaddr);
+ }
+
+ scb->cmd.basic_io.segment_4G = 0;
+ scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.basic_io.log_drv = scb->target_id;
+ scb->cmd.basic_io.sg_count = scb->sg_len;
+
+ if (scb->cmd.basic_io.lba)
+ scb->cmd.basic_io.lba =
+ cpu_to_le32(le32_to_cpu
+ (scb->cmd.basic_io.lba) +
+ le16_to_cpu(scb->cmd.basic_io.
+ sector_count));
+ else
+ scb->cmd.basic_io.lba =
+ (((scb->scsi_cmd->
+ cmnd[1] & 0x1f) << 16) | (scb->scsi_cmd->
+ cmnd[2] << 8) |
+ (scb->scsi_cmd->cmnd[3]));
+
+ scb->cmd.basic_io.sector_count =
+ cpu_to_le16(scb->data_len / IPS_BLKSIZE);
+
+ if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
+ scb->cmd.basic_io.sector_count =
+ cpu_to_le16(256);
+
+ ret = IPS_SUCCESS;
+ break;
+
+ case READ_10:
+ case WRITE_10:
+ if (!scb->sg_len) {
+ scb->cmd.basic_io.op_code =
+ (scb->scsi_cmd->cmnd[0] ==
+ READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
+ scb->cmd.basic_io.enhanced_sg = 0;
+ scb->cmd.basic_io.sg_addr =
+ cpu_to_le32(scb->data_busaddr);
+ } else {
+ scb->cmd.basic_io.op_code =
+ (scb->scsi_cmd->cmnd[0] ==
+ READ_10) ? IPS_CMD_READ_SG :
+ IPS_CMD_WRITE_SG;
+ scb->cmd.basic_io.enhanced_sg =
+ IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
+ scb->cmd.basic_io.sg_addr =
+ cpu_to_le32(scb->sg_busaddr);
+ }
+
+ scb->cmd.basic_io.segment_4G = 0;
+ scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.basic_io.log_drv = scb->target_id;
+ scb->cmd.basic_io.sg_count = scb->sg_len;
+
+ if (scb->cmd.basic_io.lba)
+ scb->cmd.basic_io.lba =
+ cpu_to_le32(le32_to_cpu
+ (scb->cmd.basic_io.lba) +
+ le16_to_cpu(scb->cmd.basic_io.
+ sector_count));
+ else
+ scb->cmd.basic_io.lba =
+ ((scb->scsi_cmd->cmnd[2] << 24) | (scb->
+ scsi_cmd->
+ cmnd[3]
+ << 16) |
+ (scb->scsi_cmd->cmnd[4] << 8) | scb->
+ scsi_cmd->cmnd[5]);
+
+ scb->cmd.basic_io.sector_count =
+ cpu_to_le16(scb->data_len / IPS_BLKSIZE);
+
+ if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
+ /*
+ * This is a null condition
+ * we don't have to do anything
+ * so just return
+ */
+ scb->scsi_cmd->result = DID_OK << 16;
+ } else
+ ret = IPS_SUCCESS;
+
+ break;
+
+ case RESERVE:
+ case RELEASE:
+ scb->scsi_cmd->result = DID_OK << 16;
+ break;
+
+ case MODE_SENSE:
+ scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
+ scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.basic_io.segment_4G = 0;
+ scb->cmd.basic_io.enhanced_sg = 0;
+ scb->data_len = sizeof (*ha->enq);
+ scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
+ ret = IPS_SUCCESS;
+ break;
+
+ case READ_CAPACITY:
+ scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
+ scb->cmd.logical_info.command_id =
+ IPS_COMMAND_ID(ha, scb);
+ scb->cmd.logical_info.reserved = 0;
+ scb->cmd.logical_info.reserved2 = 0;
+ scb->cmd.logical_info.reserved3 = 0;
+ scb->data_len = sizeof (ha->adapt->logical_drive_info);
+ scb->data_busaddr = pci_map_single(ha->pcidev,
+ &ha->adapt->
+ logical_drive_info,
+ scb->data_len,
+ IPS_DMA_DIR(scb));
+ scb->flags |= IPS_SCB_MAP_SINGLE;
+ scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
+ ret = IPS_SUCCESS;
+ break;
+
+ case SEND_DIAGNOSTIC:
+ case REASSIGN_BLOCKS:
+ case FORMAT_UNIT:
+ case SEEK_10:
+ case VERIFY:
+ case READ_DEFECT_DATA:
+ case READ_BUFFER:
+ case WRITE_BUFFER:
+ scb->scsi_cmd->result = DID_OK << 16;
+ break;
+
+ default:
+ /* Set the Return Info to appear like the Command was */
+ /* attempted, a Check Condition occurred, and Sense */
+ /* Data indicating an Invalid CDB OpCode is returned. */
+ sp = (char *) scb->scsi_cmd->sense_buffer;
+ memset(sp, 0, sizeof (scb->scsi_cmd->sense_buffer));
+
+ sp[0] = 0x70; /* Error Code */
+ sp[2] = ILLEGAL_REQUEST; /* Sense Key 5 Illegal Req. */
+ sp[7] = 0x0A; /* Additional Sense Length */
+ sp[12] = 0x20; /* ASC = Invalid OpCode */
+ sp[13] = 0x00; /* ASCQ */
+
+ device_error = 2; /* Indicate Check Condition */
+ scb->scsi_cmd->result = device_error | (DID_OK << 16);
+ break;
+ } /* end switch */
+ }
+ /* end if */
+ if (ret == IPS_SUCCESS_IMM)
+ return (ret);
+
+ /* setup DCDB */
+ if (scb->bus > 0) {
+
+ /* If we already know the Device is Not there, no need to attempt a Command */
+ /* This also protects an NT FailOver Controller from getting CDB's sent to it */
+ if (ha->conf->dev[scb->bus - 1][scb->target_id].ucState == 0) {
+ scb->scsi_cmd->result = DID_NO_CONNECT << 16;
+ return (IPS_SUCCESS_IMM);
+ }
+
+ ha->dcdb_active[scb->bus - 1] |= (1 << scb->target_id);
+ scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
+ (unsigned long) &scb->
+ dcdb -
+ (unsigned long) scb);
+ scb->cmd.dcdb.reserved = 0;
+ scb->cmd.dcdb.reserved2 = 0;
+ scb->cmd.dcdb.reserved3 = 0;
+ scb->cmd.dcdb.segment_4G = 0;
+ scb->cmd.dcdb.enhanced_sg = 0;
+
+ TimeOut = scb->scsi_cmd->timeout_per_command;
+
+ if (ha->subsys->param[4] & 0x00100000) { /* If NEW Tape DCDB is Supported */
+ if (!scb->sg_len) {
+ scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
+ } else {
+ scb->cmd.dcdb.op_code =
+ IPS_CMD_EXTENDED_DCDB_SG;
+ scb->cmd.dcdb.enhanced_sg =
+ IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
+ }
+
+ tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb; /* Use Same Data Area as Old DCDB Struct */
+ tapeDCDB->device_address =
+ ((scb->bus - 1) << 4) | scb->target_id;
+ tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
+ tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K; /* Always Turn OFF 64K Size Flag */
+
+ if (TimeOut) {
+ if (TimeOut < (10 * HZ))
+ tapeDCDB->cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
+ else if (TimeOut < (60 * HZ))
+ tapeDCDB->cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
+ else if (TimeOut < (1200 * HZ))
+ tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
+ }
+
+ tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
+ tapeDCDB->reserved_for_LUN = 0;
+ tapeDCDB->transfer_length = scb->data_len;
+ if (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)
+ tapeDCDB->buffer_pointer =
+ cpu_to_le32(scb->sg_busaddr);
+ else
+ tapeDCDB->buffer_pointer =
+ cpu_to_le32(scb->data_busaddr);
+ tapeDCDB->sg_count = scb->sg_len;
+ tapeDCDB->sense_length = sizeof (tapeDCDB->sense_info);
+ tapeDCDB->scsi_status = 0;
+ tapeDCDB->reserved = 0;
+ memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd,
+ scb->scsi_cmd->cmd_len);
+ } else {
+ if (!scb->sg_len) {
+ scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
+ } else {
+ scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
+ scb->cmd.dcdb.enhanced_sg =
+ IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
+ }
+
+ scb->dcdb.device_address =
+ ((scb->bus - 1) << 4) | scb->target_id;
+ scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
+
+ if (TimeOut) {
+ if (TimeOut < (10 * HZ))
+ scb->dcdb.cmd_attribute |= IPS_TIMEOUT10; /* TimeOut is 10 Seconds */
+ else if (TimeOut < (60 * HZ))
+ scb->dcdb.cmd_attribute |= IPS_TIMEOUT60; /* TimeOut is 60 Seconds */
+ else if (TimeOut < (1200 * HZ))
+ scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M; /* TimeOut is 20 Minutes */
+ }
+
+ scb->dcdb.transfer_length = scb->data_len;
+ if (scb->dcdb.cmd_attribute & IPS_TRANSFER64K)
+ scb->dcdb.transfer_length = 0;
+ if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG)
+ scb->dcdb.buffer_pointer =
+ cpu_to_le32(scb->sg_busaddr);
+ else
+ scb->dcdb.buffer_pointer =
+ cpu_to_le32(scb->data_busaddr);
+ scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
+ scb->dcdb.sense_length = sizeof (scb->dcdb.sense_info);
+ scb->dcdb.sg_count = scb->sg_len;
+ scb->dcdb.reserved = 0;
+ memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd,
+ scb->scsi_cmd->cmd_len);
+ scb->dcdb.scsi_status = 0;
+ scb->dcdb.reserved2[0] = 0;
+ scb->dcdb.reserved2[1] = 0;
+ scb->dcdb.reserved2[2] = 0;
+ }
+ }
+
+ return ((*ha->func.issue) (ha, scb));
}
/****************************************************************************/
@@ -3945,144 +4137,151 @@ ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
/* Assumed to be called with the HA lock */
/****************************************************************************/
static void
-ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) {
- ips_scb_t *scb;
- ips_stat_t *sp;
- uint8_t basic_status;
- uint8_t ext_status;
- int errcode;
-
- METHOD_TRACE("ips_chkstatus", 1);
-
- scb = &ha->scbs[pstatus->fields.command_id];
- scb->basic_status = basic_status = pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
- scb->extended_status = ext_status = pstatus->fields.extended_status;
-
- sp = &ha->sp;
- sp->residue_len = 0;
- sp->scb_addr = (void *) scb;
-
- /* Remove the item from the active queue */
- ips_removeq_scb(&ha->scb_activelist, scb);
-
- if (!scb->scsi_cmd)
- /* internal commands are handled in do_ipsintr */
- return ;
-
- DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
- ips_name,
- ha->host_num,
- scb->cdb[0],
- scb->cmd.basic_io.command_id,
- scb->bus,
- scb->target_id,
- scb->lun);
-
- if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
- /* passthru - just returns the raw result */
- return ;
-
- errcode = DID_OK;
-
- if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
- ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
-
- if (scb->bus == 0) {
- if ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR) {
- DEBUG_VAR(1, "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
- ips_name, ha->host_num,
- scb->cmd.basic_io.op_code, basic_status, ext_status);
- }
-
- switch (scb->scsi_cmd->cmnd[0]) {
- case ALLOW_MEDIUM_REMOVAL:
- case REZERO_UNIT:
- case ERASE:
- case WRITE_FILEMARKS:
- case SPACE:
- errcode = DID_ERROR;
- break;
-
- case START_STOP:
- break;
-
- case TEST_UNIT_READY:
- if (!ips_online(ha, scb)) {
- errcode = DID_TIME_OUT;
- }
- break;
-
- case INQUIRY:
- if (ips_online(ha, scb)) {
- ips_inquiry(ha, scb);
- } else {
- errcode = DID_TIME_OUT;
- }
- break;
-
- case REQUEST_SENSE:
- ips_reqsen(ha, scb);
- break;
-
- case READ_6:
- case WRITE_6:
- case READ_10:
- case WRITE_10:
- case RESERVE:
- case RELEASE:
- break;
-
- case MODE_SENSE:
- if (!ips_online(ha, scb) || !ips_msense(ha, scb)) {
- errcode = DID_ERROR;
- }
- break;
-
- case READ_CAPACITY:
- if (ips_online(ha, scb))
- ips_rdcap(ha, scb);
- else {
- errcode = DID_TIME_OUT;
- }
- break;
-
- case SEND_DIAGNOSTIC:
- case REASSIGN_BLOCKS:
- break;
-
- case FORMAT_UNIT:
- errcode = DID_ERROR;
- break;
-
- case SEEK_10:
- case VERIFY:
- case READ_DEFECT_DATA:
- case READ_BUFFER:
- case WRITE_BUFFER:
- break;
-
- default:
- errcode = DID_ERROR;
- } /* end switch */
-
- scb->scsi_cmd->result = errcode << 16;
- } else { /* bus == 0 */
- /* restrict access to physical drives */
- if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
- ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) {
-
- scb->scsi_cmd->result = DID_TIME_OUT << 16;
- }
- } /* else */
- } else { /* recovered error / success */
- if (scb->bus == 0) {
- DEBUG_VAR(1, "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
- ips_name, ha->host_num,
- scb->cmd.basic_io.op_code, basic_status, ext_status);
- }
-
- ips_map_status(ha, scb, sp);
- } /* else */
+ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus)
+{
+ ips_scb_t *scb;
+ ips_stat_t *sp;
+ uint8_t basic_status;
+ uint8_t ext_status;
+ int errcode;
+
+ METHOD_TRACE("ips_chkstatus", 1);
+
+ scb = &ha->scbs[pstatus->fields.command_id];
+ scb->basic_status = basic_status =
+ pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
+ scb->extended_status = ext_status = pstatus->fields.extended_status;
+
+ sp = &ha->sp;
+ sp->residue_len = 0;
+ sp->scb_addr = (void *) scb;
+
+ /* Remove the item from the active queue */
+ ips_removeq_scb(&ha->scb_activelist, scb);
+
+ if (!scb->scsi_cmd)
+ /* internal commands are handled in do_ipsintr */
+ return;
+
+ DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
+ ips_name,
+ ha->host_num,
+ scb->cdb[0],
+ scb->cmd.basic_io.command_id,
+ scb->bus, scb->target_id, scb->lun);
+
+ if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
+ /* passthru - just returns the raw result */
+ return;
+
+ errcode = DID_OK;
+
+ if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
+ ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
+
+ if (scb->bus == 0) {
+ if ((basic_status & IPS_GSC_STATUS_MASK) ==
+ IPS_CMD_RECOVERED_ERROR) {
+ DEBUG_VAR(1,
+ "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
+ ips_name, ha->host_num,
+ scb->cmd.basic_io.op_code,
+ basic_status, ext_status);
+ }
+
+ switch (scb->scsi_cmd->cmnd[0]) {
+ case ALLOW_MEDIUM_REMOVAL:
+ case REZERO_UNIT:
+ case ERASE:
+ case WRITE_FILEMARKS:
+ case SPACE:
+ errcode = DID_ERROR;
+ break;
+
+ case START_STOP:
+ break;
+
+ case TEST_UNIT_READY:
+ if (!ips_online(ha, scb)) {
+ errcode = DID_TIME_OUT;
+ }
+ break;
+
+ case INQUIRY:
+ if (ips_online(ha, scb)) {
+ ips_inquiry(ha, scb);
+ } else {
+ errcode = DID_TIME_OUT;
+ }
+ break;
+
+ case REQUEST_SENSE:
+ ips_reqsen(ha, scb);
+ break;
+
+ case READ_6:
+ case WRITE_6:
+ case READ_10:
+ case WRITE_10:
+ case RESERVE:
+ case RELEASE:
+ break;
+
+ case MODE_SENSE:
+ if (!ips_online(ha, scb)
+ || !ips_msense(ha, scb)) {
+ errcode = DID_ERROR;
+ }
+ break;
+
+ case READ_CAPACITY:
+ if (ips_online(ha, scb))
+ ips_rdcap(ha, scb);
+ else {
+ errcode = DID_TIME_OUT;
+ }
+ break;
+
+ case SEND_DIAGNOSTIC:
+ case REASSIGN_BLOCKS:
+ break;
+
+ case FORMAT_UNIT:
+ errcode = DID_ERROR;
+ break;
+
+ case SEEK_10:
+ case VERIFY:
+ case READ_DEFECT_DATA:
+ case READ_BUFFER:
+ case WRITE_BUFFER:
+ break;
+
+ default:
+ errcode = DID_ERROR;
+ } /* end switch */
+
+ scb->scsi_cmd->result = errcode << 16;
+ } else { /* bus == 0 */
+ /* restrict access to physical drives */
+ if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
+ ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) ==
+ TYPE_DISK)) {
+
+ scb->scsi_cmd->result = DID_TIME_OUT << 16;
+ }
+ } /* else */
+ } else { /* recovered error / success */
+ if (scb->bus == 0) {
+ DEBUG_VAR(1,
+ "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
+ ips_name, ha->host_num,
+ scb->cmd.basic_io.op_code, basic_status,
+ ext_status);
+ }
+
+ ips_map_status(ha, scb, sp);
+ } /* else */
}
/****************************************************************************/
@@ -4095,25 +4294,31 @@ ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) {
/* */
/****************************************************************************/
static int
-ips_online(ips_ha_t *ha, ips_scb_t *scb) {
- METHOD_TRACE("ips_online", 1);
+ips_online(ips_ha_t * ha, ips_scb_t * scb)
+{
+ METHOD_TRACE("ips_online", 1);
- if (scb->target_id >= IPS_MAX_LD)
- return (0);
+ if (scb->target_id >= IPS_MAX_LD)
+ return (0);
- if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
- memset(&ha->adapt->logical_drive_info, 0, sizeof(ha->adapt->logical_drive_info));
+ if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
+ memset(&ha->adapt->logical_drive_info, 0,
+ sizeof (ha->adapt->logical_drive_info));
- return (0);
- }
+ return (0);
+ }
- if (ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_OFFLINE &&
- ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_FREE &&
- ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_CRS &&
- ha->adapt->logical_drive_info.drive_info[scb->target_id].state != IPS_LD_SYS)
- return (1);
- else
- return (0);
+ if (ha->adapt->logical_drive_info.drive_info[scb->target_id].state !=
+ IPS_LD_OFFLINE
+ && ha->adapt->logical_drive_info.drive_info[scb->target_id].state !=
+ IPS_LD_FREE
+ && ha->adapt->logical_drive_info.drive_info[scb->target_id].state !=
+ IPS_LD_CRS
+ && ha->adapt->logical_drive_info.drive_info[scb->target_id].state !=
+ IPS_LD_SYS)
+ return (1);
+ else
+ return (0);
}
/****************************************************************************/
@@ -4126,27 +4331,29 @@ ips_online(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static int
-ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) {
- IPS_SCSI_INQ_DATA inquiry;
+ips_inquiry(ips_ha_t * ha, ips_scb_t * scb)
+{
+ IPS_SCSI_INQ_DATA inquiry;
- METHOD_TRACE("ips_inquiry", 1);
+ METHOD_TRACE("ips_inquiry", 1);
- memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA));
+ memset(&inquiry, 0, sizeof (IPS_SCSI_INQ_DATA));
- inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD;
- inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
- inquiry.Version = IPS_SCSI_INQ_REV2;
- inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
- inquiry.AdditionalLength = 31;
- inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
- inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue;
- strncpy(inquiry.VendorId, "IBM ", 8);
- strncpy(inquiry.ProductId, "SERVERAID ", 16);
- strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
+ inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD;
+ inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
+ inquiry.Version = IPS_SCSI_INQ_REV2;
+ inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
+ inquiry.AdditionalLength = 31;
+ inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
+ inquiry.Flags[1] =
+ IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue;
+ strncpy(inquiry.VendorId, "IBM ", 8);
+ strncpy(inquiry.ProductId, "SERVERAID ", 16);
+ strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
- ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof(inquiry));
+ ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof (inquiry));
- return (1);
+ return (1);
}
/****************************************************************************/
@@ -4159,20 +4366,24 @@ ips_inquiry(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static int
-ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) {
- IPS_SCSI_CAPACITY cap;
+ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)
+{
+ IPS_SCSI_CAPACITY cap;
- METHOD_TRACE("ips_rdcap", 1);
+ METHOD_TRACE("ips_rdcap", 1);
- if (scb->scsi_cmd->bufflen < 8)
- return (0);
+ if (scb->scsi_cmd->bufflen < 8)
+ return (0);
- cap.lba = cpu_to_be32(le32_to_cpu(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count) - 1);
- cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
+ cap.lba =
+ cpu_to_be32(le32_to_cpu
+ (ha->adapt->logical_drive_info.
+ drive_info[scb->target_id].sector_count) - 1);
+ cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
- ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof(cap));
+ ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof (cap));
- return (1);
+ return (1);
}
/****************************************************************************/
@@ -4185,78 +4396,85 @@ ips_rdcap(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static int
-ips_msense(ips_ha_t *ha, ips_scb_t *scb) {
- uint16_t heads;
- uint16_t sectors;
- uint32_t cylinders;
- IPS_SCSI_MODE_PAGE_DATA mdata;
-
- METHOD_TRACE("ips_msense", 1);
-
- if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 &&
- (ha->enq->ucMiscFlag & 0x8) == 0) {
- heads = IPS_NORM_HEADS;
- sectors = IPS_NORM_SECTORS;
- } else {
- heads = IPS_COMP_HEADS;
- sectors = IPS_COMP_SECTORS;
- }
-
- cylinders = (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) - 1) / (heads * sectors);
-
- memset(&mdata, 0, sizeof(IPS_SCSI_MODE_PAGE_DATA));
-
- mdata.hdr.BlockDescLength = 8;
-
- switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
- case 0x03: /* page 3 */
- mdata.pdata.pg3.PageCode = 3;
- mdata.pdata.pg3.PageLength = sizeof(IPS_SCSI_MODE_PAGE3);
- mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength;
- mdata.pdata.pg3.TracksPerZone = 0;
- mdata.pdata.pg3.AltSectorsPerZone = 0;
- mdata.pdata.pg3.AltTracksPerZone = 0;
- mdata.pdata.pg3.AltTracksPerVolume = 0;
- mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors);
- mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE);
- mdata.pdata.pg3.Interleave = cpu_to_be16(1);
- mdata.pdata.pg3.TrackSkew = 0;
- mdata.pdata.pg3.CylinderSkew = 0;
- mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector;
- break;
-
- case 0x4:
- mdata.pdata.pg4.PageCode = 4;
- mdata.pdata.pg4.PageLength = sizeof(IPS_SCSI_MODE_PAGE4);
- mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength;
- mdata.pdata.pg4.CylindersHigh = cpu_to_be16((cylinders >> 8) & 0xFFFF);
- mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF);
- mdata.pdata.pg4.Heads = heads;
- mdata.pdata.pg4.WritePrecompHigh = 0;
- mdata.pdata.pg4.WritePrecompLow = 0;
- mdata.pdata.pg4.ReducedWriteCurrentHigh = 0;
- mdata.pdata.pg4.ReducedWriteCurrentLow = 0;
- mdata.pdata.pg4.StepRate = cpu_to_be16(1);
- mdata.pdata.pg4.LandingZoneHigh = 0;
- mdata.pdata.pg4.LandingZoneLow = 0;
- mdata.pdata.pg4.flags = 0;
- mdata.pdata.pg4.RotationalOffset = 0;
- mdata.pdata.pg4.MediumRotationRate = 0;
- break;
- case 0x8:
- mdata.pdata.pg8.PageCode = 8;
- mdata.pdata.pg8.PageLength = sizeof(IPS_SCSI_MODE_PAGE8);
- mdata.hdr.DataLength = 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength;
- /* everything else is left set to 0 */
- break;
-
- default:
- return (0);
- } /* end switch */
-
- ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof(mdata));
-
- return (1);
+ips_msense(ips_ha_t * ha, ips_scb_t * scb)
+{
+ uint16_t heads;
+ uint16_t sectors;
+ uint32_t cylinders;
+ IPS_SCSI_MODE_PAGE_DATA mdata;
+
+ METHOD_TRACE("ips_msense", 1);
+
+ if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 &&
+ (ha->enq->ucMiscFlag & 0x8) == 0) {
+ heads = IPS_NORM_HEADS;
+ sectors = IPS_NORM_SECTORS;
+ } else {
+ heads = IPS_COMP_HEADS;
+ sectors = IPS_COMP_SECTORS;
+ }
+
+ cylinders =
+ (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) -
+ 1) / (heads * sectors);
+
+ memset(&mdata, 0, sizeof (IPS_SCSI_MODE_PAGE_DATA));
+
+ mdata.hdr.BlockDescLength = 8;
+
+ switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
+ case 0x03: /* page 3 */
+ mdata.pdata.pg3.PageCode = 3;
+ mdata.pdata.pg3.PageLength = sizeof (IPS_SCSI_MODE_PAGE3);
+ mdata.hdr.DataLength =
+ 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength;
+ mdata.pdata.pg3.TracksPerZone = 0;
+ mdata.pdata.pg3.AltSectorsPerZone = 0;
+ mdata.pdata.pg3.AltTracksPerZone = 0;
+ mdata.pdata.pg3.AltTracksPerVolume = 0;
+ mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors);
+ mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE);
+ mdata.pdata.pg3.Interleave = cpu_to_be16(1);
+ mdata.pdata.pg3.TrackSkew = 0;
+ mdata.pdata.pg3.CylinderSkew = 0;
+ mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector;
+ break;
+
+ case 0x4:
+ mdata.pdata.pg4.PageCode = 4;
+ mdata.pdata.pg4.PageLength = sizeof (IPS_SCSI_MODE_PAGE4);
+ mdata.hdr.DataLength =
+ 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength;
+ mdata.pdata.pg4.CylindersHigh =
+ cpu_to_be16((cylinders >> 8) & 0xFFFF);
+ mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF);
+ mdata.pdata.pg4.Heads = heads;
+ mdata.pdata.pg4.WritePrecompHigh = 0;
+ mdata.pdata.pg4.WritePrecompLow = 0;
+ mdata.pdata.pg4.ReducedWriteCurrentHigh = 0;
+ mdata.pdata.pg4.ReducedWriteCurrentLow = 0;
+ mdata.pdata.pg4.StepRate = cpu_to_be16(1);
+ mdata.pdata.pg4.LandingZoneHigh = 0;
+ mdata.pdata.pg4.LandingZoneLow = 0;
+ mdata.pdata.pg4.flags = 0;
+ mdata.pdata.pg4.RotationalOffset = 0;
+ mdata.pdata.pg4.MediumRotationRate = 0;
+ break;
+ case 0x8:
+ mdata.pdata.pg8.PageCode = 8;
+ mdata.pdata.pg8.PageLength = sizeof (IPS_SCSI_MODE_PAGE8);
+ mdata.hdr.DataLength =
+ 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength;
+ /* everything else is left set to 0 */
+ break;
+
+ default:
+ return (0);
+ } /* end switch */
+
+ ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof (mdata));
+
+ return (1);
}
/****************************************************************************/
@@ -4269,21 +4487,23 @@ ips_msense(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static int
-ips_reqsen(ips_ha_t *ha, ips_scb_t *scb) {
- IPS_SCSI_REQSEN reqsen;
+ips_reqsen(ips_ha_t * ha, ips_scb_t * scb)
+{
+ IPS_SCSI_REQSEN reqsen;
- METHOD_TRACE("ips_reqsen", 1);
+ METHOD_TRACE("ips_reqsen", 1);
- memset(&reqsen, 0, sizeof(IPS_SCSI_REQSEN));
+ memset(&reqsen, 0, sizeof (IPS_SCSI_REQSEN));
- reqsen.ResponseCode = IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR;
- reqsen.AdditionalLength = 10;
- reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
- reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
+ reqsen.ResponseCode =
+ IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR;
+ reqsen.AdditionalLength = 10;
+ reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
+ reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
- ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof(reqsen));
+ ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof (reqsen));
- return (1);
+ return (1);
}
/****************************************************************************/
@@ -4296,58 +4516,64 @@ ips_reqsen(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static void
-ips_free(ips_ha_t *ha) {
-
- METHOD_TRACE("ips_free", 1);
-
- if (ha) {
- if (ha->enq) {
- kfree(ha->enq);
- ha->enq = NULL;
- }
-
- if (ha->conf) {
- kfree(ha->conf);
- ha->conf = NULL;
- }
-
- if (ha->adapt) {
- pci_free_consistent(ha->pcidev,sizeof(IPS_ADAPTER)+ sizeof(IPS_IO_CMD),
- ha->adapt, ha->adapt->hw_status_start);
- ha->adapt = NULL;
- }
-
- if (ha->nvram) {
- kfree(ha->nvram);
- ha->nvram = NULL;
- }
-
- if (ha->subsys) {
- kfree(ha->subsys);
- ha->subsys = NULL;
- }
-
- if (ha->ioctl_data) {
- free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
- ha->ioctl_data = NULL;
- ha->ioctl_datasize = 0;
- ha->ioctl_order = 0;
- }
- ips_deallocatescbs(ha, ha->max_cmds);
-
- /* free memory mapped (if applicable) */
- if (ha->mem_ptr) {
- iounmap(ha->ioremap_ptr);
- ha->ioremap_ptr = NULL;
- ha->mem_ptr = NULL;
- }
-
- if (ha->mem_addr)
- release_mem_region(ha->mem_addr, ha->mem_len);
- ha->mem_addr = 0;
-
- }
+ips_free(ips_ha_t * ha)
+{
+
+ METHOD_TRACE("ips_free", 1);
+
+ if (ha) {
+ if (ha->enq) {
+ pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ),
+ ha->enq, ha->enq_busaddr);
+ ha->enq = NULL;
+ }
+
+ if (ha->conf) {
+ kfree(ha->conf);
+ ha->conf = NULL;
+ }
+
+ if (ha->adapt) {
+ pci_free_consistent(ha->pcidev,
+ sizeof (IPS_ADAPTER) +
+ sizeof (IPS_IO_CMD), ha->adapt,
+ ha->adapt->hw_status_start);
+ ha->adapt = NULL;
+ }
+
+ if (ha->nvram) {
+ kfree(ha->nvram);
+ ha->nvram = NULL;
+ }
+
+ if (ha->subsys) {
+ kfree(ha->subsys);
+ ha->subsys = NULL;
+ }
+
+ if (ha->ioctl_data) {
+ pci_free_consistent(ha->pcidev, ha->ioctl_len,
+ ha->ioctl_data, ha->ioctl_busaddr);
+ ha->ioctl_data = NULL;
+ ha->ioctl_datasize = 0;
+ ha->ioctl_len = 0;
+ }
+ ips_deallocatescbs(ha, ha->max_cmds);
+
+ /* free memory mapped (if applicable) */
+ if (ha->mem_ptr) {
+ iounmap(ha->ioremap_ptr);
+ ha->ioremap_ptr = NULL;
+ ha->mem_ptr = NULL;
+ }
+
+ if (ha->mem_addr)
+ release_mem_region(ha->mem_addr, ha->mem_len);
+ ha->mem_addr = 0;
+
+ }
}
+
/****************************************************************************/
/* */
/* Routine Name: ips_deallocatescbs */
@@ -4358,15 +4584,18 @@ ips_free(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_deallocatescbs(ips_ha_t *ha, int cmds) {
- if (ha->scbs) {
- pci_free_consistent(ha->pcidev, IPS_SGLIST_SIZE(ha) * IPS_MAX_SG *
- cmds, ha->scbs->sg_list.list, ha->scbs->sg_busaddr);
- pci_free_consistent(ha->pcidev, sizeof(ips_scb_t) * cmds,
- ha->scbs, ha->scbs->scb_busaddr);
- ha->scbs = NULL;
- } /* end if */
-return 1;
+ips_deallocatescbs(ips_ha_t * ha, int cmds)
+{
+ if (ha->scbs) {
+ pci_free_consistent(ha->pcidev,
+ IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * cmds,
+ ha->scbs->sg_list.list,
+ ha->scbs->sg_busaddr);
+ pci_free_consistent(ha->pcidev, sizeof (ips_scb_t) * cmds,
+ ha->scbs, ha->scbs->scb_busaddr);
+ ha->scbs = NULL;
+ } /* end if */
+ return 1;
}
/****************************************************************************/
@@ -4379,49 +4608,59 @@ return 1;
/* */
/****************************************************************************/
static int
-ips_allocatescbs(ips_ha_t *ha) {
- ips_scb_t *scb_p;
- IPS_SG_LIST ips_sg;
- int i;
- dma_addr_t command_dma, sg_dma;
-
- METHOD_TRACE("ips_allocatescbs", 1);
-
- /* Allocate memory for the SCBs */
- ha->scbs = pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof(ips_scb_t),
- &command_dma);
- if (ha->scbs == NULL)
- return 0;
- ips_sg.list = pci_alloc_consistent(ha->pcidev, IPS_SGLIST_SIZE(ha) * IPS_MAX_SG *
- ha->max_cmds, &sg_dma);
- if(ips_sg.list == NULL){
- pci_free_consistent(ha->pcidev,ha->max_cmds * sizeof(ips_scb_t),ha->scbs, command_dma);
- return 0;
- }
-
- memset(ha->scbs, 0, ha->max_cmds * sizeof(ips_scb_t));
-
- for (i = 0; i < ha->max_cmds; i++) {
- scb_p = &ha->scbs[i];
- scb_p->scb_busaddr = command_dma + sizeof(ips_scb_t) * i;
- /* set up S/G list */
- if (IPS_USE_ENH_SGLIST(ha)) {
- scb_p->sg_list.enh_list = ips_sg.enh_list + i * IPS_MAX_SG;
- scb_p->sg_busaddr = sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
- } else {
- scb_p->sg_list.std_list = ips_sg.std_list + i * IPS_MAX_SG;
- scb_p->sg_busaddr = sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
- }
-
- /* add to the free list */
- if (i < ha->max_cmds - 1) {
- scb_p->q_next = ha->scb_freelist;
- ha->scb_freelist = scb_p;
- }
- }
-
- /* success */
- return (1);
+ips_allocatescbs(ips_ha_t * ha)
+{
+ ips_scb_t *scb_p;
+ IPS_SG_LIST ips_sg;
+ int i;
+ dma_addr_t command_dma, sg_dma;
+
+ METHOD_TRACE("ips_allocatescbs", 1);
+
+ /* Allocate memory for the SCBs */
+ ha->scbs =
+ pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof (ips_scb_t),
+ &command_dma);
+ if (ha->scbs == NULL)
+ return 0;
+ ips_sg.list =
+ pci_alloc_consistent(ha->pcidev,
+ IPS_SGLIST_SIZE(ha) * IPS_MAX_SG *
+ ha->max_cmds, &sg_dma);
+ if (ips_sg.list == NULL) {
+ pci_free_consistent(ha->pcidev,
+ ha->max_cmds * sizeof (ips_scb_t), ha->scbs,
+ command_dma);
+ return 0;
+ }
+
+ memset(ha->scbs, 0, ha->max_cmds * sizeof (ips_scb_t));
+
+ for (i = 0; i < ha->max_cmds; i++) {
+ scb_p = &ha->scbs[i];
+ scb_p->scb_busaddr = command_dma + sizeof (ips_scb_t) * i;
+ /* set up S/G list */
+ if (IPS_USE_ENH_SGLIST(ha)) {
+ scb_p->sg_list.enh_list =
+ ips_sg.enh_list + i * IPS_MAX_SG;
+ scb_p->sg_busaddr =
+ sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
+ } else {
+ scb_p->sg_list.std_list =
+ ips_sg.std_list + i * IPS_MAX_SG;
+ scb_p->sg_busaddr =
+ sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
+ }
+
+ /* add to the free list */
+ if (i < ha->max_cmds - 1) {
+ scb_p->q_next = ha->scb_freelist;
+ ha->scb_freelist = scb_p;
+ }
+ }
+
+ /* success */
+ return (1);
}
/****************************************************************************/
@@ -4434,36 +4673,37 @@ ips_allocatescbs(ips_ha_t *ha) {
/* */
/****************************************************************************/
static void
-ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
- IPS_SG_LIST sg_list;
- uint32_t cmd_busaddr, sg_busaddr;
- METHOD_TRACE("ips_init_scb", 1);
-
- if (scb == NULL)
- return ;
-
- sg_list.list = scb->sg_list.list;
- cmd_busaddr = scb->scb_busaddr;
- sg_busaddr = scb->sg_busaddr;
- /* zero fill */
- memset(scb, 0, sizeof(ips_scb_t));
- memset(ha->dummy, 0, sizeof(IPS_IO_CMD));
-
- /* Initialize dummy command bucket */
- ha->dummy->op_code = 0xFF;
- ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start
- + sizeof(IPS_ADAPTER));
- ha->dummy->command_id = IPS_MAX_CMDS;
-
- /* set bus address of scb */
- scb->scb_busaddr = cmd_busaddr;
- scb->sg_busaddr = sg_busaddr;
- scb->sg_list.list = sg_list.list;
-
- /* Neptune Fix */
- scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
- scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start
- + sizeof(IPS_ADAPTER));
+ips_init_scb(ips_ha_t * ha, ips_scb_t * scb)
+{
+ IPS_SG_LIST sg_list;
+ uint32_t cmd_busaddr, sg_busaddr;
+ METHOD_TRACE("ips_init_scb", 1);
+
+ if (scb == NULL)
+ return;
+
+ sg_list.list = scb->sg_list.list;
+ cmd_busaddr = scb->scb_busaddr;
+ sg_busaddr = scb->sg_busaddr;
+ /* zero fill */
+ memset(scb, 0, sizeof (ips_scb_t));
+ memset(ha->dummy, 0, sizeof (IPS_IO_CMD));
+
+ /* Initialize dummy command bucket */
+ ha->dummy->op_code = 0xFF;
+ ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start
+ + sizeof (IPS_ADAPTER));
+ ha->dummy->command_id = IPS_MAX_CMDS;
+
+ /* set bus address of scb */
+ scb->scb_busaddr = cmd_busaddr;
+ scb->sg_busaddr = sg_busaddr;
+ scb->sg_list.list = sg_list.list;
+
+ /* Neptune Fix */
+ scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
+ scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start
+ + sizeof (IPS_ADAPTER));
}
/****************************************************************************/
@@ -4478,22 +4718,23 @@ ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static ips_scb_t *
-ips_getscb(ips_ha_t *ha) {
- ips_scb_t *scb;
+ips_getscb(ips_ha_t * ha)
+{
+ ips_scb_t *scb;
- METHOD_TRACE("ips_getscb", 1);
+ METHOD_TRACE("ips_getscb", 1);
- if ((scb = ha->scb_freelist) == NULL) {
+ if ((scb = ha->scb_freelist) == NULL) {
- return (NULL);
- }
+ return (NULL);
+ }
- ha->scb_freelist = scb->q_next;
- scb->q_next = NULL;
+ ha->scb_freelist = scb->q_next;
+ scb->q_next = NULL;
- ips_init_scb(ha, scb);
+ ips_init_scb(ha, scb);
- return (scb);
+ return (scb);
}
/****************************************************************************/
@@ -4508,21 +4749,22 @@ ips_getscb(ips_ha_t *ha) {
/* */
/****************************************************************************/
static void
-ips_freescb(ips_ha_t *ha, ips_scb_t *scb) {
-
- METHOD_TRACE("ips_freescb", 1);
- if(scb->flags & IPS_SCB_MAP_SG)
- pci_unmap_sg(ha->pcidev,scb->scsi_cmd->request_buffer, scb->scsi_cmd->use_sg,
- IPS_DMA_DIR(scb));
- else if(scb->flags & IPS_SCB_MAP_SINGLE)
- pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
- IPS_DMA_DIR(scb));
-
- /* check to make sure this is not our "special" scb */
- if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
- scb->q_next = ha->scb_freelist;
- ha->scb_freelist = scb;
- }
+ips_freescb(ips_ha_t * ha, ips_scb_t * scb)
+{
+
+ METHOD_TRACE("ips_freescb", 1);
+ if (scb->flags & IPS_SCB_MAP_SG)
+ pci_unmap_sg(ha->pcidev, scb->scsi_cmd->request_buffer,
+ scb->scsi_cmd->use_sg, IPS_DMA_DIR(scb));
+ else if (scb->flags & IPS_SCB_MAP_SINGLE)
+ pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
+ IPS_DMA_DIR(scb));
+
+ /* check to make sure this is not our "special" scb */
+ if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
+ scb->q_next = ha->scb_freelist;
+ ha->scb_freelist = scb;
+ }
}
/****************************************************************************/
@@ -4535,19 +4777,20 @@ ips_freescb(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static int
-ips_isinit_copperhead(ips_ha_t *ha) {
- uint8_t scpr;
- uint8_t isr;
+ips_isinit_copperhead(ips_ha_t * ha)
+{
+ uint8_t scpr;
+ uint8_t isr;
- METHOD_TRACE("ips_isinit_copperhead", 1);
+ METHOD_TRACE("ips_isinit_copperhead", 1);
- isr = inb(ha->io_addr + IPS_REG_HISR);
- scpr = inb(ha->io_addr + IPS_REG_SCPR);
+ isr = inb(ha->io_addr + IPS_REG_HISR);
+ scpr = inb(ha->io_addr + IPS_REG_SCPR);
- if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
- return (0);
- else
- return (1);
+ if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
+ return (0);
+ else
+ return (1);
}
/****************************************************************************/
@@ -4560,19 +4803,20 @@ ips_isinit_copperhead(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_isinit_copperhead_memio(ips_ha_t *ha) {
- uint8_t isr=0;
- uint8_t scpr;
+ips_isinit_copperhead_memio(ips_ha_t * ha)
+{
+ uint8_t isr = 0;
+ uint8_t scpr;
- METHOD_TRACE("ips_is_init_copperhead_memio", 1);
+ METHOD_TRACE("ips_is_init_copperhead_memio", 1);
- isr = readb(ha->mem_ptr + IPS_REG_HISR);
- scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
+ isr = readb(ha->mem_ptr + IPS_REG_HISR);
+ scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
- if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
- return (0);
- else
- return (1);
+ if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
+ return (0);
+ else
+ return (1);
}
/****************************************************************************/
@@ -4585,21 +4829,22 @@ ips_isinit_copperhead_memio(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_isinit_morpheus(ips_ha_t *ha) {
- uint32_t post;
- uint32_t bits;
+ips_isinit_morpheus(ips_ha_t * ha)
+{
+ uint32_t post;
+ uint32_t bits;
- METHOD_TRACE("ips_is_init_morpheus", 1);
+ METHOD_TRACE("ips_is_init_morpheus", 1);
- post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
- bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+ post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
+ bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
- if (post == 0)
- return (0);
- else if (bits & 0x3)
- return (0);
- else
- return (1);
+ if (post == 0)
+ return (0);
+ else if (bits & 0x3)
+ return (0);
+ else
+ return (1);
}
/****************************************************************************/
@@ -4611,10 +4856,12 @@ ips_isinit_morpheus(ips_ha_t *ha) {
/* */
/****************************************************************************/
static void
-ips_enable_int_copperhead(ips_ha_t *ha) {
- METHOD_TRACE("ips_enable_int_copperhead", 1);
+ips_enable_int_copperhead(ips_ha_t * ha)
+{
+ METHOD_TRACE("ips_enable_int_copperhead", 1);
- outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);
+ outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);
+ inb(ha->io_addr + IPS_REG_HISR); /*Ensure PCI Posting Completes*/
}
/****************************************************************************/
@@ -4626,10 +4873,12 @@ ips_enable_int_copperhead(ips_ha_t *ha) {
/* */
/****************************************************************************/
static void
-ips_enable_int_copperhead_memio(ips_ha_t *ha) {
- METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
+ips_enable_int_copperhead_memio(ips_ha_t * ha)
+{
+ METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
- writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
+ writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
+ readb(ha->mem_ptr + IPS_REG_HISR); /*Ensure PCI Posting Completes*/
}
/****************************************************************************/
@@ -4641,14 +4890,16 @@ ips_enable_int_copperhead_memio(ips_ha_t *ha) {
/* */
/****************************************************************************/
static void
-ips_enable_int_morpheus(ips_ha_t *ha) {
- uint32_t Oimr;
+ips_enable_int_morpheus(ips_ha_t * ha)
+{
+ uint32_t Oimr;
- METHOD_TRACE("ips_enable_int_morpheus", 1);
+ METHOD_TRACE("ips_enable_int_morpheus", 1);
- Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
- Oimr &= ~0x08;
- writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
+ Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
+ Oimr &= ~0x08;
+ writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
+ readl(ha->mem_ptr + IPS_REG_I960_OIMR); /*Ensure PCI Posting Completes*/
}
/****************************************************************************/
@@ -4661,86 +4912,88 @@ ips_enable_int_morpheus(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_init_copperhead(ips_ha_t *ha) {
- uint8_t Isr;
- uint8_t Cbsp;
- uint8_t PostByte[IPS_MAX_POST_BYTES];
- uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
- int i, j;
-
- METHOD_TRACE("ips_init_copperhead", 1);
-
- for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
- for (j = 0; j < 45; j++) {
- Isr = inb(ha->io_addr + IPS_REG_HISR);
- if (Isr & IPS_BIT_GHI)
- break;
-
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
+ips_init_copperhead(ips_ha_t * ha)
+{
+ uint8_t Isr;
+ uint8_t Cbsp;
+ uint8_t PostByte[IPS_MAX_POST_BYTES];
+ uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
+ int i, j;
+
+ METHOD_TRACE("ips_init_copperhead", 1);
+
+ for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
+ for (j = 0; j < 45; j++) {
+ Isr = inb(ha->io_addr + IPS_REG_HISR);
+ if (Isr & IPS_BIT_GHI)
+ break;
+
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
+ }
- if (j >= 45)
- /* error occurred */
- return (0);
+ if (j >= 45)
+ /* error occurred */
+ return (0);
- PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
- outb(Isr, ha->io_addr + IPS_REG_HISR);
- }
+ PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
+ outb(Isr, ha->io_addr + IPS_REG_HISR);
+ }
- if (PostByte[0] < IPS_GOOD_POST_STATUS) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "reset controller fails (post status %x %x).\n",
- PostByte[0], PostByte[1]);
+ if (PostByte[0] < IPS_GOOD_POST_STATUS) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "reset controller fails (post status %x %x).\n",
+ PostByte[0], PostByte[1]);
- return (0);
- }
+ return (0);
+ }
- for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
- for (j = 0; j < 240; j++) {
- Isr = inb(ha->io_addr + IPS_REG_HISR);
- if (Isr & IPS_BIT_GHI)
- break;
+ for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
+ for (j = 0; j < 240; j++) {
+ Isr = inb(ha->io_addr + IPS_REG_HISR);
+ if (Isr & IPS_BIT_GHI)
+ break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
+ }
- if (j >= 240)
- /* error occurred */
- return (0);
+ if (j >= 240)
+ /* error occurred */
+ return (0);
- ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
- outb(Isr, ha->io_addr + IPS_REG_HISR);
- }
+ ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
+ outb(Isr, ha->io_addr + IPS_REG_HISR);
+ }
- for (i = 0; i < 240; i++) {
- Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
+ for (i = 0; i < 240; i++) {
+ Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
- if ((Cbsp & IPS_BIT_OP) == 0)
- break;
+ if ((Cbsp & IPS_BIT_OP) == 0)
+ break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
+ }
- if (i >= 240)
- /* reset failed */
- return (0);
+ if (i >= 240)
+ /* reset failed */
+ return (0);
- /* setup CCCR */
- outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR);
+ /* setup CCCR */
+ outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR);
- /* Enable busmastering */
- outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
+ /* Enable busmastering */
+ outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- /* fix for anaconda64 */
- outl(0, ha->io_addr + IPS_REG_NDAE);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ /* fix for anaconda64 */
+ outl(0, ha->io_addr + IPS_REG_NDAE);
- /* Enable interrupts */
- outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
+ /* Enable interrupts */
+ outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
- return (1);
+ return (1);
}
/****************************************************************************/
@@ -4753,87 +5006,89 @@ ips_init_copperhead(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_init_copperhead_memio(ips_ha_t *ha) {
- uint8_t Isr=0;
- uint8_t Cbsp;
- uint8_t PostByte[IPS_MAX_POST_BYTES];
- uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
- int i, j;
-
- METHOD_TRACE("ips_init_copperhead_memio", 1);
-
- for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
- for (j = 0; j < 45; j++) {
- Isr = readb(ha->mem_ptr + IPS_REG_HISR);
- if (Isr & IPS_BIT_GHI)
- break;
-
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
+ips_init_copperhead_memio(ips_ha_t * ha)
+{
+ uint8_t Isr = 0;
+ uint8_t Cbsp;
+ uint8_t PostByte[IPS_MAX_POST_BYTES];
+ uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
+ int i, j;
+
+ METHOD_TRACE("ips_init_copperhead_memio", 1);
+
+ for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
+ for (j = 0; j < 45; j++) {
+ Isr = readb(ha->mem_ptr + IPS_REG_HISR);
+ if (Isr & IPS_BIT_GHI)
+ break;
+
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
+ }
- if (j >= 45)
- /* error occurred */
- return (0);
+ if (j >= 45)
+ /* error occurred */
+ return (0);
- PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
- writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
- }
+ PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
+ writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
+ }
- if (PostByte[0] < IPS_GOOD_POST_STATUS) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "reset controller fails (post status %x %x).\n",
- PostByte[0], PostByte[1]);
+ if (PostByte[0] < IPS_GOOD_POST_STATUS) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "reset controller fails (post status %x %x).\n",
+ PostByte[0], PostByte[1]);
- return (0);
- }
+ return (0);
+ }
- for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
- for (j = 0; j < 240; j++) {
- Isr = readb(ha->mem_ptr + IPS_REG_HISR);
- if (Isr & IPS_BIT_GHI)
- break;
+ for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
+ for (j = 0; j < 240; j++) {
+ Isr = readb(ha->mem_ptr + IPS_REG_HISR);
+ if (Isr & IPS_BIT_GHI)
+ break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
+ }
- if (j >= 240)
- /* error occurred */
- return (0);
+ if (j >= 240)
+ /* error occurred */
+ return (0);
- ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
- writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
- }
+ ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
+ writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
+ }
- for (i = 0; i < 240; i++) {
- Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
+ for (i = 0; i < 240; i++) {
+ Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
- if ((Cbsp & IPS_BIT_OP) == 0)
- break;
+ if ((Cbsp & IPS_BIT_OP) == 0)
+ break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
+ }
- if (i >= 240)
- /* error occurred */
- return (0);
+ if (i >= 240)
+ /* error occurred */
+ return (0);
- /* setup CCCR */
- writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
+ /* setup CCCR */
+ writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
- /* Enable busmastering */
- writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
+ /* Enable busmastering */
+ writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- /* fix for anaconda64 */
- writel(0, ha->mem_ptr + IPS_REG_NDAE);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ /* fix for anaconda64 */
+ writel(0, ha->mem_ptr + IPS_REG_NDAE);
- /* Enable interrupts */
- writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
+ /* Enable interrupts */
+ writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
- /* if we get here then everything went OK */
- return (1);
+ /* if we get here then everything went OK */
+ return (1);
}
/****************************************************************************/
@@ -4846,105 +5101,111 @@ ips_init_copperhead_memio(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_init_morpheus(ips_ha_t *ha) {
- uint32_t Post;
- uint32_t Config;
- uint32_t Isr;
- uint32_t Oimr;
- int i;
+ips_init_morpheus(ips_ha_t * ha)
+{
+ uint32_t Post;
+ uint32_t Config;
+ uint32_t Isr;
+ uint32_t Oimr;
+ int i;
- METHOD_TRACE("ips_init_morpheus", 1);
+ METHOD_TRACE("ips_init_morpheus", 1);
- /* Wait up to 45 secs for Post */
- for (i = 0; i < 45; i++) {
- Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+ /* Wait up to 45 secs for Post */
+ for (i = 0; i < 45; i++) {
+ Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
- if (Isr & IPS_BIT_I960_MSG0I)
- break;
+ if (Isr & IPS_BIT_I960_MSG0I)
+ break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
+ }
- if (i >= 45) {
- /* error occurred */
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "timeout waiting for post.\n");
+ if (i >= 45) {
+ /* error occurred */
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "timeout waiting for post.\n");
- return (0);
- }
+ return (0);
+ }
- Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
+ Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
- if (Post == 0x4F00) { /* If Flashing the Battery PIC */
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flashing Battery PIC, Please wait ...\n" );
+ if (Post == 0x4F00) { /* If Flashing the Battery PIC */
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Flashing Battery PIC, Please wait ...\n");
- /* Clear the interrupt bit */
- Isr = (uint32_t) IPS_BIT_I960_MSG0I;
- writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
+ /* Clear the interrupt bit */
+ Isr = (uint32_t) IPS_BIT_I960_MSG0I;
+ writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
- for (i = 0; i < 120; i++) { /* Wait Up to 2 Min. for Completion */
- Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
- if (Post != 0x4F00)
- break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
+ for (i = 0; i < 120; i++) { /* Wait Up to 2 Min. for Completion */
+ Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
+ if (Post != 0x4F00)
+ break;
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
+ }
- if (i >= 120) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "timeout waiting for Battery PIC Flash\n");
- return (0);
- }
+ if (i >= 120) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "timeout waiting for Battery PIC Flash\n");
+ return (0);
+ }
- }
+ }
- /* Clear the interrupt bit */
- Isr = (uint32_t) IPS_BIT_I960_MSG0I;
- writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
+ /* Clear the interrupt bit */
+ Isr = (uint32_t) IPS_BIT_I960_MSG0I;
+ writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
- if (Post < (IPS_GOOD_POST_STATUS << 8)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "reset controller fails (post status %x).\n", Post);
+ if (Post < (IPS_GOOD_POST_STATUS << 8)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "reset controller fails (post status %x).\n", Post);
- return (0);
- }
+ return (0);
+ }
- /* Wait up to 240 secs for config bytes */
- for (i = 0; i < 240; i++) {
- Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+ /* Wait up to 240 secs for config bytes */
+ for (i = 0; i < 240; i++) {
+ Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
- if (Isr & IPS_BIT_I960_MSG1I)
- break;
+ if (Isr & IPS_BIT_I960_MSG1I)
+ break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
+ }
- if (i >= 240) {
- /* error occurred */
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "timeout waiting for config.\n");
+ if (i >= 240) {
+ /* error occurred */
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "timeout waiting for config.\n");
- return (0);
- }
+ return (0);
+ }
- Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
+ Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
- /* Clear interrupt bit */
- Isr = (uint32_t) IPS_BIT_I960_MSG1I;
- writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
+ /* Clear interrupt bit */
+ Isr = (uint32_t) IPS_BIT_I960_MSG1I;
+ writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
- /* Turn on the interrupts */
- Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
- Oimr &= ~0x8;
- writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
+ /* Turn on the interrupts */
+ Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
+ Oimr &= ~0x8;
+ writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
- /* if we get here then everything went OK */
+ /* if we get here then everything went OK */
- /* Since we did a RESET, an EraseStripeLock may be needed */
- if (Post == 0xEF10) {
- if ( (Config == 0x000F) || (Config == 0x0009) )
- ha->requires_esl = 1;
- }
+ /* Since we did a RESET, an EraseStripeLock may be needed */
+ if (Post == 0xEF10) {
+ if ((Config == 0x000F) || (Config == 0x0009))
+ ha->requires_esl = 1;
+ }
- return (1);
+ return (1);
}
/****************************************************************************/
@@ -4957,38 +5218,39 @@ ips_init_morpheus(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_reset_copperhead(ips_ha_t *ha) {
- int reset_counter;
+ips_reset_copperhead(ips_ha_t * ha)
+{
+ int reset_counter;
+
+ METHOD_TRACE("ips_reset_copperhead", 1);
- METHOD_TRACE("ips_reset_copperhead", 1);
+ DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
+ ips_name, ha->host_num, ha->io_addr, ha->irq);
- DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
- ips_name, ha->host_num, ha->io_addr, ha->irq);
+ reset_counter = 0;
- reset_counter = 0;
+ while (reset_counter < 2) {
+ reset_counter++;
- while (reset_counter < 2) {
- reset_counter++;
+ outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
- outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
-
- outb(0, ha->io_addr + IPS_REG_SCPR);
+ outb(0, ha->io_addr + IPS_REG_SCPR);
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
-
- if ((*ha->func.init)(ha))
- break;
- else if (reset_counter >= 2) {
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
- return (0);
- }
- }
+ if ((*ha->func.init) (ha))
+ break;
+ else if (reset_counter >= 2) {
- return (1);
+ return (0);
+ }
+ }
+
+ return (1);
}
/****************************************************************************/
@@ -5001,38 +5263,39 @@ ips_reset_copperhead(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_reset_copperhead_memio(ips_ha_t *ha) {
- int reset_counter;
+ips_reset_copperhead_memio(ips_ha_t * ha)
+{
+ int reset_counter;
+
+ METHOD_TRACE("ips_reset_copperhead_memio", 1);
- METHOD_TRACE("ips_reset_copperhead_memio", 1);
+ DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
+ ips_name, ha->host_num, ha->mem_addr, ha->irq);
- DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
- ips_name, ha->host_num, ha->mem_addr, ha->irq);
+ reset_counter = 0;
- reset_counter = 0;
+ while (reset_counter < 2) {
+ reset_counter++;
- while (reset_counter < 2) {
- reset_counter++;
+ writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
- writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
-
- writeb(0, ha->mem_ptr + IPS_REG_SCPR);
+ writeb(0, ha->mem_ptr + IPS_REG_SCPR);
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
-
- if ((*ha->func.init)(ha))
- break;
- else if (reset_counter >= 2) {
+ /* Delay for 1 Second */
+ MDELAY(IPS_ONE_SEC);
- return (0);
- }
- }
+ if ((*ha->func.init) (ha))
+ break;
+ else if (reset_counter >= 2) {
- return (1);
+ return (0);
+ }
+ }
+
+ return (1);
}
/****************************************************************************/
@@ -5045,37 +5308,38 @@ ips_reset_copperhead_memio(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_reset_morpheus(ips_ha_t *ha) {
- int reset_counter;
- uint8_t junk;
+ips_reset_morpheus(ips_ha_t * ha)
+{
+ int reset_counter;
+ uint8_t junk;
- METHOD_TRACE("ips_reset_morpheus", 1);
+ METHOD_TRACE("ips_reset_morpheus", 1);
- DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
- ips_name, ha->host_num, ha->mem_addr, ha->irq);
+ DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
+ ips_name, ha->host_num, ha->mem_addr, ha->irq);
- reset_counter = 0;
+ reset_counter = 0;
- while (reset_counter < 2) {
- reset_counter++;
+ while (reset_counter < 2) {
+ reset_counter++;
- writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
+ writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
- /* Delay for 5 Seconds */
- MDELAY(5 * IPS_ONE_SEC);
-
- /* Do a PCI config read to wait for adapter */
- pci_read_config_byte(ha->pcidev, 4, &junk);
+ /* Delay for 5 Seconds */
+ MDELAY(5 * IPS_ONE_SEC);
- if ((*ha->func.init)(ha))
- break;
- else if (reset_counter >= 2) {
+ /* Do a PCI config read to wait for adapter */
+ pci_read_config_byte(ha->pcidev, 4, &junk);
- return (0);
- }
- }
+ if ((*ha->func.init) (ha))
+ break;
+ else if (reset_counter >= 2) {
- return (1);
+ return (0);
+ }
+ }
+
+ return (1);
}
/****************************************************************************/
@@ -5088,22 +5352,25 @@ ips_reset_morpheus(ips_ha_t *ha) {
/* */
/****************************************************************************/
static void
-ips_statinit(ips_ha_t *ha) {
- uint32_t phys_status_start;
+ips_statinit(ips_ha_t * ha)
+{
+ uint32_t phys_status_start;
- METHOD_TRACE("ips_statinit", 1);
+ METHOD_TRACE("ips_statinit", 1);
- ha->adapt->p_status_start = ha->adapt->status;
- ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
- ha->adapt->p_status_tail = ha->adapt->status;
+ ha->adapt->p_status_start = ha->adapt->status;
+ ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
+ ha->adapt->p_status_tail = ha->adapt->status;
- phys_status_start = ha->adapt->hw_status_start;
- outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR);
- outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->io_addr + IPS_REG_SQER);
- outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->io_addr + IPS_REG_SQHR);
- outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR);
+ phys_status_start = ha->adapt->hw_status_start;
+ outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR);
+ outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE),
+ ha->io_addr + IPS_REG_SQER);
+ outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE),
+ ha->io_addr + IPS_REG_SQHR);
+ outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR);
- ha->adapt->hw_status_tail = phys_status_start;
+ ha->adapt->hw_status_tail = phys_status_start;
}
/****************************************************************************/
@@ -5116,22 +5383,24 @@ ips_statinit(ips_ha_t *ha) {
/* */
/****************************************************************************/
static void
-ips_statinit_memio(ips_ha_t *ha) {
- uint32_t phys_status_start;
+ips_statinit_memio(ips_ha_t * ha)
+{
+ uint32_t phys_status_start;
- METHOD_TRACE("ips_statinit_memio", 1);
+ METHOD_TRACE("ips_statinit_memio", 1);
- ha->adapt->p_status_start = ha->adapt->status;
- ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
- ha->adapt->p_status_tail = ha->adapt->status;
+ ha->adapt->p_status_start = ha->adapt->status;
+ ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
+ ha->adapt->p_status_tail = ha->adapt->status;
- phys_status_start = ha->adapt->hw_status_start;
- writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
- writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER);
- writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
- writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
+ phys_status_start = ha->adapt->hw_status_start;
+ writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
+ writel(phys_status_start + IPS_STATUS_Q_SIZE,
+ ha->mem_ptr + IPS_REG_SQER);
+ writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
+ writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
- ha->adapt->hw_status_tail = phys_status_start;
+ ha->adapt->hw_status_tail = phys_status_start;
}
/****************************************************************************/
@@ -5144,20 +5413,22 @@ ips_statinit_memio(ips_ha_t *ha) {
/* */
/****************************************************************************/
static uint32_t
-ips_statupd_copperhead(ips_ha_t *ha) {
- METHOD_TRACE("ips_statupd_copperhead", 1);
+ips_statupd_copperhead(ips_ha_t * ha)
+{
+ METHOD_TRACE("ips_statupd_copperhead", 1);
- if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
- ha->adapt->p_status_tail++;
- ha->adapt->hw_status_tail += sizeof(IPS_STATUS);
- } else {
- ha->adapt->p_status_tail = ha->adapt->p_status_start;
- ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
- }
+ if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
+ ha->adapt->p_status_tail++;
+ ha->adapt->hw_status_tail += sizeof (IPS_STATUS);
+ } else {
+ ha->adapt->p_status_tail = ha->adapt->p_status_start;
+ ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
+ }
- outl(cpu_to_le32(ha->adapt->hw_status_tail), ha->io_addr + IPS_REG_SQTR);
+ outl(cpu_to_le32(ha->adapt->hw_status_tail),
+ ha->io_addr + IPS_REG_SQTR);
- return (ha->adapt->p_status_tail->value);
+ return (ha->adapt->p_status_tail->value);
}
/****************************************************************************/
@@ -5170,20 +5441,21 @@ ips_statupd_copperhead(ips_ha_t *ha) {
/* */
/****************************************************************************/
static uint32_t
-ips_statupd_copperhead_memio(ips_ha_t *ha) {
- METHOD_TRACE("ips_statupd_copperhead_memio", 1);
+ips_statupd_copperhead_memio(ips_ha_t * ha)
+{
+ METHOD_TRACE("ips_statupd_copperhead_memio", 1);
- if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
- ha->adapt->p_status_tail++;
- ha->adapt->hw_status_tail += sizeof(IPS_STATUS);
- } else {
- ha->adapt->p_status_tail = ha->adapt->p_status_start;
- ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
- }
+ if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
+ ha->adapt->p_status_tail++;
+ ha->adapt->hw_status_tail += sizeof (IPS_STATUS);
+ } else {
+ ha->adapt->p_status_tail = ha->adapt->p_status_start;
+ ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
+ }
- writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
+ writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
- return (ha->adapt->p_status_tail->value);
+ return (ha->adapt->p_status_tail->value);
}
/****************************************************************************/
@@ -5196,14 +5468,15 @@ ips_statupd_copperhead_memio(ips_ha_t *ha) {
/* */
/****************************************************************************/
static uint32_t
-ips_statupd_morpheus(ips_ha_t *ha) {
- uint32_t val;
+ips_statupd_morpheus(ips_ha_t * ha)
+{
+ uint32_t val;
- METHOD_TRACE("ips_statupd_morpheus", 1);
+ METHOD_TRACE("ips_statupd_morpheus", 1);
- val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
+ val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
- return (val);
+ return (val);
}
/****************************************************************************/
@@ -5216,48 +5489,48 @@ ips_statupd_morpheus(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
- uint32_t TimeOut;
- uint32_t val;
-
- METHOD_TRACE("ips_issue_copperhead", 1);
-
- if (scb->scsi_cmd) {
- DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
- ips_name,
- ha->host_num,
- scb->cdb[0],
- scb->cmd.basic_io.command_id,
- scb->bus,
- scb->target_id,
- scb->lun);
- } else {
- DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d",
- ips_name,
- ha->host_num,
- scb->cmd.basic_io.command_id);
- }
-
- TimeOut = 0;
-
- while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
- udelay(1000);
-
- if (++TimeOut >= IPS_SEM_TIMEOUT) {
- if (!(val & IPS_BIT_START_STOP))
- break;
-
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "ips_issue val [0x%x].\n", val);
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "ips_issue semaphore chk timeout.\n");
-
- return (IPS_FAILURE);
- } /* end if */
- } /* end while */
-
- outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR);
- outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR);
-
- return (IPS_SUCCESS);
+ips_issue_copperhead(ips_ha_t * ha, ips_scb_t * scb)
+{
+ uint32_t TimeOut;
+ uint32_t val;
+
+ METHOD_TRACE("ips_issue_copperhead", 1);
+
+ if (scb->scsi_cmd) {
+ DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
+ ips_name,
+ ha->host_num,
+ scb->cdb[0],
+ scb->cmd.basic_io.command_id,
+ scb->bus, scb->target_id, scb->lun);
+ } else {
+ DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d",
+ ips_name, ha->host_num, scb->cmd.basic_io.command_id);
+ }
+
+ TimeOut = 0;
+
+ while ((val =
+ le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
+ udelay(1000);
+
+ if (++TimeOut >= IPS_SEM_TIMEOUT) {
+ if (!(val & IPS_BIT_START_STOP))
+ break;
+
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "ips_issue val [0x%x].\n", val);
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "ips_issue semaphore chk timeout.\n");
+
+ return (IPS_FAILURE);
+ } /* end if */
+ } /* end while */
+
+ outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR);
+ outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR);
+
+ return (IPS_SUCCESS);
}
/****************************************************************************/
@@ -5270,48 +5543,47 @@ ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static int
-ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
- uint32_t TimeOut;
- uint32_t val;
-
- METHOD_TRACE("ips_issue_copperhead_memio", 1);
-
- if (scb->scsi_cmd) {
- DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
- ips_name,
- ha->host_num,
- scb->cdb[0],
- scb->cmd.basic_io.command_id,
- scb->bus,
- scb->target_id,
- scb->lun);
- } else {
- DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
- ips_name,
- ha->host_num,
- scb->cmd.basic_io.command_id);
- }
-
- TimeOut = 0;
-
- while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
- udelay(1000);
-
- if (++TimeOut >= IPS_SEM_TIMEOUT) {
- if (!(val & IPS_BIT_START_STOP))
- break;
-
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "ips_issue val [0x%x].\n", val);
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "ips_issue semaphore chk timeout.\n");
-
- return (IPS_FAILURE);
- } /* end if */
- } /* end while */
-
- writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
- writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
-
- return (IPS_SUCCESS);
+ips_issue_copperhead_memio(ips_ha_t * ha, ips_scb_t * scb)
+{
+ uint32_t TimeOut;
+ uint32_t val;
+
+ METHOD_TRACE("ips_issue_copperhead_memio", 1);
+
+ if (scb->scsi_cmd) {
+ DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
+ ips_name,
+ ha->host_num,
+ scb->cdb[0],
+ scb->cmd.basic_io.command_id,
+ scb->bus, scb->target_id, scb->lun);
+ } else {
+ DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
+ ips_name, ha->host_num, scb->cmd.basic_io.command_id);
+ }
+
+ TimeOut = 0;
+
+ while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
+ udelay(1000);
+
+ if (++TimeOut >= IPS_SEM_TIMEOUT) {
+ if (!(val & IPS_BIT_START_STOP))
+ break;
+
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "ips_issue val [0x%x].\n", val);
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "ips_issue semaphore chk timeout.\n");
+
+ return (IPS_FAILURE);
+ } /* end if */
+ } /* end while */
+
+ writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
+ writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
+
+ return (IPS_SUCCESS);
}
/****************************************************************************/
@@ -5324,29 +5596,26 @@ ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static int
-ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) {
-
- METHOD_TRACE("ips_issue_i2o", 1);
-
- if (scb->scsi_cmd) {
- DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
- ips_name,
- ha->host_num,
- scb->cdb[0],
- scb->cmd.basic_io.command_id,
- scb->bus,
- scb->target_id,
- scb->lun);
- } else {
- DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
- ips_name,
- ha->host_num,
- scb->cmd.basic_io.command_id);
- }
-
- outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ);
-
- return (IPS_SUCCESS);
+ips_issue_i2o(ips_ha_t * ha, ips_scb_t * scb)
+{
+
+ METHOD_TRACE("ips_issue_i2o", 1);
+
+ if (scb->scsi_cmd) {
+ DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
+ ips_name,
+ ha->host_num,
+ scb->cdb[0],
+ scb->cmd.basic_io.command_id,
+ scb->bus, scb->target_id, scb->lun);
+ } else {
+ DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
+ ips_name, ha->host_num, scb->cmd.basic_io.command_id);
+ }
+
+ outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ);
+
+ return (IPS_SUCCESS);
}
/****************************************************************************/
@@ -5359,29 +5628,26 @@ ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static int
-ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) {
-
- METHOD_TRACE("ips_issue_i2o_memio", 1);
-
- if (scb->scsi_cmd) {
- DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
- ips_name,
- ha->host_num,
- scb->cdb[0],
- scb->cmd.basic_io.command_id,
- scb->bus,
- scb->target_id,
- scb->lun);
- } else {
- DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
- ips_name,
- ha->host_num,
- scb->cmd.basic_io.command_id);
- }
-
- writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
-
- return (IPS_SUCCESS);
+ips_issue_i2o_memio(ips_ha_t * ha, ips_scb_t * scb)
+{
+
+ METHOD_TRACE("ips_issue_i2o_memio", 1);
+
+ if (scb->scsi_cmd) {
+ DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
+ ips_name,
+ ha->host_num,
+ scb->cdb[0],
+ scb->cmd.basic_io.command_id,
+ scb->bus, scb->target_id, scb->lun);
+ } else {
+ DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
+ ips_name, ha->host_num, scb->cmd.basic_io.command_id);
+ }
+
+ writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
+
+ return (IPS_SUCCESS);
}
/****************************************************************************/
@@ -5394,26 +5660,27 @@ ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) {
/* */
/****************************************************************************/
static int
-ips_isintr_copperhead(ips_ha_t *ha) {
- uint8_t Isr;
+ips_isintr_copperhead(ips_ha_t * ha)
+{
+ uint8_t Isr;
- METHOD_TRACE("ips_isintr_copperhead", 2);
+ METHOD_TRACE("ips_isintr_copperhead", 2);
- Isr = inb(ha->io_addr + IPS_REG_HISR);
+ Isr = inb(ha->io_addr + IPS_REG_HISR);
- if (Isr == 0xFF)
- /* ?!?! Nothing really there */
- return (0);
+ if (Isr == 0xFF)
+ /* ?!?! Nothing really there */
+ return (0);
- if (Isr & IPS_BIT_SCE)
- return (1);
- else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
- /* status queue overflow or GHI */
- /* just clear the interrupt */
- outb(Isr, ha->io_addr + IPS_REG_HISR);
- }
+ if (Isr & IPS_BIT_SCE)
+ return (1);
+ else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
+ /* status queue overflow or GHI */
+ /* just clear the interrupt */
+ outb(Isr, ha->io_addr + IPS_REG_HISR);
+ }
- return (0);
+ return (0);
}
/****************************************************************************/
@@ -5426,26 +5693,27 @@ ips_isintr_copperhead(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_isintr_copperhead_memio(ips_ha_t *ha) {
- uint8_t Isr;
+ips_isintr_copperhead_memio(ips_ha_t * ha)
+{
+ uint8_t Isr;
- METHOD_TRACE("ips_isintr_memio", 2);
+ METHOD_TRACE("ips_isintr_memio", 2);
- Isr = readb(ha->mem_ptr + IPS_REG_HISR);
+ Isr = readb(ha->mem_ptr + IPS_REG_HISR);
- if (Isr == 0xFF)
- /* ?!?! Nothing really there */
- return (0);
+ if (Isr == 0xFF)
+ /* ?!?! Nothing really there */
+ return (0);
- if (Isr & IPS_BIT_SCE)
- return (1);
- else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
- /* status queue overflow or GHI */
- /* just clear the interrupt */
- writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
- }
+ if (Isr & IPS_BIT_SCE)
+ return (1);
+ else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
+ /* status queue overflow or GHI */
+ /* just clear the interrupt */
+ writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
+ }
- return (0);
+ return (0);
}
/****************************************************************************/
@@ -5458,17 +5726,18 @@ ips_isintr_copperhead_memio(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_isintr_morpheus(ips_ha_t *ha) {
- uint32_t Isr;
+ips_isintr_morpheus(ips_ha_t * ha)
+{
+ uint32_t Isr;
- METHOD_TRACE("ips_isintr_morpheus", 2);
+ METHOD_TRACE("ips_isintr_morpheus", 2);
- Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
+ Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
- if (Isr & IPS_BIT_I2O_OPQI)
- return (1);
- else
- return (0);
+ if (Isr & IPS_BIT_I2O_OPQI)
+ return (1);
+ else
+ return (0);
}
/****************************************************************************/
@@ -5481,51 +5750,52 @@ ips_isintr_morpheus(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_wait(ips_ha_t *ha, int time, int intr) {
- int ret;
- int done;
-
- METHOD_TRACE("ips_wait", 1);
-
- ret = IPS_FAILURE;
- done = FALSE;
-
- time *= IPS_ONE_SEC; /* convert seconds */
-
- while ((time > 0) && (!done)) {
- if (intr == IPS_INTR_ON) {
- if (ha->waitflag == FALSE) {
- ret = IPS_SUCCESS;
- done = TRUE;
- break;
- }
- } else if (intr == IPS_INTR_IORL) {
- if (ha->waitflag == FALSE) {
- /*
- * controller generated an interrupt to
- * acknowledge completion of the command
- * and ips_intr() has serviced the interrupt.
- */
- ret = IPS_SUCCESS;
- done = TRUE;
- break;
- }
-
- /*
- * NOTE: we already have the io_request_lock so
- * even if we get an interrupt it won't get serviced
- * until after we finish.
- */
-
- (*ha->func.intr)(ha);
- }
-
- /* This looks like a very evil loop, but it only does this during start-up */
- udelay(1000);
- time--;
- }
-
- return (ret);
+ips_wait(ips_ha_t * ha, int time, int intr)
+{
+ int ret;
+ int done;
+
+ METHOD_TRACE("ips_wait", 1);
+
+ ret = IPS_FAILURE;
+ done = FALSE;
+
+ time *= IPS_ONE_SEC; /* convert seconds */
+
+ while ((time > 0) && (!done)) {
+ if (intr == IPS_INTR_ON) {
+ if (ha->waitflag == FALSE) {
+ ret = IPS_SUCCESS;
+ done = TRUE;
+ break;
+ }
+ } else if (intr == IPS_INTR_IORL) {
+ if (ha->waitflag == FALSE) {
+ /*
+ * controller generated an interrupt to
+ * acknowledge completion of the command
+ * and ips_intr() has serviced the interrupt.
+ */
+ ret = IPS_SUCCESS;
+ done = TRUE;
+ break;
+ }
+
+ /*
+ * NOTE: we already have the io_request_lock so
+ * even if we get an interrupt it won't get serviced
+ * until after we finish.
+ */
+
+ (*ha->func.intr) (ha);
+ }
+
+ /* This looks like a very evil loop, but it only does this during start-up */
+ udelay(1000);
+ time--;
+ }
+
+ return (ret);
}
/****************************************************************************/
@@ -5538,55 +5808,59 @@ ips_wait(ips_ha_t *ha, int time, int intr) {
/* */
/****************************************************************************/
static int
-ips_write_driver_status(ips_ha_t *ha, int intr) {
- METHOD_TRACE("ips_write_driver_status", 1);
-
- if (!ips_readwrite_page5(ha, FALSE, intr)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to read NVRAM page 5.\n");
-
- return (0);
- }
-
- /* check to make sure the page has a valid */
- /* signature */
- if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) {
- DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.",
- ips_name, ha->host_num, ha->nvram->signature);
- ha->nvram->signature = IPS_NVRAM_P5_SIG;
- }
-
- DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
- ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type),
- ha->nvram->adapter_slot,
- ha->nvram->bios_high[0], ha->nvram->bios_high[1],
- ha->nvram->bios_high[2], ha->nvram->bios_high[3],
- ha->nvram->bios_low[0], ha->nvram->bios_low[1],
- ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
-
- ips_get_bios_version(ha, intr);
-
- /* change values (as needed) */
- ha->nvram->operating_system = IPS_OS_LINUX;
- ha->nvram->adapter_type = ha->ad_type;
- strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4);
- strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4);
- strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4);
- strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4);
+ips_write_driver_status(ips_ha_t * ha, int intr)
+{
+ METHOD_TRACE("ips_write_driver_status", 1);
- ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */
+ if (!ips_readwrite_page5(ha, FALSE, intr)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "unable to read NVRAM page 5.\n");
- /* now update the page */
- if (!ips_readwrite_page5(ha, TRUE, intr)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "unable to write NVRAM page 5.\n");
+ return (0);
+ }
- return (0);
- }
+ /* check to make sure the page has a valid */
+ /* signature */
+ if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) {
+ DEBUG_VAR(1,
+ "(%s%d) NVRAM page 5 has an invalid signature: %X.",
+ ips_name, ha->host_num, ha->nvram->signature);
+ ha->nvram->signature = IPS_NVRAM_P5_SIG;
+ }
- /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */
- ha->slot_num = ha->nvram->adapter_slot;
+ DEBUG_VAR(2,
+ "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
+ ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type),
+ ha->nvram->adapter_slot, ha->nvram->bios_high[0],
+ ha->nvram->bios_high[1], ha->nvram->bios_high[2],
+ ha->nvram->bios_high[3], ha->nvram->bios_low[0],
+ ha->nvram->bios_low[1], ha->nvram->bios_low[2],
+ ha->nvram->bios_low[3]);
+
+ ips_get_bios_version(ha, intr);
+
+ /* change values (as needed) */
+ ha->nvram->operating_system = IPS_OS_LINUX;
+ ha->nvram->adapter_type = ha->ad_type;
+ strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4);
+ strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4);
+ strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4);
+ strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4);
+
+ ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */
+
+ /* now update the page */
+ if (!ips_readwrite_page5(ha, TRUE, intr)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "unable to write NVRAM page 5.\n");
+
+ return (0);
+ }
+ /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */
+ ha->slot_num = ha->nvram->adapter_slot;
- return (1);
+ return (1);
}
/****************************************************************************/
@@ -5599,38 +5873,37 @@ ips_write_driver_status(ips_ha_t *ha, int intr) {
/* */
/****************************************************************************/
static int
-ips_read_adapter_status(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- int ret;
-
- METHOD_TRACE("ips_read_adapter_status", 1);
-
- scb = &ha->scbs[ha->max_cmds-1];
-
- ips_init_scb(ha, scb);
-
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_ENQUIRY;
-
- scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.basic_io.sg_count = 0;
- scb->cmd.basic_io.lba = 0;
- scb->cmd.basic_io.sector_count = 0;
- scb->cmd.basic_io.log_drv = 0;
- scb->data_len = sizeof(*ha->enq);
- scb->data_busaddr = pci_map_single(ha->pcidev, ha->enq, scb->data_len,
- IPS_DMA_DIR(scb));
- scb->cmd.basic_io.sg_addr = scb->data_busaddr;
- scb->flags |= IPS_SCB_MAP_SINGLE;
-
- /* send command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
- return (0);
-
- return (1);
+ips_read_adapter_status(ips_ha_t * ha, int intr)
+{
+ ips_scb_t *scb;
+ int ret;
+
+ METHOD_TRACE("ips_read_adapter_status", 1);
+
+ scb = &ha->scbs[ha->max_cmds - 1];
+
+ ips_init_scb(ha, scb);
+
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_ENQUIRY;
+
+ scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
+ scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.basic_io.sg_count = 0;
+ scb->cmd.basic_io.lba = 0;
+ scb->cmd.basic_io.sector_count = 0;
+ scb->cmd.basic_io.log_drv = 0;
+ scb->data_len = sizeof (*ha->enq);
+ scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
+
+ /* send command */
+ if (((ret =
+ ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
+ || (ret == IPS_SUCCESS_IMM)
+ || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
+ return (0);
+
+ return (1);
}
/****************************************************************************/
@@ -5643,38 +5916,38 @@ ips_read_adapter_status(ips_ha_t *ha, int intr) {
/* */
/****************************************************************************/
static int
-ips_read_subsystem_parameters(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- int ret;
-
- METHOD_TRACE("ips_read_subsystem_parameters", 1);
-
- scb = &ha->scbs[ha->max_cmds-1];
-
- ips_init_scb(ha, scb);
-
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_GET_SUBSYS;
-
- scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.basic_io.sg_count = 0;
- scb->cmd.basic_io.lba = 0;
- scb->cmd.basic_io.sector_count = 0;
- scb->cmd.basic_io.log_drv = 0;
- scb->data_len = sizeof(*ha->subsys);
- scb->data_busaddr = pci_map_single(ha->pcidev, ha->subsys,
- scb->data_len, IPS_DMA_DIR(scb));
- scb->cmd.basic_io.sg_addr = scb->data_busaddr;
- scb->flags |= IPS_SCB_MAP_SINGLE;
-
- /* send command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
- return (0);
-
- return (1);
+ips_read_subsystem_parameters(ips_ha_t * ha, int intr)
+{
+ ips_scb_t *scb;
+ int ret;
+
+ METHOD_TRACE("ips_read_subsystem_parameters", 1);
+
+ scb = &ha->scbs[ha->max_cmds - 1];
+
+ ips_init_scb(ha, scb);
+
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_GET_SUBSYS;
+
+ scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS;
+ scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.basic_io.sg_count = 0;
+ scb->cmd.basic_io.lba = 0;
+ scb->cmd.basic_io.sector_count = 0;
+ scb->cmd.basic_io.log_drv = 0;
+ scb->data_len = sizeof (*ha->subsys);
+ scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr;
+
+ /* send command */
+ if (((ret =
+ ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
+ || (ret == IPS_SUCCESS_IMM)
+ || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
+ return (0);
+
+ memcpy(ha->subsys, ha->ioctl_data, sizeof(*ha->subsys));
+ return (1);
}
/****************************************************************************/
@@ -5687,51 +5960,52 @@ ips_read_subsystem_parameters(ips_ha_t *ha, int intr) {
/* */
/****************************************************************************/
static int
-ips_read_config(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- int i;
- int ret;
+ips_read_config(ips_ha_t * ha, int intr)
+{
+ ips_scb_t *scb;
+ int i;
+ int ret;
- METHOD_TRACE("ips_read_config", 1);
+ METHOD_TRACE("ips_read_config", 1);
- /* set defaults for initiator IDs */
- for (i = 0; i < 4; i++)
- ha->conf->init_id[i] = 7;
+ /* set defaults for initiator IDs */
+ for (i = 0; i < 4; i++)
+ ha->conf->init_id[i] = 7;
- scb = &ha->scbs[ha->max_cmds-1];
+ scb = &ha->scbs[ha->max_cmds - 1];
- ips_init_scb(ha, scb);
+ ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_READ_CONF;
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_READ_CONF;
- scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
- scb->data_len = sizeof(*ha->conf);
- scb->data_busaddr = pci_map_single(ha->pcidev, ha->conf,
- scb->data_len, IPS_DMA_DIR(scb));
- scb->cmd.basic_io.sg_addr = scb->data_busaddr;
- scb->flags |= IPS_SCB_MAP_SINGLE;
+ scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF;
+ scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->data_len = sizeof (*ha->conf);
+ scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr;
- /* send command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
+ /* send command */
+ if (((ret =
+ ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
+ || (ret == IPS_SUCCESS_IMM)
+ || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
- memset(ha->conf, 0, sizeof(IPS_CONF));
+ memset(ha->conf, 0, sizeof (IPS_CONF));
- /* reset initiator IDs */
- for (i = 0; i < 4; i++)
- ha->conf->init_id[i] = 7;
+ /* reset initiator IDs */
+ for (i = 0; i < 4; i++)
+ ha->conf->init_id[i] = 7;
- /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */
- if ((scb->basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_CMPLT_WERROR)
- return (1);
-
- return (0);
- }
+ /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */
+ if ((scb->basic_status & IPS_GSC_STATUS_MASK) ==
+ IPS_CMD_CMPLT_WERROR)
+ return (1);
- return (1);
+ return (0);
+ }
+
+ memcpy(ha->conf, ha->ioctl_data, sizeof(*ha->conf));
+ return (1);
}
/****************************************************************************/
@@ -5744,42 +6018,44 @@ ips_read_config(ips_ha_t *ha, int intr) {
/* */
/****************************************************************************/
static int
-ips_readwrite_page5(ips_ha_t *ha, int write, int intr) {
- ips_scb_t *scb;
- int ret;
-
- METHOD_TRACE("ips_readwrite_page5", 1);
-
- scb = &ha->scbs[ha->max_cmds-1];
-
- ips_init_scb(ha, scb);
-
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE;
-
- scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE;
- scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.nvram.page = 5;
- scb->cmd.nvram.write = write;
- scb->cmd.nvram.reserved = 0;
- scb->cmd.nvram.reserved2 = 0;
- scb->data_len = sizeof(*ha->nvram);
- scb->data_busaddr = pci_map_single(ha->pcidev, ha->nvram,
- scb->data_len, IPS_DMA_DIR(scb));
- scb->cmd.nvram.buffer_addr = scb->data_busaddr;
- scb->flags |= IPS_SCB_MAP_SINGLE;
-
- /* issue the command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
-
- memset(ha->nvram, 0, sizeof(IPS_NVRAM_P5));
-
- return (0);
- }
-
- return (1);
+ips_readwrite_page5(ips_ha_t * ha, int write, int intr)
+{
+ ips_scb_t *scb;
+ int ret;
+
+ METHOD_TRACE("ips_readwrite_page5", 1);
+
+ scb = &ha->scbs[ha->max_cmds - 1];
+
+ ips_init_scb(ha, scb);
+
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE;
+
+ scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE;
+ scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.nvram.page = 5;
+ scb->cmd.nvram.write = write;
+ scb->cmd.nvram.reserved = 0;
+ scb->cmd.nvram.reserved2 = 0;
+ scb->data_len = sizeof (*ha->nvram);
+ scb->cmd.nvram.buffer_addr = ha->ioctl_busaddr;
+ if (write)
+ memcpy(ha->ioctl_data, ha->nvram, sizeof(*ha->nvram));
+
+ /* issue the command */
+ if (((ret =
+ ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
+ || (ret == IPS_SUCCESS_IMM)
+ || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
+
+ memset(ha->nvram, 0, sizeof (IPS_NVRAM_P5));
+
+ return (0);
+ }
+ if (!write)
+ memcpy(ha->nvram, ha->ioctl_data, sizeof(*ha->nvram));
+ return (1);
}
/****************************************************************************/
@@ -5792,54 +6068,57 @@ ips_readwrite_page5(ips_ha_t *ha, int write, int intr) {
/* */
/****************************************************************************/
static int
-ips_clear_adapter(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- int ret;
-
- METHOD_TRACE("ips_clear_adapter", 1);
-
- scb = &ha->scbs[ha->max_cmds-1];
-
- ips_init_scb(ha, scb);
-
- scb->timeout = ips_reset_timeout;
- scb->cdb[0] = IPS_CMD_CONFIG_SYNC;
-
- scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC;
- scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.config_sync.channel = 0;
- scb->cmd.config_sync.source_target = IPS_POCL;
- scb->cmd.config_sync.reserved = 0;
- scb->cmd.config_sync.reserved2 = 0;
- scb->cmd.config_sync.reserved3 = 0;
-
- /* issue command */
- if (((ret = ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
- return (0);
-
- /* send unlock stripe command */
- ips_init_scb(ha, scb);
-
- scb->cdb[0] = IPS_CMD_ERROR_TABLE;
- scb->timeout = ips_reset_timeout;
-
- scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE;
- scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.unlock_stripe.log_drv = 0;
- scb->cmd.unlock_stripe.control = IPS_CSL;
- scb->cmd.unlock_stripe.reserved = 0;
- scb->cmd.unlock_stripe.reserved2 = 0;
- scb->cmd.unlock_stripe.reserved3 = 0;
-
- /* issue command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
- return (0);
-
- return (1);
+ips_clear_adapter(ips_ha_t * ha, int intr)
+{
+ ips_scb_t *scb;
+ int ret;
+
+ METHOD_TRACE("ips_clear_adapter", 1);
+
+ scb = &ha->scbs[ha->max_cmds - 1];
+
+ ips_init_scb(ha, scb);
+
+ scb->timeout = ips_reset_timeout;
+ scb->cdb[0] = IPS_CMD_CONFIG_SYNC;
+
+ scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC;
+ scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.config_sync.channel = 0;
+ scb->cmd.config_sync.source_target = IPS_POCL;
+ scb->cmd.config_sync.reserved = 0;
+ scb->cmd.config_sync.reserved2 = 0;
+ scb->cmd.config_sync.reserved3 = 0;
+
+ /* issue command */
+ if (((ret =
+ ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE)
+ || (ret == IPS_SUCCESS_IMM)
+ || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
+ return (0);
+
+ /* send unlock stripe command */
+ ips_init_scb(ha, scb);
+
+ scb->cdb[0] = IPS_CMD_ERROR_TABLE;
+ scb->timeout = ips_reset_timeout;
+
+ scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE;
+ scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.unlock_stripe.log_drv = 0;
+ scb->cmd.unlock_stripe.control = IPS_CSL;
+ scb->cmd.unlock_stripe.reserved = 0;
+ scb->cmd.unlock_stripe.reserved2 = 0;
+ scb->cmd.unlock_stripe.reserved3 = 0;
+
+ /* issue command */
+ if (((ret =
+ ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
+ || (ret == IPS_SUCCESS_IMM)
+ || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
+ return (0);
+
+ return (1);
}
/****************************************************************************/
@@ -5852,27 +6131,28 @@ ips_clear_adapter(ips_ha_t *ha, int intr) {
/* */
/****************************************************************************/
static void
-ips_ffdc_reset(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
+ips_ffdc_reset(ips_ha_t * ha, int intr)
+{
+ ips_scb_t *scb;
- METHOD_TRACE("ips_ffdc_reset", 1);
+ METHOD_TRACE("ips_ffdc_reset", 1);
- scb = &ha->scbs[ha->max_cmds-1];
+ scb = &ha->scbs[ha->max_cmds - 1];
- ips_init_scb(ha, scb);
+ ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_FFDC;
- scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
- scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.ffdc.reset_count = ha->reset_count;
- scb->cmd.ffdc.reset_type = 0x80;
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_FFDC;
+ scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
+ scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.ffdc.reset_count = ha->reset_count;
+ scb->cmd.ffdc.reset_type = 0x80;
- /* convert time to what the card wants */
- ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
+ /* convert time to what the card wants */
+ ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
- /* issue command */
- ips_send_wait(ha, scb, ips_cmd_timeout, intr);
+ /* issue command */
+ ips_send_wait(ha, scb, ips_cmd_timeout, intr);
}
/****************************************************************************/
@@ -5885,30 +6165,30 @@ ips_ffdc_reset(ips_ha_t *ha, int intr) {
/* */
/****************************************************************************/
static void
-ips_ffdc_time(ips_ha_t *ha) {
- ips_scb_t *scb;
+ips_ffdc_time(ips_ha_t * ha)
+{
+ ips_scb_t *scb;
- METHOD_TRACE("ips_ffdc_time", 1);
+ METHOD_TRACE("ips_ffdc_time", 1);
- DEBUG_VAR(1, "(%s%d) Sending time update.",
- ips_name, ha->host_num);
+ DEBUG_VAR(1, "(%s%d) Sending time update.", ips_name, ha->host_num);
- scb = &ha->scbs[ha->max_cmds-1];
+ scb = &ha->scbs[ha->max_cmds - 1];
- ips_init_scb(ha, scb);
+ ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_FFDC;
- scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
- scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.ffdc.reset_count = 0;
- scb->cmd.ffdc.reset_type = 0x80;
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_FFDC;
+ scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
+ scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.ffdc.reset_count = 0;
+ scb->cmd.ffdc.reset_type = 0;
- /* convert time to what the card wants */
- ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
+ /* convert time to what the card wants */
+ ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
- /* issue command */
- ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC);
+ /* issue command */
+ ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC);
}
/****************************************************************************/
@@ -5920,57 +6200,59 @@ ips_ffdc_time(ips_ha_t *ha) {
/* */
/****************************************************************************/
static void
-ips_fix_ffdc_time(ips_ha_t *ha, ips_scb_t *scb, time_t current_time) {
- long days;
- long rem;
- int i;
- int year;
- int yleap;
- int year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR };
- int month_lengths[12][2] = { {31, 31},
- {28, 29},
- {31, 31},
- {30, 30},
- {31, 31},
- {30, 30},
- {31, 31},
- {31, 31},
- {30, 30},
- {31, 31},
- {30, 30},
- {31, 31} };
-
- METHOD_TRACE("ips_fix_ffdc_time", 1);
-
- days = current_time / IPS_SECS_DAY;
- rem = current_time % IPS_SECS_DAY;
-
- scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR);
- rem = rem % IPS_SECS_HOUR;
- scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN);
- scb->cmd.ffdc.second = (rem % IPS_SECS_MIN);
-
- year = IPS_EPOCH_YEAR;
- while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) {
- int newy;
-
- newy = year + (days / IPS_DAYS_NORMAL_YEAR);
- if (days < 0)
- --newy;
- days -= (newy - year) * IPS_DAYS_NORMAL_YEAR +
- IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) -
- IPS_NUM_LEAP_YEARS_THROUGH(year - 1);
- year = newy;
- }
-
- scb->cmd.ffdc.yearH = year / 100;
- scb->cmd.ffdc.yearL = year % 100;
-
- for (i = 0; days >= month_lengths[i][yleap]; ++i)
- days -= month_lengths[i][yleap];
-
- scb->cmd.ffdc.month = i + 1;
- scb->cmd.ffdc.day = days + 1;
+ips_fix_ffdc_time(ips_ha_t * ha, ips_scb_t * scb, time_t current_time)
+{
+ long days;
+ long rem;
+ int i;
+ int year;
+ int yleap;
+ int year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR };
+ int month_lengths[12][2] = { {31, 31},
+ {28, 29},
+ {31, 31},
+ {30, 30},
+ {31, 31},
+ {30, 30},
+ {31, 31},
+ {31, 31},
+ {30, 30},
+ {31, 31},
+ {30, 30},
+ {31, 31}
+ };
+
+ METHOD_TRACE("ips_fix_ffdc_time", 1);
+
+ days = current_time / IPS_SECS_DAY;
+ rem = current_time % IPS_SECS_DAY;
+
+ scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR);
+ rem = rem % IPS_SECS_HOUR;
+ scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN);
+ scb->cmd.ffdc.second = (rem % IPS_SECS_MIN);
+
+ year = IPS_EPOCH_YEAR;
+ while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) {
+ int newy;
+
+ newy = year + (days / IPS_DAYS_NORMAL_YEAR);
+ if (days < 0)
+ --newy;
+ days -= (newy - year) * IPS_DAYS_NORMAL_YEAR +
+ IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) -
+ IPS_NUM_LEAP_YEARS_THROUGH(year - 1);
+ year = newy;
+ }
+
+ scb->cmd.ffdc.yearH = year / 100;
+ scb->cmd.ffdc.yearL = year % 100;
+
+ for (i = 0; days >= month_lengths[i][yleap]; ++i)
+ days -= month_lengths[i][yleap];
+
+ scb->cmd.ffdc.month = i + 1;
+ scb->cmd.ffdc.day = days + 1;
}
/****************************************************************************
@@ -5986,106 +6268,107 @@ ips_fix_ffdc_time(ips_ha_t *ha, ips_scb_t *scb, time_t current_time) {
/* */
/****************************************************************************/
static int
-ips_erase_bios(ips_ha_t *ha) {
- int timeout;
- uint8_t status=0;
-
- METHOD_TRACE("ips_erase_bios", 1);
-
- status = 0;
-
- /* Clear the status register */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- outb(0x50, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* Erase Setup */
- outb(0x20, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* Erase Confirm */
- outb(0xD0, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* Erase Status */
- outb(0x70, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- timeout = 80000; /* 80 seconds */
-
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- outl(0, ha->io_addr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
-
- status = inb(ha->io_addr + IPS_REG_FLDP);
-
- if (status & 0x80)
- break;
-
- MDELAY(1);
- timeout--;
- }
-
- /* check for timeout */
- if (timeout <= 0) {
- /* timeout */
-
- /* try to suspend the erase */
- outb(0xB0, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* wait for 10 seconds */
- timeout = 10000;
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- outl(0, ha->io_addr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
-
- status = inb(ha->io_addr + IPS_REG_FLDP);
-
- if (status & 0xC0)
- break;
-
- MDELAY(1);
- timeout--;
- }
-
- return (1);
- }
-
- /* check for valid VPP */
- if (status & 0x08)
- /* VPP failure */
- return (1);
-
- /* check for succesful flash */
- if (status & 0x30)
- /* sequence error */
- return (1);
-
- /* Otherwise, we were successful */
- /* clear status */
- outb(0x50, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* enable reads */
- outb(0xFF, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- return (0);
+ips_erase_bios(ips_ha_t * ha)
+{
+ int timeout;
+ uint8_t status = 0;
+
+ METHOD_TRACE("ips_erase_bios", 1);
+
+ status = 0;
+
+ /* Clear the status register */
+ outl(0, ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ outb(0x50, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* Erase Setup */
+ outb(0x20, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* Erase Confirm */
+ outb(0xD0, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* Erase Status */
+ outb(0x70, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ timeout = 80000; /* 80 seconds */
+
+ while (timeout > 0) {
+ if (ha->revision_id == IPS_REVID_TROMBONE64) {
+ outl(0, ha->io_addr + IPS_REG_FLAP);
+ udelay(25); /* 25 us */
+ }
+
+ status = inb(ha->io_addr + IPS_REG_FLDP);
+
+ if (status & 0x80)
+ break;
+
+ MDELAY(1);
+ timeout--;
+ }
+
+ /* check for timeout */
+ if (timeout <= 0) {
+ /* timeout */
+
+ /* try to suspend the erase */
+ outb(0xB0, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* wait for 10 seconds */
+ timeout = 10000;
+ while (timeout > 0) {
+ if (ha->revision_id == IPS_REVID_TROMBONE64) {
+ outl(0, ha->io_addr + IPS_REG_FLAP);
+ udelay(25); /* 25 us */
+ }
+
+ status = inb(ha->io_addr + IPS_REG_FLDP);
+
+ if (status & 0xC0)
+ break;
+
+ MDELAY(1);
+ timeout--;
+ }
+
+ return (1);
+ }
+
+ /* check for valid VPP */
+ if (status & 0x08)
+ /* VPP failure */
+ return (1);
+
+ /* check for succesful flash */
+ if (status & 0x30)
+ /* sequence error */
+ return (1);
+
+ /* Otherwise, we were successful */
+ /* clear status */
+ outb(0x50, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* enable reads */
+ outb(0xFF, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ return (0);
}
/****************************************************************************/
@@ -6097,106 +6380,107 @@ ips_erase_bios(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_erase_bios_memio(ips_ha_t *ha) {
- int timeout;
- uint8_t status;
-
- METHOD_TRACE("ips_erase_bios_memio", 1);
-
- status = 0;
-
- /* Clear the status register */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* Erase Setup */
- writeb(0x20, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* Erase Confirm */
- writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* Erase Status */
- writeb(0x70, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- timeout = 80000; /* 80 seconds */
-
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
-
- status = readb(ha->mem_ptr + IPS_REG_FLDP);
-
- if (status & 0x80)
- break;
-
- MDELAY(1);
- timeout--;
- }
-
- /* check for timeout */
- if (timeout <= 0) {
- /* timeout */
-
- /* try to suspend the erase */
- writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* wait for 10 seconds */
- timeout = 10000;
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
-
- status = readb(ha->mem_ptr + IPS_REG_FLDP);
-
- if (status & 0xC0)
- break;
-
- MDELAY(1);
- timeout--;
- }
-
- return (1);
- }
-
- /* check for valid VPP */
- if (status & 0x08)
- /* VPP failure */
- return (1);
-
- /* check for succesful flash */
- if (status & 0x30)
- /* sequence error */
- return (1);
-
- /* Otherwise, we were successful */
- /* clear status */
- writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* enable reads */
- writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- return (0);
+ips_erase_bios_memio(ips_ha_t * ha)
+{
+ int timeout;
+ uint8_t status;
+
+ METHOD_TRACE("ips_erase_bios_memio", 1);
+
+ status = 0;
+
+ /* Clear the status register */
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* Erase Setup */
+ writeb(0x20, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* Erase Confirm */
+ writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* Erase Status */
+ writeb(0x70, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ timeout = 80000; /* 80 seconds */
+
+ while (timeout > 0) {
+ if (ha->revision_id == IPS_REVID_TROMBONE64) {
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ udelay(25); /* 25 us */
+ }
+
+ status = readb(ha->mem_ptr + IPS_REG_FLDP);
+
+ if (status & 0x80)
+ break;
+
+ MDELAY(1);
+ timeout--;
+ }
+
+ /* check for timeout */
+ if (timeout <= 0) {
+ /* timeout */
+
+ /* try to suspend the erase */
+ writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* wait for 10 seconds */
+ timeout = 10000;
+ while (timeout > 0) {
+ if (ha->revision_id == IPS_REVID_TROMBONE64) {
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ udelay(25); /* 25 us */
+ }
+
+ status = readb(ha->mem_ptr + IPS_REG_FLDP);
+
+ if (status & 0xC0)
+ break;
+
+ MDELAY(1);
+ timeout--;
+ }
+
+ return (1);
+ }
+
+ /* check for valid VPP */
+ if (status & 0x08)
+ /* VPP failure */
+ return (1);
+
+ /* check for succesful flash */
+ if (status & 0x30)
+ /* sequence error */
+ return (1);
+
+ /* Otherwise, we were successful */
+ /* clear status */
+ writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* enable reads */
+ writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ return (0);
}
/****************************************************************************/
@@ -6208,84 +6492,86 @@ ips_erase_bios_memio(ips_ha_t *ha) {
/* */
/****************************************************************************/
static int
-ips_program_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
- int i;
- int timeout;
- uint8_t status=0;
-
- METHOD_TRACE("ips_program_bios", 1);
-
- status = 0;
-
- for (i = 0; i < buffersize; i++) {
- /* write a byte */
- outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- outb(0x40, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- outb(buffer[i], ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* wait up to one second */
- timeout = 1000;
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- outl(0, ha->io_addr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
-
- status = inb(ha->io_addr + IPS_REG_FLDP);
-
- if (status & 0x80)
- break;
-
- MDELAY(1);
- timeout--;
- }
-
- if (timeout == 0) {
- /* timeout error */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- outb(0xFF, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- return (1);
- }
-
- /* check the status */
- if (status & 0x18) {
- /* programming error */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- outb(0xFF, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- return (1);
- }
- } /* end for */
-
- /* Enable reading */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- outb(0xFF, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- return (0);
+ips_program_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
+ uint32_t offset)
+{
+ int i;
+ int timeout;
+ uint8_t status = 0;
+
+ METHOD_TRACE("ips_program_bios", 1);
+
+ status = 0;
+
+ for (i = 0; i < buffersize; i++) {
+ /* write a byte */
+ outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ outb(0x40, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ outb(buffer[i], ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* wait up to one second */
+ timeout = 1000;
+ while (timeout > 0) {
+ if (ha->revision_id == IPS_REVID_TROMBONE64) {
+ outl(0, ha->io_addr + IPS_REG_FLAP);
+ udelay(25); /* 25 us */
+ }
+
+ status = inb(ha->io_addr + IPS_REG_FLDP);
+
+ if (status & 0x80)
+ break;
+
+ MDELAY(1);
+ timeout--;
+ }
+
+ if (timeout == 0) {
+ /* timeout error */
+ outl(0, ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ outb(0xFF, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ return (1);
+ }
+
+ /* check the status */
+ if (status & 0x18) {
+ /* programming error */
+ outl(0, ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ outb(0xFF, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ return (1);
+ }
+ } /* end for */
+
+ /* Enable reading */
+ outl(0, ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ outb(0xFF, ha->io_addr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ return (0);
}
/****************************************************************************/
@@ -6297,84 +6583,86 @@ ips_program_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offse
/* */
/****************************************************************************/
static int
-ips_program_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
- int i;
- int timeout;
- uint8_t status=0;
-
- METHOD_TRACE("ips_program_bios_memio", 1);
-
- status = 0;
-
- for (i = 0; i < buffersize; i++) {
- /* write a byte */
- writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- writeb(0x40, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- /* wait up to one second */
- timeout = 1000;
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
-
- status = readb(ha->mem_ptr + IPS_REG_FLDP);
-
- if (status & 0x80)
- break;
-
- MDELAY(1);
- timeout--;
- }
-
- if (timeout == 0) {
- /* timeout error */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- return (1);
- }
-
- /* check the status */
- if (status & 0x18) {
- /* programming error */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- return (1);
- }
- } /* end for */
-
- /* Enable reading */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- return (0);
+ips_program_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize,
+ uint32_t offset)
+{
+ int i;
+ int timeout;
+ uint8_t status = 0;
+
+ METHOD_TRACE("ips_program_bios_memio", 1);
+
+ status = 0;
+
+ for (i = 0; i < buffersize; i++) {
+ /* write a byte */
+ writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ writeb(0x40, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ /* wait up to one second */
+ timeout = 1000;
+ while (timeout > 0) {
+ if (ha->revision_id == IPS_REVID_TROMBONE64) {
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ udelay(25); /* 25 us */
+ }
+
+ status = readb(ha->mem_ptr + IPS_REG_FLDP);
+
+ if (status & 0x80)
+ break;
+
+ MDELAY(1);
+ timeout--;
+ }
+
+ if (timeout == 0) {
+ /* timeout error */
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ return (1);
+ }
+
+ /* check the status */
+ if (status & 0x18) {
+ /* programming error */
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ return (1);
+ }
+ } /* end for */
+
+ /* Enable reading */
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ return (0);
}
/****************************************************************************/
@@ -6386,42 +6674,44 @@ ips_program_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t
/* */
/****************************************************************************/
static int
-ips_verify_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
- uint8_t checksum;
- int i;
-
- METHOD_TRACE("ips_verify_bios", 1);
-
- /* test 1st byte */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
- return (1);
-
- outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
- return (1);
-
- checksum = 0xff;
- for (i = 2; i < buffersize; i++) {
-
- outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
- }
-
- if (checksum != 0)
- /* failure */
- return (1);
- else
- /* success */
- return (0);
+ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
+ uint32_t offset)
+{
+ uint8_t checksum;
+ int i;
+
+ METHOD_TRACE("ips_verify_bios", 1);
+
+ /* test 1st byte */
+ outl(0, ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
+ return (1);
+
+ outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+ if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
+ return (1);
+
+ checksum = 0xff;
+ for (i = 2; i < buffersize; i++) {
+
+ outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
+ }
+
+ if (checksum != 0)
+ /* failure */
+ return (1);
+ else
+ /* success */
+ return (0);
}
/****************************************************************************/
@@ -6433,42 +6723,45 @@ ips_verify_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset
/* */
/****************************************************************************/
static int
-ips_verify_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
- uint8_t checksum;
- int i;
-
- METHOD_TRACE("ips_verify_bios_memio", 1);
-
- /* test 1st byte */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
- return (1);
-
- writel(1, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
- return (1);
-
- checksum = 0xff;
- for (i = 2; i < buffersize; i++) {
-
- writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
-
- checksum = (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
- }
-
- if (checksum != 0)
- /* failure */
- return (1);
- else
- /* success */
- return (0);
+ips_verify_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize,
+ uint32_t offset)
+{
+ uint8_t checksum;
+ int i;
+
+ METHOD_TRACE("ips_verify_bios_memio", 1);
+
+ /* test 1st byte */
+ writel(0, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
+ return (1);
+
+ writel(1, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+ if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
+ return (1);
+
+ checksum = 0xff;
+ for (i = 2; i < buffersize; i++) {
+
+ writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
+ if (ha->revision_id == IPS_REVID_TROMBONE64)
+ udelay(25); /* 25 us */
+
+ checksum =
+ (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
+ }
+
+ if (checksum != 0)
+ /* failure */
+ return (1);
+ else
+ /* success */
+ return (0);
}
/*---------------------------------------------------------------------------*/
@@ -6478,118 +6771,125 @@ ips_verify_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t
/* Assumes that ips_read_adapter_status() is called first filling in */
/* the data for SubSystem Parameters. */
/* Called from ips_write_driver_status() so it also assumes NVRAM Page 5 */
-/* Data is availaible. */
+/* Data is available. */
/* */
/*---------------------------------------------------------------------------*/
-static void ips_version_check(ips_ha_t *ha, int intr) {
- IPS_VERSION_DATA VersionInfo;
- uint8_t FirmwareVersion[ IPS_COMPAT_ID_LENGTH + 1 ];
- uint8_t BiosVersion[ IPS_COMPAT_ID_LENGTH + 1];
- int MatchError;
- int rc;
- char BiosString[10];
- char FirmwareString[10];
-
- METHOD_TRACE("ips_version_check", 1);
-
- memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
- memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
-
- /* Get the Compatible BIOS Version from NVRAM Page 5 */
- memcpy(BiosVersion, ha->nvram->BiosCompatibilityID, IPS_COMPAT_ID_LENGTH);
-
- rc = IPS_FAILURE;
- if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) /* If Versioning is Supported */
- {
- /* Get the Version Info with a Get Version Command */
- rc = ips_get_version_info(ha, &VersionInfo, intr);
- if (rc == IPS_SUCCESS)
- memcpy(FirmwareVersion, VersionInfo.compatibilityId, IPS_COMPAT_ID_LENGTH);
- }
-
- if (rc != IPS_SUCCESS) /* If Data Not Obtainable from a GetVersion Command */
- {
- /* Get the Firmware Version from Enquiry Data */
- memcpy(FirmwareVersion, ha->enq->CodeBlkVersion, IPS_COMPAT_ID_LENGTH);
- }
-
- /* printk(KERN_WARNING "Adapter's BIOS Version = %s\n", BiosVersion); */
- /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS); */
- /* printk(KERN_WARNING "Adapter's Firmware Version = %s\n", FirmwareVersion); */
- /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */
-
- MatchError = 0;
-
- if (strncmp(FirmwareVersion, Compatable[ ha->nvram->adapter_type ], IPS_COMPAT_ID_LENGTH) != 0)
- MatchError = 1;
-
- if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0)
- MatchError = 1;
-
- ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */
-
- if (MatchError)
- {
- ha->nvram->version_mismatch = 1;
- if (ips_cd_boot == 0)
- {
- strncpy(&BiosString[0], ha->nvram->bios_high, 4);
- strncpy(&BiosString[4], ha->nvram->bios_low, 4);
- BiosString[8] = 0;
-
- strncpy(&FirmwareString[0], ha->enq->CodeBlkVersion, 8);
- FirmwareString[8] = 0;
-
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Warning ! ! ! ServeRAID Version Mismatch\n");
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Bios = %s, Firmware = %s, Device Driver = %s%s\n",
- BiosString, FirmwareString, IPS_VERSION_HIGH, IPS_VERSION_LOW );
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "These levels should match to avoid possible compatibility problems.\n");
- }
- }
- else
- {
- ha->nvram->version_mismatch = 0;
- }
-
- return;
+static void
+ips_version_check(ips_ha_t * ha, int intr)
+{
+ IPS_VERSION_DATA VersionInfo;
+ uint8_t FirmwareVersion[IPS_COMPAT_ID_LENGTH + 1];
+ uint8_t BiosVersion[IPS_COMPAT_ID_LENGTH + 1];
+ int MatchError;
+ int rc;
+ char BiosString[10];
+ char FirmwareString[10];
+
+ METHOD_TRACE("ips_version_check", 1);
+
+ memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
+ memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
+
+ /* Get the Compatible BIOS Version from NVRAM Page 5 */
+ memcpy(BiosVersion, ha->nvram->BiosCompatibilityID,
+ IPS_COMPAT_ID_LENGTH);
+
+ rc = IPS_FAILURE;
+ if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) { /* If Versioning is Supported */
+ /* Get the Version Info with a Get Version Command */
+ rc = ips_get_version_info(ha, &VersionInfo, intr);
+ if (rc == IPS_SUCCESS)
+ memcpy(FirmwareVersion, VersionInfo.compatibilityId,
+ IPS_COMPAT_ID_LENGTH);
+ }
+
+ if (rc != IPS_SUCCESS) { /* If Data Not Obtainable from a GetVersion Command */
+ /* Get the Firmware Version from Enquiry Data */
+ memcpy(FirmwareVersion, ha->enq->CodeBlkVersion,
+ IPS_COMPAT_ID_LENGTH);
+ }
+
+ /* printk(KERN_WARNING "Adapter's BIOS Version = %s\n", BiosVersion); */
+ /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS); */
+ /* printk(KERN_WARNING "Adapter's Firmware Version = %s\n", FirmwareVersion); */
+ /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */
+
+ MatchError = 0;
+
+ if (strncmp
+ (FirmwareVersion, Compatable[ha->nvram->adapter_type],
+ IPS_COMPAT_ID_LENGTH) != 0)
+ MatchError = 1;
+
+ if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0)
+ MatchError = 1;
+
+ ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */
+
+ if (MatchError) {
+ ha->nvram->version_mismatch = 1;
+ if (ips_cd_boot == 0) {
+ strncpy(&BiosString[0], ha->nvram->bios_high, 4);
+ strncpy(&BiosString[4], ha->nvram->bios_low, 4);
+ BiosString[8] = 0;
+
+ strncpy(&FirmwareString[0], ha->enq->CodeBlkVersion, 8);
+ FirmwareString[8] = 0;
+
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Warning ! ! ! ServeRAID Version Mismatch\n");
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Bios = %s, Firmware = %s, Device Driver = %s%s\n",
+ BiosString, FirmwareString, IPS_VERSION_HIGH,
+ IPS_VERSION_LOW);
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "These levels should match to avoid possible compatibility problems.\n");
+ }
+ } else {
+ ha->nvram->version_mismatch = 0;
+ }
+
+ return;
}
/*---------------------------------------------------------------------------*/
/* Routine Name: ips_get_version_info */
/* */
/* Routine Description: */
-/* Issue an internal GETVERSION ServeRAID Command */
+/* Issue an internal GETVERSION Command */
/* */
/* Return Value: */
/* 0 if Successful, else non-zero */
/*---------------------------------------------------------------------------*/
-static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ) {
- ips_scb_t *scb;
- int rc;
-
- METHOD_TRACE("ips_get_version_info", 1);
-
- memset(Buffer, 0, sizeof(IPS_VERSION_DATA));
- scb = &ha->scbs[ha->max_cmds-1];
-
- ips_init_scb(ha, scb);
-
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_GET_VERSION_INFO;
- scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO;
- scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.version_info.reserved = 0;
- scb->cmd.version_info.count = sizeof( IPS_VERSION_DATA);
- scb->cmd.version_info.reserved2 = 0;
- scb->data_len = sizeof(*Buffer);
- scb->data_busaddr = pci_map_single(ha->pcidev, Buffer,
- scb->data_len, IPS_DMA_DIR(scb));
- scb->cmd.version_info.buffer_addr = scb->data_busaddr;
- scb->flags |= IPS_SCB_MAP_SINGLE;
-
- /* issue command */
- rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
- return( rc );
+static int
+ips_get_version_info(ips_ha_t * ha, IPS_VERSION_DATA * Buffer, int intr)
+{
+ ips_scb_t *scb;
+ int rc;
+
+ METHOD_TRACE("ips_get_version_info", 1);
+
+ memset(Buffer, 0, sizeof (IPS_VERSION_DATA));
+ scb = &ha->scbs[ha->max_cmds - 1];
+
+ ips_init_scb(ha, scb);
+
+ scb->timeout = ips_cmd_timeout;
+ scb->cdb[0] = IPS_CMD_GET_VERSION_INFO;
+ scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO;
+ scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb);
+ scb->cmd.version_info.reserved = 0;
+ scb->cmd.version_info.count = sizeof (IPS_VERSION_DATA);
+ scb->cmd.version_info.reserved2 = 0;
+ scb->data_len = sizeof (*Buffer);
+ scb->data_busaddr = pci_map_single(ha->pcidev, Buffer,
+ scb->data_len, IPS_DMA_DIR(scb));
+ scb->cmd.version_info.buffer_addr = scb->data_busaddr;
+ scb->flags |= IPS_SCB_MAP_SINGLE;
+
+ /* issue command */
+ rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
+ return (rc);
}
/****************************************************************************/
@@ -6598,14 +6898,17 @@ static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr
/* */
/* Routine Description: */
/* cleanup routine for a failed adapter initialization */
-/****************************************************************************/
-static int ips_abort_init(ips_ha_t *ha, int index){
- ha->active = 0;
- ips_free(ha);
- ips_ha[index] = 0;
- ips_sh[index] = 0;
- return -1;
+/****************************************************************************/
+static int
+ips_abort_init(ips_ha_t * ha, int index)
+{
+ ha->active = 0;
+ ips_free(ha);
+ ips_ha[index] = 0;
+ ips_sh[index] = 0;
+ return -1;
}
+
/****************************************************************************/
/* */
/* Routine Name: ips_shift_controllers */
@@ -6614,12 +6917,13 @@ static int ips_abort_init(ips_ha_t *ha, int index){
/* helper function for ordering adapters */
/****************************************************************************/
static void
-ips_shift_controllers(int lowindex, int highindex){
+ips_shift_controllers(int lowindex, int highindex)
+{
ips_ha_t *ha_sav = ips_ha[highindex];
struct Scsi_Host *sh_sav = ips_sh[highindex];
int i;
- for ( i = highindex; i > lowindex; i--){
+ for (i = highindex; i > lowindex; i--) {
ips_ha[i] = ips_ha[i - 1];
ips_sh[i] = ips_sh[i - 1];
ips_ha[i]->host_num = i;
@@ -6637,20 +6941,22 @@ ips_shift_controllers(int lowindex, int highindex){
/* place controllers is the "proper" boot order */
/****************************************************************************/
static void
-ips_order_controllers(void){
+ips_order_controllers(void)
+{
int i, j, tmp, position = 0;
IPS_NVRAM_P5 *nvram;
- if(!ips_ha[0])
+ if (!ips_ha[0])
return;
nvram = ips_ha[0]->nvram;
- if(nvram->adapter_order[0]){
- for(i = 1; i <= nvram->adapter_order[0]; i++){
- for(j = position; j < ips_num_controllers; j++){
- switch(ips_ha[j]->ad_type){
+ if (nvram->adapter_order[0]) {
+ for (i = 1; i <= nvram->adapter_order[0]; i++) {
+ for (j = position; j < ips_num_controllers; j++) {
+ switch (ips_ha[j]->ad_type) {
case IPS_ADTYPE_SERVERAID6M:
- if(nvram->adapter_order[i] == 'M'){
- ips_shift_controllers(position, j);
+ if (nvram->adapter_order[i] == 'M') {
+ ips_shift_controllers(position,
+ j);
position++;
}
break;
@@ -6658,16 +6964,18 @@ ips_order_controllers(void){
case IPS_ADTYPE_SERVERAID4M:
case IPS_ADTYPE_SERVERAID4MX:
case IPS_ADTYPE_SERVERAID4LX:
- if(nvram->adapter_order[i] == 'N'){
- ips_shift_controllers(position, j);
+ if (nvram->adapter_order[i] == 'N') {
+ ips_shift_controllers(position,
+ j);
position++;
}
break;
case IPS_ADTYPE_SERVERAID6I:
case IPS_ADTYPE_SERVERAID5I2:
case IPS_ADTYPE_SERVERAID5I1:
- if(nvram->adapter_order[i] == 'S'){
- ips_shift_controllers(position, j);
+ if (nvram->adapter_order[i] == 'S') {
+ ips_shift_controllers(position,
+ j);
position++;
}
break;
@@ -6678,8 +6986,9 @@ ips_order_controllers(void){
case IPS_ADTYPE_SERVERAID3L:
case IPS_ADTYPE_SERVERAID3:
case IPS_ADTYPE_SERVERAID4H:
- if(nvram->adapter_order[i] == 'A'){
- ips_shift_controllers(position, j);
+ if (nvram->adapter_order[i] == 'A') {
+ ips_shift_controllers(position,
+ j);
position++;
}
break;
@@ -6693,9 +7002,9 @@ ips_order_controllers(void){
}
/* old bios, use older ordering */
tmp = 0;
- for(i = position; i < ips_num_controllers; i++){
+ for (i = position; i < ips_num_controllers; i++) {
if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I2 ||
- ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I1){
+ ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I1) {
ips_shift_controllers(position, i);
position++;
tmp = 1;
@@ -6704,11 +7013,11 @@ ips_order_controllers(void){
/* if there were no 5I cards, then don't do any extra ordering */
if (!tmp)
return;
- for(i = position; i < ips_num_controllers; i++){
+ for (i = position; i < ips_num_controllers; i++) {
if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4L ||
ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4M ||
ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4LX ||
- ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4MX){
+ ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4MX) {
ips_shift_controllers(position, i);
position++;
}
@@ -6717,7 +7026,6 @@ ips_order_controllers(void){
return;
}
-
/****************************************************************************/
/* */
/* Routine Name: ips_register_scsi */
@@ -6726,20 +7034,23 @@ ips_order_controllers(void){
/* perform any registration and setup with the scsi layer */
/****************************************************************************/
static int
-ips_register_scsi( int index){
+ips_register_scsi(int index)
+{
struct Scsi_Host *sh;
ips_ha_t *ha, *oldha = ips_ha[index];
- sh = scsi_host_alloc(&ips_driver_template, sizeof(ips_ha_t));
- if(!sh) {
- IPS_PRINTK(KERN_WARNING, oldha->pcidev, "Unable to register controller with SCSI subsystem\n");
+ sh = scsi_host_alloc(&ips_driver_template, sizeof (ips_ha_t));
+ if (!sh) {
+ IPS_PRINTK(KERN_WARNING, oldha->pcidev,
+ "Unable to register controller with SCSI subsystem\n");
return -1;
}
ha = IPS_HA(sh);
- memcpy(ha, oldha, sizeof(ips_ha_t));
+ memcpy(ha, oldha, sizeof (ips_ha_t));
free_irq(oldha->irq, oldha);
/* Install the interrupt handler with the new ha */
if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to install interrupt handler\n" );
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Unable to install interrupt handler\n");
scsi_host_put(sh);
return -1;
}
@@ -6762,12 +7073,12 @@ ips_register_scsi( int index){
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
sh->max_sectors = 128;
-#endif
+#endif
sh->max_id = ha->ntargets;
sh->max_lun = ha->nlun;
sh->max_channel = ha->nbus - 1;
- sh->can_queue = ha->max_cmds-1;
+ sh->can_queue = ha->max_cmds - 1;
IPS_ADD_HOST(sh, NULL);
return 0;
@@ -6779,22 +7090,23 @@ ips_register_scsi( int index){
/* Routine Description: */
/* Remove one Adapter ( Hot Plugging ) */
/*---------------------------------------------------------------------------*/
-static void __devexit ips_remove_device(struct pci_dev *pci_dev)
+static void __devexit
+ips_remove_device(struct pci_dev *pci_dev)
{
- int i;
- struct Scsi_Host *sh;
- ips_ha_t *ha;
-
- for (i = 0; i < IPS_MAX_ADAPTERS; i++) {
- ha = ips_ha[i];
- if (ha) {
- if ( (pci_dev->bus->number == ha->pcidev->bus->number) &&
- (pci_dev->devfn == ha->pcidev->devfn)) {
- sh = ips_sh[i];
- ips_release(sh);
- }
- }
- }
+ int i;
+ struct Scsi_Host *sh;
+ ips_ha_t *ha;
+
+ for (i = 0; i < IPS_MAX_ADAPTERS; i++) {
+ ha = ips_ha[i];
+ if (ha) {
+ if ((pci_dev->bus->number == ha->pcidev->bus->number) &&
+ (pci_dev->devfn == ha->pcidev->devfn)) {
+ sh = ips_sh[i];
+ ips_release(sh);
+ }
+ }
+ }
}
/****************************************************************************/
@@ -6805,12 +7117,13 @@ static void __devexit ips_remove_device(struct pci_dev *pci_dev)
/* function called on module load */
/****************************************************************************/
static int __init
-ips_module_init(void){
- if( pci_module_init(&ips_pci_driver) < 0 )
+ips_module_init(void)
+{
+ if (pci_module_init(&ips_pci_driver) < 0)
return -ENODEV;
ips_driver_template.module = THIS_MODULE;
ips_order_controllers();
- if( IPS_REGISTER_HOSTS(&ips_driver_template) ){
+ if (IPS_REGISTER_HOSTS(&ips_driver_template)) {
pci_unregister_driver(&ips_pci_driver);
return -ENODEV;
}
@@ -6826,7 +7139,8 @@ ips_module_init(void){
/* function called on module unload */
/****************************************************************************/
static void __exit
-ips_module_exit(void){
+ips_module_exit(void)
+{
IPS_UNREGISTER_HOSTS(&ips_driver_template);
pci_unregister_driver(&ips_pci_driver);
unregister_reboot_notifier(&ips_notifier);
@@ -6844,33 +7158,33 @@ module_exit(ips_module_exit);
/* Return Value: */
/* 0 if Successful, else non-zero */
/*---------------------------------------------------------------------------*/
-static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent)
+static int __devinit
+ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent)
{
- int index;
- int rc;
+ int index;
+ int rc;
- METHOD_TRACE("ips_insert_device", 1);
- if (pci_enable_device(pci_dev))
+ METHOD_TRACE("ips_insert_device", 1);
+ if (pci_enable_device(pci_dev))
return -1;
- rc = ips_init_phase1(pci_dev, &index);
- if (rc == SUCCESS)
- rc = ips_init_phase2(index);
+ rc = ips_init_phase1(pci_dev, &index);
+ if (rc == SUCCESS)
+ rc = ips_init_phase2(index);
- if(ips_hotplug)
- if(ips_register_scsi(index)){
- ips_free(ips_ha[index]);
- rc = -1;
- }
+ if (ips_hotplug)
+ if (ips_register_scsi(index)) {
+ ips_free(ips_ha[index]);
+ rc = -1;
+ }
- if (rc == SUCCESS)
- ips_num_controllers++;
+ if (rc == SUCCESS)
+ ips_num_controllers++;
- ips_next_controller = ips_num_controllers;
- return rc;
+ ips_next_controller = ips_num_controllers;
+ return rc;
}
-
/*---------------------------------------------------------------------------*/
/* Routine Name: ips_init_phase1 */
/* */
@@ -6880,221 +7194,236 @@ static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci
/* Return Value: */
/* 0 if Successful, else non-zero */
/*---------------------------------------------------------------------------*/
-static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
-{
- ips_ha_t *ha;
- uint32_t io_addr;
- uint32_t mem_addr;
- uint32_t io_len;
- uint32_t mem_len;
- uint8_t revision_id;
- uint8_t bus;
- uint8_t func;
- uint8_t irq;
- uint16_t subdevice_id;
- int j;
- int index;
- uint32_t count;
- dma_addr_t dma_address;
- char *ioremap_ptr;
- char *mem_ptr;
- uint32_t IsDead;
-
- METHOD_TRACE("ips_init_phase1", 1);
- index = IPS_MAX_ADAPTERS;
- for (j = 0; j < IPS_MAX_ADAPTERS; j++) {
- if (ips_ha[j] ==0) {
- index = j;
- break;
- }
- }
-
- if (index >= IPS_MAX_ADAPTERS)
- return -1;
-
- /* stuff that we get in dev */
- irq = pci_dev->irq;
- bus = pci_dev->bus->number;
- func = pci_dev->devfn;
-
- /* Init MEM/IO addresses to 0 */
- mem_addr = 0;
- io_addr = 0;
- mem_len = 0;
- io_len = 0;
-
- for (j = 0; j < 2; j++) {
- if (!pci_resource_start(pci_dev, j))
- break;
-
- if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) {
- io_addr = pci_resource_start(pci_dev, j);
- io_len = pci_resource_len(pci_dev, j);
- } else {
- mem_addr = pci_resource_start(pci_dev, j);
- mem_len = pci_resource_len(pci_dev, j);
- }
- }
-
- /* setup memory mapped area (if applicable) */
- if (mem_addr) {
- uint32_t base;
- uint32_t offs;
-
- if (!request_mem_region(mem_addr, mem_len, "ips")) {
- IPS_PRINTK(KERN_WARNING, pci_dev, "Couldn't allocate IO Memory space %x len %d.\n", mem_addr, mem_len);
- return -1;
- }
-
- base = mem_addr & PAGE_MASK;
- offs = mem_addr - base;
- ioremap_ptr = ioremap(base, PAGE_SIZE);
- mem_ptr = ioremap_ptr + offs;
- } else {
- ioremap_ptr = NULL;
- mem_ptr = NULL;
- }
-
- /* setup I/O mapped area (if applicable) */
- if (io_addr) {
- if (!request_region(io_addr, io_len, "ips")) {
- IPS_PRINTK(KERN_WARNING, pci_dev, "Couldn't allocate IO space %x len %d.\n", io_addr, io_len);
- return -1;
- }
- }
-
- /* get the revision ID */
- if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) {
- IPS_PRINTK(KERN_WARNING, pci_dev, "Can't get revision id.\n");
- return -1;
- }
-
- subdevice_id = pci_dev->subsystem_device;
-
- /* found a controller */
- ha = kmalloc(sizeof(ips_ha_t), GFP_KERNEL);
- if (ha == NULL) {
- IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate temporary ha struct\n");
- return -1;
- }
-
- memset(ha, 0, sizeof(ips_ha_t));
-
- ips_sh[index] = NULL;
- ips_ha[index] = ha;
- ha->active = 1;
-
- /* Store info in HA structure */
- ha->irq = irq;
- ha->io_addr = io_addr;
- ha->io_len = io_len;
- ha->mem_addr = mem_addr;
- ha->mem_len = mem_len;
- ha->mem_ptr = mem_ptr;
- ha->ioremap_ptr = ioremap_ptr;
- ha->host_num = ( uint32_t) index;
- ha->revision_id = revision_id;
- ha->slot_num = PCI_SLOT(pci_dev->devfn);
- ha->device_id = pci_dev->device;
- ha->subdevice_id = subdevice_id;
- ha->pcidev = pci_dev;
-
- /*
- * Set the pci_dev's dma_mask. Not all adapters support 64bit
- * addressing so don't enable it if the adapter can't support
- * it! Also, don't use 64bit addressing if dma addresses
- * are guaranteed to be < 4G.
- */
- if ( IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) &&
- !pci_set_dma_mask(ha->pcidev, 0xffffffffffffffffULL)) {
- (ha)->flags |= IPS_HA_ENH_SG;
- } else {
- if ( pci_set_dma_mask(ha->pcidev, 0xffffffffULL) != 0 ) {
- printk(KERN_WARNING "Unable to set DMA Mask\n");
- return ips_abort_init(ha, index);
- }
- }
-
- ha->enq = kmalloc(sizeof(IPS_ENQ), IPS_INIT_GFP);
-
- if (!ha->enq) {
- IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate host inquiry structure\n" );
- return ips_abort_init(ha, index);
- }
-
- ha->adapt = pci_alloc_consistent(pci_dev, sizeof(IPS_ADAPTER) +
- sizeof(IPS_IO_CMD), &dma_address);
- if (!ha->adapt) {
- IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate host adapt & dummy structures\n");
- return ips_abort_init(ha, index);
- }
- ha->adapt->hw_status_start = dma_address;
- ha->dummy = (void *)(ha->adapt + 1);
-
- ha->conf = kmalloc(sizeof(IPS_CONF), IPS_INIT_GFP);
-
- if (!ha->conf) {
- IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate host conf structure\n");
- return ips_abort_init(ha, index);
- }
-
- ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), IPS_INIT_GFP);
-
- if (!ha->nvram) {
- IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate host NVRAM structure\n");
- return ips_abort_init(ha, index);
- }
-
- ha->subsys = kmalloc(sizeof(IPS_SUBSYS), IPS_INIT_GFP);
-
- if (!ha->subsys) {
- IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate host subsystem structure\n");
- return ips_abort_init(ha, index);
- }
-
- for (count = PAGE_SIZE, ha->ioctl_order = 0;
- count < ips_ioctlsize;
- ha->ioctl_order++, count <<= 1);
-
- ha->ioctl_data = (char *) __get_free_pages(IPS_INIT_GFP, ha->ioctl_order);
- ha->ioctl_datasize = count;
-
- if (!ha->ioctl_data) {
- IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate IOCTL data\n");
- ha->ioctl_data = NULL;
- ha->ioctl_order = 0;
- ha->ioctl_datasize = 0;
- }
-
- /*
- * Setup Functions
- */
- ips_setup_funclist(ha);
-
- if ( ( IPS_IS_MORPHEUS( ha ) ) || ( IPS_IS_MARCO( ha ) ) ) {
- /* If Morpheus appears dead, reset it */
- IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 );
- if ( IsDead == 0xDEADBEEF ) {
- ips_reset_morpheus( ha );
- }
- }
-
- /*
- * Initialize the card if it isn't already
- */
-
- if (!(*ha->func.isinit)(ha)) {
- if (!(*ha->func.init)(ha)) {
- /*
- * Initialization failed
- */
- IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to initialize controller\n");
- return ips_abort_init(ha, index);
- }
- }
-
- *indexPtr = index;
- return SUCCESS;
+static int
+ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr)
+{
+ ips_ha_t *ha;
+ uint32_t io_addr;
+ uint32_t mem_addr;
+ uint32_t io_len;
+ uint32_t mem_len;
+ uint8_t revision_id;
+ uint8_t bus;
+ uint8_t func;
+ uint8_t irq;
+ uint16_t subdevice_id;
+ int j;
+ int index;
+ dma_addr_t dma_address;
+ char *ioremap_ptr;
+ char *mem_ptr;
+ uint32_t IsDead;
+
+ METHOD_TRACE("ips_init_phase1", 1);
+ index = IPS_MAX_ADAPTERS;
+ for (j = 0; j < IPS_MAX_ADAPTERS; j++) {
+ if (ips_ha[j] == 0) {
+ index = j;
+ break;
+ }
+ }
+
+ if (index >= IPS_MAX_ADAPTERS)
+ return -1;
+
+ /* stuff that we get in dev */
+ irq = pci_dev->irq;
+ bus = pci_dev->bus->number;
+ func = pci_dev->devfn;
+
+ /* Init MEM/IO addresses to 0 */
+ mem_addr = 0;
+ io_addr = 0;
+ mem_len = 0;
+ io_len = 0;
+
+ for (j = 0; j < 2; j++) {
+ if (!pci_resource_start(pci_dev, j))
+ break;
+
+ if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) {
+ io_addr = pci_resource_start(pci_dev, j);
+ io_len = pci_resource_len(pci_dev, j);
+ } else {
+ mem_addr = pci_resource_start(pci_dev, j);
+ mem_len = pci_resource_len(pci_dev, j);
+ }
+ }
+
+ /* setup memory mapped area (if applicable) */
+ if (mem_addr) {
+ uint32_t base;
+ uint32_t offs;
+
+ if (!request_mem_region(mem_addr, mem_len, "ips")) {
+ IPS_PRINTK(KERN_WARNING, pci_dev,
+ "Couldn't allocate IO Memory space %x len %d.\n",
+ mem_addr, mem_len);
+ return -1;
+ }
+
+ base = mem_addr & PAGE_MASK;
+ offs = mem_addr - base;
+ ioremap_ptr = ioremap(base, PAGE_SIZE);
+ mem_ptr = ioremap_ptr + offs;
+ } else {
+ ioremap_ptr = NULL;
+ mem_ptr = NULL;
+ }
+
+ /* setup I/O mapped area (if applicable) */
+ if (io_addr) {
+ if (!request_region(io_addr, io_len, "ips")) {
+ IPS_PRINTK(KERN_WARNING, pci_dev,
+ "Couldn't allocate IO space %x len %d.\n",
+ io_addr, io_len);
+ return -1;
+ }
+ }
+
+ /* get the revision ID */
+ if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) {
+ IPS_PRINTK(KERN_WARNING, pci_dev, "Can't get revision id.\n");
+ return -1;
+ }
+
+ subdevice_id = pci_dev->subsystem_device;
+
+ /* found a controller */
+ ha = kmalloc(sizeof (ips_ha_t), GFP_KERNEL);
+ if (ha == NULL) {
+ IPS_PRINTK(KERN_WARNING, pci_dev,
+ "Unable to allocate temporary ha struct\n");
+ return -1;
+ }
+
+ memset(ha, 0, sizeof (ips_ha_t));
+
+ ips_sh[index] = NULL;
+ ips_ha[index] = ha;
+ ha->active = 1;
+
+ /* Store info in HA structure */
+ ha->irq = irq;
+ ha->io_addr = io_addr;
+ ha->io_len = io_len;
+ ha->mem_addr = mem_addr;
+ ha->mem_len = mem_len;
+ ha->mem_ptr = mem_ptr;
+ ha->ioremap_ptr = ioremap_ptr;
+ ha->host_num = (uint32_t) index;
+ ha->revision_id = revision_id;
+ ha->slot_num = PCI_SLOT(pci_dev->devfn);
+ ha->device_id = pci_dev->device;
+ ha->subdevice_id = subdevice_id;
+ ha->pcidev = pci_dev;
+
+ /*
+ * Set the pci_dev's dma_mask. Not all adapters support 64bit
+ * addressing so don't enable it if the adapter can't support
+ * it! Also, don't use 64bit addressing if dma addresses
+ * are guaranteed to be < 4G.
+ */
+ if (IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) &&
+ !pci_set_dma_mask(ha->pcidev, 0xffffffffffffffffULL)) {
+ (ha)->flags |= IPS_HA_ENH_SG;
+ } else {
+ if (pci_set_dma_mask(ha->pcidev, 0xffffffffULL) != 0) {
+ printk(KERN_WARNING "Unable to set DMA Mask\n");
+ return ips_abort_init(ha, index);
+ }
+ }
+ if(ips_cd_boot && !ips_FlashData){
+ ips_FlashData = pci_alloc_consistent(pci_dev, PAGE_SIZE << 7,
+ &ips_flashbusaddr);
+ }
+
+ ha->enq = pci_alloc_consistent(pci_dev, sizeof (IPS_ENQ),
+ &ha->enq_busaddr);
+ if (!ha->enq) {
+ IPS_PRINTK(KERN_WARNING, pci_dev,
+ "Unable to allocate host inquiry structure\n");
+ return ips_abort_init(ha, index);
+ }
+
+ ha->adapt = pci_alloc_consistent(pci_dev, sizeof (IPS_ADAPTER) +
+ sizeof (IPS_IO_CMD), &dma_address);
+ if (!ha->adapt) {
+ IPS_PRINTK(KERN_WARNING, pci_dev,
+ "Unable to allocate host adapt & dummy structures\n");
+ return ips_abort_init(ha, index);
+ }
+ ha->adapt->hw_status_start = dma_address;
+ ha->dummy = (void *) (ha->adapt + 1);
+
+ ha->conf = kmalloc(sizeof (IPS_CONF), GFP_KERNEL);
+
+ if (!ha->conf) {
+ IPS_PRINTK(KERN_WARNING, pci_dev,
+ "Unable to allocate host conf structure\n");
+ return ips_abort_init(ha, index);
+ }
+
+ ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), GFP_KERNEL);
+
+ if (!ha->nvram) {
+ IPS_PRINTK(KERN_WARNING, pci_dev,
+ "Unable to allocate host NVRAM structure\n");
+ return ips_abort_init(ha, index);
+ }
+
+ ha->subsys = kmalloc(sizeof (IPS_SUBSYS), GFP_KERNEL);
+
+ if (!ha->subsys) {
+ IPS_PRINTK(KERN_WARNING, pci_dev,
+ "Unable to allocate host subsystem structure\n");
+ return ips_abort_init(ha, index);
+ }
+
+ /* the ioctl buffer is now used during adapter initialization, so its
+ * successful allocation is now required */
+ if (ips_ioctlsize < PAGE_SIZE)
+ ips_ioctlsize = PAGE_SIZE;
+
+ ha->ioctl_data = pci_alloc_consistent(pci_dev, ips_ioctlsize,
+ &ha->ioctl_busaddr);
+ ha->ioctl_len = ips_ioctlsize;
+ if (!ha->ioctl_data) {
+ IPS_PRINTK(KERN_WARNING, pci_dev,
+ "Unable to allocate IOCTL data\n");
+ return ips_abort_init(ha, index);
+ }
+
+ /*
+ * Setup Functions
+ */
+ ips_setup_funclist(ha);
+
+ if ((IPS_IS_MORPHEUS(ha)) || (IPS_IS_MARCO(ha))) {
+ /* If Morpheus appears dead, reset it */
+ IsDead = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
+ if (IsDead == 0xDEADBEEF) {
+ ips_reset_morpheus(ha);
+ }
+ }
+
+ /*
+ * Initialize the card if it isn't already
+ */
+
+ if (!(*ha->func.isinit) (ha)) {
+ if (!(*ha->func.init) (ha)) {
+ /*
+ * Initialization failed
+ */
+ IPS_PRINTK(KERN_WARNING, pci_dev,
+ "Unable to initialize controller\n");
+ return ips_abort_init(ha, index);
+ }
+ }
+
+ *indexPtr = index;
+ return SUCCESS;
}
/*---------------------------------------------------------------------------*/
@@ -7106,52 +7435,56 @@ static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
/* Return Value: */
/* 0 if Successful, else non-zero */
/*---------------------------------------------------------------------------*/
-static int ips_init_phase2( int index )
-{
- ips_ha_t *ha;
-
- ha = ips_ha[index];
-
- METHOD_TRACE("ips_init_phase2", 1);
- if (!ha->active) {
- ips_ha[index] = NULL;
- return -1;
- }
-
- /* Install the interrupt handler */
- if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to install interrupt handler\n");
- return ips_abort_init(ha, index);
- }
-
- /*
- * Allocate a temporary SCB for initialization
- */
- ha->max_cmds = 1;
- if (!ips_allocatescbs(ha)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to allocate a CCB\n");
- free_irq(ha->irq, ha);
- return ips_abort_init(ha, index);
- }
-
- if (!ips_hainit(ha)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to initialize controller\n");
- free_irq(ha->irq, ha);
- return ips_abort_init(ha, index);
- }
- /* Free the temporary SCB */
- ips_deallocatescbs(ha, 1);
-
- /* allocate CCBs */
- if (!ips_allocatescbs(ha)) {
- IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to allocate CCBs\n");
- free_irq(ha->irq, ha);
- return ips_abort_init(ha, index);
- }
-
- return SUCCESS;
-}
+static int
+ips_init_phase2(int index)
+{
+ ips_ha_t *ha;
+
+ ha = ips_ha[index];
+
+ METHOD_TRACE("ips_init_phase2", 1);
+ if (!ha->active) {
+ ips_ha[index] = NULL;
+ return -1;
+ }
+
+ /* Install the interrupt handler */
+ if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Unable to install interrupt handler\n");
+ return ips_abort_init(ha, index);
+ }
+
+ /*
+ * Allocate a temporary SCB for initialization
+ */
+ ha->max_cmds = 1;
+ if (!ips_allocatescbs(ha)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Unable to allocate a CCB\n");
+ free_irq(ha->irq, ha);
+ return ips_abort_init(ha, index);
+ }
+ if (!ips_hainit(ha)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Unable to initialize controller\n");
+ free_irq(ha->irq, ha);
+ return ips_abort_init(ha, index);
+ }
+ /* Free the temporary SCB */
+ ips_deallocatescbs(ha, 1);
+
+ /* allocate CCBs */
+ if (!ips_allocatescbs(ha)) {
+ IPS_PRINTK(KERN_WARNING, ha->pcidev,
+ "Unable to allocate CCBs\n");
+ free_irq(ha->irq, ha);
+ return ips_abort_init(ha, index);
+ }
+
+ return SUCCESS;
+}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
MODULE_LICENSE("GPL");
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h
index 47fe2c278661..28b7acac3713 100644
--- a/drivers/scsi/ips.h
+++ b/drivers/scsi/ips.h
@@ -106,8 +106,10 @@
#define IPS_REMOVE_HOST(shost)
#define IPS_SCSI_SET_DEVICE(sh,ha) scsi_set_pci_device(sh, (ha)->pcidev)
#define IPS_PRINTK(level, pcidev, format, arg...) \
- printk(level "%s %s:" format , (pcidev)->driver->name , \
- pci_name(pcidev) , ## arg)
+ printk(level "%s %s:" format , "ips" , \
+ (pcidev)->slot_name , ## arg)
+ #define scsi_host_alloc(sh,size) scsi_register(sh,size)
+ #define scsi_host_put(sh) scsi_unregister(sh)
#else
#define IPS_REGISTER_HOSTS(SHT) (!ips_detect(SHT))
#define IPS_UNREGISTER_HOSTS(SHT)
@@ -126,22 +128,13 @@
#define min(x,y) ((x) < (y) ? x : y)
#endif
+ #define pci_dma_hi32(a) ((a >> 16) >> 16)
#define pci_dma_lo32(a) (a & 0xffffffff)
#if (BITS_PER_LONG > 32) || (defined CONFIG_HIGHMEM64G && defined IPS_HIGHIO)
#define IPS_ENABLE_DMA64 (1)
- #define pci_dma_hi32(a) (a >> 32)
#else
#define IPS_ENABLE_DMA64 (0)
- #define pci_dma_hi32(a) (0)
- #endif
-
- #if defined(__ia64__)
- #define IPS_ATOMIC_GFP (GFP_DMA | GFP_ATOMIC)
- #define IPS_INIT_GFP GFP_DMA
- #else
- #define IPS_ATOMIC_GFP GFP_ATOMIC
- #define IPS_INIT_GFP GFP_KERNEL
#endif
/*
@@ -451,9 +444,11 @@
* Scsi_Host Template
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ static int ips_proc24_info(char *, char **, off_t, int, int, int);
static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
static int ips_biosparam(Disk *disk, kdev_t dev, int geom[]);
#else
+ int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int geom[]);
int ips_slave_configure(Scsi_Device *SDptr);
@@ -1106,7 +1101,8 @@ typedef struct ips_ha {
uint16_t device_id; /* PCI device ID */
uint8_t slot_num; /* PCI Slot Number */
uint16_t subdevice_id; /* Subsystem device ID */
- uint8_t ioctl_order; /* Number of pages in ioctl */
+ int ioctl_len; /* size of ioctl buffer */
+ dma_addr_t ioctl_busaddr; /* dma address of ioctl buffer*/
uint8_t bios_version[8]; /* BIOS Revision */
uint32_t mem_addr; /* Memory mapped address */
uint32_t io_len; /* Size of IO Address */
@@ -1116,8 +1112,10 @@ typedef struct ips_ha {
ips_hw_func_t func; /* hw function pointers */
struct pci_dev *pcidev; /* PCI device handle */
char *flash_data; /* Save Area for flash data */
- u8 flash_order; /* Save Area for flash size order */
+ int flash_len; /* length of flash buffer */
u32 flash_datasize; /* Save Area for flash data size */
+ dma_addr_t flash_busaddr; /* dma address of flash buffer*/
+ dma_addr_t enq_busaddr; /* dma address of enq struct */
uint8_t requires_esl; /* Requires an EraseStripeLock */
} ips_ha_t;
@@ -1203,25 +1201,29 @@ typedef struct {
*
*************************************************************************/
-#define IPS_VER_MAJOR 5
-#define IPS_VER_MAJOR_STRING "5"
-#define IPS_VER_MINOR 99
-#define IPS_VER_MINOR_STRING "99"
-#define IPS_VER_BUILD 00
-#define IPS_VER_BUILD_STRING "00"
-#define IPS_VER_STRING "5.99.00"
-#define IPS_BUILD_IDENT 1132
+#define IPS_VER_MAJOR 6
+#define IPS_VER_MAJOR_STRING "6"
+#define IPS_VER_MINOR 10
+#define IPS_VER_MINOR_STRING "10"
+#define IPS_VER_BUILD 90
+#define IPS_VER_BUILD_STRING "90"
+#define IPS_VER_STRING "6.10.90"
+#define IPS_RELEASE_ID 0x00010000
+#define IPS_BUILD_IDENT 364
+#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003. All Rights Reserved."
+#define IPS_ADAPTECCOPYRIGHT_STRING "(c) Copyright Adaptec, Inc. 2002 to present. All Rights Reserved."
+#define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2003."
/* Version numbers for various adapters */
#define IPS_VER_SERVERAID1 "2.25.01"
#define IPS_VER_SERVERAID2 "2.88.13"
#define IPS_VER_NAVAJO "2.88.13"
-#define IPS_VER_SERVERAID3 "5.11.05"
-#define IPS_VER_SERVERAID4H "5.11.05"
-#define IPS_VER_SERVERAID4MLx "5.11.05"
-#define IPS_VER_SARASOTA "5.11.05"
-#define IPS_VER_MARCO "0.00.00"
-#define IPS_VER_SEBRING "0.00.00"
+#define IPS_VER_SERVERAID3 "6.10.24"
+#define IPS_VER_SERVERAID4H "6.10.24"
+#define IPS_VER_SERVERAID4MLx "6.10.24"
+#define IPS_VER_SARASOTA "6.10.24"
+#define IPS_VER_MARCO "6.10.24"
+#define IPS_VER_SEBRING "6.10.24"
/* Compatability IDs for various adapters */
#define IPS_COMPAT_UNKNOWN ""
@@ -1230,17 +1232,17 @@ typedef struct {
#define IPS_COMPAT_SERVERAID2 "2.88.13"
#define IPS_COMPAT_NAVAJO "2.88.13"
#define IPS_COMPAT_KIOWA "2.88.13"
-#define IPS_COMPAT_SERVERAID3H "SA510"
-#define IPS_COMPAT_SERVERAID3L "SA510"
-#define IPS_COMPAT_SERVERAID4H "SA510"
-#define IPS_COMPAT_SERVERAID4M "SA510"
-#define IPS_COMPAT_SERVERAID4L "SA510"
-#define IPS_COMPAT_SERVERAID4Mx "SA510"
-#define IPS_COMPAT_SERVERAID4Lx "SA510"
-#define IPS_COMPAT_SARASOTA "SA510"
-#define IPS_COMPAT_MARCO "SA000"
-#define IPS_COMPAT_SEBRING "SA000"
-#define IPS_COMPAT_BIOS "SA510"
+#define IPS_COMPAT_SERVERAID3H "SB610"
+#define IPS_COMPAT_SERVERAID3L "SB610"
+#define IPS_COMPAT_SERVERAID4H "SB610"
+#define IPS_COMPAT_SERVERAID4M "SB610"
+#define IPS_COMPAT_SERVERAID4L "SB610"
+#define IPS_COMPAT_SERVERAID4Mx "SB610"
+#define IPS_COMPAT_SERVERAID4Lx "SB610"
+#define IPS_COMPAT_SARASOTA "SB610"
+#define IPS_COMPAT_MARCO "SB610"
+#define IPS_COMPAT_SEBRING "SB610"
+#define IPS_COMPAT_BIOS "SB610"
#define IPS_COMPAT_MAX_ADAPTER_TYPE 16
#define IPS_COMPAT_ID_LENGTH 8
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index 25cff061f4a1..3fabd0618de0 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -86,14 +86,10 @@ lasi700_driver_callback(struct parisc_device *dev)
struct NCR_700_Host_Parameters *hostdata;
struct Scsi_Host *host;
- snprintf(dev->dev.name, sizeof(dev->dev.name), "%s",
- (dev->id.sversion == LASI_700_SVERSION) ?
- "lasi700" : "lasi710");
-
hostdata = kmalloc(sizeof(*hostdata), GFP_KERNEL);
if (!hostdata) {
printk(KERN_ERR "%s: Failed to allocate host data\n",
- dev->dev.name);
+ dev->dev.bus_id);
return 1;
}
memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
@@ -121,9 +117,9 @@ lasi700_driver_callback(struct parisc_device *dev)
host->irq = dev->irq;
if (request_irq(dev->irq, NCR_700_intr, SA_SHIRQ,
- dev->dev.name, host)) {
+ dev->dev.bus_id, host)) {
printk(KERN_ERR "%s: irq problem, detaching\n",
- dev->dev.name);
+ dev->dev.bus_id);
goto out_put_host;
}
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 0e381b816734..604a668b2342 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -177,13 +177,8 @@ static void aha152x_detach(dev_link_t *link)
if (*linkp == NULL)
return;
- if (link->state & DEV_CONFIG) {
+ if (link->state & DEV_CONFIG)
aha152x_release_cs(link);
- if (link->state & DEV_STALE_CONFIG) {
- link->state |= DEV_STALE_LINK;
- return;
- }
- }
if (link->handle)
CardServices(DeregisterClient, link->handle);
@@ -302,9 +297,6 @@ static void aha152x_release_cs(dev_link_t *link)
link->state &= ~DEV_CONFIG;
scsi_unregister(info->host);
-
- if (link->state & DEV_STALE_LINK)
- aha152x_detach(link);
}
static int aha152x_event(event_t event, int priority,
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index 09ef39d759e7..35cd7e3e8b74 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -166,13 +166,8 @@ static void fdomain_detach(dev_link_t *link)
if (*linkp == NULL)
return;
- if (link->state & DEV_CONFIG) {
+ if (link->state & DEV_CONFIG)
fdomain_release(link);
- if (link->state & DEV_STALE_CONFIG) {
- link->state |= DEV_STALE_LINK;
- return;
- }
- }
if (link->handle)
CardServices(DeregisterClient, link->handle);
@@ -283,9 +278,7 @@ static void fdomain_release(dev_link_t *link)
scsi_unregister(info->host);
link->state &= ~DEV_CONFIG;
- if (link->state & DEV_STALE_LINK)
- fdomain_detach(link);
-} /* fdomain_release */
+}
/*====================================================================*/
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 01c56a591d9e..e057b857d884 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1553,18 +1553,12 @@ static void nsp_cs_detach(dev_link_t *link)
return;
}
- if (link->state & DEV_CONFIG) {
+ if (link->state & DEV_CONFIG)
nsp_cs_release(link);
- if (link->state & DEV_STALE_CONFIG) {
- link->state |= DEV_STALE_LINK;
- return;
- }
- }
/* Break the link with Card Services */
- if (link->handle) {
+ if (link->handle)
CardServices(DeregisterClient, link->handle);
- }
/* Unlink device structure, free bits */
*linkp = link->next;
@@ -1792,17 +1786,6 @@ static void nsp_cs_release(dev_link_t *link)
DEBUG(0, "%s(0x%p)\n", __FUNCTION__, link);
- /*
- * If the device is currently in use, we won't release until it
- * is actually closed.
- */
- if (link->open) {
- DEBUG(1, "nsp_cs: release postponed, '%s' still open\n",
- link->dev->dev_name);
- link->state |= DEV_STALE_CONFIG;
- return;
- }
-
/* Unlink the device chain */
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,2))
scsi_unregister_module(MODULE_SCSI_HA, &nsp_driver_template);
@@ -1824,11 +1807,7 @@ static void nsp_cs_release(dev_link_t *link)
CardServices(ReleaseIRQ, link->handle, &link->irq);
}
link->state &= ~DEV_CONFIG;
-
- if (link->state & DEV_STALE_LINK) {
- nsp_cs_detach(link);
- }
-} /* nsp_cs_release */
+}
/*======================================================================
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 8cee766334ec..82ff20073c68 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -165,13 +165,8 @@ static void qlogic_detach(dev_link_t * link)
if (*linkp == NULL)
return;
- if (link->state & DEV_CONFIG) {
+ if (link->state & DEV_CONFIG)
qlogic_release(link);
- if (link->state & DEV_STALE_CONFIG) {
- link->state |= DEV_STALE_LINK;
- return;
- }
- }
if (link->handle)
CardServices(DeregisterClient, link->handle);
@@ -296,9 +291,7 @@ static void qlogic_release(dev_link_t *link)
scsi_unregister(info->host);
link->state &= ~DEV_CONFIG;
- if (link->state & DEV_STALE_LINK)
- qlogic_detach(link);
-} /* qlogic_release */
+}
/*====================================================================*/
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index a30d9fbe6e16..d2088d3da0c8 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -76,6 +76,7 @@ int ppa_release(struct Scsi_Host *host)
int host_no = host->unique_id;
printk("Releasing ppa%i\n", host_no);
+ scsi_unregister(host);
parport_unregister_device(ppa_hosts[host_no].dev);
return 0;
}
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 72ca360a950a..bd05b2a7268f 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -16,9 +16,11 @@
* General Public License for more details.
*
******************************************************************************/
-#define QLA1280_VERSION "3.23.34"
+#define QLA1280_VERSION "3.23.35"
/*****************************************************************************
Revision History:
+ Rev 3.23.35 August 14, 2003, Jes Sorensen
+ - Build against 2.6
Rev 3.23.34 July 23, 2003, Jes Sorensen
- Remove pointless TRUE/FALSE macros
- Clean up vchan handling
@@ -296,14 +298,12 @@
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/proc_fs.h>
-#include <linux/blk.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/pci_ids.h>
#include <linux/interrupt.h>
#include <linux/init.h>
-
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/byteorder.h>
@@ -312,7 +312,10 @@
#include <asm/system.h>
#if LINUX_VERSION_CODE < 0x020545
+#include <linux/blk.h>
#include "sd.h"
+#else
+#include <scsi/scsi_host.h>
#endif
#include "scsi.h"
#include "hosts.h"
@@ -634,11 +637,14 @@ static int ql_debug_level = 1;
*************************************************************************/
#define PROC_BUF &qla1280_buffer[len]
-int
-qla1280_proc_info(char *buffer, char **start, off_t offset, int length,
- int hostno, int inout)
+#if LINUX_VERSION_CODE < 0x020600
+int qla1280_proc_info(char *buffer, char **start, off_t offset, int length,
+ int hostno, int inout)
+#else
+int qla1280_proc_info(struct Scsi_Host *host, char *buffer, char **start,
+ off_t offset, int length, int inout)
+#endif
{
- struct Scsi_Host *host;
struct scsi_qla_host *ha;
int size = 0;
int len = 0;
@@ -647,7 +653,10 @@ qla1280_proc_info(char *buffer, char **start, off_t offset, int length,
struct scsi_lu *up;
uint32_t b, t, l;
#endif
-
+#if LINUX_VERSION_CODE >= 0x020600
+ ha = (struct scsi_qla_host *)host->hostdata;
+#else
+ struct Scsi_Host *host;
/* Find the host that was specified */
for (ha = qla1280_hostlist; (ha != NULL)
&& ha->host->host_no != hostno; ha = ha->next) ;
@@ -664,6 +673,7 @@ qla1280_proc_info(char *buffer, char **start, off_t offset, int length,
}
host = ha->host;
+#endif
if (inout)
return -ENOSYS;
@@ -1828,7 +1838,7 @@ qla1280_done(struct scsi_qla_host *ha, struct srb ** done_q_first,
CMD_HANDLE(sp->cmd) = (unsigned char *)INVALID_HANDLE;
ha->actthreads--;
-#if LINUX_KERNEL_VERSION < 0x020500
+#if LINUX_VERSION_CODE < 0x020500
if (cmd->cmnd[0] == INQUIRY)
qla1280_get_target_options(cmd, ha);
#endif
@@ -4497,7 +4507,7 @@ qla1280_rst_aen(struct scsi_qla_host *ha)
}
-#if LINUX_KERNEL_VERSION < 0x020500
+#if LINUX_VERSION_CODE < 0x020500
/*
*
*/
diff --git a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h
index 177107d31976..3af8ca3ce462 100644
--- a/drivers/scsi/qla1280.h
+++ b/drivers/scsi/qla1280.h
@@ -1111,7 +1111,11 @@ struct scsi_qla_host {
/*
* Linux - SCSI Driver Interface Function Prototypes.
*/
+#if LINUX_VERSION_CODE < 0x020600
int qla1280_proc_info(char *, char **, off_t, int, int, int);
+#else
+int qla1280_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
+#endif
const char *qla1280_info(struct Scsi_Host *host);
int qla1280_detect(Scsi_Host_Template *);
int qla1280_release(struct Scsi_Host *);
@@ -1147,8 +1151,6 @@ int qla1280_eh_adapter_reset(struct scsi_cmnd *cmd);
.detect = qla1280_detect, \
.release = qla1280_release, \
.info = qla1280_info, \
- .ioctl = NULL, \
- .command = NULL, \
.queuecommand = qla1280_queuecommand, \
.eh_strategy_handler = NULL, \
.eh_abort_handler = qla1280_eh_abort, \
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 6e17a28d4afe..d5894886fcea 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -1003,9 +1003,12 @@ static int __init init_scsi(void)
error = scsi_init_devinfo();
if (error)
goto cleanup_procfs;
- error = scsi_sysfs_register();
+ error = scsi_init_hosts();
if (error)
goto cleanup_devlist;
+ error = scsi_sysfs_register();
+ if (error)
+ goto cleanup_hosts;
for (i = 0; i < NR_CPUS; i++)
INIT_LIST_HEAD(&done_q[i]);
@@ -1015,6 +1018,8 @@ static int __init init_scsi(void)
printk(KERN_NOTICE "SCSI subsystem initialized\n");
return 0;
+cleanup_hosts:
+ scsi_exit_hosts();
cleanup_devlist:
scsi_exit_devinfo();
cleanup_procfs:
@@ -1029,6 +1034,7 @@ cleanup_queue:
static void __exit exit_scsi(void)
{
scsi_sysfs_unregister();
+ scsi_exit_hosts();
scsi_exit_devinfo();
devfs_remove("scsi");
scsi_exit_procfs();
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index f5d18f74beaf..6e4906ab2241 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1285,7 +1285,12 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
maybe_retry:
- if ((++scmd->retries) < scmd->allowed) {
+ /* we requeue for retry because the error was retryable, and
+ * the request was not marked fast fail. Note that above,
+ * even if the request is marked fast fail, we still requeue
+ * for queue congestion conditions (QUEUE_FULL or BUSY) */
+ if ((++scmd->retries) < scmd->allowed
+ && !blk_noretry_request(scmd->request)) {
return NEEDS_RETRY;
} else {
/*
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ef55ac3f119f..415be0cf47b0 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -502,14 +502,22 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
* to queue the remainder of them.
*/
if (end_that_request_first(req, uptodate, sectors)) {
- if (requeue) {
- /*
- * Bleah. Leftovers again. Stick the leftovers in
- * the front of the queue, and goose the queue again.
- */
- scsi_requeue_command(q, cmd);
+ int leftover = req->hard_nr_sectors - sectors;
+
+ /* kill remainder if no retrys */
+ if (!uptodate && blk_noretry_request(req))
+ end_that_request_first(req, 0, leftover);
+ else {
+ if (requeue)
+ /*
+ * Bleah. Leftovers again. Stick the
+ * leftovers in the front of the
+ * queue, and goose the queue again.
+ */
+ scsi_requeue_command(q, cmd);
+
+ return cmd;
}
- return cmd;
}
add_disk_randomness(req->rq_disk);
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 56566e3eef57..8608752c0fa4 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -42,6 +42,12 @@
(((scmd)->sense_buffer[0] & 0x70) == 0x70)
/*
+ * Special value for scanning to specify scanning or rescanning of all
+ * possible channels, (target) ids, or luns on a given shost.
+ */
+#define SCAN_WILD_CARD ~0
+
+/*
* scsi_target: representation of a scsi target, for now, this is only
* used for single_lun devices. If no one has active IO to the target,
* starget_sdev_user is NULL, else it points to the active sdev.
@@ -51,6 +57,9 @@ struct scsi_target {
unsigned int starget_refcnt;
};
+/* hosts.c */
+extern int scsi_init_hosts(void);
+extern void scsi_exit_hosts(void);
/* scsi.c */
extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
@@ -106,20 +115,18 @@ extern void scsi_exit_procfs(void);
#endif /* CONFIG_PROC_FS */
/* scsi_scan.c */
+int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, unsigned int,
+ unsigned int, int);
extern void scsi_forget_host(struct Scsi_Host *);
extern void scsi_free_sdev(struct scsi_device *);
-extern void scsi_free_shost(struct Scsi_Host *);
extern void scsi_rescan_device(struct device *);
/* scsi_sysfs.c */
extern int scsi_device_register(struct scsi_device *);
-extern void scsi_sysfs_init_host(struct Scsi_Host *);
-extern int scsi_sysfs_add_host(struct Scsi_Host *, struct device *);
-extern void scsi_sysfs_remove_host(struct Scsi_Host *);
+extern int scsi_sysfs_add_host(struct Scsi_Host *);
extern int scsi_sysfs_register(void);
extern void scsi_sysfs_unregister(void);
-extern struct class shost_class;
extern struct class sdev_class;
extern struct bus_type scsi_bus_type;
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
index 02a66f128ace..dd8bfd4b36c6 100644
--- a/drivers/scsi/scsi_proc.c
+++ b/drivers/scsi/scsi_proc.c
@@ -81,6 +81,9 @@ out:
void scsi_proc_hostdir_add(struct scsi_host_template *sht)
{
+ if (!sht->proc_info)
+ return;
+
down(&global_host_template_sem);
if (!sht->present++) {
sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi);
@@ -96,6 +99,9 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht)
void scsi_proc_hostdir_rm(struct scsi_host_template *sht)
{
+ if (!sht->proc_info)
+ return;
+
down(&global_host_template_sem);
if (!--sht->present && sht->proc_dir) {
remove_proc_entry(sht->proc_name, proc_scsi);
@@ -189,21 +195,13 @@ static int proc_print_scsidevice(struct device *dev, void *data)
static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
{
struct Scsi_Host *shost;
- struct scsi_device *sdev;
int error = -ENXIO;
shost = scsi_host_lookup(host);
if (IS_ERR(shost))
return PTR_ERR(shost);
- if (!scsi_find_device(shost, channel, id, lun)) {
- sdev = scsi_add_device(shost, channel, id, lun);
- if (IS_ERR(sdev))
- error = PTR_ERR(sdev);
- else
- error = 0;
- }
-
+ error = scsi_scan_host_selected(shost, channel, id, lun, 1);
scsi_host_put(shost);
return error;
}
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index b970bb416d8f..cef0c4467a92 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -656,13 +656,32 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
**/
static int scsi_probe_and_add_lun(struct Scsi_Host *host,
uint channel, uint id, uint lun, int *bflagsp,
- struct scsi_device **sdevp)
+ struct scsi_device **sdevp, int rescan)
{
struct scsi_device *sdev;
struct scsi_request *sreq;
unsigned char *result;
int bflags, res = SCSI_SCAN_NO_RESPONSE;
+ /*
+ * The rescan flag is used as an optimization, the first scan of a
+ * host adapter calls into here with rescan == 0.
+ */
+ if (rescan) {
+ sdev = scsi_find_device(host, channel, id, lun);
+ if (sdev) {
+ SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
+ "scsi scan: device exists on <%d:%d:%d:%d>\n",
+ host->host_no, channel, id, lun));
+ if (sdevp)
+ *sdevp = sdev;
+ if (bflagsp)
+ *bflagsp = scsi_get_device_flags(sdev->vendor,
+ sdev->model);
+ return SCSI_SCAN_LUN_PRESENT;
+ }
+ }
+
sdev = scsi_alloc_sdev(host, channel, id, lun);
if (!sdev)
goto out;
@@ -737,7 +756,7 @@ static int scsi_probe_and_add_lun(struct Scsi_Host *host,
* Modifies sdevscan->lun.
**/
static void scsi_sequential_lun_scan(struct Scsi_Host *shost, uint channel,
- uint id, int bflags, int lun0_res, int scsi_level)
+ uint id, int bflags, int lun0_res, int scsi_level, int rescan)
{
unsigned int sparse_lun, lun, max_dev_lun;
@@ -806,7 +825,8 @@ static void scsi_sequential_lun_scan(struct Scsi_Host *shost, uint channel,
*/
for (lun = 1; lun < max_dev_lun; ++lun)
if ((scsi_probe_and_add_lun(shost, channel, id, lun,
- NULL, NULL) != SCSI_SCAN_LUN_PRESENT) && !sparse_lun)
+ NULL, NULL, rescan) != SCSI_SCAN_LUN_PRESENT) &&
+ !sparse_lun)
return;
}
@@ -857,7 +877,8 @@ static int scsilun_to_int(struct scsi_lun *scsilun)
* 0: scan completed (or no memory, so further scanning is futile)
* 1: no report lun scan, or not configured
**/
-static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
+static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
+ int rescan)
{
char devname[64];
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
@@ -1011,7 +1032,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
int res;
res = scsi_probe_and_add_lun(sdev->host, sdev->channel,
- sdev->id, lun, NULL, NULL);
+ sdev->id, lun, NULL, NULL, rescan);
if (res == SCSI_SCAN_NO_RESPONSE) {
/*
* Got some results, but now none, abort.
@@ -1037,7 +1058,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
return 0;
}
#else
-# define scsi_report_lun_scan(sdev, blags) (1)
+# define scsi_report_lun_scan(sdev, blags, rescan) (1)
#endif /* CONFIG_SCSI_REPORT_LUNS */
struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
@@ -1046,7 +1067,7 @@ struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
struct scsi_device *sdev;
int res;
- res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev);
+ res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev, 1);
if (res != SCSI_SCAN_LUN_PRESENT)
sdev = ERR_PTR(-ENODEV);
return sdev;
@@ -1083,7 +1104,7 @@ void scsi_rescan_device(struct device *dev)
* sequential scan of LUNs on the target id.
**/
static void scsi_scan_target(struct Scsi_Host *shost, unsigned int channel,
- unsigned int id)
+ unsigned int id, unsigned int lun, int rescan)
{
int bflags = 0;
int res;
@@ -1095,19 +1116,29 @@ static void scsi_scan_target(struct Scsi_Host *shost, unsigned int channel,
*/
return;
+ if (lun != SCAN_WILD_CARD) {
+ /*
+ * Scan for a specific host/chan/id/lun.
+ */
+ scsi_probe_and_add_lun(shost, channel, id, lun, NULL, NULL,
+ rescan);
+ return;
+ }
+
/*
* Scan LUN 0, if there is some response, scan further. Ideally, we
* would not configure LUN 0 until all LUNs are scanned.
*/
- res = scsi_probe_and_add_lun(shost, channel, id, 0, &bflags, &sdev);
+ res = scsi_probe_and_add_lun(shost, channel, id, 0, &bflags, &sdev,
+ rescan);
if (res == SCSI_SCAN_LUN_PRESENT) {
- if (scsi_report_lun_scan(sdev, bflags) != 0)
+ if (scsi_report_lun_scan(sdev, bflags, rescan) != 0)
/*
* The REPORT LUN did not scan the target,
* do a sequential scan.
*/
scsi_sequential_lun_scan(shost, channel, id, bflags,
- res, sdev->scsi_level);
+ res, sdev->scsi_level, rescan);
} else if (res == SCSI_SCAN_TARGET_PRESENT) {
/*
* There's a target here, but lun 0 is offline so we
@@ -1116,37 +1147,26 @@ static void scsi_scan_target(struct Scsi_Host *shost, unsigned int channel,
* a default scsi level of SCSI_2
*/
scsi_sequential_lun_scan(shost, channel, id, BLIST_SPARSELUN,
- SCSI_SCAN_TARGET_PRESENT, SCSI_2);
+ SCSI_SCAN_TARGET_PRESENT, SCSI_2, rescan);
}
}
-/**
- * scsi_scan_host - scan the given adapter
- * @shost: adapter to scan
- *
- * Description:
- * Iterate and call scsi_scan_target to scan all possible target id's
- * on all possible channels.
- **/
-void scsi_scan_host(struct Scsi_Host *shost)
+static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
+ unsigned int id, unsigned int lun, int rescan)
{
- uint channel, id, order_id;
+ uint order_id;
- /*
- * The sdevscan host, channel, id and lun are filled in as
- * needed to scan.
- */
- for (channel = 0; channel <= shost->max_channel; channel++) {
- /*
- * XXX adapter drivers when possible (FCP, iSCSI)
- * could modify max_id to match the current max,
- * not the absolute max.
- *
- * XXX add a shost id iterator, so for example,
- * the FC ID can be the same as a target id
- * without a huge overhead of sparse id's.
- */
+ if (id == SCAN_WILD_CARD)
for (id = 0; id < shost->max_id; ++id) {
+ /*
+ * XXX adapter drivers when possible (FCP, iSCSI)
+ * could modify max_id to match the current max,
+ * not the absolute max.
+ *
+ * XXX add a shost id iterator, so for example,
+ * the FC ID can be the same as a target id
+ * without a huge overhead of sparse id's.
+ */
if (shost->reverse_ordering)
/*
* Scan from high to low id.
@@ -1154,9 +1174,39 @@ void scsi_scan_host(struct Scsi_Host *shost)
order_id = shost->max_id - id - 1;
else
order_id = id;
- scsi_scan_target(shost, channel, order_id);
+ scsi_scan_target(shost, channel, order_id, lun, rescan);
}
- }
+ else
+ scsi_scan_target(shost, channel, id, lun, rescan);
+}
+
+int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
+ unsigned int id, unsigned int lun, int rescan)
+{
+ SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "%s: <%u:%u:%u:%u>\n",
+ __FUNCTION__, shost->host_no, channel, id, lun));
+
+ if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
+ ((id != SCAN_WILD_CARD) && (id > shost->max_id)) ||
+ ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
+ return -EINVAL;
+
+ if (channel == SCAN_WILD_CARD)
+ for (channel = 0; channel <= shost->max_channel; channel++)
+ scsi_scan_channel(shost, channel, id, lun, rescan);
+ else
+ scsi_scan_channel(shost, channel, id, lun, rescan);
+ return 0;
+}
+
+/**
+ * scsi_scan_host - scan the given adapter
+ * @shost: adapter to scan
+ **/
+void scsi_scan_host(struct Scsi_Host *shost)
+{
+ scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
+ SCAN_WILD_CARD, 0);
}
void scsi_forget_host(struct Scsi_Host *shost)
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 8aaa149375b6..cd1b6e02ec7d 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -15,6 +15,43 @@
#include "hosts.h"
#include "scsi_priv.h"
+#include "scsi_logging.h"
+
+static int check_set(unsigned int *val, char *src)
+{
+ char *last;
+
+ if (strncmp(src, "-", 20) == 0) {
+ *val = SCAN_WILD_CARD;
+ } else {
+ /*
+ * Doesn't check for int overflow
+ */
+ *val = simple_strtoul(src, &last, 0);
+ if (*last != '\0')
+ return 1;
+ }
+ return 0;
+}
+
+static int scsi_scan(struct Scsi_Host *shost, const char *str)
+{
+ char s1[15], s2[15], s3[15], junk;
+ unsigned int channel, id, lun;
+ int res;
+
+ res = sscanf(str, "%10s %10s %10s %c", s1, s2, s3, &junk);
+ if (res != 3)
+ return -EINVAL;
+ if (check_set(&channel, s1))
+ return -EINVAL;
+ if (check_set(&id, s2))
+ return -EINVAL;
+ if (check_set(&lun, s3))
+ return -EINVAL;
+ res = scsi_scan_host_selected(shost, channel, id, lun, 1);
+ return res;
+}
/*
* shost_show_function: macro to create an attr function that can be used to
@@ -39,6 +76,20 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL)
/*
* Create the actual show/store functions and data structures.
*/
+
+static ssize_t store_scan(struct class_device *class_dev, const char *buf,
+ size_t count)
+{
+ struct Scsi_Host *shost = class_to_shost(class_dev);
+ int res;
+
+ res = scsi_scan(shost, buf);
+ if (res == 0)
+ res = count;
+ return res;
+};
+static CLASS_DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);
+
shost_rd_attr(unique_id, "%u\n");
shost_rd_attr(host_busy, "%hu\n");
shost_rd_attr(cmd_per_lun, "%hd\n");
@@ -51,33 +102,10 @@ static struct class_device_attribute *scsi_sysfs_shost_attrs[] = {
&class_device_attr_cmd_per_lun,
&class_device_attr_sg_tablesize,
&class_device_attr_unchecked_isa_dma,
+ &class_device_attr_scan,
NULL
};
-static void scsi_host_cls_release(struct class_device *class_dev)
-{
- struct Scsi_Host *shost;
-
- shost = class_to_shost(class_dev);
- put_device(&shost->shost_gendev);
-}
-
-static void scsi_host_dev_release(struct device *dev)
-{
- struct Scsi_Host *shost;
- struct device *parent;
-
- parent = dev->parent;
- shost = dev_to_shost(dev);
- scsi_free_shost(shost);
- put_device(parent);
-}
-
-struct class shost_class = {
- .name = "scsi_host",
- .release = scsi_host_cls_release,
-};
-
static void scsi_device_cls_release(struct class_device *class_dev)
{
struct scsi_device *sdev;
@@ -113,33 +141,23 @@ struct bus_type scsi_bus_type = {
.match = scsi_bus_match,
};
-
int scsi_sysfs_register(void)
{
int error;
error = bus_register(&scsi_bus_type);
- if (error)
- return error;
- error = class_register(&shost_class);
- if (error)
- goto bus_unregister;
- error = class_register(&sdev_class);
- if (error)
- goto class_unregister;
- return 0;
+ if (!error) {
+ error = class_register(&sdev_class);
+ if (error)
+ bus_unregister(&scsi_bus_type);
+ }
- class_unregister:
- class_unregister(&shost_class);
- bus_unregister:
- bus_unregister(&scsi_bus_type);
return error;
}
void scsi_sysfs_unregister(void)
{
class_unregister(&sdev_class);
- class_unregister(&shost_class);
bus_unregister(&scsi_bus_type);
}
@@ -243,6 +261,24 @@ store_rescan_field (struct device *dev, const char *buf, size_t count)
static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field)
+static ssize_t sdev_store_delete(struct device *dev, const char *buf,
+ size_t count)
+{
+ struct scsi_device *sdev = to_scsi_device(dev);
+ int res = count;
+
+ if (sdev->access_count)
+ /*
+ * FIXME and scsi_proc.c: racey use of access_count,
+ * possibly add a new arg to scsi_remove_device.
+ */
+ res = -EBUSY;
+ else
+ scsi_remove_device(sdev);
+ return res;
+};
+static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete);
+
/* Default template for device attributes. May NOT be modified */
static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
&dev_attr_device_blocked,
@@ -255,6 +291,7 @@ static struct device_attribute *scsi_sysfs_sdev_attrs[] = {
&dev_attr_rev,
&dev_attr_online,
&dev_attr_rescan,
+ &dev_attr_delete,
NULL
};
@@ -403,20 +440,6 @@ int scsi_register_interface(struct class_interface *intf)
}
-void scsi_sysfs_init_host(struct Scsi_Host *shost)
-{
- device_initialize(&shost->shost_gendev);
- snprintf(shost->shost_gendev.bus_id, BUS_ID_SIZE, "host%d",
- shost->host_no);
- shost->shost_gendev.release = scsi_host_dev_release;
-
- class_device_initialize(&shost->shost_classdev);
- shost->shost_classdev.dev = &shost->shost_gendev;
- shost->shost_classdev.class = &shost_class;
- snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d",
- shost->host_no);
-}
-
static struct class_device_attribute *class_attr_overridden(
struct class_device_attribute **attrs,
struct class_device_attribute *attr)
@@ -459,31 +482,16 @@ static int class_attr_add(struct class_device *classdev,
* @shost: scsi host struct to add to subsystem
* @dev: parent struct device pointer
**/
-int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev)
+int scsi_sysfs_add_host(struct Scsi_Host *shost)
{
int error, i;
- if (!shost->shost_gendev.parent)
- shost->shost_gendev.parent = dev ? dev : &legacy_bus;
-
- error = device_add(&shost->shost_gendev);
- if (error)
- return error;
-
- set_bit(SHOST_ADD, &shost->shost_state);
- get_device(shost->shost_gendev.parent);
-
- error = class_device_add(&shost->shost_classdev);
- if (error)
- goto clean_device;
-
- get_device(&shost->shost_gendev);
if (shost->hostt->shost_attrs) {
for (i = 0; shost->hostt->shost_attrs[i]; i++) {
error = class_attr_add(&shost->shost_classdev,
shost->hostt->shost_attrs[i]);
if (error)
- goto clean_class;
+ return error;
}
}
@@ -493,31 +501,9 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost, struct device *dev)
error = class_device_create_file(&shost->shost_classdev,
scsi_sysfs_shost_attrs[i]);
if (error)
- goto clean_class;
+ return error;
}
}
- return error;
-
-clean_class:
- class_device_del(&shost->shost_classdev);
-clean_device:
- device_del(&shost->shost_gendev);
-
- return error;
-}
-
-/**
- * scsi_sysfs_remove_host - remove scsi host from subsystem
- * @shost: scsi host to remove from subsystem
- **/
-void scsi_sysfs_remove_host(struct Scsi_Host *shost)
-{
- unsigned long flags;
- spin_lock_irqsave(shost->host_lock, flags);
- set_bit(SHOST_DEL, &shost->shost_state);
- spin_unlock_irqrestore(shost->host_lock, flags);
-
- class_device_unregister(&shost->shost_classdev);
- device_del(&shost->shost_gendev);
+ return 0;
}
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 30bdd330828a..2d9c592537b7 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -308,6 +308,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
SCpnt->cmnd[4] = (unsigned char) this_count;
SCpnt->cmnd[5] = 0;
}
+ SCpnt->request_bufflen = SCpnt->bufflen =
+ this_count * sdp->sector_size;
/*
* We shouldn't disconnect in the middle of a sector, so with a dumb
@@ -1353,10 +1355,14 @@ static int sd_remove(struct device *dev)
static void sd_shutdown(struct device *dev)
{
struct scsi_device *sdp = to_scsi_device(dev);
- struct scsi_disk *sdkp = dev_get_drvdata(dev);
+ struct scsi_disk *sdkp;
struct scsi_request *sreq;
int retries, res;
+ sdkp = dev_get_drvdata(dev);
+ if (!sdkp)
+ return; /* this can happen */
+
if (!sdp->online || !sdkp->WCE)
return;
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index e91c870710d9..f648b265fa26 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -340,6 +340,20 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
return 0;
}
+ {
+ struct scatterlist *sg = SCpnt->request_buffer;
+ int i, size = 0;
+ for (i = 0; i < SCpnt->use_sg; i++)
+ size += sg[i].length;
+
+ if (size != SCpnt->request_bufflen && SCpnt->use_sg) {
+ printk(KERN_ERR "sr: mismatch count %d, bytes %d\n",
+ size, SCpnt->request_bufflen);
+ if (SCpnt->request_bufflen > size)
+ SCpnt->request_bufflen = SCpnt->bufflen = size;
+ }
+ }
+
/*
* request doesn't start on hw block boundary, add scatter pads
*/
@@ -361,8 +375,11 @@ static int sr_init_command(struct scsi_cmnd * SCpnt)
SCpnt->cmnd[1] = 0;
block = (unsigned int)SCpnt->request->sector / (s_size >> 9);
- if (this_count > 0xffff)
+ if (this_count > 0xffff) {
this_count = 0xffff;
+ SCpnt->request_bufflen = SCpnt->bufflen =
+ this_count * s_size;
+ }
SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff;
@@ -390,18 +407,6 @@ queue:
*/
SCpnt->done = rw_intr;
- {
- struct scatterlist *sg = SCpnt->request_buffer;
- int i, size = 0;
- for (i = 0; i < SCpnt->use_sg; i++)
- size += sg[i].length;
-
- if (size != SCpnt->request_bufflen && SCpnt->use_sg) {
- printk("sr: mismatch count %d, bytes %d\n", size, SCpnt->request_bufflen);
- SCpnt->request_bufflen = size;
- }
- }
-
/*
* This indicates that the command is ready from our end to be
* queued.
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 7498d20f8c28..9ece10b15e3a 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -2029,7 +2029,7 @@ attach_failed:
printf_info("%s: giving up ...\n", sym_name(np));
if (np)
sym_free_resources(np);
- scsi_unregister(instance);
+ scsi_host_put(instance);
return -1;
}
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index 7e228977fa1c..7d83f2c28869 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -5942,14 +5942,7 @@ int sym_hcb_attach(hcb_p np, struct sym_fw *fw)
*/
return 0;
- /*
- * We have failed.
- * We will try to free all the resources we have
- * allocated, but if we are a boot device, this
- * will not help that much.;)
- */
attach_failed:
- sym_hcb_free(np);
return -ENXIO;
}
diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
index 05700528818b..769ca36b8a3d 100644
--- a/drivers/scsi/zalon.c
+++ b/drivers/scsi/zalon.c
@@ -135,11 +135,9 @@ zalon_scsi_callback(struct parisc_device *dev)
if(!host)
goto fail;
- strlcpy(dev->dev.name, "zalon7xx", sizeof(dev->dev.name));
-
- if(request_irq(irq, ncr53c8xx_intr, SA_SHIRQ, dev->dev.name, host)) {
+ if(request_irq(irq, ncr53c8xx_intr, SA_SHIRQ, dev->dev.bus_id, host)) {
printk(KERN_ERR "%s: irq problem with %d, detaching\n ",
- dev->dev.name, irq);
+ dev->dev.bus_id, irq);
goto fail;
}
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 8ebc42f66376..41d546521a77 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -16,6 +16,8 @@
*/
+#include <linux/types.h>
+
/*
* SCSI command lengths
*/