Skip to contentSkip to conversation

dpt_i2o: 64 bit support (take 5)

PATCH In review Miquel van Smoorenburg 6 participants 13 messages May 1, 2008 – May 13, 2008 SCSI

lore
Share & tools
lore
#0 lore raw

cover dpt_i2o: 64 bit support (take 5)

[PATCH 0/4] dpt_i2o: 64 bit support (take 5)

These patches update the dpt_i2o driver to work on 64-bit platforms like x86_64.

This code is based in part on the unofficial adaptec 64-bit dpt_i2o driver update that I got from Mark Salyzyn at Adaptec.

The driver can use some additional cleanups but that wasn't the focus for this patch series.

Thanks to Rolf Eike Beer and James Bottomley for reviewing the previous patches and offering constructive criticism. I tried to take all your comments into account.

Please consider this for 2.6.26.

[PATCH 1/4] dpt_i2o: use standard __init / __exit code
[PATCH 2/4] dpt_i2o: move from virt_to_bus/bus_to_virt to dma_alloc_coherent [PATCH 3/4] dpt_i2o: 64 bit support
[PATCH 4/4] dpt_i2o: sysfs code

Mike.

#1 lore raw

PATCH 1/4 dpt_i2o: use standard __init / __exit code

[PATCH 1/4] dpt_i2o: use standard __init / __exit code

Update dpt_i2o.c to use the standard __init / __exit code instead of the legacy '#include "scsi_module.c"' code.

This is needed in preparation of 64-bit support. scsi_module.c calls scsi_add_host() with the device pointer set to NULL, and that crashes code like arch/x64/kernel/pci-gart_64.c::need_iommu().

The reboot_notifier code is deleted because it wasn't compiled in ever anyway, and it would be useless to duplicate it in the new code.

drivers/scsi/dpt_i2o.c renamed from linux-2.6.25/drivers/scsi/dpt_i2o.c +51 -53
diff -ruN orig/linux-2.6.25/drivers/scsi/dpt_i2o.c linux-2.6.25-dpt64-01/drivers/scsi/dpt_i2o.c
@@ -118,17 +114,8 @@
 static const struct file_operations adpt_fops = {
 	.ioctl		= adpt_ioctl,
 	.open		= adpt_open,
-	.release	= adpt_close
-};
-
-#ifdef REBOOT_NOTIFIER
-static struct notifier_block adpt_reboot_notifier =
-{
-	 adpt_reboot_event,
-	 NULL,
-	 0
+	.release	= adpt_close
 };
-#endif
 
 /* Structures and definitions for synchronous message posting.
  * See adpt_i2o_post_wait() for description
@@ -178,8 +175,6 @@
 	struct pci_dev *pDev = NULL;
 	adpt_hba* pHba;
 
-	adpt_init();
-
 	PINFO("Detecting Adaptec I2O RAID controllers...\n");
 
         /* search for all Adatpec I2O RAID cards */
@@ -248,7 +243,7 @@
 	}
 
 	for (pHba = hba_chain; pHba; pHba = pHba->next) {
-		if( adpt_scsi_register(pHba,sht) < 0){
+		if (adpt_scsi_host_alloc(pHba, sht) < 0){
 			adpt_i2o_delete_hba(pHba);
 			continue;
 		}
@@ -861,27 +856,6 @@
 	 printk(KERN_INFO "Adaptec I2O controllers down.\n");
 }
 
-/*
- * reboot/shutdown notification.
- *
- * - Quiesce each IOP in the system
- *
- */
-
-#ifdef REBOOT_NOTIFIER
-static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p)
-{
-
-	 if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)
-		  return NOTIFY_DONE;
-
-	 adpt_i2o_sys_shutdown();
-
-	 return NOTIFY_DONE;
-}
-#endif
-
-
 static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev)
 {
 
@@ -1080,18 +1092,6 @@
 	}
 }
 
-
-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;
@@ -2177,13 +2202,13 @@
 }
 
 
-static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
+static s32 adpt_scsi_host_alloc(adpt_hba* pHba, struct scsi_host_template *sht)
 {
-	struct Scsi_Host *host = NULL;
+	struct Scsi_Host *host;
 
-	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;
@@ -3323,11 +3391,10 @@
 #endif
 
 static struct scsi_host_template driver_template = {
+	.module			= THIS_MODULE,
 	.name			= "dpt_i2o",
 	.proc_name		= "dpt_i2o",
 	.proc_info		= adpt_proc_info,
-	.detect			= adpt_detect,
-	.release		= adpt_release,
 	.info			= adpt_info,
 	.queuecommand		= adpt_queue,
 	.eh_abort_handler	= adpt_abort,
@@ -3341,5 +3408,48 @@
 	.cmd_per_lun		= 1,
 	.use_clustering		= ENABLE_CLUSTERING,
 };
-#include "scsi_module.c"
+
+static int __init adpt_init(void)
+{
+	int		error;
+	adpt_hba	*pHba, *next;
+
+	printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
+
+	error = adpt_detect(&driver_template);
+	if (error < 0)
+		return error;
+	if (hba_chain == NULL)
+		return -ENODEV;
+
+	for (pHba = hba_chain; pHba; pHba = pHba->next) {
+		error = scsi_add_host(pHba->host, &pHba->pDev->dev);
+		if (error)
+			goto fail;
+		scsi_scan_host(pHba->host);
+	}
+	return 0;
+fail:
+	for (pHba = hba_chain; pHba; pHba = next) {
+		next = pHba->next;
+		scsi_remove_host(pHba->host);
+	}
+	return error;
+}
+
+static void __exit adpt_exit(void)
+{
+	adpt_hba	*pHba, *next;
+
+	for (pHba = hba_chain; pHba; pHba = pHba->next)
+		scsi_remove_host(pHba->host);
+	for (pHba = hba_chain; pHba; pHba = next) {
+		next = pHba->next;
+		adpt_release(pHba->host);
+	}
+}
+
+module_init(adpt_init);
+module_exit(adpt_exit);
+
 MODULE_LICENSE("GPL");
drivers/scsi/dpti.h renamed from linux-2.6.25/drivers/scsi/dpti.h +1 -5
diff -ruN orig/linux-2.6.25/drivers/scsi/dpti.h linux-2.6.25-dpt64-01/drivers/scsi/dpti.h
@@ -84,7 +84,6 @@
 #define PCI_DPT_DEVICE_ID         (0xA501)	// DPT PCI I2O Device ID
 #define PCI_DPT_RAPTOR_DEVICE_ID  (0xA511)	
 
-//#define REBOOT_NOTIFIER 1
 /* Debugging macro from Linux Device Drivers - Rubini */
 #undef PDEBUG
 #ifdef DEBUG
@@ -264,9 +269,6 @@
 static int adpt_init(void);
 static int adpt_i2o_build_sys_table(void);
 static irqreturn_t adpt_isr(int irq, void *dev_id);
-#ifdef REBOOT_NOTIFIER
-static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p);
-#endif
 
 static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d);
 static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, 
@@ -289,7 +292,7 @@
 static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
 static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice);
 static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd);
-static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht);
+static s32 adpt_scsi_host_alloc(adpt_hba* pHba,struct scsi_host_template * sht);
 static s32 adpt_hba_reset(adpt_hba* pHba);
 static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
 static s32 adpt_rescan(adpt_hba* pHba);
#2 lore raw

Re: [PATCH 1/4] dpt_i2o: use standard __init / __exit code

ACK

Quoted 15 lines · Miquel van Smoorenburg

[PATCH 1/4] dpt_i2o: use standard __init / __exit code

Update dpt_i2o.c to use the standard __init / __exit code instead of the legacy '#include "scsi_module.c"' code.

This is needed in preparation of 64-bit support. scsi_module.c calls scsi_add_host() with the device pointer set to NULL, and that crashes code like arch/x64/kernel/pci-gart_64.c::need_iommu().

The reboot_notifier code is deleted because it wasn't compiled in ever anyway, and it would be useless to duplicate it in the new code.

#3 lore raw

PATCH 2/4 dpt_i2o: move from virt_to_bus/bus_to_virt to dma_alloc_coherent

In reply to Miquel van Smoorenburg

[PATCH 2/4] dpt_i2o: move from virt_to_bus/bus_to_virt to dma_alloc_coherent

Remove virt_to_bus/bus_to_virt code from dpt_i2o, and use dma_alloc_coherent() / dma_free_coherent().

This is in preparation of 64-bit support, dma_alloc_coherent() can allocate memory in the lower 32 bits of physical memory which is needed because the HBA only supports message blocks under 4GB

This code is based in part on the unofficial adaptec 64-bit dpt_i2o driver update that I got from Mark Salyzyn at Adaptec.

linux-2.6.25-dpt64-01/drivers/scsi/dpt_i2o.c renamed from drivers/scsi/dpt_i2o.c +163 -73
diff -ruN linux-2.6.25/drivers/scsi/dpt_i2o.c ../linux-2.6.25-dpt64-01/drivers/scsi/dpt_i2o.c
@@ -29,11 +29,6 @@
 /*#define DEBUG 1 */
 /*#define UARTDELAY 1 */
 
-/* On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates
-   high pages. Keep the macro around because of the broken unmerged ia64 tree */
-
-#define ADDR32 (0)
-
 #include <linux/module.h>
 
 MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
@@ -108,9 +103,10 @@
 
 static DEFINE_MUTEX(adpt_configuration_lock);
 
-static struct i2o_sys_tbl *sys_tbl = NULL;
-static int sys_tbl_ind = 0;
-static int sys_tbl_len = 0;
+static struct i2o_sys_tbl *sys_tbl;
+static dma_addr_t sys_tbl_pa;
+static int sys_tbl_ind;
+static int sys_tbl_len;
 
 static adpt_hba* hba_chain = NULL;
 static int hba_count = 0;
@@ -142,6 +138,16 @@
  *============================================================================
  */
 
+static inline u32 dma_high(dma_addr_t addr)
+{
+	return upper_32_bits(addr);
+}
+
+static inline u32 dma_low(dma_addr_t addr)
+{
+	return (u32)addr;
+}
+
 static u8 adpt_read_blink_led(adpt_hba* host)
 {
 	if(host->FwDebugBLEDflag_P != 0) {
@@ -279,11 +285,12 @@
 	u32 len;
 	u32 reqlen;
 	u8* buf;
+	dma_addr_t addr;
 	u8  scb[16];
 	s32 rcode;
 
 	memset(msg, 0, sizeof(msg));
-	buf = kmalloc(80,GFP_KERNEL|ADDR32);
+	buf = dma_alloc_coherent(&pHba->pDev->dev, 80, &addr, GFP_KERNEL);
 	if(!buf){
 		printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
 		return;
@@ -328,7 +335,7 @@
 	/* Now fill in the SGList and command */
 	*lenptr = len;
 	*mptr++ = 0xD0000000|direction|len;
-	*mptr++ = virt_to_bus(buf);
+	*mptr++ = addr;
 
 	// Send it on it's way
 	rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
@@ -336,7 +343,7 @@
 		sprintf(pHba->detail, "Adaptec I2O RAID");
 		printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
 		if (rcode != -ETIME && rcode != -EINTR)
-			kfree(buf);
+			dma_free_coherent(&pHba->pDev->dev, 80, buf, addr);
 	} else {
 		memset(pHba->detail, 0, sizeof(pHba->detail));
 		memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
@@ -345,7 +352,7 @@
 		memcpy(&(pHba->detail[40]), " FW: ", 4);
 		memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
 		pHba->detail[48] = '\0';	/* precautionary */
-		kfree(buf);
+		dma_free_coherent(&pHba->pDev->dev, 80, buf, addr);
 	}
 	adpt_i2o_status_get(pHba);
 	return ;
@@ -621,7 +628,6 @@
 	return len;
 }
 
-
 /*===========================================================================
  * Error Handling routines
  *===========================================================================
@@ -877,6 +883,9 @@
 	if (pci_set_dma_mask(pDev, DMA_32BIT_MASK))
 		return -EINVAL;
 
+	/* adapter only supports message blocks below 4GB */
+	pci_set_consistent_dma_mask(pDev, DMA_32BIT_MASK);
+
 	base_addr0_phys = pci_resource_start(pDev,0);
 	hba_map0_area_size = pci_resource_len(pDev,0);
 
@@ -1021,10 +1030,24 @@
 	if(pHba->msg_addr_virt != pHba->base_addr_virt){
 		iounmap(pHba->msg_addr_virt);
 	}
-	kfree(pHba->hrt);
-	kfree(pHba->lct);
-	kfree(pHba->status_block);
-	kfree(pHba->reply_pool);
+	if(pHba->hrt) {
+		dma_free_coherent(&pHba->pDev->dev,
+			pHba->hrt->num_entries * pHba->hrt->entry_len << 2,
+			pHba->hrt, pHba->hrt_pa);
+	}
+	if(pHba->lct) {
+		dma_free_coherent(&pHba->pDev->dev, pHba->lct_size,
+			pHba->lct, pHba->lct_pa);
+	}
+	if(pHba->status_block) {
+		dma_free_coherent(&pHba->pDev->dev, sizeof(i2o_status_block),
+			pHba->status_block, pHba->status_block_pa);
+	}
+	if(pHba->reply_pool) {
+		dma_free_coherent(&pHba->pDev->dev,
+			pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4,
+			pHba->reply_pool, pHba->reply_pool_pa);
+	}
 
 	for(d = pHba->devices; d ; d = next){
 		next = d->next;
@@ -1239,6 +1262,7 @@
 {
 	u32 msg[8];
 	u8* status;
+	dma_addr_t addr;
 	u32 m = EMPTY_QUEUE ;
 	ulong timeout = jiffies + (TMOUT_IOPRESET*HZ);
 
@@ -1261,12 +1285,13 @@
 		schedule_timeout_uninterruptible(1);
 	} while (m == EMPTY_QUEUE);
 
-	status = kzalloc(4, GFP_KERNEL|ADDR32);
+	status = dma_alloc_coherent(&pHba->pDev->dev, 4, &addr, GFP_KERNEL);
 	if(status == NULL) {
 		adpt_send_nop(pHba, m);
 		printk(KERN_ERR"IOP reset failed - no free memory.\n");
 		return -ENOMEM;
 	}
+	memset(status,0,4);
 
 	msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
 	msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
@@ -1274,8 +1299,8 @@
 	msg[3]=0;
 	msg[4]=0;
 	msg[5]=0;
-	msg[6]=virt_to_bus(status);
-	msg[7]=0;     
+	msg[6]=dma_low(addr);
+	msg[7]=dma_high(addr);
 
 	memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg));
 	wmb();
@@ -1285,7 +1310,10 @@
 	while(*status == 0){
 		if(time_after(jiffies,timeout)){
 			printk(KERN_WARNING"%s: IOP Reset Timeout\n",pHba->name);
-			kfree(status);
+			/* We lose 4 bytes of "status" here, but we cannot
+			   free these because controller may awake and corrupt
+			   those bytes at any time */
+			/* dma_free_coherent(&pHba->pDev->dev, 4, buf, addr); */
 			return -ETIMEDOUT;
 		}
 		rmb();
@@ -1304,6 +1332,10 @@
 			}
 			if(time_after(jiffies,timeout)){
 				printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
+				/* We lose 4 bytes of "status" here, but we
+				   cannot free these because controller may
+				   awake and corrupt those bytes at any time */
+				/* dma_free_coherent(&pHba->pDev->dev, 4, buf, addr); */
 				return -ETIMEDOUT;
 			}
 			schedule_timeout_uninterruptible(1);
@@ -1320,7 +1352,7 @@
 		PDEBUG("%s: Reset completed.\n", pHba->name);
 	}
 
-	kfree(status);
+	dma_free_coherent(&pHba->pDev->dev, 4, status, addr);
 #ifdef UARTDELAY
 	// This delay is to allow someone attached to the card through the debug UART to 
 	// set up the dump levels that they want before the rest of the initialization sequence
@@ -1592,6 +1624,7 @@
 	u32 i = 0;
 	u32 rcode = 0;
 	void *p = NULL;
+	dma_addr_t addr;
 	ulong flags = 0;
 
 	memset(&msg, 0, MAX_MESSAGE_SIZE*4);
@@ -1646,7 +1679,7 @@
 			}
 			sg_size = sg[i].flag_count & 0xffffff;      
 			/* Allocate memory for the transfer */
-			p = kmalloc(sg_size, GFP_KERNEL|ADDR32);
+			p = dma_alloc_coherent(&pHba->pDev->dev, sg_size, &addr, GFP_KERNEL);
 			if(!p) {
 				printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
 						pHba->name,sg_size,i,sg_count);
@@ -1743,12 +1776,17 @@
 
 
 cleanup:
-	if (rcode != -ETIME && rcode != -EINTR)
+	if (rcode != -ETIME && rcode != -EINTR) {
+		struct sg_simple_element *sg =
+				(struct sg_simple_element*) (msg +sg_offset);
 		kfree (reply);
-	while(sg_index) {
-		if(sg_list[--sg_index]) {
-			if (rcode != -ETIME && rcode != -EINTR)
-				kfree(sg_list[sg_index]);
+		while(sg_index) {
+			if(sg_list[--sg_index]) {
+				dma_free_coherent(&pHba->pDev->dev,
+					sg[sg_index].flag_count & 0xffffff,
+					sg_list[sg_index],
+					sg[sg_index].addr_bus);
+			}
 		}
 	}
 	return rcode;
@@ -1965,7 +2003,16 @@
 				goto out;
 			}
 		}
-		reply = bus_to_virt(m);
+		if (pHba->reply_pool_pa <= m &&
+		    m < pHba->reply_pool_pa +
+			(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4)) {
+			reply = (u8 *)pHba->reply_pool +
+						(m - pHba->reply_pool_pa);
+		} else {
+			/* Ick, we should *never* be here */
+			printk(KERN_ERR "dpti: reply frame not from pool\n");
+			reply = (u8 *)bus_to_virt(m);
+		}
 
 		if (readl(reply) & MSG_FAIL) {
 			u32 old_m = readl(reply+28); 
@@ -2008,6 +2055,7 @@
 		} else { // SCSI message
 			cmd = (struct scsi_cmnd*) readl(reply+12); 
 			if(cmd != NULL){
+				scsi_dma_unmap(cmd);
 				if(cmd->serial_number != 0) { // If not timedout
 					adpt_i2o_to_scsi(reply, cmd);
 				}
@@ -2156,7 +2204,7 @@
 	host->max_lun = 256;
 	host->max_channel = pHba->top_scsi_channel + 1;
 	host->cmd_per_lun = 1;
-	host->unique_id = (uint) pHba;
+	host->unique_id = (u32)sys_tbl_pa + pHba->unit;
 	host->sg_tablesize = pHba->sg_tablesize;
 	host->can_queue = pHba->post_fifo_size;
 
@@ -2596,11 +2644,10 @@
 static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
 {
 	u8 *status;
+	dma_addr_t addr;
 	u32 __iomem *msg = NULL;
 	int i;
 	ulong timeout = jiffies + TMOUT_INITOUTBOUND*HZ;
-	u32* ptr;
-	u32 outbound_frame;  // This had to be a 32 bit address
 	u32 m;
 
 	do {
@@ -2619,13 +2666,14 @@
 
 	msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
 
-	status = kzalloc(4, GFP_KERNEL|ADDR32);
+	status = dma_alloc_coherent(&pHba->pDev->dev, 4, &addr, GFP_KERNEL);
 	if (!status) {
 		adpt_send_nop(pHba, m);
 		printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n",
 			pHba->name);
 		return -ENOMEM;
 	}
+	memset(status, 0, 4);
 
 	writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
 	writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
@@ -2634,7 +2682,7 @@
 	writel(4096, &msg[4]);		/* Host page frame size */
 	writel((REPLY_FRAME_SIZE)<<16|0x80, &msg[5]);	/* Outbound msg frame size and Initcode */
 	writel(0xD0000004, &msg[6]);		/* Simple SG LE, EOB */
-	writel(virt_to_bus(status), &msg[7]);
+	writel((u32)addr, &msg[7]);
 
 	writel(m, pHba->post_port);
 	wmb();
@@ -2649,6 +2697,10 @@
 		rmb();
 		if(time_after(jiffies,timeout)){
 			printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
+			/* We lose 4 bytes of "status" here, but we
+			   cannot free these because controller may
+			   awake and corrupt those bytes at any time */
+			/* dma_free_coherent(&pHba->pDev->dev, 4, status, addr); */
 			return -ETIMEDOUT;
 		}
 		schedule_timeout_uninterruptible(1);
@@ -2657,25 +2709,30 @@
 	// If the command was successful, fill the fifo with our reply
 	// message packets
 	if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
-		kfree(status);
+		dma_free_coherent(&pHba->pDev->dev, 4, status, addr);
 		return -2;
 	}
-	kfree(status);
+	dma_free_coherent(&pHba->pDev->dev, 4, status, addr);
 
-	kfree(pHba->reply_pool);
+	if(pHba->reply_pool != NULL) {
+		dma_free_coherent(&pHba->pDev->dev,
+			pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4,
+			pHba->reply_pool, pHba->reply_pool_pa);
+	}
 
-	pHba->reply_pool = kzalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
+	pHba->reply_pool = dma_alloc_coherent(&pHba->pDev->dev,
+				pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4,
+				&pHba->reply_pool_pa, GFP_KERNEL);
 	if (!pHba->reply_pool) {
 		printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name);
 		return -ENOMEM;
 	}
+	memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4);
 
-	ptr = pHba->reply_pool;
 	for(i = 0; i < pHba->reply_fifo_size; i++) {
-		outbound_frame = (u32)virt_to_bus(ptr);
-		writel(outbound_frame, pHba->reply_port);
+		writel(pHba->reply_pool_pa + (i * REPLY_FRAME_SIZE * 4),
+			pHba->reply_port);
 		wmb();
-		ptr +=  REPLY_FRAME_SIZE;
 	}
 	adpt_i2o_status_get(pHba);
 	return 0;
@@ -2699,11 +2756,11 @@
 	u32 m;
 	u32 __iomem *msg;
 	u8 *status_block=NULL;
-	ulong status_block_bus;
 
 	if(pHba->status_block == NULL) {
-		pHba->status_block = (i2o_status_block*)
-			kmalloc(sizeof(i2o_status_block),GFP_KERNEL|ADDR32);
+		pHba->status_block = dma_alloc_coherent(&pHba->pDev->dev,
+					sizeof(i2o_status_block),
+					&pHba->status_block_pa, GFP_KERNEL);
 		if(pHba->status_block == NULL) {
 			printk(KERN_ERR
 			"dpti%d: Get Status Block failed; Out of memory. \n", 
@@ -2713,7 +2770,6 @@
 	}
 	memset(pHba->status_block, 0, sizeof(i2o_status_block));
 	status_block = (u8*)(pHba->status_block);
-	status_block_bus = virt_to_bus(pHba->status_block);
 	timeout = jiffies+TMOUT_GETSTATUS*HZ;
 	do {
 		rmb();
@@ -2738,8 +2794,8 @@
 	writel(0, &msg[3]);
 	writel(0, &msg[4]);
 	writel(0, &msg[5]);
-	writel(((u32)status_block_bus)&0xffffffff, &msg[6]);
-	writel(0, &msg[7]);
+	writel( dma_low(pHba->status_block_pa), &msg[6]);
+	writel( dma_high(pHba->status_block_pa), &msg[7]);
 	writel(sizeof(i2o_status_block), &msg[8]); // 88 bytes
 
 	//post message
@@ -2819,7 +2875,9 @@
 	}
 	do {
 		if (pHba->lct == NULL) {
-			pHba->lct = kmalloc(pHba->lct_size, GFP_KERNEL|ADDR32);
+			pHba->lct = dma_alloc_coherent(&pHba->pDev->dev,
+					pHba->lct_size, &pHba->lct_pa,
+					GFP_KERNEL);
 			if(pHba->lct == NULL) {
 				printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
 					pHba->name);
@@ -2835,7 +2893,7 @@
 		msg[4] = 0xFFFFFFFF;	/* All devices */
 		msg[5] = 0x00000000;	/* Report now */
 		msg[6] = 0xD0000000|pHba->lct_size;
-		msg[7] = virt_to_bus(pHba->lct);
+		msg[7] = (u32)pHba->lct_pa;
 
 		if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) {
 			printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n", 
@@ -2846,7 +2904,8 @@
 
 		if ((pHba->lct->table_size << 2) > pHba->lct_size) {
 			pHba->lct_size = pHba->lct->table_size << 2;
-			kfree(pHba->lct);
+			dma_free_coherent(&pHba->pDev->dev, pHba->lct_size,
+					pHba->lct, pHba->lct_pa);
 			pHba->lct = NULL;
 		}
 	} while (pHba->lct == NULL);
@@ -2871,25 +2930,30 @@
 
 static int adpt_i2o_build_sys_table(void)
 {
-	adpt_hba* pHba = NULL;
+	adpt_hba* pHba = hba_chain;
 	int count = 0;
 
+	if (sys_tbl)
+		dma_free_coherent(&pHba->pDev->dev, sys_tbl_len,
+					sys_tbl, sys_tbl_pa);
+
 	sys_tbl_len = sizeof(struct i2o_sys_tbl) +	// Header + IOPs
 				(hba_count) * sizeof(struct i2o_sys_tbl_entry);
 
-	kfree(sys_tbl);
-
-	sys_tbl = kzalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
+	sys_tbl = dma_alloc_coherent(&pHba->pDev->dev,
+				sys_tbl_len, &sys_tbl_pa, GFP_KERNEL);
 	if (!sys_tbl) {
 		printk(KERN_WARNING "SysTab Set failed. Out of memory.\n");	
 		return -ENOMEM;
 	}
+	memset(sys_tbl, 0, sys_tbl_len);
 
 	sys_tbl->num_entries = hba_count;
 	sys_tbl->version = I2OVERSION;
 	sys_tbl->change_ind = sys_tbl_ind++;
 
 	for(pHba = hba_chain; pHba; pHba = pHba->next) {
+		u64 addr;
 		// Get updated Status Block so we have the latest information
 		if (adpt_i2o_status_get(pHba)) {
 			sys_tbl->num_entries--;
@@ -2905,8 +2969,9 @@
 		sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
 		sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
 		sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
-		sys_tbl->iops[count].inbound_low = (u32)virt_to_bus(pHba->post_port);
-		sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus(pHba->post_port)>>32);
+		addr = pHba->base_addr_phys + 0x40;
+		sys_tbl->iops[count].inbound_low = dma_low(addr);
+		sys_tbl->iops[count].inbound_high = dma_high(addr);
 
 		count++;
 	}
@@ -3042,7 +3107,8 @@
 
 	do {
 		if (pHba->hrt == NULL) {
-			pHba->hrt=kmalloc(size, GFP_KERNEL|ADDR32);
+			pHba->hrt = dma_alloc_coherent(&pHba->pDev->dev,
+					size, &pHba->hrt_pa, GFP_KERNEL);
 			if (pHba->hrt == NULL) {
 				printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", pHba->name);
 				return -ENOMEM;
@@ -3054,7 +3120,7 @@
 		msg[2]= 0;
 		msg[3]= 0;
 		msg[4]= (0xD0000000 | size);    /* Simple transaction */
-		msg[5]= virt_to_bus(pHba->hrt);   /* Dump it here */
+		msg[5]= (u32)pHba->hrt_pa;	/* Dump it here */
 
 		if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg),20))) {
 			printk(KERN_ERR "%s: Unable to get HRT (status=%#10x)\n", pHba->name, ret);
@@ -3062,8 +3128,10 @@
 		}
 
 		if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) {
-			size = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
-			kfree(pHba->hrt);
+			int newsize = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
+			dma_free_coherent(&pHba->pDev->dev, size,
+				pHba->hrt, pHba->hrt_pa);
+			size = newsize;
 			pHba->hrt = NULL;
 		}
 	} while(pHba->hrt == NULL);
@@ -3077,33 +3145,54 @@
 			int group, int field, void *buf, int buflen)
 {
 	u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
-	u8 *resblk;
+	u8 *opblk_va;
+	dma_addr_t opblk_pa;
+	u8 *resblk_va;
+	dma_addr_t resblk_pa;
 
 	int size;
 
 	/* 8 bytes for header */
-	resblk = kmalloc(sizeof(u8) * (8+buflen), GFP_KERNEL|ADDR32);
-	if (resblk == NULL) {
+	resblk_va = dma_alloc_coherent(&pHba->pDev->dev,
+			sizeof(u8) * (8 + buflen), &resblk_pa, GFP_KERNEL);
+	if (resblk_va == NULL) {
 		printk(KERN_CRIT "%s: query scalar failed; Out of memory.\n", pHba->name);
 		return -ENOMEM;
 	}
 
+	opblk_va = dma_alloc_coherent(&pHba->pDev->dev,
+			sizeof(opblk), &opblk_pa, GFP_KERNEL);
+	if (opblk_va == NULL) {
+		dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
+			resblk_va, resblk_pa);
+		printk(KERN_CRIT "%s: query operatio failed; Out of memory.\n",
+			pHba->name);
+		return -ENOMEM;
+	}
 	if (field == -1)  		/* whole group */
 			opblk[4] = -1;
 
+	memcpy(opblk_va, opblk, sizeof(opblk));
 	size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid, 
-		opblk, sizeof(opblk), resblk, sizeof(u8)*(8+buflen));
+		opblk_va, opblk_pa, sizeof(opblk),
+		resblk_va, resblk_pa, sizeof(u8)*(8+buflen));
+	dma_free_coherent(&pHba->pDev->dev, sizeof(opblk), opblk_va, opblk_pa);
 	if (size == -ETIME) {
+		dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
+							resblk_va, resblk_pa);
 		printk(KERN_WARNING "%s: issue params failed; Timed out.\n", pHba->name);
 		return -ETIME;
 	} else if (size == -EINTR) {
+		dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
+							resblk_va, resblk_pa);
 		printk(KERN_WARNING "%s: issue params failed; Interrupted.\n", pHba->name);
 		return -EINTR;
 	}
 			
-	memcpy(buf, resblk+8, buflen);  /* cut off header */
+	memcpy(buf, resblk_va+8, buflen);  /* cut off header */
 
-	kfree(resblk);
+	dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
+						resblk_va, resblk_pa);
 	if (size < 0)
 		return size;	
 
@@ -3120,10 +3209,11 @@
  *	ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
  */
 static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
-		  void *opblk, int oplen, void *resblk, int reslen)
+		  void *opblk_va,  dma_addr_t opblk_pa, int oplen,
+		void *resblk_va, dma_addr_t resblk_pa, int reslen)
 {
 	u32 msg[9]; 
-	u32 *res = (u32 *)resblk;
+	u32 *res = (u32 *)resblk_va;
 	int wait_status;
 
 	msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
@@ -3132,12 +3222,12 @@
 	msg[3] = 0;
 	msg[4] = 0;
 	msg[5] = 0x54000000 | oplen;	/* OperationBlock */
-	msg[6] = virt_to_bus(opblk);
+	msg[6] = (u32)opblk_pa;
 	msg[7] = 0xD0000000 | reslen;	/* ResultBlock */
-	msg[8] = virt_to_bus(resblk);
+	msg[8] = (u32)resblk_pa;
 
 	if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
-		printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk);
+		printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk_va);
    		return wait_status; 	/* -DetailedStatus */
 	}
 
@@ -3240,7 +3330,7 @@
 	 * Private i/o space declaration  
 	 */
 	msg[6] = 0x54000000 | sys_tbl_len;
-	msg[7] = virt_to_phys(sys_tbl);
+	msg[7] = (u32)sys_tbl_pa;
 	msg[8] = 0x54000000 | 0;
 	msg[9] = 0;
 	msg[10] = 0xD4000000 | 0;
linux-2.6.25-dpt64-01/drivers/scsi/dpti.h renamed from drivers/scsi/dpti.h +6 -1
diff -ruN linux-2.6.25/drivers/scsi/dpti.h ../linux-2.6.25-dpt64-01/drivers/scsi/dpti.h
@@ -228,14 +228,18 @@
 	u32  post_fifo_size;
 	u32  reply_fifo_size;
 	u32* reply_pool;
+	dma_addr_t reply_pool_pa;
 	u32  sg_tablesize;	// Scatter/Gather List Size.       
 	u8  top_scsi_channel;
 	u8  top_scsi_id;
 	u8  top_scsi_lun;
 
 	i2o_status_block* status_block;
+	dma_addr_t status_block_pa;
 	i2o_hrt* hrt;
+	dma_addr_t hrt_pa;
 	i2o_lct* lct;
+	dma_addr_t lct_pa;
 	uint lct_size;
 	struct i2o_device* devices;
 	struct adpt_channel channel[MAX_CHANNEL];
@@ -271,7 +275,8 @@
 static const char *adpt_i2o_get_class_name(int class);
 #endif
 static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, 
-		  void *opblk, int oplen, void *resblk, int reslen);
+		  void *opblk, dma_addr_t opblk_pa, int oplen,
+		  void *resblk, dma_addr_t resblk_pa, int reslen);
 static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout);
 static int adpt_i2o_lct_get(adpt_hba* pHba);
 static int adpt_i2o_parse_lct(adpt_hba* pHba);
#4 lore raw

Re: [PATCH 2/4] dpt_i2o: move from virt_to_bus/bus_to_virt to dma_alloc_coherent

Quoted 9 lines · Miquel van Smoorenburg

[PATCH 2/4] dpt_i2o: move from virt_to_bus/bus_to_virt to dma_alloc_coherent

Remove virt_to_bus/bus_to_virt code from dpt_i2o, and use dma_alloc_coherent() / dma_free_coherent().

*==========================================================================
== */

linux-2.6.25-dpt64-01/drivers/scsi/dpt_i2o.c line 150

Quoted 10 lines
linux-2.6.25-dpt64-01/drivers/scsi/dpt_i2o.c renamed from drivers/scsi/dpt_i2o.c +10 -0
+static inline u32 dma_high(dma_addr_t addr)
+{
+	return upper_32_bits(addr);
+}
+
+static inline u32 dma_low(dma_addr_t addr)
+{
+	return (u32)addr;
+}
+

Just use these instructions directly, no need to introduce functions for that.

Eike

#5 lore raw

Re: [PATCH 2/4] dpt_i2o: move from virt_to_bus/bus_to_virt to dma_alloc_coherent

Quoted 10 lines · Rolf Eike Beer
Quoted 9 lines · Miquel van Smoorenburg

[PATCH 2/4] dpt_i2o: move from virt_to_bus/bus_to_virt to dma_alloc_coherent

Remove virt_to_bus/bus_to_virt code from dpt_i2o, and use dma_alloc_coherent() / dma_free_coherent().

*==========================================================================
== */

Quoted 12 lines

linux-2.6.25-dpt64-01/drivers/scsi/dpt_i2o.c line 150

Quoted 10 lines
linux-2.6.25-dpt64-01/drivers/scsi/dpt_i2o.c renamed from drivers/scsi/dpt_i2o.c +10 -0
+static inline u32 dma_high(dma_addr_t addr)
+{
+	return upper_32_bits(addr);
+}
+
+static inline u32 dma_low(dma_addr_t addr)
+{
+	return (u32)addr;
+}
+

Just use these instructions directly, no need to introduce functions for that.

I think it makes it more readable. They are inline functions (used like macro's, really), there's no overhead. Is this against the kernel codingstyle ?

Mike.

#6 lore raw

PATCH 3/4 dpt_i2o: 64 bit support

In reply to Miquel van Smoorenburg

[PATCH 3/4] dpt_i2o: 64 bit support

This is the code to actually support 64 bit platforms. 64 bit DMA is enabled on both x86_32 PAE and 64 bit platforms.

This code is based in part on the unofficial adaptec 64-bit dpt_i2o driver update that I got from Mark Salyzyn at Adaptec.

linux-2.6.25-dpt64-02/drivers/scsi/Kconfig renamed from drivers/scsi/Kconfig +1 -2
diff -ruN linux-2.6.25/drivers/scsi/Kconfig ../linux-2.6.25-dpt64-02/drivers/scsi/Kconfig
@@ -504,10 +504,9 @@
 source "drivers/scsi/aic7xxx/Kconfig.aic79xx"
 source "drivers/scsi/aic94xx/Kconfig"
 
-# All the I2O code and drivers do not seem to be 64bit safe.
 config SCSI_DPT_I2O
 	tristate "Adaptec I2O RAID support "
-	depends on !64BIT && SCSI && PCI && VIRT_TO_BUS
+	depends on SCSI && PCI && VIRT_TO_BUS
 	help
 	  This driver supports all of Adaptec's I2O based RAID controllers as 
 	  well as the DPT SmartRaid V cards.  This is an Adaptec maintained
linux-2.6.25-dpt64-02/drivers/scsi/dpt/dpti_ioctl.h renamed from drivers/scsi/dpt/dpti_ioctl.h +8 -8
diff -ruN linux-2.6.25/drivers/scsi/dpt/dpti_ioctl.h ../linux-2.6.25-dpt64-02/drivers/scsi/dpt/dpti_ioctl.h
@@ -89,7 +89,7 @@
 	int      njobs;            /* # of jobs sent to HA            */
 	int      qdepth;           /* Controller queue depth.         */
 	int      wakebase;         /* mpx wakeup base index.          */
-	uLONG    SGsize;           /* Scatter/Gather list size.       */
+	uINT     SGsize;           /* Scatter/Gather list size.       */
 	unsigned heads;            /* heads for drives on cntlr.      */
 	unsigned sectors;          /* sectors for drives on cntlr.    */
 	uCHAR    do_drive32;       /* Flag for Above 16 MB Ability    */
@@ -97,8 +97,8 @@
 	char     idPAL[4];         /* 4 Bytes Of The ID Pal           */
 	uCHAR    primary;          /* 1 For Primary, 0 For Secondary  */
 	uCHAR    eataVersion;      /* EATA Version                    */
-	uLONG    cpLength;         /* EATA Command Packet Length      */
-	uLONG    spLength;         /* EATA Status Packet Length       */
+	uINT     cpLength;         /* EATA Command Packet Length      */
+	uINT     spLength;         /* EATA Status Packet Length       */
 	uCHAR    drqNum;           /* DRQ Index (0,5,6,7)             */
 	uCHAR    flag1;            /* EATA Flags 1 (Byte 9)           */
 	uCHAR    flag2;            /* EATA Flags 2 (Byte 30)          */
@@ -107,23 +107,23 @@
 typedef struct {
 	uSHORT length;		// Remaining length of this
 	uSHORT drvrHBAnum;	// Relative HBA # used by the driver
-	uLONG baseAddr;		// Base I/O address
+	uINT baseAddr;		// Base I/O address
 	uSHORT blinkState;	// Blink LED state (0=Not in blink LED)
 	uCHAR pciBusNum;	// PCI Bus # (Optional)
 	uCHAR pciDeviceNum;	// PCI Device # (Optional)
 	uSHORT hbaFlags;	// Miscellaneous HBA flags
 	uSHORT Interrupt;	// Interrupt set for this device.
 #   if (defined(_DPT_ARC))
-	uLONG baseLength;
+	uINT baseLength;
 	ADAPTER_OBJECT *AdapterObject;
 	LARGE_INTEGER DmaLogicalAddress;
 	PVOID DmaVirtualAddress;
 	LARGE_INTEGER ReplyLogicalAddress;
 	PVOID ReplyVirtualAddress;
 #   else
-	uLONG reserved1;	// Reserved for future expansion
-	uLONG reserved2;	// Reserved for future expansion
-	uLONG reserved3;	// Reserved for future expansion
+	uINT reserved1;		// Reserved for future expansion
+	uINT reserved2;		// Reserved for future expansion
+	uINT reserved3;		// Reserved for future expansion
 #   endif
 } drvrHBAinfo_S;
 
linux-2.6.25-dpt64-02/drivers/scsi/dpt/dptsig.h renamed from drivers/scsi/dpt/dptsig.h +2 -6
diff -ruN linux-2.6.25/drivers/scsi/dpt/dptsig.h ../linux-2.6.25-dpt64-02/drivers/scsi/dpt/dptsig.h
@@ -33,11 +33,7 @@
 /* to make sure we are talking the same size under all OS's     */
 typedef unsigned char sigBYTE;
 typedef unsigned short sigWORD;
-#if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32))
-typedef uint32_t sigLONG;
-#else
-typedef unsigned long sigLONG;
-#endif
+typedef unsigned int sigINT;
 
 /*
  * use sigWORDLittleEndian for:
@@ -300,7 +296,7 @@
     sigBYTE dsFiletype;          /* type of file */
     sigBYTE dsFiletypeFlags;     /* flags to specify load type, etc. */
     sigBYTE dsOEM;               /* OEM file was created for */
-    sigLONG dsOS;                /* which Operating systems */
+    sigINT  dsOS;                /* which Operating systems */
     sigWORD dsCapabilities;      /* RAID levels, etc. */
     sigWORD dsDeviceSupp;        /* Types of SCSI devices supported */
     sigWORD dsAdapterSupp;       /* DPT adapter families supported */
linux-2.6.25-dpt64-02/drivers/scsi/dpt/sys_info.h renamed from drivers/scsi/dpt/sys_info.h +2 -2
diff -ruN linux-2.6.25/drivers/scsi/dpt/sys_info.h ../linux-2.6.25-dpt64-02/drivers/scsi/dpt/sys_info.h
@@ -145,8 +145,8 @@
    uCHAR        smartROMRevision;
    uSHORT       flags;                  /* See bit definitions above */
    uSHORT       conventionalMemSize;    /* in KB */
-   uLONG        extendedMemSize;        /* in KB */
-   uLONG        osType;                 /* Same as DPTSIG's definition */
+   uINT         extendedMemSize;        /* in KB */
+   uINT         osType;                 /* Same as DPTSIG's definition */
    uCHAR        osMajorVersion;
    uCHAR        osMinorVersion;         /* The OS version */
    uCHAR        osRevision;
linux-2.6.25-dpt64-02/drivers/scsi/dpt_i2o.c renamed from drivers/scsi/dpt_i2o.c +245 -35

468 lines not on this page · raw message

linux-2.6.25-dpt64-02/drivers/scsi/dpti.h renamed from drivers/scsi/dpti.h +2 -0
diff -ruN linux-2.6.25/drivers/scsi/dpti.h ../linux-2.6.25-dpt64-02/drivers/scsi/dpti.h
@@ -233,6 +233,7 @@
 	u8  top_scsi_channel;
 	u8  top_scsi_id;
 	u8  top_scsi_lun;
+	u8  dma64;
 
 	i2o_status_block* status_block;
 	dma_addr_t status_block_pa;
@@ -252,6 +253,7 @@
 	void __iomem *FwDebugBLEDflag_P;// Virtual Addr Of FW Debug BLED
 	void __iomem *FwDebugBLEDvalue_P;// Virtual Addr Of FW Debug BLED
 	u32 FwDebugFlags;
+	u32 *ioctl_reply_context[4];
 } adpt_hba;
 
 struct sg_simple_element {
#7 lore raw

Re: [PATCH 3/4] dpt_i2o: 64 bit support

linux-2.6.25-dpt64-02/drivers/scsi/dpt_i2o.c line 157

Quoted 13 lines · Miquel van Smoorenburg

[PATCH 3/4] dpt_i2o: 64 bit support

This is the code to actually support 64 bit platforms. 64 bit DMA is enabled on both x86_32 PAE and 64 bit platforms.

This code is based in part on the unofficial adaptec 64-bit dpt_i2o driver update that I got from Mark Salyzyn at Adaptec.

linux-2.6.25-dpt64-02/drivers/scsi/dpt_i2o.c renamed from drivers/scsi/dpt_i2o.c +5 -0
+static inline int dpt_dma64(adpt_hba *pHba)
+{
+	return (sizeof(dma_addr_t) > 4 && (pHba)->dma64);
+}
+

Just a note: you never set dma64 if sizeof(dma_addr_t) == 4. Doing it this way has the advantage that the compiler can optimize that away completely.

Eike

#8 lore raw

PATCH 4/4 dpt_i2o: sysfs code

In reply to Miquel van Smoorenburg

[PATCH 4/4] dpt_i2o: sysfs code

Create a /sys/class/dpt_i2o directory and populate it with dptiN directories. Each dptiN directory contains a "dev" file that makes udev create /dev/dptiN

drivers/scsi/dpt_i2o.c +26 -0
diff -ruN linux-2.6.25-03/drivers/scsi/dpt_i2o.c linux-2.6.25-04/drivers/scsi/dpt_i2o.c
@@ -111,6 +111,8 @@
 static adpt_hba* hba_chain = NULL;
 static int hba_count = 0;
 
+static struct class *adpt_sysfs_class;
+
 #ifdef CONFIG_COMPAT
 static long compat_adpt_ioctl(struct file *, unsigned int, unsigned long);
 #endif
@@ -254,6 +256,12 @@
 		adpt_inquiry(pHba);
 	}
 
+	adpt_sysfs_class = class_create(THIS_MODULE, "dpt_i2o");
+	if (IS_ERR(adpt_sysfs_class)) {
+		printk(KERN_WARNING"dpti: unable to create dpt_i2o class\n");
+		adpt_sysfs_class = NULL;
+	}
+
 	for (pHba = hba_chain; pHba; pHba = pHba->next) {
 		if (adpt_scsi_host_alloc(pHba, sht) < 0){
 			adpt_i2o_delete_hba(pHba);
@@ -261,6 +269,16 @@
 		}
 		pHba->initialized = TRUE;
 		pHba->state &= ~DPTI_STATE_RESET;
+		if (adpt_sysfs_class) {
+			struct device *dev = device_create(adpt_sysfs_class,
+				NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit),
+				"dpti%d", pHba->unit);
+			if (IS_ERR(dev)) {
+				printk(KERN_WARNING"dpti%d: unable to "
+					"create device in dpt_i2o class\n",
+					pHba->unit);
+			}
+		}
 	}
 
 	// Register our control device node
@@ -1212,8 +1230,16 @@
 	pci_dev_put(pHba->pDev);
 	kfree(pHba);
 
+	if (adpt_sysfs_class)
+		device_destroy(adpt_sysfs_class,
+				MKDEV(DPTI_I2O_MAJOR, pHba->unit));
+
 	if(hba_count <= 0){
 		unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);   
+		if (adpt_sysfs_class) {
+			class_destroy(adpt_sysfs_class);
+			adpt_sysfs_class = NULL;
+		}
 	}
 }
 
#9 lore raw

Re: [PATCH 4/4] dpt_i2o: sysfs code

ACK

Quoted 8 lines · Miquel van Smoorenburg

[PATCH 4/4] dpt_i2o: sysfs code

Create a /sys/class/dpt_i2o directory and populate it with dptiN directories. Each dptiN directory contains a "dev" file that makes udev create /dev/dptiN

#10 lore raw
In reply to Miquel van Smoorenburg
Quoted 2 lines · On Fri, 2 May 2008 01:02:15 +0200 Miquel van Smoorenburg <[email protected]>…

These patches update the dpt_i2o driver to work on 64-bit platforms like x86_64.

wheeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee! Mailing list to mainline (while avoiding checkpatch by 100 miles) in what? Six hours? Hooray for the merge window!

I'll fix alpha. I'll let someone else ponder ia64:

drivers/scsi/dpt_i2o.c:83: error: PROC_IA64' undeclared here (not in a function) drivers/scsi/dpt_i2o.c:83: error: initializer element is not constant drivers/scsi/dpt_i2o.c:83: error: (near initialization for DPTI_sig.dsProcessor')

From: Andrew Morton <[email protected]>

alpha:

drivers/scsi/dpt_i2o.c:1997: error: implicit declaration of function 'adpt_alpha_info' drivers/scsi/dpt_i2o.c: At top level:
drivers/scsi/dpt_i2o.c:2032: warning: conflicting types for 'adpt_alpha_info' drivers/scsi/dpt_i2o.c:2032: error: static declaration of 'adpt_alpha_info' follows non-static declaration drivers/scsi/dpt_i2o.c:1997: error: previous implicit declaration of 'adpt_alpha_info' was here

Due to a copy-n-paste error in drivers/scsi/dpti.h.

Fix that up and remove some of the many daft static-declarations-in-a-header which this driver enjoys.

Cc Miquel van Smoorenburg <[email protected]>
Cc James Bottomley <[email protected]>

---

 drivers/scsi/dpt_i2o.c |   78 ++++++++++++++++++---------------------
 drivers/scsi/dpti.h    |   13 ------
 2 files changed, 36 insertions(+), 55 deletions(-)
drivers/scsi/dpt_i2o.c renamed from drivers/scsi/dpt_i2o.c~drivers-scsi-dpt_i2oc-fix-build-on-alpha +36 -42
diff -puN drivers/scsi/dpt_i2o.c~drivers-scsi-dpt_i2oc-fix-build-on-alpha drivers/scsi/dpt_i2o.c
@@ -1967,45 +1967,6 @@ cleanup:
 	return rcode;
 }
 
-
-/*
- * This routine returns information about the system.  This does not effect
- * any logic and if the info is wrong - it doesn't matter.
- */
-
-/* Get all the info we can not get from kernel services */
-static int adpt_system_info(void __user *buffer)
-{
-	sysInfo_S si;
-
-	memset(&si, 0, sizeof(si));
-
-	si.osType = OS_LINUX;
-	si.osMajorVersion = 0;
-	si.osMinorVersion = 0;
-	si.osRevision = 0;
-	si.busType = SI_PCI_BUS;
-	si.processorFamily = DPTI_sig.dsProcessorFamily;
-
-#if defined __i386__ 
-	adpt_i386_info(&si);
-#elif defined (__ia64__)
-	adpt_ia64_info(&si);
-#elif defined(__sparc__)
-	adpt_sparc_info(&si);
-#elif defined (__alpha__)
-	adpt_alpha_info(&si);
-#else
-	si.processorType = 0xff ;
-#endif
-	if(copy_to_user(buffer, &si, sizeof(si))){
-		printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
-		return -EFAULT;
-	}
-
-	return 0;
-}
-
 #if defined __ia64__ 
 static void adpt_ia64_info(sysInfo_S* si)
 {
@@ -2016,7 +1977,6 @@ static void adpt_ia64_info(sysInfo_S* si
 }
 #endif
 
-
 #if defined __sparc__ 
 static void adpt_sparc_info(sysInfo_S* si)
 {
@@ -2026,7 +1986,6 @@ static void adpt_sparc_info(sysInfo_S* s
 	si->processorType = PROC_ULTRASPARC;
 }
 #endif
-
 #if defined __alpha__ 
 static void adpt_alpha_info(sysInfo_S* si)
 {
@@ -2038,7 +1997,6 @@ static void adpt_alpha_info(sysInfo_S* s
 #endif
 
 #if defined __i386__
-
 static void adpt_i386_info(sysInfo_S* si)
 {
 	// This is all the info we need for now
@@ -2059,9 +2017,45 @@ static void adpt_i386_info(sysInfo_S* si
 		break;
 	}
 }
+#endif
+
+/*
+ * This routine returns information about the system.  This does not effect
+ * any logic and if the info is wrong - it doesn't matter.
+ */
+
+/* Get all the info we can not get from kernel services */
+static int adpt_system_info(void __user *buffer)
+{
+	sysInfo_S si;
+
+	memset(&si, 0, sizeof(si));
+
+	si.osType = OS_LINUX;
+	si.osMajorVersion = 0;
+	si.osMinorVersion = 0;
+	si.osRevision = 0;
+	si.busType = SI_PCI_BUS;
+	si.processorFamily = DPTI_sig.dsProcessorFamily;
 
+#if defined __i386__
+	adpt_i386_info(&si);
+#elif defined (__ia64__)
+	adpt_ia64_info(&si);
+#elif defined(__sparc__)
+	adpt_sparc_info(&si);
+#elif defined (__alpha__)
+	adpt_alpha_info(&si);
+#else
+	si.processorType = 0xff ;
 #endif
+	if(copy_to_user(buffer, &si, sizeof(si))){
+		printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
+		return -EFAULT;
+	}
 
+	return 0;
+}
 
 static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
 	      ulong arg)
drivers/scsi/dpti.h renamed from drivers/scsi/dpti.h~drivers-scsi-dpt_i2oc-fix-build-on-alpha +0 -13
diff -puN drivers/scsi/dpti.h~drivers-scsi-dpt_i2oc-fix-build-on-alpha drivers/scsi/dpti.h
@@ -316,19 +316,6 @@ static int adpt_close(struct inode *inod
 static void adpt_delay(int millisec);
 #endif
 
-#if defined __ia64__ 
-static void adpt_ia64_info(sysInfo_S* si);
-#endif
-#if defined __sparc__ 
-static void adpt_sparc_info(sysInfo_S* si);
-#endif
-#if defined __alpha__ 
-static void adpt_sparc_info(sysInfo_S* si);
-#endif
-#if defined __i386__
-static void adpt_i386_info(sysInfo_S* si);
-#endif
-
 #define PRINT_BUFFER_SIZE     512
 
 #define HBA_FLAGS_DBG_FLAGS_MASK         0xffff0000	// Mask for debug flags

_

#11 lore raw
Quoted 5 lines · On Tue, 6 May 2008 20:10:55 -0700 Andrew Morton <[email protected]>…

I'll let someone else ponder ia64:

drivers/scsi/dpt_i2o.c:83: error: PROC_IA64' undeclared here (not in a function) drivers/scsi/dpt_i2o.c:83: error: initializer element is not constant drivers/scsi/dpt_i2o.c:83: error: (near initialization for DPTI_sig.dsProcessor')

fyi, this is still happening.

maintainer
#12 lore raw
Quoted 9 lines · Andrew Morton
Quoted 5 lines · On Tue, 6 May 2008 20:10:55 -0700 Andrew Morton <[email protected]>…

I'll let someone else ponder ia64:

drivers/scsi/dpt_i2o.c:83: error: PROC_IA64' undeclared here (not in a function) drivers/scsi/dpt_i2o.c:83: error: initializer element is not constant drivers/scsi/dpt_i2o.c:83: error: (near initialization for DPTI_sig.dsProcessor')

fyi, this is still happening.

OK, this fixes it on my ia64.

I think this fix is the best approach, since -1 and 0xff mean unknown processor type to the management tool. The correct fix is obviously to add the definition of PROC_IA64 to dpt/dptsig.h, but I have no idea what the value should be.

James

---

drivers/scsi/dpt_i2o.c +2 -2
index 8508816..bfa9f09 100644
@@ -80,7 +80,7 @@ static dpt_sig_S DPTI_sig = {
 #ifdef __i386__
 	PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
 #elif defined(__ia64__)
-	PROC_INTEL, PROC_IA64,
+	PROC_INTEL, -1,
 #elif defined(__sparc__)
 	PROC_ULTRASPARC, PROC_ULTRASPARC,
 #elif defined(__alpha__)
@@ -1973,7 +1973,7 @@ static void adpt_ia64_info(sysInfo_S* si)
 	// This is all the info we need for now
 	// We will add more info as our new
 	// managmenent utility requires it
-	si->processorType = PROC_IA64;
+	si->processorType = 0xff;
 }
 #endif