aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/qla2xxx/qla_listops.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_listops.h')
-rw-r--r--drivers/scsi/qla2xxx/qla_listops.h351
1 files changed, 351 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_listops.h b/drivers/scsi/qla2xxx/qla_listops.h
new file mode 100644
index 00000000000..5da034f61af
--- /dev/null
+++ b/drivers/scsi/qla2xxx/qla_listops.h
@@ -0,0 +1,351 @@
+/******************************************************************************
+ * QLOGIC LINUX SOFTWARE
+ *
+ * QLogic ISP2x00 device driver for Linux 2.6.x
+ * Copyright (C) 2003-2004 QLogic Corporation
+ * (www.qlogic.com)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ ******************************************************************************/
+
+/* Management functions for various lists */
+
+/* __add_to_done_queue()
+ *
+ * Place SRB command on done queue.
+ *
+ * Input:
+ * ha = host pointer
+ * sp = srb pointer.
+ * Locking:
+ * this function assumes the ha->list_lock is already taken
+ */
+static inline void
+__add_to_done_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ /*
+ if (sp->state != SRB_NO_QUEUE_STATE &&
+ sp->state != SRB_ACTIVE_STATE)
+ BUG();
+ */
+
+ /* Place block on done queue */
+ sp->cmd->host_scribble = (unsigned char *) NULL;
+ sp->state = SRB_DONE_STATE;
+ list_add_tail(&sp->list,&ha->done_queue);
+ ha->done_q_cnt++;
+ sp->ha = ha;
+}
+
+static inline void
+__add_to_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ /*
+ if( sp->state != SRB_NO_QUEUE_STATE &&
+ sp->state != SRB_ACTIVE_STATE)
+ BUG();
+ */
+
+ /* Place block on retry queue */
+ list_add_tail(&sp->list,&ha->retry_queue);
+ ha->retry_q_cnt++;
+ sp->flags |= SRB_WATCHDOG;
+ sp->state = SRB_RETRY_STATE;
+ sp->ha = ha;
+}
+
+static inline void
+__add_to_scsi_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ /*
+ if( sp->state != SRB_NO_QUEUE_STATE &&
+ sp->state != SRB_ACTIVE_STATE)
+ BUG();
+ */
+
+ /* Place block on retry queue */
+ list_add_tail(&sp->list,&ha->scsi_retry_queue);
+ ha->scsi_retry_q_cnt++;
+ sp->state = SRB_SCSI_RETRY_STATE;
+ sp->ha = ha;
+}
+
+static inline void
+add_to_done_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ha->list_lock, flags);
+ __add_to_done_queue(ha,sp);
+ spin_unlock_irqrestore(&ha->list_lock, flags);
+}
+
+static inline void
+add_to_free_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ mempool_free(sp, ha->srb_mempool);
+}
+
+static inline void
+add_to_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ha->list_lock, flags);
+ __add_to_retry_queue(ha,sp);
+ spin_unlock_irqrestore(&ha->list_lock, flags);
+}
+
+static inline void
+add_to_scsi_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ha->list_lock, flags);
+ __add_to_scsi_retry_queue(ha,sp);
+ spin_unlock_irqrestore(&ha->list_lock, flags);
+}
+
+/*
+ * __del_from_retry_queue
+ * Function used to remove a command block from the
+ * watchdog timer queue.
+ *
+ * Note: Must insure that command is on watchdog
+ * list before calling del_from_retry_queue
+ * if (sp->flags & SRB_WATCHDOG)
+ *
+ * Input:
+ * ha = adapter block pointer.
+ * sp = srb pointer.
+ * Locking:
+ * this function assumes the list_lock is already taken
+ */
+static inline void
+__del_from_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ list_del_init(&sp->list);
+
+ sp->flags &= ~(SRB_WATCHDOG | SRB_BUSY);
+ sp->state = SRB_NO_QUEUE_STATE;
+ ha->retry_q_cnt--;
+}
+
+/*
+ * __del_from_scsi_retry_queue
+ * Function used to remove a command block from the
+ * scsi retry queue.
+ *
+ * Input:
+ * ha = adapter block pointer.
+ * sp = srb pointer.
+ * Locking:
+ * this function assumes the list_lock is already taken
+ */
+static inline void
+__del_from_scsi_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ list_del_init(&sp->list);
+
+ ha->scsi_retry_q_cnt--;
+ sp->state = SRB_NO_QUEUE_STATE;
+}
+
+/*
+ * del_from_retry_queue
+ * Function used to remove a command block from the
+ * watchdog timer queue.
+ *
+ * Note: Must insure that command is on watchdog
+ * list before calling del_from_retry_queue
+ * if (sp->flags & SRB_WATCHDOG)
+ *
+ * Input:
+ * ha = adapter block pointer.
+ * sp = srb pointer.
+ * Locking:
+ * this function takes and releases the list_lock
+ */
+static inline void
+del_from_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ unsigned long flags;
+
+ /* if (unlikely(!(sp->flags & SRB_WATCHDOG)))
+ BUG();*/
+ spin_lock_irqsave(&ha->list_lock, flags);
+
+ /* if (unlikely(list_empty(&ha->retry_queue)))
+ BUG();*/
+
+ __del_from_retry_queue(ha,sp);
+
+ spin_unlock_irqrestore(&ha->list_lock, flags);
+}
+/*
+ * del_from_scsi_retry_queue
+ * Function used to remove a command block from the
+ * scsi retry queue.
+ *
+ * Input:
+ * ha = adapter block pointer.
+ * sp = srb pointer.
+ * Locking:
+ * this function takes and releases the list_lock
+ */
+static inline void
+del_from_scsi_retry_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ha->list_lock, flags);
+
+ /* if (unlikely(list_empty(&ha->scsi_retry_queue)))
+ BUG();*/
+
+ __del_from_scsi_retry_queue(ha,sp);
+
+ spin_unlock_irqrestore(&ha->list_lock, flags);
+}
+
+/*
+ * __add_to_pending_queue
+ * Add the standard SCB job to the bottom of standard SCB commands.
+ *
+ * Input:
+ * COMPLETE!!!
+ * q = SCSI LU pointer.
+ * sp = srb pointer.
+ * SCSI_LU_Q lock must be already obtained.
+ */
+static inline int
+__add_to_pending_queue(struct scsi_qla_host *ha, srb_t * sp)
+{
+ int empty;
+ /*
+ if( sp->state != SRB_NO_QUEUE_STATE &&
+ sp->state != SRB_FREE_STATE &&
+ sp->state != SRB_ACTIVE_STATE)
+ BUG();
+ */
+
+ empty = list_empty(&ha->pending_queue);
+ list_add_tail(&sp->list, &ha->pending_queue);
+ ha->qthreads++;
+ sp->state = SRB_PENDING_STATE;
+
+ return (empty);
+}
+
+static inline void
+__add_to_pending_queue_head(struct scsi_qla_host *ha, srb_t * sp)
+{
+ /*
+ if( sp->state != SRB_NO_QUEUE_STATE &&
+ sp->state != SRB_FREE_STATE &&
+ sp->state != SRB_ACTIVE_STATE)
+ BUG();
+ */
+
+ list_add(&sp->list, &ha->pending_queue);
+ ha->qthreads++;
+ sp->state = SRB_PENDING_STATE;
+}
+
+static inline int
+add_to_pending_queue(struct scsi_qla_host *ha, srb_t *sp)
+{
+ int empty;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ha->list_lock, flags);
+ empty = __add_to_pending_queue(ha, sp);
+ spin_unlock_irqrestore(&ha->list_lock, flags);
+
+ return (empty);
+}
+static inline void
+add_to_pending_queue_head(struct scsi_qla_host *ha, srb_t *sp)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ha->list_lock, flags);
+ __add_to_pending_queue_head(ha, sp);
+ spin_unlock_irqrestore(&ha->list_lock, flags);
+}
+
+static inline void
+__del_from_pending_queue(struct scsi_qla_host *ha, srb_t *sp)
+{
+ list_del_init(&sp->list);
+ ha->qthreads--;
+ sp->state = SRB_NO_QUEUE_STATE;
+}
+
+/*
+ * Failover Stuff.
+ */
+static inline void
+__add_to_failover_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ /*
+ if( sp->state != SRB_NO_QUEUE_STATE &&
+ sp->state != SRB_ACTIVE_STATE)
+ BUG();
+ */
+
+ list_add_tail(&sp->list,&ha->failover_queue);
+ ha->failover_cnt++;
+ sp->state = SRB_FAILOVER_STATE;
+ sp->ha = ha;
+}
+
+static inline void add_to_failover_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ha->list_lock, flags);
+
+ __add_to_failover_queue(ha,sp);
+
+ spin_unlock_irqrestore(&ha->list_lock, flags);
+}
+static inline void __del_from_failover_queue(struct scsi_qla_host * ha, srb_t *
+ sp)
+{
+ ha->failover_cnt--;
+ list_del_init(&sp->list);
+ sp->state = SRB_NO_QUEUE_STATE;
+}
+
+static inline void del_from_failover_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ha->list_lock, flags);
+
+ __del_from_failover_queue(ha,sp);
+
+ spin_unlock_irqrestore(&ha->list_lock, flags);
+}
+
+static inline void
+del_from_pending_queue(struct scsi_qla_host * ha, srb_t * sp)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ha->list_lock, flags);
+
+ __del_from_pending_queue(ha,sp);
+
+ spin_unlock_irqrestore(&ha->list_lock, flags);
+}