All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] dpt_i2o pci_driver model
@ 2005-08-17 17:04 Salyzyn, Mark
  2005-08-19 14:59 ` Christoph Hellwig
  0 siblings, 1 reply; 5+ messages in thread
From: Salyzyn, Mark @ 2005-08-17 17:04 UTC (permalink / raw)
  To: linux-scsi; +Cc: Christoph Hellwig

[-- Attachment #1: Type: text/plain, Size: 855 bytes --]

Christoph Hellwig [mailto:hch@infradead.org] writes:
> ... update the driver to use the pci_driver model ...

The patch applies to the scsi-misc-2.6 git tree. The moving of
adpt_install_hba to the near bottom of the dpt_i2o.c file creates a
dirty context diff in that region which is hard to inspect from within
the patch. No coding style changes were made when moving content from
the original initialization code to the module_init and module_exit
functions to aid before and after comparisons for inspection; even
despite the fact C++ style comments are used in these sections. We
expect such style cleanup to occur either on any necessary follow-up
rewrites after basic functional approval, or as a follow-up cleanup
patch.

Signed-off-by: Mark Salyzyn <aacraid@adaptec.com>

Sent as an attachment due to MIS policy and mailer tools.

[-- Attachment #2: pci_scan1.patch --]
[-- Type: application/octet-stream, Size: 24344 bytes --]

diff -ru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	2005-08-17 07:13:30.459137562 -0400
+++ b/drivers/scsi/dpt_i2o.c	2005-08-17 09:58:41.512956079 -0400
@@ -1,8 +1,8 @@
 /***************************************************************************
-                          dpti.c  -  description
+                          dpt_i2o.c  -  description
                              -------------------
     begin                : Thu Sep 7 2000
-    copyright            : (C) 2000 by Adaptec
+    copyright            : (C) 2000-2005 by Adaptec
 
 			   July 30, 2001 First version being submitted
 			   for inclusion in the kernel.  V2.4
@@ -173,98 +173,6 @@
 };
 MODULE_DEVICE_TABLE(pci,dptids);
 
-static int adpt_detect(struct scsi_host_template* sht)
-{
-	struct pci_dev *pDev = NULL;
-	adpt_hba* pHba;
-
-	adpt_init();
-
-	PINFO("Detecting Adaptec I2O RAID controllers...\n");
-
-        /* search for all Adatpec I2O RAID cards */
-	while ((pDev = pci_find_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
-		if(pDev->device == PCI_DPT_DEVICE_ID ||
-		   pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
-			if(adpt_install_hba(sht, pDev) ){
-				PERROR("Could not Init an I2O RAID device\n");
-				PERROR("Will not try to detect others.\n");
-				return hba_count-1;
-			}
-		}
-	}
-
-	/* In INIT state, Activate IOPs */
-	for (pHba = hba_chain; pHba; pHba = pHba->next) {
-		// Activate does get status , init outbound, and get hrt
-		if (adpt_i2o_activate_hba(pHba) < 0) {
-			adpt_i2o_delete_hba(pHba);
-		}
-	}
-
-
-	/* Active IOPs in HOLD state */
-
-rebuild_sys_tab:
-	if (hba_chain == NULL) 
-		return 0;
-
-	/*
-	 * If build_sys_table fails, we kill everything and bail
-	 * as we can't init the IOPs w/o a system table
-	 */	
-	if (adpt_i2o_build_sys_table() < 0) {
-		adpt_i2o_sys_shutdown();
-		return 0;
-	}
-
-	PDEBUG("HBA's in HOLD state\n");
-
-	/* If IOP don't get online, we need to rebuild the System table */
-	for (pHba = hba_chain; pHba; pHba = pHba->next) {
-		if (adpt_i2o_online_hba(pHba) < 0) {
-			adpt_i2o_delete_hba(pHba);	
-			goto rebuild_sys_tab;
-		}
-	}
-
-	/* Active IOPs now in OPERATIONAL state */
-	PDEBUG("HBA's in OPERATIONAL state\n");
-
-	printk("dpti: If you have a lot of devices this could take a few minutes.\n");
-	for (pHba = hba_chain; pHba; pHba = pHba->next) {
-		printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
-		if (adpt_i2o_lct_get(pHba) < 0){
-			adpt_i2o_delete_hba(pHba);
-			continue;
-		}
-
-		if (adpt_i2o_parse_lct(pHba) < 0){
-			adpt_i2o_delete_hba(pHba);
-			continue;
-		}
-		adpt_inquiry(pHba);
-	}
-
-	for (pHba = hba_chain; pHba; pHba = pHba->next) {
-		if( adpt_scsi_register(pHba,sht) < 0){
-			adpt_i2o_delete_hba(pHba);
-			continue;
-		}
-		pHba->initialized = TRUE;
-		pHba->state &= ~DPTI_STATE_RESET;
-	}
-
-	// Register our control device node
-	// nodes will need to be created in /dev to access this
-	// the nodes can not be created from within the driver
-	if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
-		adpt_i2o_sys_shutdown();
-		return 0;
-	}
-	return hba_count;
-}
-
 
 /*
  * scsi_unregister will be called AFTER we return. 
@@ -272,9 +180,10 @@
 static int adpt_release(struct Scsi_Host *host)
 {
 	adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
+	if (!pHba)
+		return 0;
 //	adpt_i2o_quiesce_hba(pHba);
 	adpt_i2o_delete_hba(pHba);
-	scsi_unregister(host);
 	return 0;
 }
 
@@ -865,310 +774,102 @@
 #endif
 
 
-static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) 
+static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
 {
+	struct adpt_device* d;
 
-	adpt_hba* pHba = NULL;
-	adpt_hba* p = NULL;
-	ulong base_addr0_phys = 0;
-	ulong base_addr1_phys = 0;
-	u32 hba_map0_area_size = 0;
-	u32 hba_map1_area_size = 0;
-	void __iomem *base_addr_virt = NULL;
-	void __iomem *msg_addr_virt = NULL;
-
-	int raptorFlag = FALSE;
-
-	if(pci_enable_device(pDev)) {
-		return -EINVAL;
+	if(chan < 0 || chan >= MAX_CHANNEL)
+		return NULL;
+	
+	if( pHba->channel[chan].device == NULL){
+		printk(KERN_DEBUG"Adaptec I2O RAID: Trying to find device before they are allocated\n");
+		return NULL;
 	}
-	pci_set_master(pDev);
-	if (pci_set_dma_mask(pDev, 0xffffffffffffffffULL) &&
-	    pci_set_dma_mask(pDev, 0xffffffffULL))
-		return -EINVAL;
 
-	base_addr0_phys = pci_resource_start(pDev,0);
-	hba_map0_area_size = pci_resource_len(pDev,0);
+	if (id < 0 || id >= MAX_ID)
+		return NULL;
 
-	// Check if standard PCI card or single BAR Raptor
-	if(pDev->device == PCI_DPT_DEVICE_ID){
-		if(pDev->subsystem_device >=0xc032 && pDev->subsystem_device <= 0xc03b){
-			// Raptor card with this device id needs 4M
-			hba_map0_area_size = 0x400000;
-		} else { // Not Raptor - it is a PCI card
-			if(hba_map0_area_size > 0x100000 ){ 
-				hba_map0_area_size = 0x100000;
-			}
-		}
-	} else {// Raptor split BAR config
-		// Use BAR1 in this configuration
-		base_addr1_phys = pci_resource_start(pDev,1);
-		hba_map1_area_size = pci_resource_len(pDev,1);
-		raptorFlag = TRUE;
+	d = pHba->channel[chan].device[id];
+	if(!d || d->tid == 0) {
+		return NULL;
 	}
 
-
-	base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size);
-	if (!base_addr_virt) {
-		PERROR("dpti: adpt_config_hba: io remap failed\n");
-		return -EINVAL;
+	/* If it is the only lun at that address then this should match*/
+	if(d->scsi_lun == lun){
+		return d;
 	}
 
-        if(raptorFlag == TRUE) {
-		msg_addr_virt = ioremap(base_addr1_phys, hba_map1_area_size );
-		if (!msg_addr_virt) {
-			PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
-			iounmap(base_addr_virt);
-			return -EINVAL;
-		}
-	} else {
-		msg_addr_virt = base_addr_virt;
-	}
-	
-	// Allocate and zero the data structure
-	pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL);
-	if( pHba == NULL) {
-		if(msg_addr_virt != base_addr_virt){
-			iounmap(msg_addr_virt);
+	/* else we need to look through all the luns */
+	for(d=d->next_lun ; d ; d = d->next_lun){
+		if(d->scsi_lun == lun){
+			return d;
 		}
-		iounmap(base_addr_virt);
-		return -ENOMEM;
 	}
-	memset(pHba, 0, sizeof(adpt_hba));
+	return NULL;
+}
 
-	down(&adpt_configuration_lock);
 
-	if(hba_chain != NULL){
-		for(p = hba_chain; p->next; p = p->next);
-		p->next = pHba;
-	} else {
-		hba_chain = pHba;
-	}
-	pHba->next = NULL;
-	pHba->unit = hba_count;
-	sprintf(pHba->name, "dpti%d", hba_count);
-	hba_count++;
-	
-	up(&adpt_configuration_lock);
+static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
+{
+	// I used my own version of the WAIT_QUEUE_HEAD
+	// to handle some version differences
+	// When embedded in the kernel this could go back to the vanilla one
+	ADPT_DECLARE_WAIT_QUEUE_HEAD(adpt_wq_i2o_post);
+	int status = 0;
+	ulong flags = 0;
+	struct adpt_i2o_post_wait_data *p1, *p2;
+	struct adpt_i2o_post_wait_data *wait_data =
+		kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL);
+	DECLARE_WAITQUEUE(wait, current);
 
-	pHba->pDev = pDev;
-	pHba->base_addr_phys = base_addr0_phys;
+	if (!wait_data)
+		return -ENOMEM;
 
-	// Set up the Virtual Base Address of the I2O Device
-	pHba->base_addr_virt = base_addr_virt;
-	pHba->msg_addr_virt = msg_addr_virt;
-	pHba->irq_mask = base_addr_virt+0x30;
-	pHba->post_port = base_addr_virt+0x40;
-	pHba->reply_port = base_addr_virt+0x44;
+	/*
+	 * The spin locking is needed to keep anyone from playing
+	 * with the queue pointers and id while we do the same
+	 */
+	spin_lock_irqsave(&adpt_post_wait_lock, flags);
+       // TODO we need a MORE unique way of getting ids
+       // to support async LCT get
+	wait_data->next = adpt_post_wait_queue;
+	adpt_post_wait_queue = wait_data;
+	adpt_post_wait_id++;
+	adpt_post_wait_id &= 0x7fff;
+	wait_data->id =  adpt_post_wait_id;
+	spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
 
-	pHba->hrt = NULL;
-	pHba->lct = NULL;
-	pHba->lct_size = 0;
-	pHba->status_block = NULL;
-	pHba->post_count = 0;
-	pHba->state = DPTI_STATE_RESET;
-	pHba->pDev = pDev;
-	pHba->devices = NULL;
+	wait_data->wq = &adpt_wq_i2o_post;
+	wait_data->status = -ETIMEDOUT;
 
-	// Initializing the spinlocks
-	spin_lock_init(&pHba->state_lock);
-	spin_lock_init(&adpt_post_wait_lock);
+	add_wait_queue(&adpt_wq_i2o_post, &wait);
 
-	if(raptorFlag == 0){
-		printk(KERN_INFO"Adaptec I2O RAID controller %d at %p size=%x irq=%d\n", 
-			hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq);
-	} else {
-		printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq);
-		printk(KERN_INFO"     BAR0 %p - size= %x\n",base_addr_virt,hba_map0_area_size);
-		printk(KERN_INFO"     BAR1 %p - size= %x\n",msg_addr_virt,hba_map1_area_size);
+	msg[2] |= 0x80000000 | ((u32)wait_data->id);
+	timeout *= HZ;
+	if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
+		set_current_state(TASK_INTERRUPTIBLE);
+		if(pHba->host)
+			spin_unlock_irq(pHba->host->host_lock);
+		if (!timeout)
+			schedule();
+		else{
+			timeout = schedule_timeout(timeout);
+			if (timeout == 0) {
+				// I/O issued, but cannot get result in
+				// specified time. Freeing resorces is
+				// dangerous.
+				status = -ETIME;
+			}
+		}
+		if(pHba->host)
+			spin_lock_irq(pHba->host->host_lock);
 	}
+	remove_wait_queue(&adpt_wq_i2o_post, &wait);
 
-	if (request_irq (pDev->irq, adpt_isr, SA_SHIRQ, pHba->name, pHba)) {
-		printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
-		adpt_i2o_delete_hba(pHba);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-
-static void adpt_i2o_delete_hba(adpt_hba* pHba)
-{
-	adpt_hba* p1;
-	adpt_hba* p2;
-	struct i2o_device* d;
-	struct i2o_device* next;
-	int i;
-	int j;
-	struct adpt_device* pDev;
-	struct adpt_device* pNext;
-
-
-	down(&adpt_configuration_lock);
-	// scsi_unregister calls our adpt_release which
-	// does a quiese
-	if(pHba->host){
-		free_irq(pHba->host->irq, pHba);
-	}
-	p2 = NULL;
-	for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
-		if(p1 == pHba) {
-			if(p2) {
-				p2->next = p1->next;
-			} else {
-				hba_chain = p1->next;
-			}
-			break;
-		}
-	}
-
-	hba_count--;
-	up(&adpt_configuration_lock);
-
-	iounmap(pHba->base_addr_virt);
-	if(pHba->msg_addr_virt != pHba->base_addr_virt){
-		iounmap(pHba->msg_addr_virt);
-	}
-	if(pHba->hrt) {
-		kfree(pHba->hrt);
-	}
-	if(pHba->lct){
-		kfree(pHba->lct);
-	}
-	if(pHba->status_block) {
-		kfree(pHba->status_block);
-	}
-	if(pHba->reply_pool){
-		kfree(pHba->reply_pool);
-	}
-
-	for(d = pHba->devices; d ; d = next){
-		next = d->next;
-		kfree(d);
-	}
-	for(i = 0 ; i < pHba->top_scsi_channel ; i++){
-		for(j = 0; j < MAX_ID; j++){
-			if(pHba->channel[i].device[j] != NULL){
-				for(pDev = pHba->channel[i].device[j]; pDev; pDev = pNext){
-					pNext = pDev->next_lun;
-					kfree(pDev);
-				}
-			}
-		}
-	}
-	kfree(pHba);
-
-	if(hba_count <= 0){
-		unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
-	}
-}
-
-
-static int adpt_init(void)
-{
-	printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
-#ifdef REBOOT_NOTIFIER
-	register_reboot_notifier(&adpt_reboot_notifier);
-#endif
-
-	return 0;
-}
-
-
-static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
-{
-	struct adpt_device* d;
-
-	if(chan < 0 || chan >= MAX_CHANNEL)
-		return NULL;
-	
-	if( pHba->channel[chan].device == NULL){
-		printk(KERN_DEBUG"Adaptec I2O RAID: Trying to find device before they are allocated\n");
-		return NULL;
-	}
-
-	d = pHba->channel[chan].device[id];
-	if(!d || d->tid == 0) {
-		return NULL;
-	}
-
-	/* If it is the only lun at that address then this should match*/
-	if(d->scsi_lun == lun){
-		return d;
-	}
-
-	/* else we need to look through all the luns */
-	for(d=d->next_lun ; d ; d = d->next_lun){
-		if(d->scsi_lun == lun){
-			return d;
-		}
-	}
-	return NULL;
-}
-
-
-static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
-{
-	// I used my own version of the WAIT_QUEUE_HEAD
-	// to handle some version differences
-	// When embedded in the kernel this could go back to the vanilla one
-	ADPT_DECLARE_WAIT_QUEUE_HEAD(adpt_wq_i2o_post);
-	int status = 0;
-	ulong flags = 0;
-	struct adpt_i2o_post_wait_data *p1, *p2;
-	struct adpt_i2o_post_wait_data *wait_data =
-		kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL);
-	DECLARE_WAITQUEUE(wait, current);
-
-	if (!wait_data)
-		return -ENOMEM;
-
-	/*
-	 * The spin locking is needed to keep anyone from playing
-	 * with the queue pointers and id while we do the same
-	 */
-	spin_lock_irqsave(&adpt_post_wait_lock, flags);
-       // TODO we need a MORE unique way of getting ids
-       // to support async LCT get
-	wait_data->next = adpt_post_wait_queue;
-	adpt_post_wait_queue = wait_data;
-	adpt_post_wait_id++;
-	adpt_post_wait_id &= 0x7fff;
-	wait_data->id =  adpt_post_wait_id;
-	spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
-
-	wait_data->wq = &adpt_wq_i2o_post;
-	wait_data->status = -ETIMEDOUT;
-
-	add_wait_queue(&adpt_wq_i2o_post, &wait);
-
-	msg[2] |= 0x80000000 | ((u32)wait_data->id);
-	timeout *= HZ;
-	if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
-		set_current_state(TASK_INTERRUPTIBLE);
-		if(pHba->host)
-			spin_unlock_irq(pHba->host->host_lock);
-		if (!timeout)
-			schedule();
-		else{
-			timeout = schedule_timeout(timeout);
-			if (timeout == 0) {
-				// I/O issued, but cannot get result in
-				// specified time. Freeing resorces is
-				// dangerous.
-				status = -ETIME;
-			}
-		}
-		if(pHba->host)
-			spin_lock_irq(pHba->host->host_lock);
-	}
-	remove_wait_queue(&adpt_wq_i2o_post, &wait);
-
-	if(status == -ETIMEDOUT){
-		printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
-		// We will have to free the wait_data memory during shutdown
-		return status;
+	if(status == -ETIMEDOUT){
+		printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
+		// We will have to free the wait_data memory during shutdown
+		return status;
 	}
 
 	/* Remove the entry from the queue.  */
@@ -2183,9 +1884,9 @@
 {
 	struct Scsi_Host *host = NULL;
 
-	host = scsi_register(sht, sizeof(adpt_hba*));
+	host = scsi_host_alloc(sht, sizeof(adpt_hba*));
 	if (host == NULL) {
-		printk ("%s: scsi_register returned NULL\n",pHba->name);
+		printk ("%s: scsi_host_alloc returned NULL\n",pHba->name);
 		return -1;
 	}
 	host->hostdata[0] = (unsigned long)pHba;
@@ -2201,10 +1902,16 @@
 	host->max_id = 16;
 	host->max_lun = 256;
 	host->max_channel = pHba->top_scsi_channel + 1;
-	host->cmd_per_lun = 1;
+	host->cmd_per_lun = 256;
 	host->unique_id = (uint) pHba;
 	host->sg_tablesize = pHba->sg_tablesize;
 	host->can_queue = pHba->post_fifo_size;
+	scsi_set_device(host, &pHba->pDev->dev);
+	if (scsi_add_host(host, &pHba->pDev->dev)) {
+		scsi_unregister(pHba->host);
+		return -1;
+	}
+	scsi_scan_host(host);
 
 	return 0;
 }
@@ -3338,11 +3045,9 @@
 #endif
 
 static struct scsi_host_template driver_template = {
-	.name			= "dpt_i2o",
-	.proc_name		= "dpt_i2o",
+	.name			= DPT_DRIVER,
+	.proc_name		= DPT_DRIVER,
 	.proc_info		= adpt_proc_info,
-	.detect			= adpt_detect,	
-	.release		= adpt_release,
 	.info			= adpt_info,
 	.queuecommand		= adpt_queue,
 	.eh_abort_handler	= adpt_abort,
@@ -3356,5 +3061,360 @@
 	.cmd_per_lun		= 1,
 	.use_clustering		= ENABLE_CLUSTERING,
 };
-#include "scsi_module.c"
+
+static void dpt_shutdown(struct pci_dev *pDev)
+{
+	adpt_i2o_sys_shutdown();
+}
+
+static void __devexit dpt_remove_one(struct pci_dev * pDev)
+{
+	struct Scsi_Host *shost;
+	adpt_hba* pHba;
+
+	shost = pci_get_drvdata(pDev);
+	if (!shost)
+		return;
+	adpt_release(shost);
+	scsi_remove_host(shost);
+	scsi_host_put(shost);
+	pHba = *((adpt_hba**) shost->hostdata);
+	if (pHba)
+		pHba->host = NULL;
+	pci_disable_device(pDev);
+}
+
+static int __devinit dpt_probe_one(struct pci_dev *pDev,
+		const struct pci_device_id * id)
+{
+	adpt_hba* pHba = NULL;
+	adpt_hba* p = NULL;
+	ulong base_addr0_phys = 0;
+	ulong base_addr1_phys = 0;
+	u32 hba_map0_area_size = 0;
+	u32 hba_map1_area_size = 0;
+	void __iomem * base_addr_virt = 0;
+	void __iomem * msg_addr_virt = 0;
+	int error = -EINVAL;
+	int raptorFlag = 0;
+
+	if(pci_enable_device(pDev))
+		return error;
+	pci_set_master(pDev);
+	if (pci_set_dma_mask(pDev, DMA_64BIT_MASK) &&
+	    pci_set_dma_mask(pDev, DMA_32BIT_MASK))
+		return -EINVAL;
+
+	base_addr0_phys = pci_resource_start(pDev,0);
+	hba_map0_area_size = pci_resource_len(pDev,0);
+
+	// Check if standard PCI card or single BAR Raptor
+	if(pDev->device == PCI_DPT_DEVICE_ID){
+		if(pDev->subsystem_device >=0xc032 && pDev->subsystem_device <= 0xc03b){
+			// Raptor card with this device id needs 4M
+			hba_map0_area_size = 0x400000;
+		} else { // Not Raptor - it is a PCI card
+			if(hba_map0_area_size > 0x100000 ){ 
+				hba_map0_area_size = 0x100000;
+			}
+		}
+	} else {// Raptor split BAR config
+		// Use BAR1 in this configuration
+		base_addr1_phys = pci_resource_start(pDev,1);
+		hba_map1_area_size = pci_resource_len(pDev,1);
+		raptorFlag = 1;
+	}
+	/* x86_64 machines need more optimal mappings */
+        if(raptorFlag == 1) {
+		if (hba_map0_area_size > 128)
+			hba_map0_area_size = 128;
+		if (hba_map1_area_size > 524288)
+			hba_map1_area_size = 524288;
+	} else {
+		if (hba_map0_area_size > 524288)
+			hba_map0_area_size = 524288;
+	}
+
+	if (pci_request_regions(pDev, DPT_DRIVER)) {
+		PERROR("dpti: adpt_config_hba: pci request region failed\n");
+		return error;
+	}
+	base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size);
+	if (!base_addr_virt) {
+		pci_release_regions(pDev);
+		PERROR("dpti: adpt_config_hba: io remap failed\n");
+		return error;
+	}
+
+        if(raptorFlag == 1) {
+		msg_addr_virt = ioremap(base_addr1_phys, hba_map1_area_size );
+		if (!msg_addr_virt) {
+			PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
+			iounmap(base_addr_virt);
+			pci_release_regions(pDev);
+			return error;
+		}
+	} else {
+		msg_addr_virt = base_addr_virt;
+	}
+	
+	// Allocate and zero the data structure
+	pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL);
+	if( pHba == NULL) {
+		if(msg_addr_virt != base_addr_virt){
+			iounmap(msg_addr_virt);
+		}
+		iounmap(base_addr_virt);
+		pci_release_regions(pDev);
+		return -ENOMEM;
+	}
+	memset(pHba, 0, sizeof(adpt_hba));
+
+	down(&adpt_configuration_lock);
+
+	if(hba_chain != NULL){
+		for(p = hba_chain; p->next; p = p->next);
+		p->next = pHba;
+	} else {
+		hba_chain = pHba;
+	}
+	pHba->next = NULL;
+	pHba->unit = hba_count;
+	sprintf(pHba->name, "dpti%d", hba_count);
+	hba_count++;
+	
+	up(&adpt_configuration_lock);
+
+	pHba->pDev = pDev;
+	pHba->base_addr_phys = base_addr0_phys;
+
+	// Set up the Virtual Base Address of the I2O Device
+	pHba->base_addr_virt = base_addr_virt;
+	pHba->msg_addr_virt = msg_addr_virt;
+	pHba->irq_mask = (u32 __iomem *)(base_addr_virt+0x30);
+	pHba->post_port = (u32 __iomem *)(base_addr_virt+0x40);
+	pHba->reply_port = (u32 __iomem *)(base_addr_virt+0x44);
+
+	pHba->hrt = NULL;
+	pHba->lct = NULL;
+	pHba->lct_size = 0;
+	pHba->status_block = NULL;
+	pHba->post_count = 0;
+	pHba->state = DPTI_STATE_RESET;
+	pHba->devices = NULL;
+
+	// Initializing the spinlocks
+	spin_lock_init(&pHba->state_lock);
+	spin_lock_init(&adpt_post_wait_lock);
+
+	if(raptorFlag == 0){
+		printk(KERN_INFO"Adaptec I2O RAID controller %d at %p size=%x irq=%d\n", 
+			hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq);
+	} else {
+		printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq);
+		printk(KERN_INFO"     BAR0 %p - size= %x\n",base_addr_virt,hba_map0_area_size);
+		printk(KERN_INFO"     BAR1 %p - size= %x\n",msg_addr_virt,hba_map1_area_size);
+	}
+
+	if (request_irq (pDev->irq, adpt_isr, SA_SHIRQ, pHba->name, pHba)) {
+		printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
+		adpt_i2o_delete_hba(pHba);
+		return error;
+	}
+
+	return 0;
+}
+
+static struct pci_driver dpt_pci_driver = {
+	.name		= DPT_DRIVER,
+	.id_table	= dptids,
+	.probe		= dpt_probe_one,
+	.remove		= __devexit_p(dpt_remove_one),
+	.shutdown	= dpt_shutdown,
+};
+
+static void adpt_i2o_delete_hba(adpt_hba* pHba)
+{
+	adpt_hba* p1;
+	adpt_hba* p2;
+	struct i2o_device* d;
+	struct i2o_device* next;
+	int i;
+	int j;
+	struct adpt_device* pDev;
+	struct adpt_device* pNext;
+
+	if (pHba->host) {
+		scsi_remove_host(pHba->host);
+		free_irq(pHba->host->irq, pHba);
+	}
+	down(&adpt_configuration_lock);
+	// scsi_unregister calls our adpt_release which
+	// does a quiese
+	p2 = NULL;
+	for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
+		if(p1 == pHba) {
+			if(p2) {
+				p2->next = p1->next;
+			} else {
+				hba_chain = p1->next;
+			}
+			break;
+		}
+	}
+
+	hba_count--;
+	up(&adpt_configuration_lock);
+
+	iounmap(pHba->base_addr_virt);
+	pHba->irq_mask = NULL;
+	pHba->post_port = NULL;
+	pHba->reply_port = NULL;
+	if(pHba->msg_addr_virt != pHba->base_addr_virt){
+		iounmap(pHba->msg_addr_virt);
+		pHba->msg_addr_virt = NULL;
+	}
+	pHba->base_addr_virt = NULL;
+	pci_release_regions(pHba->pDev);
+	if(pHba->hrt) {
+		kfree(pHba->hrt);
+		pHba->hrt = NULL;
+	}
+	if(pHba->lct){
+		kfree(pHba->lct);
+		pHba->lct = NULL;
+	}
+	if(pHba->status_block) {
+		kfree(pHba->status_block);
+		pHba->status_block = NULL;
+	}
+	if(pHba->reply_pool){
+		kfree(pHba->reply_pool);
+		pHba->reply_pool = NULL;
+	}
+
+	for(d = pHba->devices; d ; d = next){
+		next = d->next;
+		kfree(d);
+	}
+	pHba->devices = NULL;
+	for(i = 0 ; i < pHba->top_scsi_channel ; i++){
+		for(j = 0; j < MAX_ID; j++){
+			if(pHba->channel[i].device[j] != NULL){
+				for(pDev = pHba->channel[i].device[j]; pDev; pDev = pNext){
+					pNext = pDev->next_lun;
+					kfree(pDev);
+				}
+				pHba->channel[i].device[j] = NULL;
+			}
+		}
+	}
+
+	if (pHba->host != NULL) {
+		scsi_host_put(pHba->host);
+		pci_set_drvdata(pHba->pDev, NULL);
+		pHba->host = NULL;
+	}
+	pci_disable_device(pHba->pDev);
+	kfree(pHba);
+
+	if(hba_count <= 0){
+		unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
+		pci_unregister_driver(&dpt_pci_driver);
+	}
+}
+
+static int __init dpt_init(void)
+{
+	int error;
+	adpt_hba* pHba;
+
+	printk(KERN_INFO"Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
+	PINFO("Detecting Adaptec I2O RAID controllers...\n");
+
+	error = pci_register_driver(&dpt_pci_driver);
+	if (error < 0)
+		return error;
+	if (hba_count == 0)
+		return -ENODEV;
+	/* In INIT state, Activate IOPs */
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		// Activate does get status , init outbound, and get hrt
+		if (adpt_i2o_activate_hba(pHba) < 0) {
+			adpt_i2o_delete_hba(pHba);
+		}
+	}
+
+	/* Active IOPs in HOLD state */
+
+rebuild_sys_tab:
+	if (hba_chain == NULL) 
+		return -ENODEV;
+
+	/*
+	 * If build_sys_table fails, we kill everything and bail
+	 * as we can't init the IOPs w/o a system table
+	 */	
+	if (adpt_i2o_build_sys_table() < 0) {
+		adpt_i2o_sys_shutdown();
+		return -ENODEV;
+	}
+
+	PDEBUG("HBA's in HOLD state\n");
+
+	/* If IOP don't get online, we need to rebuild the System table */
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		if (adpt_i2o_online_hba(pHba) < 0) {
+			adpt_i2o_delete_hba(pHba);	
+			goto rebuild_sys_tab;
+		}
+	}
+
+	/* Active IOPs now in OPERATIONAL state */
+	PDEBUG("HBA's in OPERATIONAL state\n");
+
+	printk("dpti: If you have a lot of devices this could take a few minutes.\n");
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
+		if (adpt_i2o_lct_get(pHba) < 0){
+			adpt_i2o_delete_hba(pHba);
+			continue;
+		}
+
+		if (adpt_i2o_parse_lct(pHba) < 0){
+			adpt_i2o_delete_hba(pHba);
+			continue;
+		}
+		adpt_inquiry(pHba);
+	}
+
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		pHba->initialized = 1;
+		pHba->state &= ~DPTI_STATE_RESET;
+		if( adpt_scsi_register(pHba, &driver_template) < 0){
+			adpt_i2o_delete_hba(pHba);
+			continue;
+		}
+	}
+
+	// Register our control device node
+	// nodes will need to be created in /dev to access this
+	// the nodes can not be created from within the driver
+	if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
+		adpt_i2o_sys_shutdown();
+		return -EINVAL;
+	}
+
+	return hba_count == 0;
+}
+
+static void __exit dpt_exit(void)
+{
+	adpt_i2o_sys_shutdown();
+}
+
+module_init(dpt_init);
+module_exit(dpt_exit);
+
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DPT_I2O_VERSION);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] dpt_i2o pci_driver model
  2005-08-17 17:04 [PATCH] dpt_i2o pci_driver model Salyzyn, Mark
@ 2005-08-19 14:59 ` Christoph Hellwig
  0 siblings, 0 replies; 5+ messages in thread
From: Christoph Hellwig @ 2005-08-19 14:59 UTC (permalink / raw)
  To: Salyzyn, Mark; +Cc: linux-scsi

On Wed, Aug 17, 2005 at 01:04:05PM -0400, Salyzyn, Mark wrote:
> Christoph Hellwig [mailto:hch@infradead.org] writes:
> > ... update the driver to use the pci_driver model ...
> 
> The patch applies to the scsi-misc-2.6 git tree. The moving of
> adpt_install_hba to the near bottom of the dpt_i2o.c file creates a
> dirty context diff in that region which is hard to inspect from within
> the patch. No coding style changes were made when moving content from
> the original initialization code to the module_init and module_exit
> functions to aid before and after comparisons for inspection; even
> despite the fact C++ style comments are used in these sections. We
> expect such style cleanup to occur either on any necessary follow-up
> rewrites after basic functional approval, or as a follow-up cleanup
> patch.

This looks wrong to me.  It's still walking a lot of driver-global
hba lists in the init routine.  All hba initialization should happen
in the ->probe callback, and there should be very little global
initialization.  There shouldn't really be any global list of hbas.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH] dpt_i2o pci_driver model
@ 2005-08-19 15:05 Salyzyn, Mark
  2005-09-06 11:45 ` Christoph Hellwig
  0 siblings, 1 reply; 5+ messages in thread
From: Salyzyn, Mark @ 2005-08-19 15:05 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-scsi

The sysinit structure is supposed to be a complete list of all peered
i2o adapters. The current driver structure issued the sysinit command
after all adapters were discovered rather than re-issuing as each was
added.

The structure still must be global, but I will look into moving the
instantiation.

Sincerely -- Mark Salyzyn


-----Original Message-----
From: Christoph Hellwig [mailto:hch@infradead.org] 
Sent: Friday, August 19, 2005 10:59 AM
To: Salyzyn, Mark
Cc: linux-scsi
Subject: Re: [PATCH] dpt_i2o pci_driver model


On Wed, Aug 17, 2005 at 01:04:05PM -0400, Salyzyn, Mark wrote:
> Christoph Hellwig [mailto:hch@infradead.org] writes:
> > ... update the driver to use the pci_driver model ...
> 
> The patch applies to the scsi-misc-2.6 git tree. The moving of 
> adpt_install_hba to the near bottom of the dpt_i2o.c file creates a 
> dirty context diff in that region which is hard to inspect from within

> the patch. No coding style changes were made when moving content from 
> the original initialization code to the module_init and module_exit 
> functions to aid before and after comparisons for inspection; even 
> despite the fact C++ style comments are used in these sections. We 
> expect such style cleanup to occur either on any necessary follow-up 
> rewrites after basic functional approval, or as a follow-up cleanup 
> patch.

This looks wrong to me.  It's still walking a lot of driver-global hba
lists in the init routine.  All hba initialization should happen in the
->probe callback, and there should be very little global initialization.
There shouldn't really be any global list of hbas.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] dpt_i2o pci_driver model
  2005-08-19 15:05 Salyzyn, Mark
@ 2005-09-06 11:45 ` Christoph Hellwig
  0 siblings, 0 replies; 5+ messages in thread
From: Christoph Hellwig @ 2005-09-06 11:45 UTC (permalink / raw)
  To: Salyzyn, Mark; +Cc: Christoph Hellwig, linux-scsi

On Fri, Aug 19, 2005 at 11:05:41AM -0400, Salyzyn, Mark wrote:
> The sysinit structure is supposed to be a complete list of all peered
> i2o adapters. The current driver structure issued the sysinit command
> after all adapters were discovered rather than re-issuing as each was
> added.

Yeah, I noticed that, but the question is why that's nessecary, after
all the i2o layer drivers don't need that either.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH] dpt_i2o pci_driver model
@ 2005-09-06 12:28 Salyzyn, Mark
  0 siblings, 0 replies; 5+ messages in thread
From: Salyzyn, Mark @ 2005-09-06 12:28 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-scsi

Christoph Hellwig writes:

> On Fri, Aug 19, 2005 at 11:05:41AM -0400, Salyzyn, Mark wrote:
> > The sysinit structure is supposed to be a complete list of all
peered 
> > i2o adapters. The current driver structure issued the sysinit
command 
> > after all adapters were discovered rather than re-issuing as each
was 
> > added.
> Yeah, I noticed that, but the question is why that's nessecary, after
all the i2o layer drivers don't need that either.

Strictly no longer required, even our multi-controller failover software
made alternate daemon application arrangements for inter-card
communications (cache synchronization). Cross Adapter RAID was dropped
in 1998. It was merely a pedantic continuation of this support.

As I indicated (and once I have time) I will recode the paths to
instantiate the adapters individually.

-- Mark Salyzyn

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-09-06 12:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-17 17:04 [PATCH] dpt_i2o pci_driver model Salyzyn, Mark
2005-08-19 14:59 ` Christoph Hellwig
  -- strict thread matches above, loose matches on Subject: below --
2005-08-19 15:05 Salyzyn, Mark
2005-09-06 11:45 ` Christoph Hellwig
2005-09-06 12:28 Salyzyn, Mark

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.