* [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
@ 2004-02-10 20:53 Salyzyn, Mark
2004-02-10 21:21 ` Christoph Hellwig
0 siblings, 1 reply; 11+ messages in thread
From: Salyzyn, Mark @ 2004-02-10 20:53 UTC (permalink / raw)
To: linux-scsi
[-- Attachment #1: Type: text/plain, Size: 534 bytes --]
Read the CHANGELOG in set of patches for complete description of all the
history and modifications to the driver.
This is a whole scale synchronization of the driver in the 2.6.2 tree to
the Adaptec source code. I know the drill, this is just too big to be
accepted ;-> but it will be very difficult to separate out such a
fundamental set of changes in the driver.
This patch is broken into 5 parts, one for CHANGELOG, README.dpti and
dpt_sig.h each, plus a two part for the main source code.
Sincerely -- Mark Salyzyn
[-- Attachment #2: dpt_i2o.2.6.patch.pt1 --]
[-- Type: application/octet-stream, Size: 39337 bytes --]
diff -u -P --recursive linux-2.6.2.generic/drivers/scsi/dpt/dpti_ioctl.h linux-2.6.2-2322/drivers/scsi/dpt/dpti_ioctl.h
--- linux-2.6.2.generic/drivers/scsi/dpt/dpti_ioctl.h Mon May 26 18:00:39 2003
+++ linux-2.6.2-2322/drivers/scsi/dpt/dpti_ioctl.h Tue Aug 5 05:10:51 2003
@@ -3,10 +3,10 @@
-------------------
begin : Thu Sep 7 2000
copyright : (C) 2001 by Adaptec
- email : deanna_bonds@adaptec.com
+ email : Mark_Salyzyn@adaptec.com
+ original author : doug_anderson@adaptec.com & deanna_bonds@adaptec.com
- See Documentation/scsi/dpti.txt for history, notes, license info
- and credits
+ See README.dpti for history, notes, license info, and credits
***************************************************************************/
/***************************************************************************
diff -u -P --recursive linux-2.6.2.generic/drivers/scsi/dpt_i2o.c linux-2.6.2-2322/drivers/scsi/dpt_i2o.c
--- linux-2.6.2.generic/drivers/scsi/dpt_i2o.c Wed Nov 26 12:45:21 2003
+++ linux-2.6.2-2322/drivers/scsi/dpt_i2o.c Wed Feb 4 14:18:58 2004
@@ -1,14 +1,15 @@
/***************************************************************************
- dpti.c - description
+ dpt_i2o.c - description
-------------------
begin : Thu Sep 7 2000
- copyright : (C) 2000 by Adaptec
- email : deanna_bonds@adaptec.com
+ copyright : (C) 2000-2003 by Adaptec
+ email : Mark_Salyzyn@adaptec.com
+ original author : deanna_bonds@adaptec.com
- July 30, 2001 First version being submitted
+ July 30, 2001 First version being submitted
for inclusion in the kernel. V2.4
- See Documentation/scsi/dpti.txt for history, notes, license info
+ See Documentation/scsi/dpti.txt for history, notes, license info,
and credits
***************************************************************************/
@@ -24,17 +25,11 @@
//#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)
-
-#error Please convert me to Documentation/DMA-mapping.txt
-
#include <linux/version.h>
+
#include <linux/module.h>
-MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
+MODULE_AUTHOR("Deanna Bonds & Mark Salyzyn");
MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
////////////////////////////////////////////////////////////////
@@ -70,6 +65,10 @@
#include "dpt/dptsig.h"
#include "dpti.h"
+#if (defined(__x86_64__))
+# include <asm-x86_64/ioctl32.h>
+#endif
+
/*============================================================================
* Create a binary signature - this is read by dptsig
* Needed for our management apps
@@ -79,14 +78,16 @@
{'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
#ifdef __i386__
PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
-#elif defined(__ia64__)
- PROC_INTEL, PROC_IA64,
-#elif defined(__sparc__)
- PROC_ULTRASPARC,
-#elif defined(__alpha__)
- PROC_ALPHA ,
+#elif defined __ia64__
+ PROC_INTEL, PROC_ITANIUM,
+#elif defined __x86_64__
+ PROC_INTEL, PROC_SEXIUM,
+#elif defined __sparc__
+ PROC_ULTRASPARC, ~(sigBYTE)0U,
+#elif defined __alpha__
+ PROC_ALPHA, ~(sigBYTE)0U,
#else
- (-1),(-1)
+ ~(sigBYTE)0U, ~(sigBYTE)0U,
#endif
FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
@@ -102,8 +103,8 @@
*/
DECLARE_MUTEX(adpt_configuration_lock);
-
-static struct i2o_sys_tbl *sys_tbl = NULL;
+static struct i2o_sys_tbl *sys_tbl_va = NULL;
+static dma_addr_t sys_tbl_pa;
static int sys_tbl_ind = 0;
static int sys_tbl_len = 0;
@@ -111,6 +112,15 @@
static adpt_hba* hba_chain = NULL;
static int hba_count = 0;
+// If this is driver is embedded in the kernel this define
+// should be moved to include/linux/proc_fs.h as an emumerated type
+#define PROC_SCSI_DPT_I2O 0
+struct proc_dir_entry proc_scsi_dptI2O = {
+ PROC_SCSI_DPT_I2O, 7, DPT_DRIVER,
+ S_IFDIR | S_IRUGO | S_IXUGO, 2,
+ 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
static struct file_operations adpt_fops = {
.ioctl = adpt_ioctl,
.open = adpt_open,
@@ -149,9 +159,9 @@
static u8 adpt_read_blink_led(adpt_hba* host)
{
- if(host->FwDebugBLEDflag_P != 0) {
- if( readb(host->FwDebugBLEDflag_P) == 0xbc ){
- return readb(host->FwDebugBLEDvalue_P);
+ if(host->bled_flag_addr_virt != 0) {
+ if( readb(host->bled_flag_addr_virt) == 0xbc ){
+ return readb(host->bled_value_addr_virt);
}
}
return 0;
@@ -178,10 +188,10 @@
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){
+ /* search for all Adaptec I2O RAID cards */
+ while ((pDev = pci_find_device( dptids[0].vendor, PCI_ANY_ID, pDev))) {
+ if(pDev->device == dptids[0].device ||
+ pDev->device == dptids[1].device){
if(adpt_install_hba(sht, pDev) ){
PERROR("Could not Init an I2O RAID device\n");
PERROR("Will not try to detect others.\n");
@@ -258,6 +268,17 @@
adpt_i2o_sys_shutdown();
return 0;
}
+# if (defined(__x86_64__))
+ register_ioctl32_conversion(DPT_SIGNATURE, sys_ioctl);
+ register_ioctl32_conversion(I2OUSRCMD, sys_ioctl);
+ register_ioctl32_conversion(DPT_CTRLINFO, sys_ioctl);
+ register_ioctl32_conversion(DPT_SYSINFO, sys_ioctl);
+ register_ioctl32_conversion(DPT_BLINKLED, sys_ioctl);
+ register_ioctl32_conversion(I2ORESETCMD, sys_ioctl);
+ register_ioctl32_conversion(I2ORESCANCMD, sys_ioctl);
+ register_ioctl32_conversion(DPT_TARGET_BUSY & 0xFFFF, sys_ioctl);
+ register_ioctl32_conversion(DPT_TARGET_BUSY, sys_ioctl);
+# endif
return hba_count;
}
@@ -284,11 +305,12 @@
u32 len;
u32 reqlen;
u8* buf;
+ dma_addr_t addr;
u8 scb[16];
s32 rcode;
memset(msg, 0, sizeof(msg));
- buf = (u8*)kmalloc(80,GFP_KERNEL|ADDR32);
+ buf = (u8*)pci_alloc_consistent(pHba->pDev, 80, &addr);
if(!buf){
printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
return;
@@ -301,18 +323,18 @@
reqlen = 14; // SINGLE SGE
/* Stick the headers on */
- msg[0] = reqlen<<16 | SGL_OFFSET_12;
- msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID);
+ msg[0] = cpu_to_le32(reqlen<<16 | SGL_OFFSET_12);
+ msg[1] = cpu_to_le32(0xff<<24|HOST_TID<<12|ADAPTER_TID);
msg[2] = 0;
- msg[3] = 0;
+ msg[3] = 0;
// Adaptec/DPT Private stuff
- msg[4] = I2O_CMD_SCSI_EXEC|DPT_ORGANIZATION_ID<<16;
- msg[5] = ADAPTER_TID | 1<<16 /* Interpret*/;
+ msg[4] = cpu_to_le32(I2O_CMD_SCSI_EXEC|DPT_ORGANIZATION_ID<<16);
+ msg[5] = cpu_to_le32(ADAPTER_TID | 1<<16) /* Interpret*/;
/* Direction, disconnect ok | sense data | simple queue , CDBLen */
// I2O_SCB_FLAG_ENABLE_DISCONNECT |
// I2O_SCB_FLAG_SIMPLE_QUEUE_TAG |
// I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
- msg[6] = scsidir|0x20a00000| 6 /* cmd len*/;
+ msg[6] = cpu_to_le32(scsidir|0x20a00000| 6) /* cmd len*/;
mptr=msg+7;
@@ -331,15 +353,28 @@
lenptr=mptr++; /* Remember me - fill in when we know */
/* Now fill in the SGList and command */
- *lenptr = len;
- *mptr++ = 0xD0000000|direction|len;
- *mptr++ = virt_to_bus(buf);
+ *lenptr = cpu_to_le32(len);
+ /* The following test gets optimized out if dma_addr_t is <= 32 bits */
+ if( (sizeof(dma_addr_t) > 4) && (pHba->pae_support) && (((u64)addr >> 32) != 0) ) {
+ *mptr++ = cpu_to_le32((0x7C<<24)+(2<<16)+0x02); /* Enable 64 bit */
+ *mptr++ = cpu_to_le32(1 << PAGE_SHIFT);
+ *mptr++ = cpu_to_le32(0xD0000000|direction|len);
+ *mptr++ = cpu_to_le32(addr);
+ *mptr++ = cpu_to_le32((u64)addr >> 32);
+ reqlen += 3;
+ msg[0] = cpu_to_le32(reqlen<<16 | SGL_OFFSET_12);
+ } else {
+ *mptr++ = cpu_to_le32(0xD0000000|direction|len);
+ *mptr++ = cpu_to_le32(addr);
+ }
// Send it on it's way
rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
if (rcode != 0) {
sprintf(pHba->detail, "Adaptec I2O RAID");
printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
+ if (rcode != -ETIME && rcode != -EINTR)
+ pci_free_consistent(pHba->pDev, 80, buf, addr);
} else {
memset(pHba->detail, 0, sizeof(pHba->detail));
memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
@@ -348,8 +383,8 @@
memcpy(&(pHba->detail[40]), " FW: ", 4);
memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
pHba->detail[48] = '\0'; /* precautionary */
+ pci_free_consistent(pHba->pDev, 80, buf, addr);
}
- kfree(buf);
adpt_i2o_status_get(pHba);
return ;
}
@@ -357,17 +392,17 @@
static int adpt_slave_configure(Scsi_Device * device)
{
- struct Scsi_Host *host = device->host;
- adpt_hba* pHba;
+ struct Scsi_Host * host = device->host;
+ adpt_hba * pHba;
pHba = (adpt_hba *) host->hostdata[0];
if (host->can_queue && device->tagged_supported) {
scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
- host->can_queue - 1);
+ host->can_queue - 1);
} else {
scsi_adjust_queue_depth(device, 0, 1);
- }
+ }
return 0;
}
@@ -411,8 +446,9 @@
return 1;
}
- if(cmd->eh_state != SCSI_STATE_QUEUED){
- // If we are not doing error recovery
+ if ((cmd->eh_state != SCSI_STATE_QUEUED)
+ && (cmd->device->type == TYPE_DISK)) {
+ // If the controller is doing error recovery
mod_timer(&cmd->eh_timeout, timeout);
}
@@ -445,8 +481,9 @@
return adpt_scsi_to_i2o(pHba, cmd, pDev);
}
-static int adpt_bios_param(struct scsi_device *sdev, struct block_device *dev,
- sector_t capacity, int geom[])
+static int adpt_bios_param(
+ struct scsi_device *sdev, struct block_device *dev, sector_t capacity,
+ int geom[])
{
int heads=-1;
int sectors=-1;
@@ -479,7 +516,8 @@
heads = 255;
sectors = 63;
}
- cylinders = capacity / (heads * sectors);
+ sector_div(capacity, heads * sectors);
+ cylinders = (unsigned)capacity;
// Special case if CDROM
if(sdev->type == 5) { // CDROM
@@ -505,8 +543,10 @@
return (char *) (pHba->detail);
}
-static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
- int length, int inout)
+static int adpt_proc_info(
+ struct Scsi_Host *host,
+ char *buffer, char **start, off_t offset, int length,
+ int inout)
{
struct adpt_device* d;
int id;
@@ -538,7 +578,8 @@
// Find HBA (host bus adapter) we are looking for
down(&adpt_configuration_lock);
for (pHba = hba_chain; pHba; pHba = pHba->next) {
- if (pHba->host == host) {
+ if (pHba->host == host)
+ {
break; /* found adapter */
}
}
@@ -548,7 +589,11 @@
}
host = pHba->host;
- len = sprintf(buffer , "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);
+# if (defined(DPT_I2O_DRIVER_BUILD))
+ len = sprintf(buffer , "Adaptec I2O RAID Driver Version: %s[%d]\n\n", DPT_I2O_VERSION, DPT_I2O_DRIVER_BUILD);
+# else
+ len = sprintf(buffer , "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);
+# endif
len += sprintf(buffer+len, "%s\n", pHba->detail);
len += sprintf(buffer+len, "SCSI Host=scsi%d Control Node=/dev/%s irq=%d\n",
pHba->host->host_no, pHba->name, host->irq);
@@ -575,8 +620,10 @@
for(id = 0; id < MAX_ID; id++) {
d = pHba->channel[chan].device[id];
while(d){
- len += sprintf(buffer+len,"\t%-24.24s", d->pScsi_dev->vendor);
- len += sprintf(buffer+len," Rev: %-8.8s\n", d->pScsi_dev->rev);
+ if (d->pScsi_dev) {
+ len += sprintf(buffer+len,"\t%-24.24s", d->pScsi_dev->vendor);
+ len += sprintf(buffer+len," Rev: %-8.8s\n", d->pScsi_dev->rev);
+ }
pos = begin + len;
@@ -589,10 +636,10 @@
begin = pos;
}
- unit = d->pI2o_dev->lct_data.tid;
+ unit = le32_to_cpu(d->pI2o_dev->lct_data.tid);
len += sprintf(buffer+len, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d) (%s)\n\n",
unit, (int)d->scsi_channel, (int)d->scsi_id, (int)d->scsi_lun,
- d->pScsi_dev->online? "online":"offline");
+ (d->pScsi_dev && d->pScsi_dev->online)? "online":"offline");
pos = begin + len;
/* CHECKPOINT */
@@ -654,11 +701,14 @@
}
memset(msg, 0, sizeof(msg));
- msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;
+ msg[0] = cpu_to_le32(FIVE_WORD_MSG_SIZE|SGL_OFFSET_0);
+ msg[1] = cpu_to_le32(I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid);
msg[2] = 0;
- msg[3]= 0;
- msg[4] = (u32)cmd;
+ msg[3] = 0;
+ if (sizeof(cmd) > sizeof(u32))
+ msg[4] = (u32)cmd->serial_number;
+ else
+ msg[4] = (u32)cmd; /* EVIL, not 64 bit safe, but faster */
if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){
if(rcode == -EOPNOTSUPP ){
printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
@@ -691,8 +741,8 @@
return FAILED;
}
memset(msg, 0, sizeof(msg));
- msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = (I2O_DEVICE_RESET<<24|HOST_TID<<12|d->tid);
+ msg[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0);
+ msg[1] = cpu_to_le32(I2O_DEVICE_RESET<<24|HOST_TID<<12|d->tid);
msg[2] = 0;
msg[3] = 0;
@@ -720,12 +770,14 @@
{
adpt_hba* pHba;
u32 msg[4];
+ int channel;
+ channel = cmd->device->channel;
pHba = (adpt_hba*)cmd->device->host->hostdata[0];
memset(msg, 0, sizeof(msg));
- printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->device->channel,pHba->channel[cmd->device->channel].tid );
- msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
- msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
+ printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, channel,pHba->channel[channel].tid );
+ msg[0] = cpu_to_le32(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0);
+ msg[1] = cpu_to_le32(I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[channel].tid);
msg[2] = 0;
msg[3] = 0;
if(adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){
@@ -742,8 +794,11 @@
{
adpt_hba* pHba;
int rcode;
+ int channel;
+
+ channel = cmd->device->channel;
pHba = (adpt_hba*)cmd->device->host->hostdata[0];
- printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->device->channel,pHba->channel[cmd->device->channel].tid );
+ printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,channel,pHba->channel[channel].tid );
rcode = adpt_hba_reset(pHba);
if(rcode == 0){
printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name);
@@ -789,6 +844,8 @@
adpt_i2o_delete_hba(pHba);
return rcode;
}
+ adpt_inquiry(pHba);
+
pHba->state &= ~DPTI_STATE_RESET;
adpt_fail_posted_scbs(pHba);
@@ -862,8 +919,8 @@
ulong base_addr1_phys = 0;
u32 hba_map0_area_size = 0;
u32 hba_map1_area_size = 0;
- ulong base_addr_virt = 0;
- ulong msg_addr_virt = 0;
+ char * base_addr_virt = 0;
+ char * msg_addr_virt = 0;
int raptorFlag = FALSE;
int i;
@@ -894,14 +951,14 @@
}
- base_addr_virt = (ulong)ioremap(base_addr0_phys,hba_map0_area_size);
+ base_addr_virt = (char *)ioremap(base_addr0_phys,hba_map0_area_size);
if(base_addr_virt == 0) {
PERROR("dpti: adpt_config_hba: io remap failed\n");
return -EINVAL;
}
if(raptorFlag == TRUE) {
- msg_addr_virt = (ulong)ioremap(base_addr1_phys, hba_map1_area_size );
+ msg_addr_virt = (char *)ioremap(base_addr1_phys, hba_map1_area_size );
if(msg_addr_virt == 0) {
PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
iounmap((void*)base_addr_virt);
@@ -949,32 +1006,31 @@
// 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 = (ulong)(base_addr_virt+0x30);
- pHba->post_port = (ulong)(base_addr_virt+0x40);
- pHba->reply_port = (ulong)(base_addr_virt+0x44);
+ pHba->irq_mask = (u32 *)(base_addr_virt+0x30);
+ pHba->post_port = (u32 *)(base_addr_virt+0x40);
+ pHba->reply_port = (u32 *)(base_addr_virt+0x44);
- pHba->hrt = NULL;
- pHba->lct = NULL;
+ pHba->hrt_va = NULL;
+ pHba->lct_va = NULL;
pHba->lct_size = 0;
- pHba->status_block = NULL;
+ pHba->status_block_va = NULL;
pHba->post_count = 0;
pHba->state = DPTI_STATE_RESET;
- pHba->pDev = pDev;
pHba->devices = NULL;
// Initializing the spinlocks
spin_lock_init(&pHba->state_lock);
if(raptorFlag == 0){
- printk(KERN_INFO"Adaptec I2O RAID controller %d at %lx size=%x irq=%d\n",
+ 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 %lx - size= %x\n",base_addr_virt,hba_map0_area_size);
- printk(KERN_INFO" BAR1 %lx - size= %x\n",msg_addr_virt,hba_map1_area_size);
+ 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)) {
+ if (request_irq (pDev->irq, adpt_isr, SA_SHIRQ, pHba->name, (void *)pHba)) {
printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
adpt_i2o_delete_hba(pHba);
return -EINVAL;
@@ -1026,17 +1082,17 @@
if(pHba->msg_addr_virt != pHba->base_addr_virt){
iounmap((void*)pHba->msg_addr_virt);
}
- if(pHba->hrt) {
- kfree(pHba->hrt);
+ if(pHba->hrt_va) {
+ pci_free_consistent(pHba->pDev, le32_to_cpu(pHba->hrt_va->num_entries) * le32_to_cpu(pHba->hrt_va->entry_len) << 2, pHba->hrt_va, pHba->hrt_pa);
}
- if(pHba->lct){
- kfree(pHba->lct);
+ if(pHba->lct_va){
+ pci_free_consistent(pHba->pDev, pHba->lct_size, pHba->lct_va, pHba->lct_pa);
}
- if(pHba->status_block) {
- kfree(pHba->status_block);
+ if(pHba->status_block_va) {
+ pci_free_consistent(pHba->pDev, sizeof(i2o_status_block), pHba->status_block_va, pHba->status_block_pa);
}
- if(pHba->reply_pool){
- kfree(pHba->reply_pool);
+ if(pHba->reply_pool_va){
+ pci_free_consistent(pHba->pDev, pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, pHba->reply_pool_va, pHba->reply_pool_pa);
}
for(d = pHba->devices; d ; d = next){
@@ -1053,9 +1109,23 @@
}
}
}
- kfree(pHba);
+ if (pHba->host != NULL) {
+ scsi_unregister(pHba->host);
+ }
+ kfree(pHba);
if(hba_count <= 0){
+# if (defined(__x86_64__))
+ unregister_ioctl32_conversion(DPT_SIGNATURE);
+ unregister_ioctl32_conversion(I2OUSRCMD);
+ unregister_ioctl32_conversion(DPT_CTRLINFO);
+ unregister_ioctl32_conversion(DPT_SYSINFO);
+ unregister_ioctl32_conversion(DPT_BLINKLED);
+ unregister_ioctl32_conversion(I2ORESETCMD);
+ unregister_ioctl32_conversion(I2ORESCANCMD);
+ unregister_ioctl32_conversion(DPT_TARGET_BUSY & 0xFFFF);
+ unregister_ioctl32_conversion(DPT_TARGET_BUSY);
+# endif
unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);
}
}
@@ -1135,7 +1205,7 @@
wait_data->next = adpt_post_wait_queue;
adpt_post_wait_queue = wait_data;
adpt_post_wait_id++;
- adpt_post_wait_id &= 0x7fff;
+ adpt_post_wait_id = (adpt_post_wait_id & 0x7fff);
wait_data->id = adpt_post_wait_id;
spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
@@ -1145,27 +1215,56 @@
// this code is taken from kernel/sched.c:interruptible_sleep_on_timeout
wait.task = current;
init_waitqueue_entry(&wait, current);
- spin_lock_irqsave(&adpt_wq_i2o_post.lock, flags);
+ spin_lock_irqsave(&adpt_wq_i2o_post.lock,flags);
__add_wait_queue(&adpt_wq_i2o_post, &wait);
spin_unlock(&adpt_wq_i2o_post.lock);
msg[2] |= 0x80000000 | ((u32)wait_data->id);
timeout *= HZ;
if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
+ spinlock_t * was_locked = (spinlock_t *)NULL;
set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_irq(pHba->host->host_lock);
- if (!timeout)
+ /*
+ * We are called before the host & host lock has been
+ * assigned, and may be called with, or without, the host lock
+ * held. We need to free the lock, if held, before going
+ * to sleep.
+ */
+ if ((pHba->host != NULL) /* Sad */
+ && (spin_is_locked(pHba->host->host_lock))) {
+ was_locked = pHba->host->host_lock;
+ spin_unlock_irq(was_locked);
+ }
+ if(!timeout){
schedule();
- else
- schedule_timeout(timeout*HZ);
- spin_lock_irq(pHba->host->host_lock);
+ } else {
+ timeout = schedule_timeout(timeout*HZ);
+ if (timeout == 0) {
+ // I/O issued, but cannot get result in
+ // specified time. Freeing resources is
+ // dangerous.
+ status = -ETIME;
+ }
+ }
+ if (was_locked)
+ spin_lock_irq(was_locked);
+ if (signal_pending(current)) {
+ printk("adpt_i2o_post_wait: interrupted\n");
+ status = -EINTR;
+ }
}
spin_lock_irq(&adpt_wq_i2o_post.lock);
__remove_wait_queue(&adpt_wq_i2o_post, &wait);
- spin_unlock_irqrestore(&adpt_wq_i2o_post.lock, flags);
+ spin_unlock_irqrestore(&adpt_wq_i2o_post.lock,flags);
+
+ wait_data->wq = 0;
- if(status == -ETIMEDOUT){
- printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
+ if (status == -EINTR)
+ return status;
+
+ if(status == -ETIMEDOUT || status == -ETIME) {
+ printk(KERN_INFO"dpti%d: POST WAIT FAILED (%d)\n",
+ pHba->unit, status);
// We will have to free the wait_data memory during shutdown
return status;
}
@@ -1247,12 +1346,13 @@
if(p1->id == context) {
p1->status = status;
spin_unlock(&adpt_post_wait_lock);
- wake_up_interruptible(p1->wq);
+ if (p1->wq)
+ wake_up_interruptible(p1->wq);
return;
}
}
spin_unlock(&adpt_post_wait_lock);
- // If this happens we lose commands that probably really completed
+ // If this happens we loose commands that probably really completed
printk(KERN_DEBUG"dpti: Could Not find task %d in wait queue\n",context);
printk(KERN_DEBUG" Tasks in wait queue:\n");
for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
@@ -1265,6 +1365,8 @@
{
u32 msg[8];
u8* status;
+ dma_addr_t addr;
+ u64 addr64;
u32 m = EMPTY_QUEUE ;
ulong timeout = jiffies + (TMOUT_IOPRESET*HZ);
@@ -1277,16 +1379,16 @@
do {
rmb();
m = readl(pHba->post_port);
- if (m != EMPTY_QUEUE) {
+ if (m != cpu_to_le32(EMPTY_QUEUE)) {
break;
}
if(time_after(jiffies,timeout)){
printk(KERN_WARNING"Timeout waiting for message!\n");
return -ETIMEDOUT;
}
- } while (m == EMPTY_QUEUE);
+ } while (m == cpu_to_le32(EMPTY_QUEUE));
- status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
+ status = (u8*)pci_alloc_consistent(pHba->pDev, 4, &addr);
if(status == NULL) {
adpt_send_nop(pHba, m);
printk(KERN_ERR"IOP reset failed - no free memory.\n");
@@ -1294,16 +1396,17 @@
}
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;
+ msg[0]=cpu_to_le32(EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0);
+ msg[1]=cpu_to_le32(I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID);
msg[2]=0;
msg[3]=0;
msg[4]=0;
msg[5]=0;
- msg[6]=virt_to_bus(status);
- msg[7]=0;
+ addr64 = cpu_to_le64(addr);
+ msg[6]=(u32)addr64;
+ msg[7]=(u32)(addr64 >> 32);
- memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg));
+ memcpy_toio(pHba->msg_addr_virt+le32_to_cpu(m), msg, sizeof(msg));
wmb();
writel(m, pHba->post_port);
wmb();
@@ -1311,40 +1414,47 @@
while(*status == 0){
if(time_after(jiffies,timeout)){
printk(KERN_WARNING"%s: IOP Reset Timeout\n",pHba->name);
- kfree(status);
+ /* We loose 4 bytes of "status" here, but we cannot
+ free these because controller may awake and corrupt
+ those bytes at any time */
+ /* pci_free_consistent(pHba->pDev, 4, buf, addr); */
return -ETIMEDOUT;
}
rmb();
}
- if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
+ if(*status == cpu_to_le32(0x01) /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
PDEBUG("%s: Reset in progress...\n", pHba->name);
// Here we wait for message frame to become available
// indicated that reset has finished
do {
rmb();
m = readl(pHba->post_port);
- if (m != EMPTY_QUEUE) {
+ if (m != cpu_to_le32(EMPTY_QUEUE)) {
break;
}
if(time_after(jiffies,timeout)){
printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
+ /* We loose 4 bytes of "status" here, but we
+ cannot free these because controller may
+ awake and corrupt those bytes at any time */
+ /* pci_free_consistent(pHba->pDev, 4, buf, addr); */
return -ETIMEDOUT;
}
- } while (m == EMPTY_QUEUE);
+ } while (m == cpu_to_le32(EMPTY_QUEUE));
// Flush the offset
adpt_send_nop(pHba, m);
}
adpt_i2o_status_get(pHba);
- if(*status == 0x02 ||
- pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
+ if(*status == cpu_to_le32(0x02) ||
+ pHba->status_block_va->iop_state != cpu_to_le32(ADAPTER_STATE_RESET)) {
printk(KERN_WARNING"%s: Reset reject, trying to clear\n",
pHba->name);
} else {
PDEBUG("%s: Reset completed.\n", pHba->name);
}
- kfree(status);
+ pci_free_consistent(pHba->pDev, 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
@@ -1360,7 +1470,7 @@
int max;
int tid;
struct i2o_device *d;
- i2o_lct *lct = pHba->lct;
+ i2o_lct *lct = pHba->lct_va;
u8 bus_no = 0;
s16 scsi_id;
s16 scsi_lun;
@@ -1377,7 +1487,7 @@
max /= 9;
for(i=0;i<max;i++) {
- if( lct->lct_entry[i].user_tid != 0xfff){
+ if( lct->lct_entry[i].user_tid != cpu_to_le32(0xfff)){
/*
* If we have hidden devices, we need to inform the upper layers about
* the possible maximum id reference to handle device access when
@@ -1385,12 +1495,12 @@
* allow us future access to devices that are currently hidden
* behind arrays, hotspares or have not been configured (JBOD mode).
*/
- if( lct->lct_entry[i].class_id != I2O_CLASS_RANDOM_BLOCK_STORAGE &&
- lct->lct_entry[i].class_id != I2O_CLASS_SCSI_PERIPHERAL &&
- lct->lct_entry[i].class_id != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+ if( lct->lct_entry[i].class_id != cpu_to_le32(I2O_CLASS_RANDOM_BLOCK_STORAGE) &&
+ lct->lct_entry[i].class_id != cpu_to_le32(I2O_CLASS_SCSI_PERIPHERAL) &&
+ lct->lct_entry[i].class_id != cpu_to_le32(I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL) ){
continue;
}
- tid = lct->lct_entry[i].tid;
+ tid = le32_to_cpu(lct->lct_entry[i].tid);
// I2O_DPT_DEVICE_INFO_GROUP_NO;
if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
continue;
@@ -1402,7 +1512,7 @@
printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
continue;
}
- if (scsi_id >= MAX_ID){
+ if(scsi_id > MAX_ID){
printk(KERN_WARNING"%s: SCSI ID %d out of range \n", pHba->name, bus_no);
continue;
}
@@ -1430,21 +1540,21 @@
memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
d->flags = 0;
- tid = d->lct_data.tid;
+ tid = le32_to_cpu(d->lct_data.tid);
adpt_i2o_report_hba_unit(pHba, d);
adpt_i2o_install_device(pHba, d);
}
bus_no = 0;
for(d = pHba->devices; d ; d = d->next) {
- if(d->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT ||
- d->lct_data.class_id == I2O_CLASS_FIBRE_CHANNEL_PORT){
- tid = d->lct_data.tid;
+ if(d->lct_data.class_id == cpu_to_le32(I2O_CLASS_BUS_ADAPTER_PORT) ||
+ d->lct_data.class_id == cpu_to_le32(I2O_CLASS_FIBRE_CHANNEL_PORT)){
+ tid = le32_to_cpu(d->lct_data.tid);
// TODO get the bus_no from hrt-but for now they are in order
//bus_no =
if(bus_no > pHba->top_scsi_channel){
pHba->top_scsi_channel = bus_no;
}
- pHba->channel[bus_no].type = d->lct_data.class_id;
+ pHba->channel[bus_no].type = le32_to_cpu(d->lct_data.class_id);
pHba->channel[bus_no].tid = tid;
if(adpt_i2o_query_scalar(pHba, tid, 0x0200, -1, buf, 28)>=0)
{
@@ -1462,11 +1572,11 @@
// Setup adpt_device table
for(d = pHba->devices; d ; d = d->next) {
- if(d->lct_data.class_id == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
- d->lct_data.class_id == I2O_CLASS_SCSI_PERIPHERAL ||
- d->lct_data.class_id == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+ if(d->lct_data.class_id == cpu_to_le32(I2O_CLASS_RANDOM_BLOCK_STORAGE) ||
+ d->lct_data.class_id == cpu_to_le32(I2O_CLASS_SCSI_PERIPHERAL) ||
+ d->lct_data.class_id == cpu_to_le32(I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL) ){
- tid = d->lct_data.tid;
+ tid = le32_to_cpu(d->lct_data.tid);
scsi_id = -1;
// I2O_DPT_DEVICE_INFO_GROUP_NO;
if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)>=0) {
@@ -1476,7 +1586,7 @@
if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
continue;
}
- if (scsi_id >= MAX_ID) {
+ if(scsi_id > MAX_ID){
continue;
}
if( pHba->channel[bus_no].device[scsi_id] == NULL){
@@ -1602,7 +1712,6 @@
return 0;
}
-
static int adpt_i2o_passthru(adpt_hba* pHba, u32* arg)
{
u32 msg[MAX_MESSAGE_SIZE];
@@ -1611,13 +1720,14 @@
u32 reply_size = 0;
u32* user_msg = (u32*)arg;
u32* user_reply = NULL;
- ulong sg_list[pHba->sg_tablesize];
+ void * sg_list[pHba->sg_tablesize];
u32 sg_offset = 0;
u32 sg_count = 0;
int sg_index = 0;
u32 i = 0;
u32 rcode = 0;
- ulong p = 0;
+ void * p = 0;
+ dma_addr_t addr;
ulong flags = 0;
memset(&msg, 0, MAX_MESSAGE_SIZE*4);
@@ -1651,10 +1761,26 @@
memset(reply,0,REPLY_FRAME_SIZE*4);
sg_offset = (msg[0]>>4)&0xf;
msg[2] = 0x40000000; // IOCTL context
- msg[3] = (u32)reply;
+ if (sizeof(reply) > sizeof(u32)) {
+ spin_lock_irqsave(pHba->host->host_lock, flags);
+ for (i = 0; i < (sizeof(pHba->ioctl_reply_context) / sizeof(pHba->ioctl_reply_context[0])); ++i) {
+ if (pHba->ioctl_reply_context[i] == NULL) {
+ pHba->ioctl_reply_context[i] = reply;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(pHba->host->host_lock, flags);
+ if (i >= (sizeof(pHba->ioctl_reply_context) / sizeof(pHba->ioctl_reply_context[0]))) {
+ kfree (reply);
+ printk(KERN_WARNING"%s: Too many outstanding ioctl commands\n",pHba->name);
+ return -EBUSY;
+ }
+ msg[3] = i;
+ } else
+ msg[3] = (u32)reply; // EVIL, not 64 bit safe
memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize);
if(sg_offset) {
- // TODO 64bit fix
+ // TODO 64 bit fix ?
struct sg_simple_element *sg = (struct sg_simple_element*) (msg+sg_offset);
sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
if (sg_count > pHba->sg_tablesize){
@@ -1673,7 +1799,7 @@
}
sg_size = sg[i].flag_count & 0xffffff;
/* Allocate memory for the transfer */
- p = (ulong)kmalloc(sg_size, GFP_KERNEL|ADDR32);
+ p = pci_alloc_consistent(pHba->pDev, sg_size, &addr);
if(p == 0) {
printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
pHba->name,sg_size,i,sg_count);
@@ -1681,9 +1807,15 @@
goto cleanup;
}
sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
+ if( (sizeof(dma_addr_t) > 4) && (pHba->pae_support) && (((u64)addr >> 32) != 0) ) {
+ printk(KERN_DEBUG"%s: Could not allocate SG buffer in 32 space - size = %d buffer number %d of %d\n",
+ pHba->name,sg_size,i,sg_count);
+ rcode = -ENOMEM;
+ goto cleanup;
+ }
/* Copy in the user's SG buffer if necessary */
if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
- // TODO 64bit fix
+ // TODO 64 bit fix?
if (copy_from_user((void*)p,(void*)sg[i].addr_bus, sg_size)) {
printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);
rcode = -EFAULT;
@@ -1691,7 +1823,7 @@
}
}
//TODO 64bit fix
- sg[i].addr_bus = (u32)virt_to_bus((void*)p);
+ sg[i].addr_bus = cpu_to_le32(addr);
}
}
@@ -1741,8 +1873,8 @@
if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {
sg_size = sg[j].flag_count & 0xffffff;
// TODO 64bit fix
- if (copy_to_user((void*)sg[j].addr_bus,(void*)sg_list[j], sg_size)) {
- printk(KERN_WARNING"%s: Could not copy %lx TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
+ if (copy_to_user((void*)sg[j].addr_bus,sg_list[j], sg_size)) {
+ printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
rcode = -EFAULT;
goto cleanup;
}
@@ -1765,10 +1897,13 @@
cleanup:
- kfree (reply);
- while(sg_index) {
- if(sg_list[--sg_index]) {
- kfree((void*)(sg_list[sg_index]));
+ 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]) {
+ pci_free_consistent(pHba->pDev, sg[sg_index].flag_count & 0xffffff, sg_list[sg_index], le32_to_cpu(sg[sg_index].addr_bus));
+ }
}
}
return rcode;
@@ -1796,11 +1931,11 @@
#if defined __i386__
adpt_i386_info(&si);
-#elif defined (__ia64__)
+#elif defined __ia64__
adpt_ia64_info(&si);
-#elif defined(__sparc__)
+#elif defined __sparc__
adpt_sparc_info(&si);
-#elif defined (__alpha__)
+#elif defined __alpha__
adpt_alpha_info(&si);
#else
si.processorType = 0xff ;
@@ -1819,7 +1954,7 @@
// 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 = PROC_ITANIUM;
}
#endif
@@ -1894,7 +2029,7 @@
}
while((volatile u32) pHba->state & DPTI_STATE_RESET ) {
- set_task_state(current,TASK_UNINTERRUPTIBLE);
+ set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(2);
}
@@ -1949,6 +2084,28 @@
case I2ORESCANCMD:
adpt_rescan(pHba);
break;
+ case DPT_TARGET_BUSY & 0xFFFF:
+ case DPT_TARGET_BUSY:
+ {
+ TARGET_BUSY_T busy;
+ struct adpt_device* d;
+
+ if (copy_from_user((void*)&busy, (void*)arg, sizeof(TARGET_BUSY_T))) {
+ return -EFAULT;
+ }
+
+ d = adpt_find_device(pHba, busy.channel, busy.id, busy.lun);
+ if(d == NULL){
+ return -ENODEV;
+ }
+ busy.isBusy = ((d->pScsi_dev)
+ && (d->pScsi_dev->device_busy /* Imperfect */
+ || test_bit(SHOST_RECOVERY, &pHba->host->shost_state)));
+ if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
+ return -EFAULT;
+ }
+ break;
+ }
default:
return -EINVAL;
}
@@ -1956,77 +2113,126 @@
return error;
}
+static inline Scsi_Cmnd * adpt_cmd_from_context(adpt_hba * pHba, u32 context)
+{
+ Scsi_Cmnd * cmd;
+
+ if (context == 0)
+ return NULL;
+ if (sizeof(cmd) > sizeof(u32)) {
+ Scsi_Device * d;
+ shost_for_each_device(d, pHba->host) {
+ unsigned long flags;
+ spin_lock_irqsave(&d->list_lock, flags);
+ list_for_each_entry(cmd, &d->cmd_list, list) {
+ if (((u32)cmd->serial_number == context)
+ || ((u32)cmd->serial_number_at_timeout == context)) {
+ spin_unlock_irqrestore(&d->list_lock, flags);
+ return cmd;
+ }
+ }
+ spin_unlock_irqrestore(&d->list_lock, flags);
+ }
+ } else
+ return (Scsi_Cmnd*) context; /* 64 bit! */
+ return NULL;
+}
-static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
{
Scsi_Cmnd* cmd;
adpt_hba* pHba = dev_id;
u32 m;
- ulong reply;
+ u8 * reply = (u8 *)-1L;
u32 status=0;
u32 context;
ulong flags = 0;
if (pHba == NULL ){
printk(KERN_WARNING"adpt_isr: NULL dev_id\n");
- return;
+ return IRQ_NONE;
}
- spin_lock_irqsave(pHba->host->host_lock, flags);
- while( readl(pHba->irq_mask) & I2O_INTERRUPT_PENDING_B) {
+ if (pHba->host != NULL) /* Sad */
+ spin_lock_irqsave(pHba->host->host_lock, flags);
+ while( readl(pHba->irq_mask) & cpu_to_le32(I2O_INTERRUPT_PENDING_B)) {
m = readl(pHba->reply_port);
- if(m == EMPTY_QUEUE){
+ if(m == cpu_to_le32(EMPTY_QUEUE)){
// Try twice then give up
rmb();
m = readl(pHba->reply_port);
- if(m == EMPTY_QUEUE){
+ if(m == cpu_to_le32(EMPTY_QUEUE)){
// This really should not happen
printk(KERN_ERR"dpti: Could not get reply frame\n");
goto out;
}
}
- reply = (ulong)bus_to_virt(m);
+ if ((pHba->reply_pool_pa <= le32_to_cpu(m))
+ && (le32_to_cpu(m) < (pHba->reply_pool_pa + (pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4)))) {
+ reply = ((u8 *)pHba->reply_pool_va) + (le32_to_cpu(m) - pHba->reply_pool_pa);
+ } else {
+ /* Ick, we should *never* be here */
+ printk(KERN_ERR"dpti: replay frame not from pool\n");
+ reply = (u8 *)bus_to_virt(le32_to_cpu(m));
+ }
- if (readl(reply) & MSG_FAIL) {
+ if (readl(reply) & cpu_to_le32(MSG_FAIL)) {
u32 old_m = readl(reply+28);
- ulong msg;
+ char * msg;
u32 old_context;
PDEBUG("%s: Failed message\n",pHba->name);
- if(old_m >= 0x100000){
+ if(le32_to_cpu(old_m) >= 0x100000){
printk(KERN_ERR"%s: Bad preserved MFA (%x)- dropping frame\n",pHba->name,old_m);
writel(m,pHba->reply_port);
continue;
}
// Transaction context is 0 in failed reply frame
- msg = (ulong)(pHba->msg_addr_virt + old_m);
+ msg = pHba->msg_addr_virt + le32_to_cpu(old_m);
old_context = readl(msg+12);
writel(old_context, reply+12);
adpt_send_nop(pHba, old_m);
}
context = readl(reply+8);
if(context & 0x40000000){ // IOCTL
- ulong p = (ulong)(readl(reply+12));
+ u32 context = readl(reply+12);
+ void * p;
+ if (sizeof(reply) > sizeof(u32)) {
+ p = pHba->ioctl_reply_context[context];
+ pHba->ioctl_reply_context[context] = NULL;
+ } else
+ p = (void *)(readl(reply+12));
if( p != 0) {
- memcpy((void*)p, (void*)reply, REPLY_FRAME_SIZE * 4);
+ memcpy_fromio(p, (void*)reply, REPLY_FRAME_SIZE * 4);
}
// All IOCTLs will also be post wait
}
if(context & 0x80000000){ // Post wait message
- status = readl(reply+16);
+ status = le32_to_cpu(readl(reply+16));
if(status >> 24){
status &= 0xffff; /* Get detail status */
} else {
status = I2O_POST_WAIT_OK;
}
if(!(context & 0x40000000)) {
- cmd = (Scsi_Cmnd*) readl(reply+12);
+ cmd = adpt_cmd_from_context (pHba, readl(reply+12));
if(cmd != NULL) {
printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
}
}
adpt_i2o_post_wait_complete(context, status);
} else { // SCSI message
- cmd = (Scsi_Cmnd*) readl(reply+12);
+ cmd = adpt_cmd_from_context (pHba, readl(reply+12));
if(cmd != NULL){
+ if(cmd->use_sg)
+ pci_unmap_sg(pHba->pDev,
+ (struct scatterlist *)cmd->buffer,
+ cmd->use_sg,
+ scsi_to_pci_dma_dir(cmd->sc_data_direction));
+ else if(cmd->request_bufflen)
+ pci_unmap_single(pHba->pDev,
+ cmd->SCp.dma_handle,
+ cmd->request_bufflen,
+ scsi_to_pci_dma_dir(cmd->sc_data_direction));
+
if(cmd->serial_number != 0) { // If not timedout
adpt_i2o_to_scsi(reply, cmd);
}
@@ -2036,7 +2242,14 @@
wmb();
rmb();
}
-out: spin_unlock_irqrestore(pHba->host->host_lock, flags);
+out:
+ if (pHba->host != NULL) /* Sad */
+ spin_unlock_irqrestore(pHba->host->host_lock, flags);
+ if (reply == (u8 *)-1) {
+ return IRQ_NONE;
+ }
+ return IRQ_HANDLED;
+
}
static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d)
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
2004-02-10 20:53 Salyzyn, Mark
@ 2004-02-10 21:21 ` Christoph Hellwig
0 siblings, 0 replies; 11+ messages in thread
From: Christoph Hellwig @ 2004-02-10 21:21 UTC (permalink / raw)
To: Salyzyn, Mark; +Cc: linux-scsi
+#if (defined(__x86_64__))
+# include <asm-x86_64/ioctl32.h>
+#endif
This is broken. Please use the generic ioctl32 facilities.
-static struct i2o_sys_tbl *sys_tbl = NULL;
+static struct i2o_sys_tbl *sys_tbl_va = NULL;
No need to NULL-initialize this..
+// If this is driver is embedded in the kernel this define
+// should be moved to include/linux/proc_fs.h as an emumerated type
+#define PROC_SCSI_DPT_I2O 0
+struct proc_dir_entry proc_scsi_dptI2O = {
+ PROC_SCSI_DPT_I2O, 7, DPT_DRIVER,
+ S_IFDIR | S_IRUGO | S_IXUGO, 2,
+ 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
This seems unused, and if it wasn't it would be a bug.
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){
+ /* search for all Adaptec I2O RAID cards */
+ while ((pDev = pci_find_device( dptids[0].vendor, PCI_ANY_ID, pDev))) {
+ if(pDev->device == dptids[0].device ||
+ pDev->device == dptids[1].device){
This screams for using a proper pci_driver interface..
+ /*
+ * We are called before the host & host lock has been
+ * assigned, and may be called with, or without, the host lock
+ * held. We need to free the lock, if held, before going
+ * to sleep.
+ */
+ if ((pHba->host != NULL) /* Sad */
+ && (spin_is_locked(pHba->host->host_lock))) {
This is bogus as hell. Who said you took the lock?
+ case DPT_TARGET_BUSY & 0xFFFF:
+ case DPT_TARGET_BUSY:
+ {
+ TARGET_BUSY_T busy;
+ struct adpt_device* d;
+
+ if (copy_from_user((void*)&busy, (void*)arg, sizeof(TARGET_BUSY_T))) {
+ return -EFAULT;
+ }
+
+ d = adpt_find_device(pHba, busy.channel, busy.id, busy.lun);
+ if(d == NULL){
+ return -ENODEV;
+ }
+ busy.isBusy = ((d->pScsi_dev)
+ && (d->pScsi_dev->device_busy /* Imperfect */
+ || test_bit(SHOST_RECOVERY, &pHba->host->shost_state)));
+ if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
+ return -EFAULT;
+ }
+ break;
+ }
This ioctl was removed because it's broken. Don't readd it.
+ shost_for_each_device(d, pHba->host) {
+ unsigned long flags;
+ spin_lock_irqsave(&d->list_lock, flags);
+ list_for_each_entry(cmd, &d->cmd_list, list) {
+ if (((u32)cmd->serial_number == context)
+ || ((u32)cmd->serial_number_at_timeout == context)) {
+ spin_unlock_irqrestore(&d->list_lock, flags);
+ return cmd;
Where do release the reference to the scsi_device again?
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
@ 2004-02-10 21:47 Salyzyn, Mark
0 siblings, 0 replies; 11+ messages in thread
From: Salyzyn, Mark @ 2004-02-10 21:47 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
Responses embedded with [MS]
Thanks!
Sincerely -- Mark Salyzyn
-----Original Message-----
From: Christoph Hellwig [mailto:hch@infradead.org]
Sent: Tuesday, February 10, 2004 4:22 PM
To: Salyzyn, Mark
Cc: linux-scsi
Subject: Re: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64
bit and bitrot (part 1)
+#if (defined(__x86_64__))
+# include <asm-x86_64/ioctl32.h>
+#endif
This is broken. Please use the generic ioctl32 facilities.
[MS] baby steps perhaps. This *worked* with the 32 bit configuration
utilities under an AMD-64 machine using a 2.4 based kernel and we are
merely seeing me poluting code coming in from the 2.4 tree. I had a ToDo
in order to investigate IA64 support and application function under the
2.6 kernel.
-static struct i2o_sys_tbl *sys_tbl = NULL;
+static struct i2o_sys_tbl *sys_tbl_va = NULL;
No need to NULL-initialize this..
[MS] no disagreement here!
+// If this is driver is embedded in the kernel this define
+// should be moved to include/linux/proc_fs.h as an emumerated type
+#define PROC_SCSI_DPT_I2O 0
+struct proc_dir_entry proc_scsi_dptI2O = {
+ PROC_SCSI_DPT_I2O, 7, DPT_DRIVER,
+ S_IFDIR | S_IRUGO | S_IXUGO, 2,
+ 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
This seems unused, and if it wasn't it would be a bug.
PINFO("Detecting Adaptec I2O RAID controllers...\n");
[MS] I am unsure of the origin of this change, could be dropped I am
sure.
- /* 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){
+ /* search for all Adaptec I2O RAID cards */
+ while ((pDev = pci_find_device( dptids[0].vendor, PCI_ANY_ID,
pDev))) {
+ if(pDev->device == dptids[0].device ||
+ pDev->device == dptids[1].device){
This screams for using a proper pci_driver interface..
[MS] on the to-do list. This patch is already big enough just to '64bit'
enable the driver.
+ /*
+ * We are called before the host & host lock has
been
+ * assigned, and may be called with, or without, the
host lock
+ * held. We need to free the lock, if held, before going
+ * to sleep.
+ */
+ if ((pHba->host != NULL) /* Sad */
+ && (spin_is_locked(pHba->host->host_lock))) {
This is bogus as hell. Who said you took the lock?
[MS] without this code (under the 2.4 tree) I had a lockup. I did not
check that this problem existed under the 2.6 tree, simply mimicking the
innocuous 2.4ism. This would need to be tested when removed
+ case DPT_TARGET_BUSY & 0xFFFF:
+ case DPT_TARGET_BUSY:
+ {
+ TARGET_BUSY_T busy;
+ struct adpt_device* d;
+
+ if (copy_from_user((void*)&busy, (void*)arg,
sizeof(TARGET_BUSY_T))) {
+ return -EFAULT;
+ }
+
+ d = adpt_find_device(pHba, busy.channel, busy.id,
busy.lun);
+ if(d == NULL){
+ return -ENODEV;
+ }
+ busy.isBusy = ((d->pScsi_dev)
+ && (d->pScsi_dev->device_busy /* Imperfect */
+ || test_bit(SHOST_RECOVERY,
&pHba->host->shost_state)));
+ if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
+ return -EFAULT;
+ }
+ break;
+ }
This ioctl was removed because it's broken. Don't readd it.
[MS] the applications need this ... without this the user is *not*
warned when they perform dangerous raid manipulations when the device is
in use, or for that matter currently in error recovery. Suggestions to
re-enable this support in the 2.6 tree?
+ shost_for_each_device(d, pHba->host) {
+ unsigned long flags;
+ spin_lock_irqsave(&d->list_lock, flags);
+ list_for_each_entry(cmd, &d->cmd_list, list) {
+ if (((u32)cmd->serial_number == context)
+ || ((u32)cmd->serial_number_at_timeout
== context)) {
+
spin_unlock_irqrestore(&d->list_lock, flags);
+ return cmd;
Where do release the reference to the scsi_device again?
[MS] Eeek. I may need some 'splaining here. Am I using the
shost_for_each_device interface incorrectly? We are using
__shost_for_each_device in the aacraid driver ...
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
@ 2004-04-05 17:56 Salyzyn, Mark
2004-04-05 20:47 ` Christoph Hellwig
0 siblings, 1 reply; 11+ messages in thread
From: Salyzyn, Mark @ 2004-04-05 17:56 UTC (permalink / raw)
To: linux-scsi; +Cc: Christoph Hellwig
We need a means for an application to tell if a scsi device is currently
in use; one of in-error or with any I/O still pending or opened or
mounted. This is necessary to inform users of the RAID management
applications that the device is not to be adjusted.
In-error is easy enough, test_bit(SHOST_RECOVERY,
&pHba->host->host_state) for 2.6, and pHba->host->in_recovery for 2.4.
I/O pending can be determined with Scsi_Device::access_count for 2.6.
Unfortunately new members like struct scsi_disk::openers are
inaccessible to the scsi driver to indicate whether there are any
applications that have the scsi device open.
This is complicated further if the device is accessed via the sg layer
as well (sd's openers does not meter sg's openers).
Are there any suggestions, either for the application, or for the scsi
driver to meter disk in-use? Without this, it is *impossible* for us to
support reliable native RAID management applications; a user application
should *never* be a source of an OS panic (whether it be someone
destroying the boot array, or simply a file system driver panicking when
a device no longer exists)
Sincerely -- Mark Salyzyn
-----Original Message-----
From: Christoph Hellwig [mailto:hch@infradead.org]
Sent: Tuesday, February 10, 2004 4:22 PM
To: Salyzyn, Mark
Cc: linux-scsi
Subject: Re: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64
bit and bitrot (part 1)
< snip >
+ case DPT_TARGET_BUSY & 0xFFFF:
+ case DPT_TARGET_BUSY:
+ {
+ TARGET_BUSY_T busy;
+ struct adpt_device* d;
+
+ if (copy_from_user((void*)&busy, (void*)arg,
sizeof(TARGET_BUSY_T))) {
+ return -EFAULT;
+ }
+
+ d = adpt_find_device(pHba, busy.channel, busy.id,
busy.lun);
+ if(d == NULL){
+ return -ENODEV;
+ }
+ busy.isBusy = ((d->pScsi_dev)
+ && (d->pScsi_dev->device_busy /* Imperfect */
+ || test_bit(SHOST_RECOVERY,
&pHba->host->shost_state)));
+ if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
+ return -EFAULT;
+ }
+ break;
+ }
This ioctl was removed because it's broken. Don't readd it.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
2004-04-05 17:56 Salyzyn, Mark
@ 2004-04-05 20:47 ` Christoph Hellwig
0 siblings, 0 replies; 11+ messages in thread
From: Christoph Hellwig @ 2004-04-05 20:47 UTC (permalink / raw)
To: Salyzyn, Mark; +Cc: linux-scsi, Christoph Hellwig
On Mon, Apr 05, 2004 at 01:56:12PM -0400, Salyzyn, Mark wrote:
> We need a means for an application to tell if a scsi device is currently
> in use; one of in-error or with any I/O still pending or opened or
> mounted. This is necessary to inform users of the RAID management
> applications that the device is not to be adjusted.
We had this a few times already. If your applications wants to remove
a volume it'll do exactly that, and that's expected behaviour in unix
land where you have enough rope to shoot yourself in the foot.
> Unfortunately new members like struct scsi_disk::openers are
> inaccessible to the scsi driver to indicate whether there are any
> applications that have the scsi device open.
Which is intentional as the opencount of one particular upperlevel driver
has absolutely no meaning for a LLDD.
> Are there any suggestions, either for the application, or for the scsi
> driver to meter disk in-use?
The simple answer is: don't do it.
> Without this, it is *impossible* for us to
> support reliable native RAID management applications; a user application
> should *never* be a source of an OS panic (whether it be someone
> destroying the boot array, or simply a file system driver panicking when
> a device no longer exists)
A filesystem should not panic when the underlying device is offlines or
removed. At least XFS doesn't and if some other fs does file a bug
against it.
As for userland tools making the system unsuable, try a simple
cat /dev/zero > /dev/kmem
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
@ 2004-04-05 22:23 Salyzyn, Mark
2004-04-06 5:20 ` Christoph Hellwig
2004-04-06 14:48 ` Matthew Wilcox
0 siblings, 2 replies; 11+ messages in thread
From: Salyzyn, Mark @ 2004-04-05 22:23 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
Christoph Hellwig [mailto:hch@infradead.org] writes:
>On Mon, Apr 05, 2004 at 01:56:12PM -0400, Salyzyn, Mark wrote:
>> We need a means for an application to tell if a scsi device is
>> currently in use; one of in-error or with any I/O still pending or
>> opened or mounted.
>We had this a few times already. If your applications wants to remove
a >volume it'll do exactly that, and that's expected behaviour in unix
land >where you have enough rope to shoot yourself in the foot.
You mean Linux land, all other operating systems, other UNIXii included,
offer the ability to determine if a device is in-use in a timely manner.
Does this mean Windoze has a feature that Linux does not have?
What about something more generic than being in scsi LLDD land, pick a
level ... however we do need to know if *any* of the possible slices for
a scsi addressed device object are in use, not just the individual
device exports.
static int fn(struct device * dev, void * arg)
{
busy_arg * busy = (busy_arg *)arg;
struct scsi_device * sdev = to_scsi_device(dev);
if ((busy->host_no == sdev->host->host_no)
&& (busy->channel == sdev->channel)
&& (busy->id == sdev->id)
&& (busy->lun == sdev->lun))
return magic_missing_dev_busy_check_routine(dev);
return 0;
}
. . .
static scsi_busy(host_no, channel, id, lun)
{
busy_arg busy;
busy.host_no = host_no;
busy.channel = channel;
busy.id = id;
busy.lun = lun;
return bus_for_each_device(&scsi_bus_type, NULL, &busy, fn);
}
>> Are there any suggestions, either for the application, or for the
scsi
>> driver to meter disk in-use?
>The simple answer is: don't do it.
This would be unacceptable to our OEMs and users of our applications.
The fact that an operating system can not tell us that a specific device
is currently in-use would be considered criminal operating system
behavior along the lines of not being able to determine if a network
interface is up or down or a semaphore may, or may not, be taken. We are
not making abstract paintings for a living folks ...
In user land, lsmod tells us how many users of a module exist, what is
so secret about a scsi disk devices that we are afraid of telling them
if any of the access points are being used?
> As for userland tools making the system unsuable, try a simple
>
> cat /dev/zero > /dev/kmem
Good to know ...
Sincerely -- Mark Salyzyn
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
2004-04-05 22:23 Salyzyn, Mark
@ 2004-04-06 5:20 ` Christoph Hellwig
2004-04-06 14:48 ` Matthew Wilcox
1 sibling, 0 replies; 11+ messages in thread
From: Christoph Hellwig @ 2004-04-06 5:20 UTC (permalink / raw)
To: Salyzyn, Mark; +Cc: Christoph Hellwig, linux-scsi
On Mon, Apr 05, 2004 at 06:23:49PM -0400, Salyzyn, Mark wrote:
> You mean Linux land, all other operating systems, other UNIXii included,
> offer the ability to determine if a device is in-use in a timely manner.
> Does this mean Windoze has a feature that Linux does not have?
Depends on what you call a feature. It also doesn't allow to remove in-use
files..
> This would be unacceptable to our OEMs and users of our applications.
Could you please stop this OEM crap? No one cares more for someone just
because he's an OEM. And we already had the stupid user discussion a few
times, look up the long EVMS and Aunþ Tilly threads.
> In user land, lsmod tells us how many users of a module exist, what is
> so secret about a scsi disk devices that we are afraid of telling them
> if any of the access points are being used?
For many module types lsmod can't anymore. Look at the use count of
your network driver module.
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
@ 2004-04-06 14:03 Salyzyn, Mark
2004-04-06 14:17 ` Christoph Hellwig
0 siblings, 1 reply; 11+ messages in thread
From: Salyzyn, Mark @ 2004-04-06 14:03 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
Christoph Hellwig [mailto:hch@infradead.org] writes:
> On Mon, Apr 05, 2004 at 06:23:49PM -0400, Salyzyn, Mark wrote:
>> This would be unacceptable to our OEMs and users of our applications.
> Could you please stop this OEM crap? No one cares more for someone just
> because he's an OEM. And we already had the stupid user discussion a few
> times, look up the long EVMS and Aunþ Tilly threads.
And *that* is the root of the problem ... sigh ... but I will try not take the flame bait, for what now will no doubt be an infamous statement of the goals of the Linux kernel community. I do not want to turn this into a flame war, but rather have us admit our differences and respect each other's needs.
OEMs and their users are virtually *all* we are concerned about. If we can not qualify our products within their needs, we disappear, or at least we disappear on operating systems that fail to provide for the needs of the users.
These users that are represented by us, and our OEMs, are overworked IS people, working overtime hours, most likely working remote, and I am sorry, I *need* to tell them when they make a critical mistake, in the fog of their war, that will panic their system. I need to tell them, at the *instant* of the mistake, that they are about to delete an array that is currently `in-use' by the operating system. I *really* need to tell them that they are about to incorporate their in-use, possibly boot, drive as a component of an array. I do *not* need to tell them that they are stupid.
I loose sleep at night thinking about these poor souls. No, to be honest, actually it is because our OEM's test group thinks out fantastic scenarios of ways to break yours and my products and hold us accountable for such failures. "Deleting array causes kernel ooops" news at 11 ...
Which reason do we ascribe to this failure of the operating system to provide the service of knowing if a drive is currently in-use:
1) system has been architected in such a manner that it would be impossible at this juncture to add?
2) Someone made a conscientious decision to not provide this functionality?
3) There is a way to tell, it just is not clear to any of us at this moment?
4) There is a way to tell, but it would be an ugly hack that will no doubt break upon the next revision (as this hack has done traversing from 2.4 to 2.6)?
5) Pride?
Sincerely -- Mark Salyzyn
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
2004-04-06 14:03 [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1) Salyzyn, Mark
@ 2004-04-06 14:17 ` Christoph Hellwig
0 siblings, 0 replies; 11+ messages in thread
From: Christoph Hellwig @ 2004-04-06 14:17 UTC (permalink / raw)
To: Salyzyn, Mark; +Cc: linux-scsi
On Tue, Apr 06, 2004 at 10:03:58AM -0400, Salyzyn, Mark wrote:
> OEMs and their users are virtually *all* we are concerned about. If we can not qualify our products within their needs, we disappear, or at least we disappear on operating systems that fail to provide for the needs of the users.
Well, bad luck for adaptec then. It's not like there aren't other RAID HBA
vendors.
> I loose sleep at night thinking about these poor souls. No, to be honest, actually it is because our OEM's test group thinks out fantastic scenarios of ways to break yours and my products and hold us accountable for such failures. "Deleting array causes kernel ooops" news at 11 ...
Again, where do you see that oops? if I remove the lun under a filesystem
that one spews EIO all over and becomes unusable. But if you get a panic
that's a bug in the filesystem driver.
> Which reason do we ascribe to this failure of the operating system to provide the service of knowing if a drive is currently in-use:
>
> 1) system has been architected in such a manner that it would be impossible at this juncture to add?
> 2) Someone made a conscientious decision to not provide this functionality?
> 3) There is a way to tell, it just is not clear to any of us at this moment?
> 4) There is a way to tell, but it would be an ugly hack that will no doubt break upon the next revision (as this hack has done traversing from 2.4 to 2.6)?
> 5) Pride?
There is a way to tell whether it's inuse, but it's a different defintion of
inuse than you want, and it's not a public interface so it could break all
the time. Probably as soon as some out of tree driver gets the bright idea
to use it inspite everyone telling them not to.
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
@ 2004-04-06 14:47 Salyzyn, Mark
0 siblings, 0 replies; 11+ messages in thread
From: Salyzyn, Mark @ 2004-04-06 14:47 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
Christoph Hellwig [mailto:hch@infradead.org] writes:
> On Tue, Apr 06, 2004 at 10:03:58AM -0400, Salyzyn, Mark wrote:
>> OEMs and their users are virtually *all* we are concerned about. If
>> we can not qualify our products within their needs, we disappear, or
>> at least we disappear on operating systems that fail to provide for
>> the needs of the users.
>Well, bad luck for adaptec then. It's not like there aren't other RAID
HBA
>vendors.
Remember DPT? Thanks for all the Fish ...
These competitors have the same problem !!!
The failure is not bad luck for the storage vendors, but bad luck for
the users and those that think Linux can survive without users. I
represent the users, not Storage Vendors.
>> I loose sleep at night thinking about these poor souls. No, to be
>> honest, actually it is because our OEM's test group thinks out
>> fantastic scenarios of ways to break yours and my products and hold
>> us accountable for such failures. "Deleting array causes kernel
>> ooops" news at 11 ...
>Again, where do you see that oops? if I remove the lun under a
>filesystem that one spews EIO all over and becomes unusable. But if
>you get a panic that's a bug in the filesystem driver.
Ooops, system lockup, system unusable, panic, dogs and cats sleeping
with eachother; it doesn't matter the semantics of the failure. The bug
is that the OS provided no means to avert the disaster. One of the major
precepts of user interface design is the ability to predict what a
specific action will take when taken. The OS is not predictable in this
case, and as such can not end up earning our trust.
An untrusted OS is an unused OS.
>> Which reason do we ascribe to this failure of the operating system to
provide the service of knowing if a drive is currently in-use:
>>
>> 1) system has been architected in such a manner that it would be
impossible at this juncture to add?
>> 2) Someone made a conscientious decision to not provide this
functionality?
>> 3) There is a way to tell, it just is not clear to any of us at this
moment?
>> 4) There is a way to tell, but it would be an ugly hack that will no
doubt break upon the next revision (as this hack has done traversing
from 2.4 to 2.6)?
>> 5) Pride?
>There is a way to tell whether it's inuse, but it's a different
definition
>of inuse than you want, and it's not a public interface so it could
break
>all the time. Probably as soon as some out of tree driver gets the
bright
>idea to use it inspite everyone telling them not to.
BTW, name calling like `out of tree driver' had me rotfl. I would like
to point out that the dpt_i2o driver is currently unusable in the tree
and is disabled. The only driver that works is the one I provide to the
community for the asking ...
Ok, so it is a mix of #1 (because it can not be fixed reliably) and #4
(we hate hacks around system deficiencies). Are you sure we can not
provide a reliable defined interface for this service?
Sincerely -- Mark Salyzyn
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1)
2004-04-05 22:23 Salyzyn, Mark
2004-04-06 5:20 ` Christoph Hellwig
@ 2004-04-06 14:48 ` Matthew Wilcox
1 sibling, 0 replies; 11+ messages in thread
From: Matthew Wilcox @ 2004-04-06 14:48 UTC (permalink / raw)
To: Salyzyn, Mark; +Cc: Christoph Hellwig, linux-scsi
On Mon, Apr 05, 2004 at 06:23:49PM -0400, Salyzyn, Mark wrote:
> Does this mean Windoze has a feature that Linux does not have?
*yawn* *plonk*
--
"Next the statesmen will invent cheap lies, putting the blame upon
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince
himself that the war is just, and will thank God for the better sleep
he enjoys after this process of grotesque self-deception." -- Mark Twain
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2004-04-06 14:48 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-04-06 14:03 [PATCH] dpt_i2o changes for 2.6.2 kernel in support of 64 bit and bitrot (part 1) Salyzyn, Mark
2004-04-06 14:17 ` Christoph Hellwig
-- strict thread matches above, loose matches on Subject: below --
2004-04-06 14:47 Salyzyn, Mark
2004-04-05 22:23 Salyzyn, Mark
2004-04-06 5:20 ` Christoph Hellwig
2004-04-06 14:48 ` Matthew Wilcox
2004-04-05 17:56 Salyzyn, Mark
2004-04-05 20:47 ` Christoph Hellwig
2004-02-10 21:47 Salyzyn, Mark
2004-02-10 20:53 Salyzyn, Mark
2004-02-10 21:21 ` Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox