mirror of
https://github.com/adulau/aha.git
synced 2025-01-01 13:46:24 +00:00
1da177e4c3
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
351 lines
8.5 KiB
C
351 lines
8.5 KiB
C
/******************************************************************************
|
|
* 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);
|
|
}
|