Commit 95152a4c authored by Mark Haverkamp's avatar Mark Haverkamp Committed by James Bottomley

[PATCH] New aacraid driver fixed.

I have the new aacraid driver working on my system now.  The patch is
against the 2.5.66 updates that you gave me.  I made the following
changes:

aachba.c aac_scsi_cmd()
There was a race accessing the scsicmd pointer accessing the host_lock.
I made a local pointer to the Scsi_Host so the spin_lock_irq after
aac_read wouldn't panic.  I think that sometimes the I/O would be done
and the memory freed before returning invalidating the scsicmd pointer.
I made the same change in aac_io_done in case scsi_done had freed the
scsicmd memory before returning.

comminit.c aac_alloc_comm()
AdapterFibsVirtualAddress was set to the virtual address of base.  I
changed it to set it to the phys address.  I compared this to code
pointed to by matt domsch on the aacraid devel list on the 5th.  Its
aac_alloc_comm sets this variable to the phys address.  This fixed the
probelem where the entry->addr was bad.  Another was to fix it I guess
would be to leave this change alone and not try to convert the address
in aac_command_normal.

dpcsup.c aac_response_normal()
Changed the bus_to_virt to the calculation we talked about last month.
dpcsup.c aac_command_normal()
Changed the bus_to_virt to the calculation.
parent 3f642845
......@@ -466,9 +466,10 @@ void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
static void aac_io_done(Scsi_Cmnd * scsicmd)
{
unsigned long cpu_flags;
spin_lock_irqsave(scsicmd->device->host->host_lock, cpu_flags);
struct Scsi_Host *host = scsicmd->device->host;
spin_lock_irqsave(host->host_lock, cpu_flags);
scsicmd->scsi_done(scsicmd);
spin_unlock_irqrestore(scsicmd->device->host->host_lock, cpu_flags);
spin_unlock_irqrestore(host->host_lock, cpu_flags);
}
static void __aac_io_done(Scsi_Cmnd * scsicmd)
......@@ -877,18 +878,19 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd)
struct fsa_scsi_hba *fsa_dev_ptr;
int cardtype;
int ret;
struct aac_dev *dev = (struct aac_dev *)scsicmd->device->host->hostdata;
struct Scsi_Host *host = scsicmd->device->host;
struct aac_dev *dev = (struct aac_dev *)host->hostdata;
cardtype = dev->cardtype;
fsa_dev_ptr = fsa_dev[scsicmd->device->host->unique_id];
fsa_dev_ptr = fsa_dev[host->unique_id];
/*
* If the bus, target or lun is out of range, return fail
* Test does not apply to ID 16, the pseudo id for the controller
* itself.
*/
if (scsicmd->device->id != scsicmd->device->host->this_id) {
if (scsicmd->device->id != host->this_id) {
if ((scsicmd->device->channel == 0) ){
if( (scsicmd->device->id >= AAC_MAX_TARGET) || (scsicmd->device->lun != 0)){
scsicmd->result = DID_NO_CONNECT << 16;
......@@ -906,9 +908,9 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd)
case SS_INQUIR:
case SS_RDCAP:
case SS_TEST:
spin_unlock_irq(scsicmd->device->host->host_lock);
spin_unlock_irq(host->host_lock);
probe_container(dev, cid);
spin_lock_irq(scsicmd->device->host->host_lock);
spin_lock_irq(host->host_lock);
if (fsa_dev_ptr->valid[cid] == 0) {
scsicmd->result = DID_NO_CONNECT << 16;
__aac_io_done(scsicmd);
......@@ -977,7 +979,7 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd)
* see: <vendor>.c i.e. aac.c
*/
setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr->type[cid]);
if (scsicmd->device->id == scsicmd->device->host->this_id)
if (scsicmd->device->id == host->this_id)
inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */
else
inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
......@@ -1071,21 +1073,21 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd)
* containers to /dev/sd device names
*/
spin_unlock_irq(scsicmd->device->host->host_lock);
spin_unlock_irq(host->host_lock);
if (scsicmd->request->rq_disk)
memcpy(fsa_dev_ptr->devname[cid],
scsicmd->request->rq_disk->disk_name,
8);
ret = aac_read(scsicmd, cid);
spin_lock_irq(scsicmd->device->host->host_lock);
spin_lock_irq(host->host_lock);
return ret;
case SS_WRITE:
case SM_WRITE:
spin_unlock_irq(scsicmd->device->host->host_lock);
spin_unlock_irq(host->host_lock);
ret = aac_write(scsicmd, cid);
spin_lock_irq(scsicmd->device->host->host_lock);
spin_lock_irq(host->host_lock);
return ret;
default:
/*
......
......@@ -88,7 +88,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
*/
dev->fib_base_va = (ulong)base;
init->AdapterFibsVirtualAddress = cpu_to_le32((u32)(ulong)base);
init->AdapterFibsVirtualAddress = cpu_to_le32((u32)(ulong)phys);
init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
init->AdapterFibsSize = cpu_to_le32(fibsize);
init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
......
......@@ -75,9 +75,8 @@ unsigned int aac_response_normal(struct aac_queue * q)
{
u32 fast ;
fast = (entry->addr & cpu_to_le32(0x01));
// fib = &dev->fibs[(entry->addr >> 1)];
// hwfib = fib->hw_fib;
hwfib = bus_to_virt(le32_to_cpu(entry->addr & cpu_to_le32(~0x01)));
hwfib = (struct hw_fib *)((char *)dev->hw_fib_va +
((entry->addr & ~0x01) - dev->hw_fib_pa));
fib = &dev->fibs[hwfib->header.SenderData];
aac_consumer_free(dev, q, HostNormRespQueue);
......@@ -174,7 +173,8 @@ unsigned int aac_command_normal(struct aac_queue *q)
while(aac_consumer_get(dev, q, &entry))
{
struct hw_fib * hw_fib;
hw_fib = bus_to_virt(le32_to_cpu(entry->addr & cpu_to_le32(~0x01)));
hw_fib = (struct hw_fib *)((char *)dev->hw_fib_va +
((entry->addr & ~0x01) - dev->hw_fib_pa));
if (dev->aif_thread) {
aac_list_add_tail(&hw_fib->header.FibLinks, &q->cmdq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment