Commit 9f0b7b10 authored by Doug Ledford's avatar Doug Ledford

Initial initio a100 driver DMA mapping changes + selected cleanups

* 06/25/02 Doug Ledford <dledford@redhat.com> - v1.02d
*          - Remove limit on number of controllers
*          - Port to DMA mapping API
*          - Clean up interrupt handler registration
*          - Fix memory leaks
*          - Fix allocation of scsi host structs and private data
parent 2ffe5f2f
...@@ -66,12 +66,24 @@ ...@@ -66,12 +66,24 @@
* 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up
* 01/31/99 bv - v1.02b Use mdelay instead of waitForPause * 01/31/99 bv - v1.02b Use mdelay instead of waitForPause
* 08/08/99 bv - v1.02c Use waitForPause again. * 08/08/99 bv - v1.02c Use waitForPause again.
* 06/25/02 Doug Ledford <dledford@redhat.com> - v1.02d
* - Remove limit on number of controllers
* - Port to DMA mapping API
* - Clean up interrupt handler registration
* - Fix memory leaks
* - Fix allocation of scsi host structs and private data
**************************************************************************/ **************************************************************************/
#include <linux/version.h> #include <linux/version.h>
#include <linux/jiffies.h> #include <linux/module.h>
#include <asm/irq.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <asm/io.h> #include <asm/io.h>
#include "i60uscsi.h" #include <linux/blkdev.h>
#include "scsi.h"
#include "hosts.h"
#include "inia100.h"
#define JIFFIES_TO_MS(t) ((t) * 1000 / HZ) #define JIFFIES_TO_MS(t) ((t) * 1000 / HZ)
#define MS_TO_JIFFIES(j) ((j * HZ) / 1000) #define MS_TO_JIFFIES(j) ((j * HZ) / 1000)
...@@ -98,10 +110,7 @@ ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp); ...@@ -98,10 +110,7 @@ ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp);
extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb); extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb);
/* ---- INTERNAL VARIABLES ---- */ /* ---- INTERNAL VARIABLES ---- */
ORC_HCS orc_hcs[MAX_SUPPORTED_ADAPTERS]; static INIA100_ADPT_STRUCT *inia100_adpt;
static INIA100_ADPT_STRUCT inia100_adpt[MAX_SUPPORTED_ADAPTERS];
/* set by inia100_setup according to the command line */
int orc_num_scb;
NVRAM nvram, *nvramp = &nvram; NVRAM nvram, *nvramp = &nvram;
static UCHAR dftNvRam[64] = static UCHAR dftNvRam[64] =
...@@ -300,7 +309,7 @@ UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn) ...@@ -300,7 +309,7 @@ UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn)
/***************************************************************************/ /***************************************************************************/
void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp) void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
{ {
scbp->SCB_Status = SCB_POST; scbp->SCB_Status = ORCSCB_POST;
ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx); ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx);
return; return;
} }
...@@ -439,17 +448,11 @@ void setup_SCBs(ORC_HCS * hcsp) ...@@ -439,17 +448,11 @@ void setup_SCBs(ORC_HCS * hcsp)
{ {
ORC_SCB *pVirScb; ORC_SCB *pVirScb;
int i; int i;
UCHAR j;
ESCB *pVirEscb; ESCB *pVirEscb;
PVOID pPhysEscb; dma_addr_t pPhysEscb;
PVOID tPhysEscb;
j = 0;
pVirScb = NULL;
tPhysEscb = (PVOID) NULL;
pPhysEscb = (PVOID) NULL;
/* Setup SCB HCS_Base and SCB Size registers */ /* Setup SCB HCS_Base and SCB Size registers */
ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, orc_num_scb); /* Total number of SCBs */ ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, ORC_MAXQUEUE); /* Total number of SCBs */
/* SCB HCS_Base address 0 */ /* SCB HCS_Base address 0 */
ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray); ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray);
/* SCB HCS_Base address 1 */ /* SCB HCS_Base address 1 */
...@@ -459,8 +462,8 @@ void setup_SCBs(ORC_HCS * hcsp) ...@@ -459,8 +462,8 @@ void setup_SCBs(ORC_HCS * hcsp)
pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray; pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray;
pVirEscb = (ESCB *) hcsp->HCS_virEscbArray; pVirEscb = (ESCB *) hcsp->HCS_virEscbArray;
for (i = 0; i < orc_num_scb; i++) { for (i = 0; i < ORC_MAXQUEUE; i++) {
pPhysEscb = (PVOID) (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i)); pPhysEscb = (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i));
pVirScb->SCB_SGPAddr = (U32) pPhysEscb; pVirScb->SCB_SGPAddr = (U32) pPhysEscb;
pVirScb->SCB_SensePAddr = (U32) pPhysEscb; pVirScb->SCB_SensePAddr = (U32) pPhysEscb;
pVirScb->SCB_EScb = pVirEscb; pVirScb->SCB_EScb = pVirEscb;
...@@ -534,7 +537,7 @@ int init_orchid(ORC_HCS * hcsp) ...@@ -534,7 +537,7 @@ int init_orchid(ORC_HCS * hcsp)
readBytep = (UCHAR *) & (nvramp->Target00Config); readBytep = (UCHAR *) & (nvramp->Target00Config);
for (i = 0; i < 16; readBytep++, i++) { for (i = 0; i < 16; readBytep++, i++) {
hcsp->TargetFlag[i] = *readBytep; hcsp->TargetFlag[i] = *readBytep;
hcsp->MaximumTags[i] = orc_num_scb; hcsp->MaximumTags[i] = ORC_MAXTAGS;
} /* for */ } /* for */
if (nvramp->SCSI0Config & NCC_BUSRESET) { /* Reset SCSI bus */ if (nvramp->SCSI0Config & NCC_BUSRESET) { /* Reset SCSI bus */
...@@ -578,7 +581,7 @@ int orc_reset_scsi_bus(ORC_HCS * pHCB) ...@@ -578,7 +581,7 @@ int orc_reset_scsi_bus(ORC_HCS * pHCB)
Output : None. Output : None.
Return : pSRB - Pointer to SCSI request block. Return : pSRB - Pointer to SCSI request block.
*****************************************************************************/ *****************************************************************************/
int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned int ResetFlags) int orc_device_reset(ORC_HCS * pHCB, Scsi_Cmnd *SCpnt, unsigned int target, unsigned int ResetFlags)
{ /* I need Host Control Block Information */ { /* I need Host Control Block Information */
ORC_SCB *pScb; ORC_SCB *pScb;
ESCB *pVirEscb; ESCB *pVirEscb;
...@@ -595,14 +598,14 @@ int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned ...@@ -595,14 +598,14 @@ int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned
initAFlag(pHCB); initAFlag(pHCB);
/* device reset */ /* device reset */
for (i = 0; i < orc_num_scb; i++) { for (i = 0; i < ORC_MAXQUEUE; i++) {
pVirEscb = pVirScb->SCB_EScb; pVirEscb = pVirScb->SCB_EScb;
if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt)) if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt))
break; break;
pVirScb++; pVirScb++;
} }
if (i == orc_num_scb) { if (i == ORC_MAXQUEUE) {
printk("Unable to Reset - No SCB Found\n"); printk("Unable to Reset - No SCB Found\n");
spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
return (SCSI_RESET_NOT_RUNNING); return (SCSI_RESET_NOT_RUNNING);
...@@ -624,7 +627,7 @@ int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned ...@@ -624,7 +627,7 @@ int orc_device_reset(ORC_HCS * pHCB, ULONG SCpnt, unsigned int target, unsigned
pVirEscb->SCB_Srb = 0; pVirEscb->SCB_Srb = 0;
if (ResetFlags & SCSI_RESET_SYNCHRONOUS) { if (ResetFlags & SCSI_RESET_SYNCHRONOUS) {
pVirEscb->SCB_Srb = (unsigned char *) SCpnt; pVirEscb->SCB_Srb = SCpnt;
} }
orc_exec_scb(pHCB, pScb); /* Start execute SCB */ orc_exec_scb(pHCB, pScb); /* Start execute SCB */
spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags);
...@@ -640,7 +643,6 @@ ORC_SCB *__orc_alloc_scb(ORC_HCS * hcsp) ...@@ -640,7 +643,6 @@ ORC_SCB *__orc_alloc_scb(ORC_HCS * hcsp)
ULONG idx; ULONG idx;
UCHAR index; UCHAR index;
UCHAR i; UCHAR i;
ULONG flags;
Ch = hcsp->HCS_Index; Ch = hcsp->HCS_Index;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
...@@ -687,6 +689,29 @@ void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp) ...@@ -687,6 +689,29 @@ void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
} }
/***************************************************************************/
void orc_release_dma(ORC_HCS * hcsp, ORC_SCB * scbp)
{
ESCB *pEScb;
Scsi_Cmnd *SCpnt;
struct scatterlist *pSrbSG;
ORC_SG *pSG;
pEScb = scbp->SCB_EScb;
SCpnt = pEScb->SCB_Srb;
pSG = (ORC_SG *) & pEScb->ESCB_SGList[0];
if (SCpnt->use_sg) {
pSrbSG = (struct scatterlist *)SCpnt->request_buffer;
pci_unmap_sg(hcsp->pdev, pSrbSG, SCpnt->use_sg,
scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
} else {
pci_unmap_single(hcsp->pdev, (U32)SCpnt->host_scribble,
SCpnt->request_bufflen,
scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
}
}
/***************************************************************************** /*****************************************************************************
Function name : Addinia100_into_Adapter_table Function name : Addinia100_into_Adapter_table
Description : This function will scan PCI bus to get all Orchid card Description : This function will scan PCI bus to get all Orchid card
...@@ -695,33 +720,29 @@ void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp) ...@@ -695,33 +720,29 @@ void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp)
Return : SUCCESSFUL - Successful scan Return : SUCCESSFUL - Successful scan
ohterwise - No drives founded ohterwise - No drives founded
*****************************************************************************/ *****************************************************************************/
int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt, int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, struct pci_dev *pdev,
BYTE bBus, BYTE bDevice) int iAdapters)
{ {
unsigned int i, j; unsigned int i, j;
for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { for (i = 0; i < iAdapters; i++) {
if (inia100_adpt[i].ADPT_BIOS < wBIOS) if (inia100_adpt[i].ADPT_BIOS < wBIOS)
continue; continue;
if (inia100_adpt[i].ADPT_BIOS == wBIOS) { if (inia100_adpt[i].ADPT_BIOS == wBIOS) {
if (inia100_adpt[i].ADPT_BASE == wBASE) { if (inia100_adpt[i].ADPT_BASE == wBASE) {
if (inia100_adpt[i].ADPT_Bus != 0xFF) if (inia100_adpt[i].ADPT_pdev->bus->number != 0xFF)
return (FAILURE); return (FAILURE);
} else if (inia100_adpt[i].ADPT_BASE < wBASE) } else if (inia100_adpt[i].ADPT_BASE < wBASE)
continue; continue;
} }
for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) { for (j = iAdapters - 1; j > i; j--) {
inia100_adpt[j].ADPT_BASE = inia100_adpt[j - 1].ADPT_BASE; inia100_adpt[j].ADPT_BASE = inia100_adpt[j - 1].ADPT_BASE;
inia100_adpt[j].ADPT_INTR = inia100_adpt[j - 1].ADPT_INTR;
inia100_adpt[j].ADPT_BIOS = inia100_adpt[j - 1].ADPT_BIOS; inia100_adpt[j].ADPT_BIOS = inia100_adpt[j - 1].ADPT_BIOS;
inia100_adpt[j].ADPT_Bus = inia100_adpt[j - 1].ADPT_Bus; inia100_adpt[j].ADPT_pdev = inia100_adpt[j - 1].ADPT_pdev;
inia100_adpt[j].ADPT_Device = inia100_adpt[j - 1].ADPT_Device;
} }
inia100_adpt[i].ADPT_BASE = wBASE; inia100_adpt[i].ADPT_BASE = wBASE;
inia100_adpt[i].ADPT_INTR = bInterrupt;
inia100_adpt[i].ADPT_BIOS = wBIOS; inia100_adpt[i].ADPT_BIOS = wBIOS;
inia100_adpt[i].ADPT_Bus = bBus; inia100_adpt[i].ADPT_pdev = pdev;
inia100_adpt[i].ADPT_Device = bDevice;
return (SUCCESSFUL); return (SUCCESSFUL);
} }
return (FAILURE); return (FAILURE);
...@@ -733,20 +754,23 @@ int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt, ...@@ -733,20 +754,23 @@ int Addinia100_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
Description : This function will scan PCI bus to get all Orchid card Description : This function will scan PCI bus to get all Orchid card
Input : None. Input : None.
Output : None. Output : None.
Return : SUCCESSFUL - Successful scan Return : 0 on success, 1 on failure
ohterwise - No drives founded
*****************************************************************************/ *****************************************************************************/
void init_inia100Adapter_table(void) int init_inia100Adapter_table(int iAdapters)
{ {
int i; int i;
for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { /* Initialize adapter structure */ inia100_adpt = kmalloc(sizeof(INIA100_ADPT_STRUCT) * iAdapters,
GFP_KERNEL);
if(inia100_adpt == NULL)
return 1;
for (i = 0; i < iAdapters; i++) {/* Initialize adapter structure */
inia100_adpt[i].ADPT_BIOS = 0xffff; inia100_adpt[i].ADPT_BIOS = 0xffff;
inia100_adpt[i].ADPT_BASE = 0xffff; inia100_adpt[i].ADPT_BASE = 0xffff;
inia100_adpt[i].ADPT_INTR = 0xff; inia100_adpt[i].ADPT_pdev = NULL;
inia100_adpt[i].ADPT_Bus = 0xff;
inia100_adpt[i].ADPT_Device = 0xff;
} }
return 0;
} }
/***************************************************************************** /*****************************************************************************
...@@ -760,7 +784,7 @@ void get_orcPCIConfig(ORC_HCS * pCurHcb, int ch_idx) ...@@ -760,7 +784,7 @@ void get_orcPCIConfig(ORC_HCS * pCurHcb, int ch_idx)
{ {
pCurHcb->HCS_Base = inia100_adpt[ch_idx].ADPT_BASE; /* Supply base address */ pCurHcb->HCS_Base = inia100_adpt[ch_idx].ADPT_BASE; /* Supply base address */
pCurHcb->HCS_BIOS = inia100_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */ pCurHcb->HCS_BIOS = inia100_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */
pCurHcb->HCS_Intr = inia100_adpt[ch_idx].ADPT_INTR; /* Supply interrupt line */ pCurHcb->HCS_Intr = inia100_adpt[ch_idx].ADPT_pdev->irq; /* Supply interrupt line */
return; return;
} }
...@@ -805,7 +829,7 @@ int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb) ...@@ -805,7 +829,7 @@ int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb)
Output : None. Output : None.
Return : pSRB - Pointer to SCSI request block. Return : pSRB - Pointer to SCSI request block.
*****************************************************************************/ *****************************************************************************/
int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt) int orc_abort_srb(ORC_HCS * hcsp, Scsi_Cmnd *SCpnt)
{ {
ESCB *pVirEscb; ESCB *pVirEscb;
ORC_SCB *pVirScb; ORC_SCB *pVirScb;
...@@ -816,9 +840,9 @@ int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt) ...@@ -816,9 +840,9 @@ int orc_abort_srb(ORC_HCS * hcsp, ULONG SCpnt)
pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray; pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray;
for (i = 0; i < orc_num_scb; i++, pVirScb++) { for (i = 0; i < ORC_MAXQUEUE; i++, pVirScb++) {
pVirEscb = pVirScb->SCB_EScb; pVirEscb = pVirScb->SCB_EScb;
if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == (unsigned char *) SCpnt)) { if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt)) {
if (pVirScb->SCB_TagMsg == 0) { if (pVirScb->SCB_TagMsg == 0) {
spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags);
return (SCSI_ABORT_BUSY); return (SCSI_ABORT_BUSY);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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