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, ...@@ -466,9 +466,10 @@ void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code,
static void aac_io_done(Scsi_Cmnd * scsicmd) static void aac_io_done(Scsi_Cmnd * scsicmd)
{ {
unsigned long cpu_flags; 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); 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) static void __aac_io_done(Scsi_Cmnd * scsicmd)
...@@ -877,18 +878,19 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd) ...@@ -877,18 +878,19 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd)
struct fsa_scsi_hba *fsa_dev_ptr; struct fsa_scsi_hba *fsa_dev_ptr;
int cardtype; int cardtype;
int ret; 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; 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 * 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 * Test does not apply to ID 16, the pseudo id for the controller
* itself. * 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->channel == 0) ){
if( (scsicmd->device->id >= AAC_MAX_TARGET) || (scsicmd->device->lun != 0)){ if( (scsicmd->device->id >= AAC_MAX_TARGET) || (scsicmd->device->lun != 0)){
scsicmd->result = DID_NO_CONNECT << 16; scsicmd->result = DID_NO_CONNECT << 16;
...@@ -906,9 +908,9 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd) ...@@ -906,9 +908,9 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd)
case SS_INQUIR: case SS_INQUIR:
case SS_RDCAP: case SS_RDCAP:
case SS_TEST: case SS_TEST:
spin_unlock_irq(scsicmd->device->host->host_lock); spin_unlock_irq(host->host_lock);
probe_container(dev, cid); 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) { if (fsa_dev_ptr->valid[cid] == 0) {
scsicmd->result = DID_NO_CONNECT << 16; scsicmd->result = DID_NO_CONNECT << 16;
__aac_io_done(scsicmd); __aac_io_done(scsicmd);
...@@ -977,7 +979,7 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd) ...@@ -977,7 +979,7 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd)
* see: <vendor>.c i.e. aac.c * see: <vendor>.c i.e. aac.c
*/ */
setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr->type[cid]); 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 */ inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */
else else
inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ inq_data_ptr->inqd_pdt = INQD_PDT_DA; /* Direct/random access device */
...@@ -1071,21 +1073,21 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd) ...@@ -1071,21 +1073,21 @@ int aac_scsi_cmd(Scsi_Cmnd * scsicmd)
* containers to /dev/sd device names * 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) if (scsicmd->request->rq_disk)
memcpy(fsa_dev_ptr->devname[cid], memcpy(fsa_dev_ptr->devname[cid],
scsicmd->request->rq_disk->disk_name, scsicmd->request->rq_disk->disk_name,
8); 8);
ret = aac_read(scsicmd, cid); ret = aac_read(scsicmd, cid);
spin_lock_irq(scsicmd->device->host->host_lock); spin_lock_irq(host->host_lock);
return ret; return ret;
case SS_WRITE: case SS_WRITE:
case SM_WRITE: case SM_WRITE:
spin_unlock_irq(scsicmd->device->host->host_lock); spin_unlock_irq(host->host_lock);
ret = aac_write(scsicmd, cid); ret = aac_write(scsicmd, cid);
spin_lock_irq(scsicmd->device->host->host_lock); spin_lock_irq(host->host_lock);
return ret; return ret;
default: default:
/* /*
......
...@@ -72,7 +72,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co ...@@ -72,7 +72,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
dev->comm_addr = (void *)base; dev->comm_addr = (void *)base;
dev->comm_phys = phys; dev->comm_phys = phys;
dev->comm_size = size; dev->comm_size = size;
dev->init = (struct aac_init *)(base + fibsize); dev->init = (struct aac_init *)(base + fibsize);
dev->init_pa = phys + fibsize; dev->init_pa = phys + fibsize;
...@@ -88,7 +88,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co ...@@ -88,7 +88,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
*/ */
dev->fib_base_va = (ulong)base; 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->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
init->AdapterFibsSize = cpu_to_le32(fibsize); init->AdapterFibsSize = cpu_to_le32(fibsize);
init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib)); init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
......
...@@ -75,9 +75,8 @@ unsigned int aac_response_normal(struct aac_queue * q) ...@@ -75,9 +75,8 @@ unsigned int aac_response_normal(struct aac_queue * q)
{ {
u32 fast ; u32 fast ;
fast = (entry->addr & cpu_to_le32(0x01)); fast = (entry->addr & cpu_to_le32(0x01));
// fib = &dev->fibs[(entry->addr >> 1)]; hwfib = (struct hw_fib *)((char *)dev->hw_fib_va +
// hwfib = fib->hw_fib; ((entry->addr & ~0x01) - dev->hw_fib_pa));
hwfib = bus_to_virt(le32_to_cpu(entry->addr & cpu_to_le32(~0x01)));
fib = &dev->fibs[hwfib->header.SenderData]; fib = &dev->fibs[hwfib->header.SenderData];
aac_consumer_free(dev, q, HostNormRespQueue); aac_consumer_free(dev, q, HostNormRespQueue);
...@@ -174,7 +173,8 @@ unsigned int aac_command_normal(struct aac_queue *q) ...@@ -174,7 +173,8 @@ unsigned int aac_command_normal(struct aac_queue *q)
while(aac_consumer_get(dev, q, &entry)) while(aac_consumer_get(dev, q, &entry))
{ {
struct hw_fib * hw_fib; 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) { if (dev->aif_thread) {
aac_list_add_tail(&hw_fib->header.FibLinks, &q->cmdq); 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