Skip to content

Commit

Permalink
[SCSI] aacraid: rework communication support code
Browse files Browse the repository at this point in the history
Received from Mark Salyzyn,

Replace all if/else communication transports with a platform function call.
This is in recognition of the need to migrate to up-and-coming transports.
Currently the Linux driver does not support two available communication
transports provided by our products, these will be added in future patches, and
will expand the platform function set.

Signed-off-by Mark Haverkamp <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
  • Loading branch information
Mark Haverkamp authored and James Bottomley committed Jan 27, 2007
1 parent 9cd065a commit 2871332
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 179 deletions.
27 changes: 22 additions & 5 deletions drivers/scsi/aacraid/aacraid.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#define _nblank(x) #x
#define nblank(x) _nblank(x)[0]

#include <linux/interrupt.h>

/*------------------------------------------------------------------------------
* D E F I N E S
Expand Down Expand Up @@ -488,13 +489,20 @@ struct fib;

struct adapter_ops
{
/* Low level operations */
void (*adapter_interrupt)(struct aac_dev *dev);
void (*adapter_notify)(struct aac_dev *dev, u32 event);
void (*adapter_disable_int)(struct aac_dev *dev);
void (*adapter_enable_int)(struct aac_dev *dev);
int (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
int (*adapter_check_health)(struct aac_dev *dev);
int (*adapter_send)(struct fib * fib);
/* Transport operations */
int (*adapter_ioremap)(struct aac_dev * dev, u32 size);
irqreturn_t (*adapter_intr)(int irq, void *dev_id);
/* Packet operations */
int (*adapter_deliver)(struct fib * fib);
/* Administrative operations */
int (*adapter_comm)(struct aac_dev * dev, int comm);
};

/*
Expand Down Expand Up @@ -1018,7 +1026,9 @@ struct aac_dev
u8 nondasd_support;
u8 dac_support;
u8 raid_scsi_mode;
u8 new_comm_interface;
u8 comm_interface;
# define AAC_COMM_PRODUCER 0
# define AAC_COMM_MESSAGE 1
/* macro side-effects BEWARE */
# define raw_io_interface \
init->InitStructRevision==cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4)
Expand All @@ -1036,18 +1046,24 @@ struct aac_dev
#define aac_adapter_disable_int(dev) \
(dev)->a_ops.adapter_disable_int(dev)

#define aac_adapter_enable_int(dev) \
(dev)->a_ops.adapter_enable_int(dev)

#define aac_adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4) \
(dev)->a_ops.adapter_sync_cmd(dev, command, p1, p2, p3, p4, p5, p6, status, r1, r2, r3, r4)

#define aac_adapter_check_health(dev) \
(dev)->a_ops.adapter_check_health(dev)

#define aac_adapter_send(fib) \
((fib)->dev)->a_ops.adapter_send(fib)

#define aac_adapter_ioremap(dev, size) \
(dev)->a_ops.adapter_ioremap(dev, size)

#define aac_adapter_deliver(fib) \
((fib)->dev)->a_ops.adapter_deliver(fib)

#define aac_adapter_comm(dev,comm) \
(dev)->a_ops.adapter_comm(dev, comm)

#define FIB_CONTEXT_FLAG_TIMED_OUT (0x00000001)

/*
Expand Down Expand Up @@ -1795,6 +1811,7 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg);
int aac_rx_init(struct aac_dev *dev);
int aac_rkt_init(struct aac_dev *dev);
int aac_sa_init(struct aac_dev *dev);
int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify);
unsigned int aac_response_normal(struct aac_queue * q);
unsigned int aac_command_normal(struct aac_queue * q);
unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index);
Expand Down
14 changes: 8 additions & 6 deletions drivers/scsi/aacraid/comminit.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);

init->InitFlags = 0;
if (dev->new_comm_interface) {
if (dev->comm_interface == AAC_COMM_MESSAGE) {
init->InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
}
Expand Down Expand Up @@ -297,21 +297,23 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
- sizeof(struct aac_fibhdr)
- sizeof(struct aac_write) + sizeof(struct sgentry))
/ sizeof(struct sgentry);
dev->new_comm_interface = 0;
dev->comm_interface = AAC_COMM_PRODUCER;
dev->raw_io_64 = 0;
if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
(status[0] == 0x00000001)) {
if (status[1] & AAC_OPT_NEW_COMM_64)
dev->raw_io_64 = 1;
if (status[1] & AAC_OPT_NEW_COMM)
dev->new_comm_interface = dev->a_ops.adapter_send != 0;
if (dev->new_comm_interface && (status[2] > dev->base_size)) {
if (dev->a_ops.adapter_comm &&
(status[1] & AAC_OPT_NEW_COMM))
dev->comm_interface = AAC_COMM_MESSAGE;
if ((dev->comm_interface == AAC_COMM_MESSAGE) &&
(status[2] > dev->base_size)) {
aac_adapter_ioremap(dev, 0);
dev->base_size = status[2];
if (aac_adapter_ioremap(dev, status[2])) {
/* remap failed, go back ... */
dev->new_comm_interface = 0;
dev->comm_interface = AAC_COMM_PRODUCER;
if (aac_adapter_ioremap(dev, AAC_MIN_FOOTPRINT_SIZE)) {
printk(KERN_WARNING
"aacraid: unable to map adapter.\n");
Expand Down
40 changes: 6 additions & 34 deletions drivers/scsi/aacraid/commsup.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
* success.
*/

static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify)
int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw_fib, int wait, struct fib * fibptr, unsigned long *nonotify)
{
struct aac_entry * entry = NULL;
int map = 0;
Expand Down Expand Up @@ -387,7 +387,6 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
{
struct aac_dev * dev = fibptr->dev;
struct hw_fib * hw_fib = fibptr->hw_fib;
struct aac_queue * q;
unsigned long flags = 0;
unsigned long qflags;

Expand Down Expand Up @@ -469,38 +468,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,

if (!dev->queues)
return -EBUSY;
q = &dev->queues->queue[AdapNormCmdQueue];

if(wait)
spin_lock_irqsave(&fibptr->event_lock, flags);
spin_lock_irqsave(q->lock, qflags);
if (dev->new_comm_interface) {
unsigned long count = 10000000L; /* 50 seconds */
q->numpending++;
spin_unlock_irqrestore(q->lock, qflags);
while (aac_adapter_send(fibptr) != 0) {
if (--count == 0) {
if (wait)
spin_unlock_irqrestore(&fibptr->event_lock, flags);
spin_lock_irqsave(q->lock, qflags);
q->numpending--;
spin_unlock_irqrestore(q->lock, qflags);
return -ETIMEDOUT;
}
udelay(5);
}
} else {
u32 index;
unsigned long nointr = 0;
aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr);

q->numpending++;
*(q->headers.producer) = cpu_to_le32(index + 1);
spin_unlock_irqrestore(q->lock, qflags);
dprintk((KERN_DEBUG "aac_fib_send: inserting a queue entry at index %d.\n",index));
if (!(nointr & aac_config.irq_mod))
aac_adapter_notify(dev, AdapNormCmdQueue);
}
aac_adapter_deliver(fibptr);

/*
* If the caller wanted us to wait for response wait now.
Expand All @@ -520,6 +491,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
while (down_trylock(&fibptr->event_wait)) {
int blink;
if (--count == 0) {
struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue];
spin_lock_irqsave(q->lock, qflags);
q->numpending--;
spin_unlock_irqrestore(q->lock, qflags);
Expand Down Expand Up @@ -659,15 +631,15 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
unsigned long qflags;

if (hw_fib->header.XferState == 0) {
if (dev->new_comm_interface)
if (dev->comm_interface == AAC_COMM_MESSAGE)
kfree (hw_fib);
return 0;
}
/*
* If we plan to do anything check the structure type first.
*/
if ( hw_fib->header.StructType != FIB_MAGIC ) {
if (dev->new_comm_interface)
if (dev->comm_interface == AAC_COMM_MESSAGE)
kfree (hw_fib);
return -EINVAL;
}
Expand All @@ -679,7 +651,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
* send the completed cdb to the adapter.
*/
if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {
if (dev->new_comm_interface) {
if (dev->comm_interface == AAC_COMM_MESSAGE) {
kfree (hw_fib);
} else {
u32 index;
Expand Down
64 changes: 36 additions & 28 deletions drivers/scsi/aacraid/rkt.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,40 @@

#include "aacraid.h"

#define AAC_NUM_IO_FIB_RKT (246 - AAC_NUM_MGT_FIB)

/**
* aac_rkt_select_comm - Select communications method
* @dev: Adapter
* @comm: communications method
*/

static int aac_rkt_select_comm(struct aac_dev *dev, int comm)
{
int retval;
extern int aac_rx_select_comm(struct aac_dev *dev, int comm);
retval = aac_rx_select_comm(dev, comm);
if (comm == AAC_COMM_MESSAGE) {
/*
* FIB Setup has already been done, but we can minimize the
* damage by at least ensuring the OS never issues more
* commands than we can handle. The Rocket adapters currently
* can only handle 246 commands and 8 AIFs at the same time,
* and in fact do notify us accordingly if we negotiate the
* FIB size. The problem that causes us to add this check is
* to ensure that we do not overdo it with the adapter when a
* hard coded FIB override is being utilized. This special
* case warrants this half baked, but convenient, check here.
*/
if (dev->scsi_host_ptr->can_queue > AAC_NUM_IO_FIB_RKT) {
dev->init->MaxIoCommands =
cpu_to_le32(AAC_NUM_IO_FIB_RKT + AAC_NUM_MGT_FIB);
dev->scsi_host_ptr->can_queue = AAC_NUM_IO_FIB_RKT;
}
}
return retval;
}

/**
* aac_rkt_ioremap
* @size: mapping resize request
Expand Down Expand Up @@ -63,39 +97,13 @@ static int aac_rkt_ioremap(struct aac_dev * dev, u32 size)

int aac_rkt_init(struct aac_dev *dev)
{
int retval;
extern int _aac_rx_init(struct aac_dev *dev);
extern void aac_rx_start_adapter(struct aac_dev *dev);

/*
* Fill in the function dispatch table.
*/
dev->a_ops.adapter_ioremap = aac_rkt_ioremap;
dev->a_ops.adapter_comm = aac_rkt_select_comm;

retval = _aac_rx_init(dev);
if (retval)
return retval;
if (dev->new_comm_interface) {
/*
* FIB Setup has already been done, but we can minimize the
* damage by at least ensuring the OS never issues more
* commands than we can handle. The Rocket adapters currently
* can only handle 246 commands and 8 AIFs at the same time,
* and in fact do notify us accordingly if we negotiate the
* FIB size. The problem that causes us to add this check is
* to ensure that we do not overdo it with the adapter when a
* hard coded FIB override is being utilized. This special
* case warrants this half baked, but convenient, check here.
*/
if (dev->scsi_host_ptr->can_queue > (246 - AAC_NUM_MGT_FIB)) {
dev->init->MaxIoCommands = cpu_to_le32(246);
dev->scsi_host_ptr->can_queue = 246 - AAC_NUM_MGT_FIB;
}
}
/*
* Tell the adapter that all is configured, and it can start
* accepting requests
*/
aac_rx_start_adapter(dev);
return 0;
return _aac_rx_init(dev);
}
Loading

0 comments on commit 2871332

Please sign in to comment.