Commit f455d910 authored by James Bottomley's avatar James Bottomley Committed by Christoph Hellwig

Convert tmcscsim to new probing interfaces

From: 	Guennadi Liakhovetski <g.liakhovetski@gmx.de>

Update the driver to use the new pci, scsi and
module interfaces.

Modified with feedback from hch
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 5776e385
......@@ -33,7 +33,6 @@
# define USE_NEW_EH
#endif
static int DC390_detect(Scsi_Host_Template *psht);
static int DC390_queue_command(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
static int DC390_abort(Scsi_Cmnd *cmd);
static int DC390_reset(Scsi_Cmnd *cmd);
......
......@@ -789,7 +789,7 @@ dc390_MsgIn_complete (UCHAR *msgbuf, UINT len)
/* read and eval received messages */
void
static void
dc390_MsgIn_0( PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
PDCB pDCB = pACB->pActiveDCB;
......@@ -948,7 +948,7 @@ dc390_DataInPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
dc390_DataIO_Comm (pACB, pSRB, READ_DIRECTION);
}
void
static void
dc390_CommandPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
PDCB pDCB;
......@@ -989,7 +989,7 @@ dc390_StatusPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
//DC390_write8 (DMA_Cmd, DMA_IDLE_CMD);
}
void
static void
dc390_MsgOutPhase( PACB pACB, PSRB pSRB, PUCHAR psstatus)
{
UCHAR bval, i, cnt;
......@@ -1097,7 +1097,7 @@ dc390_SetXferRate( PACB pACB, PDCB pDCB )
}
void
static void
dc390_Disconnect( PACB pACB )
{
PDCB pDCB;
......@@ -1179,7 +1179,7 @@ dc390_Disconnect( PACB pACB )
}
void
static void
dc390_Reselect( PACB pACB )
{
PDCB pDCB;
......@@ -1349,10 +1349,10 @@ dc390_add_dev (PACB pACB, PDCB pDCB, PSCSI_INQDATA ptr)
};
void
static void
dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
{
UCHAR bval, status, i, DCB_removed;
UCHAR bval, status, i;
PSCSICMD pcmd;
PSCSI_INQDATA ptr;
PSGL ptr2;
......@@ -1362,7 +1362,6 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
/* KG: Moved pci_unmap here */
dc390_pci_unmap(pSRB);
DCB_removed = 0;
status = pSRB->TargetStatus;
ptr = (PSCSI_INQDATA) (pcmd->request_buffer);
if( pcmd->use_sg )
......@@ -1569,8 +1568,6 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
(pcmd->sense_buffer[2] & 0xf) == ILLEGAL_REQUEST) || host_byte(pcmd->result) & DID_ERROR )
{
/* device not present: remove */
//dc390_Going_remove (pDCB, pSRB);
dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
((pcmd->device->lun == 0) || (pcmd->device->lun == pACB->pScsiHost->max_lun - 1)) )
......@@ -1582,24 +1579,14 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
(pcmd->device->lun == pACB->pScsiHost->max_lun - 1) )
pACB->scan_devices = END_SCAN ;
/* pACB->DeviceCnt++; */ /* Dev is added on INQUIRY */
}
}
}
//if( pSRB->pcmd->cmnd[0] == INQUIRY &&
// (host_byte(pcmd->result) == DID_OK || status_byte(pcmd->result) & CHECK_CONDITION) )
if( pcmd->cmnd[0] == INQUIRY &&
(pcmd->result == (DID_OK << 16) || status_byte(pcmd->result) & CHECK_CONDITION) )
{
if ((ptr->DevType & SCSI_DEVTYPE) == TYPE_NODEV && !DCB_removed)
{
//printk ("DC390: Type = nodev! (%02i-%i)\n", pcmd->target, pcmd->lun);
/* device not present: remove */
//dc390_Going_remove (pDCB, pSRB);
dc390_remove_dev (pACB, pDCB); DCB_removed = 1;
}
else
if ((ptr->DevType & SCSI_DEVTYPE) != TYPE_NODEV)
{
/* device found: add */
dc390_add_dev (pACB, pDCB, ptr);
......@@ -1608,11 +1595,11 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
if( (pcmd->device->id == pACB->pScsiHost->max_id - 1) &&
(pcmd->device->lun == pACB->pScsiHost->max_lun - 1) )
pACB->scan_devices = 0;
};
}
pcmd->resid = pcmd->request_bufflen - pSRB->TotalXferredLen;
if (!DCB_removed) dc390_Going_remove (pDCB, pSRB);
dc390_Going_remove (pDCB, pSRB);
/* Add to free list */
dc390_Free_insert (pACB, pSRB);
......@@ -1625,7 +1612,7 @@ dc390_SRBdone( PACB pACB, PDCB pDCB, PSRB pSRB )
/* Remove all SRBs from Going list and inform midlevel */
void
static void
dc390_DoingSRB_Done( PACB pACB, PSCSICMD cmd )
{
PDCB pDCB, pdcb;
......@@ -1760,4 +1747,3 @@ dc390_InvalidCmd( PACB pACB )
if( pACB->pActiveDCB->pActiveSRB->SRBState & (SRB_START_+SRB_MSGOUT) )
DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
}
......@@ -267,7 +267,6 @@
#include <linux/init.h>
#include <linux/spinlock.h>
#if defined(MODULE)
static struct pci_device_id tmscsim_pci_tbl[] = {
{
.vendor = PCI_VENDOR_ID_AMD,
......@@ -278,8 +277,7 @@ static struct pci_device_id tmscsim_pci_tbl[] = {
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(pci, tmscsim_pci_tbl);
#endif
#define USE_SPINLOCKS 1
#define DC390_IFLAGS unsigned long iflags
......@@ -342,6 +340,8 @@ static void dc390_updateDCB (PACB pACB, PDCB pDCB);
static int DC390_release(struct Scsi_Host *host);
static int dc390_shutdown (struct Scsi_Host *host);
static int DC390_proc_info (struct Scsi_Host *shpnt, char *buffer, char **start,
off_t offset, int length, int inout);
static PACB dc390_pACB_start= NULL;
static PACB dc390_pACB_current = NULL;
......@@ -351,16 +351,14 @@ static UCHAR dc390_adapterCnt = 0;
/* Startup values, to be overriden on the commandline */
static int tmscsim[] = {-2, -2, -2, -2, -2, -2};
static int tmscsim_paramnum = ARRAY_SIZE(tmscsim);
#if defined(MODULE)
MODULE_PARM(tmscsim, "1-6i");
module_param_array(tmscsim, int, tmscsim_paramnum, 0);
MODULE_PARM_DESC(tmscsim, "Host SCSI ID, Speed (0=10MHz), Device Flags, Adapter Flags, Max Tags (log2(tags)-1), DelayReset (s)");
MODULE_AUTHOR("C.L. Huang / Kurt Garloff");
MODULE_DESCRIPTION("SCSI host adapter driver for Tekram DC390 and other AMD53C974A based PCI SCSI adapters");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
#endif
static PVOID dc390_phase0[]={
dc390_DataOut_0,
......@@ -1051,41 +1049,29 @@ static int DC390_queue_command (Scsi_Cmnd *cmd, void (* done)(Scsi_Cmnd *))
* commands and alloc a DCB for the device if not yet there. DCB will
* be removed in dc390_SRBdone if SEL_TIMEOUT */
if( (pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY) )
pACB->scan_devices = 0;
else if( (pACB->scan_devices) && (cmd->cmnd[0] == READ_6) )
if (((pACB->scan_devices == END_SCAN) && (cmd->cmnd[0] != INQUIRY)) ||
((pACB->scan_devices) && (cmd->cmnd[0] == READ_6)))
pACB->scan_devices = 0;
if( (pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) &&
!(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
{
pACB->scan_devices = 1;
dc390_initDCB( pACB, &pDCB, cmd->device->id, cmd->device->lun );
if (!pDCB)
{
printk (KERN_ERR "DC390: kmalloc for DCB failed, target %02x lun %02x\n",
cmd->device->id, cmd->device->lun);
goto fail;
}
}
else if( !(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun)) )
{
if ((pACB->scan_devices || cmd->cmnd[0] == TEST_UNIT_READY || cmd->cmnd[0] == INQUIRY) &&
!(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun))) {
pACB->scan_devices = 1;
DCBDEBUG(printk("Scanning target %02x lun %02x\n", cmd->device->id, cmd->device->lun));
} else if (!(pACB->scan_devices) && !(pACB->DCBmap[cmd->device->id] & (1 << cmd->device->lun))) {
printk(KERN_INFO "DC390: Ignore target %02x lun %02x\n",
cmd->device->id, cmd->device->lun);
goto fail;
}
else
{
pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
if (!pDCB)
{ /* should never happen */
printk (KERN_ERR "DC390: no DCB failed, target %02x lun %02x\n",
cmd->device->id, cmd->device->lun);
goto fail;
}
pDCB = dc390_findDCB (pACB, cmd->device->id, cmd->device->lun);
/* Should it be: BUG_ON(!pDCB); ? */
if (!pDCB)
{ /* should never happen */
printk (KERN_ERR "DC390: no DCB found, target %02x lun %02x\n",
cmd->device->id, cmd->device->lun);
goto fail;
}
pACB->Cmds++;
......@@ -1856,7 +1842,7 @@ static int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR in
*
* Inputs : host - pointer to this host adapter's structure
* io_port - IO ports mapped to this adapter
* Irq - IRQ assigned to this adpater
* irq - IRQ assigned to this adpater
* struct pci_dev - PCI access handle
* index - Adapter index
*
......@@ -1865,10 +1851,8 @@ static int __init dc390_initAdapter (PSH psh, ULONG io_port, UCHAR Irq, UCHAR in
* Note: written in capitals, because the locking is only done here,
* not in DC390_detect, called from outside
***********************************************************************/
static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, struct pci_dev *pdev, UCHAR index)
static int __init dc390_init (PSH psh, unsigned long io_port, u8 irq, struct pci_dev *pdev, UCHAR index)
{
PSH psh;
PACB pACB;
if (dc390_CheckEEpromCheckSum (PDEV, index))
......@@ -1890,25 +1874,16 @@ static int __init DC390_init (PSHT psht, ULONG io_port, UCHAR Irq, struct pci_de
dc390_check_for_safe_settings ();
dc390_EEprom_Override (index);
}
psh = scsi_register( psht, sizeof(DC390_ACB) );
if( !psh ) return( -1 );
scsi_set_device(psh, &pdev->dev);
pACB = (PACB) psh->hostdata;
DEBUG0(printk(KERN_INFO "DC390: pSH = %8x, Index %02i\n", (UINT) psh, index));
dc390_initACB( psh, io_port, Irq, index );
dc390_initACB( psh, io_port, irq, index );
PDEVSET;
if( !dc390_initAdapter( psh, io_port, Irq, index ) )
if( !dc390_initAdapter( psh, io_port, irq, index ) )
{
DEBUG0(printk("DC390: pACB = %8x, pDCBmap = %8x, pSRB_array = %8x\n",\
(UINT) pACB, (UINT) pACB->DCBmap, (UINT) pACB->SRB_array));
DEBUG0(printk("DC390: ACB size= %4x, DCB size= %4x, SRB size= %4x\n",\
sizeof(DC390_ACB), sizeof(DC390_DCB), sizeof(DC390_SRB) ));
return (0);
}
else
......@@ -1927,42 +1902,119 @@ static void __init dc390_set_pci_cfg (PDEVDECL)
PCI_WRITE_CONFIG_WORD (PDEV, PCI_STATUS, (PCI_STATUS_SIG_SYSTEM_ERROR | PCI_STATUS_DETECTED_PARITY));
}
int __init DC390_detect (Scsi_Host_Template *psht)
/**
* dc390_slave_alloc - Called by the scsi mid layer to tell us about a new
* scsi device that we need to deal with.
*
* @scsi_device: The new scsi device that we need to handle.
*/
static int dc390_slave_alloc(struct scsi_device *scsi_device)
{
PDCB pDCB;
PACB pACB = (PACB) scsi_device->host->hostdata;
dc390_initDCB(pACB, &pDCB, scsi_device->id, scsi_device->lun);
if (pDCB != NULL)
return 0;
return -ENOMEM;
}
/**
* dc390_slave_destroy - Called by the scsi mid layer to tell us about a
* device that is going away.
*
* @scsi_device: The scsi device that we need to remove.
*/
static void dc390_slave_destroy(struct scsi_device *scsi_device)
{
PACB pACB = (PACB) scsi_device->host->hostdata;
PDCB pDCB = dc390_findDCB (pACB, scsi_device->id, scsi_device->lun);;
if (pDCB != NULL)
dc390_remove_dev(pACB, pDCB);
else
printk(KERN_ERR"%s() called for non-existing device!\n", __FUNCTION__);
}
static Scsi_Host_Template driver_template = {
.module = THIS_MODULE,
.proc_name = "tmscsim",
.proc_info = DC390_proc_info,
.name = DC390_BANNER " V" DC390_VERSION,
.slave_alloc = dc390_slave_alloc,
.slave_destroy = dc390_slave_destroy,
.queuecommand = DC390_queue_command,
.eh_abort_handler = DC390_abort,
.eh_bus_reset_handler = DC390_reset,
.bios_param = DC390_bios_param,
.can_queue = 42,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 16,
.use_clustering = DISABLE_CLUSTERING,
};
static int __devinit dc390_init_one(struct pci_dev *dev,
const struct pci_device_id *id)
{
struct pci_dev *pdev = NULL;
UCHAR irq;
ULONG io_port;
struct Scsi_Host *scsi_host;
unsigned long io_port;
u8 irq;
PACB pACB;
int ret = -ENOMEM;
dc390_pACB_start = NULL;
if (pci_enable_device(dev))
return -ENODEV;
if ( PCI_PRESENT )
while ((pdev = pci_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD53C974, pdev)))
{
if (pci_enable_device (pdev))
continue;
io_port = pci_resource_start(dev, 0);
irq = dev->irq;
if (pci_set_dma_mask(pdev, 0xffffffff)) {
printk(KERN_ERR "DC390(%i): No suitable DMA available.\n", dc390_adapterCnt);
continue;
}
PCI_GET_IO_AND_IRQ;
DEBUG0(printk(KERN_INFO "DC390(%i): IO_PORT=%04x,IRQ=%x\n", dc390_adapterCnt, (UINT) io_port, irq));
/* allocate scsi host information (includes out adapter) */
scsi_host = scsi_host_alloc(&driver_template, sizeof(struct _ACB));
if (!scsi_host)
goto nomem;
if( !DC390_init(psht, io_port, irq, PDEV, dc390_adapterCnt))
{
pci_set_master(pdev);
dc390_set_pci_cfg (PDEV);
dc390_adapterCnt++;
}
pACB = (PACB)scsi_host->hostdata;
if (dc390_init(scsi_host, io_port, irq, dev, dc390_adapterCnt)) {
ret = -EBUSY;
goto busy;
}
else
printk (KERN_ERR "DC390: No PCI BIOS found!\n");
if (dc390_adapterCnt)
psht->proc_name = "tmscsim";
printk(KERN_INFO "DC390: %i adapters found\n", dc390_adapterCnt);
return( dc390_adapterCnt );
pci_set_master(dev);
dc390_set_pci_cfg(dev);
dc390_adapterCnt++;
/* get the scsi mid level to scan for new devices on the bus */
if (scsi_add_host(scsi_host, &dev->dev)) {
ret = -ENODEV;
goto nodev;
}
pci_set_drvdata(dev, scsi_host);
scsi_scan_host(scsi_host);
return 0;
nodev:
busy:
scsi_host_put(scsi_host);
nomem:
pci_disable_device(dev);
return ret;
}
/**
* dc390_remove_one - Called to remove a single instance of the adapter.
*
* @dev: The PCI device to remove.
*/
static void __devexit dc390_remove_one(struct pci_dev *dev)
{
struct Scsi_Host *scsi_host = pci_get_drvdata(dev);
scsi_remove_host(scsi_host);
DC390_release(scsi_host);
pci_disable_device(dev);
scsi_host_put(scsi_host);
pci_set_drvdata(dev, NULL);
}
/********************************************************************
......@@ -2177,24 +2229,25 @@ static int DC390_release (struct Scsi_Host *host)
release_region(host->io_port,host->n_io_port);
dc390_freeDCBs (host);
DC390_UNLOCK_IO(host);
scsi_unregister(host);
return( 1 );
}
static Scsi_Host_Template driver_template = {
.proc_name = "tmscsim",
.proc_info = DC390_proc_info,
.name = DC390_BANNER " V" DC390_VERSION,
.detect = DC390_detect,
.release = DC390_release,
.queuecommand = DC390_queue_command,
.eh_abort_handler = DC390_abort,
.eh_bus_reset_handler = DC390_reset,
.bios_param = DC390_bios_param,
.can_queue = 42,
.this_id = 7,
.sg_tablesize = SG_ALL,
.cmd_per_lun = 16,
.use_clustering = DISABLE_CLUSTERING,
static struct pci_driver dc390_driver = {
.name = "tmscsim",
.id_table = tmscsim_pci_tbl,
.probe = dc390_init_one,
.remove = __devexit_p(dc390_remove_one),
};
#include "scsi_module.c"
static int __init dc390_module_init(void)
{
return pci_module_init(&dc390_driver);
}
static void __exit dc390_module_exit(void)
{
pci_unregister_driver(&dc390_driver);
}
module_init(dc390_module_init);
module_exit(dc390_module_exit);
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