Commit 11741f8a authored by Andrew Morton's avatar Andrew Morton Committed by James Bottomley

[PATCH] Fix dpt_i2o

From: Go Taniguchi <go@turbolinux.co.jp>

Make it build (and work) again.
parent 1b51f242
...@@ -363,7 +363,7 @@ source "drivers/scsi/aic7xxx/Kconfig.aic79xx" ...@@ -363,7 +363,7 @@ source "drivers/scsi/aic7xxx/Kconfig.aic79xx"
# All the I2O code and drivers do not seem to be 64bit safe. # All the I2O code and drivers do not seem to be 64bit safe.
config SCSI_DPT_I2O config SCSI_DPT_I2O
tristate "Adaptec I2O RAID support " tristate "Adaptec I2O RAID support "
depends on !64BIT && SCSI && BROKEN depends on !64BIT && SCSI
help help
This driver supports all of Adaptec's I2O based RAID controllers as This driver supports all of Adaptec's I2O based RAID controllers as
well as the DPT SmartRaid V cards. This is an Adaptec maintained well as the DPT SmartRaid V cards. This is an Adaptec maintained
......
...@@ -20,17 +20,21 @@ ...@@ -20,17 +20,21 @@
* (at your option) any later version. * * (at your option) any later version. *
* * * *
***************************************************************************/ ***************************************************************************/
/***************************************************************************
* Sat Dec 20 2003 Go Taniguchi <go@turbolinux.co.jp>
- Support 2.6 kernel and DMA-mapping
- ioctl fix for raid tools
- use schedule_timeout in long long loop
**************************************************************************/
//#define DEBUG 1 /*#define DEBUG 1 */
//#define UARTDELAY 1 /*#define UARTDELAY 1 */
// On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates /* 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 high pages. Keep the macro around because of the broken unmerged ia64 tree */
#define ADDR32 (0) #define ADDR32 (0)
#error Please convert me to Documentation/DMA-mapping.txt
#include <linux/version.h> #include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -53,6 +57,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver"); ...@@ -53,6 +57,7 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
#include <linux/kernel.h> /* for printk */ #include <linux/kernel.h> /* for printk */
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/timer.h> #include <linux/timer.h>
...@@ -86,7 +91,7 @@ static dpt_sig_S DPTI_sig = { ...@@ -86,7 +91,7 @@ static dpt_sig_S DPTI_sig = {
#elif defined(__alpha__) #elif defined(__alpha__)
PROC_ALPHA , PROC_ALPHA ,
#else #else
(-1),(-1) (-1),(-1),
#endif #endif
FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL, FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION, ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
...@@ -227,7 +232,7 @@ static int adpt_detect(Scsi_Host_Template* sht) ...@@ -227,7 +232,7 @@ static int adpt_detect(Scsi_Host_Template* sht)
/* Active IOPs now in OPERATIONAL state */ /* Active IOPs now in OPERATIONAL state */
PDEBUG("HBA's in OPERATIONAL state\n"); PDEBUG("HBA's in OPERATIONAL state\n");
printk(KERN_INFO"dpti: If you have a lot of devices this could take a few minutes.\n"); printk("dpti: If you have a lot of devices this could take a few minutes.\n");
for (pHba = hba_chain; pHba; pHba = pHba->next) { for (pHba = hba_chain; pHba; pHba = pHba->next) {
printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name); printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
if (adpt_i2o_lct_get(pHba) < 0){ if (adpt_i2o_lct_get(pHba) < 0){
...@@ -270,6 +275,7 @@ static int adpt_release(struct Scsi_Host *host) ...@@ -270,6 +275,7 @@ static int adpt_release(struct Scsi_Host *host)
adpt_hba* pHba = (adpt_hba*) host->hostdata[0]; adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
// adpt_i2o_quiesce_hba(pHba); // adpt_i2o_quiesce_hba(pHba);
adpt_i2o_delete_hba(pHba); adpt_i2o_delete_hba(pHba);
scsi_unregister(host);
return 0; return 0;
} }
...@@ -340,6 +346,8 @@ static void adpt_inquiry(adpt_hba* pHba) ...@@ -340,6 +346,8 @@ static void adpt_inquiry(adpt_hba* pHba)
if (rcode != 0) { if (rcode != 0) {
sprintf(pHba->detail, "Adaptec I2O RAID"); sprintf(pHba->detail, "Adaptec I2O RAID");
printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode); printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
if (rcode != -ETIME && rcode != -EINTR)
kfree(buf);
} else { } else {
memset(pHba->detail, 0, sizeof(pHba->detail)); memset(pHba->detail, 0, sizeof(pHba->detail));
memcpy(&(pHba->detail), "Vendor: Adaptec ", 16); memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
...@@ -348,8 +356,8 @@ static void adpt_inquiry(adpt_hba* pHba) ...@@ -348,8 +356,8 @@ static void adpt_inquiry(adpt_hba* pHba)
memcpy(&(pHba->detail[40]), " FW: ", 4); memcpy(&(pHba->detail[40]), " FW: ", 4);
memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4); memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
pHba->detail[48] = '\0'; /* precautionary */ pHba->detail[48] = '\0'; /* precautionary */
kfree(buf);
} }
kfree(buf);
adpt_i2o_status_get(pHba); adpt_i2o_status_get(pHba);
return ; return ;
} }
...@@ -479,7 +487,7 @@ static int adpt_bios_param(struct scsi_device *sdev, struct block_device *dev, ...@@ -479,7 +487,7 @@ static int adpt_bios_param(struct scsi_device *sdev, struct block_device *dev,
heads = 255; heads = 255;
sectors = 63; sectors = 63;
} }
cylinders = capacity / (heads * sectors); cylinders = sector_div(capacity, heads * sectors);
// Special case if CDROM // Special case if CDROM
if(sdev->type == 5) { // CDROM if(sdev->type == 5) { // CDROM
...@@ -872,6 +880,9 @@ static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) ...@@ -872,6 +880,9 @@ static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev)
return -EINVAL; return -EINVAL;
} }
pci_set_master(pDev); pci_set_master(pDev);
if (pci_set_dma_mask(pDev, 0xffffffffffffffffULL) &&
pci_set_dma_mask(pDev, 0xffffffffULL))
return -EINVAL;
base_addr0_phys = pci_resource_start(pDev,0); base_addr0_phys = pci_resource_start(pDev,0);
hba_map0_area_size = pci_resource_len(pDev,0); hba_map0_area_size = pci_resource_len(pDev,0);
...@@ -964,6 +975,7 @@ static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) ...@@ -964,6 +975,7 @@ static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev)
// Initializing the spinlocks // Initializing the spinlocks
spin_lock_init(&pHba->state_lock); spin_lock_init(&pHba->state_lock);
spin_lock_init(&adpt_post_wait_lock);
if(raptorFlag == 0){ 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 %lx size=%x irq=%d\n",
...@@ -1065,7 +1077,7 @@ static int adpt_init(void) ...@@ -1065,7 +1077,7 @@ static int adpt_init(void)
{ {
int i; int i;
printk(KERN_INFO"Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
for (i = 0; i < DPTI_MAX_HBA; i++) { for (i = 0; i < DPTI_MAX_HBA; i++) {
hbas[i] = NULL; hbas[i] = NULL;
} }
...@@ -1153,12 +1165,22 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout) ...@@ -1153,12 +1165,22 @@ static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
timeout *= HZ; timeout *= HZ;
if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){ if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irq(pHba->host->host_lock); if(pHba->host)
spin_unlock_irq(pHba->host->host_lock);
if (!timeout) if (!timeout)
schedule(); schedule();
else else{
timeout = schedule_timeout(timeout);
if (timeout == 0) {
// I/O issued, but cannot get result in
// specified time. Freeing resorces is
// dangerous.
status = -ETIME;
}
schedule_timeout(timeout*HZ); schedule_timeout(timeout*HZ);
spin_lock_irq(pHba->host->host_lock); }
if(pHba->host)
spin_lock_irq(pHba->host->host_lock);
} }
spin_lock_irq(&adpt_wq_i2o_post.lock); spin_lock_irq(&adpt_wq_i2o_post.lock);
__remove_wait_queue(&adpt_wq_i2o_post, &wait); __remove_wait_queue(&adpt_wq_i2o_post, &wait);
...@@ -1210,6 +1232,8 @@ static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len) ...@@ -1210,6 +1232,8 @@ static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit); printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while(m == EMPTY_QUEUE); } while(m == EMPTY_QUEUE);
msg = (u32*) (pHba->msg_addr_virt + m); msg = (u32*) (pHba->msg_addr_virt + m);
...@@ -1284,6 +1308,8 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) ...@@ -1284,6 +1308,8 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
printk(KERN_WARNING"Timeout waiting for message!\n"); printk(KERN_WARNING"Timeout waiting for message!\n");
return -ETIMEDOUT; return -ETIMEDOUT;
} }
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while (m == EMPTY_QUEUE); } while (m == EMPTY_QUEUE);
status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32); status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
...@@ -1315,6 +1341,8 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) ...@@ -1315,6 +1341,8 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
rmb(); rmb();
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} }
if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) { if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
...@@ -1331,6 +1359,8 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba) ...@@ -1331,6 +1359,8 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name); printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while (m == EMPTY_QUEUE); } while (m == EMPTY_QUEUE);
// Flush the offset // Flush the offset
adpt_send_nop(pHba, m); adpt_send_nop(pHba, m);
...@@ -1696,15 +1726,20 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32* arg) ...@@ -1696,15 +1726,20 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32* arg)
} }
do { do {
spin_lock_irqsave(pHba->host->host_lock, flags); if(pHba->host)
spin_lock_irqsave(pHba->host->host_lock, flags);
// This state stops any new commands from enterring the // This state stops any new commands from enterring the
// controller while processing the ioctl // controller while processing the ioctl
// pHba->state |= DPTI_STATE_IOCTL; // pHba->state |= DPTI_STATE_IOCTL;
// We can't set this now - The scsi subsystem sets host_blocked and // We can't set this now - The scsi subsystem sets host_blocked and
// the queue empties and stops. We need a way to restart the queue // the queue empties and stops. We need a way to restart the queue
rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER); rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
if (rcode != 0)
printk("adpt_i2o_passthru: post wait failed %d %p\n",
rcode, reply);
// pHba->state &= ~DPTI_STATE_IOCTL; // pHba->state &= ~DPTI_STATE_IOCTL;
spin_unlock_irqrestore(pHba->host->host_lock, flags); if(pHba->host)
spin_unlock_irqrestore(pHba->host->host_lock, flags);
} while(rcode == -ETIMEDOUT); } while(rcode == -ETIMEDOUT);
if(rcode){ if(rcode){
...@@ -1765,10 +1800,12 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32* arg) ...@@ -1765,10 +1800,12 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32* arg)
cleanup: cleanup:
kfree (reply); if (rcode != -ETIME && rcode != -EINTR)
kfree (reply);
while(sg_index) { while(sg_index) {
if(sg_list[--sg_index]) { if(sg_list[--sg_index]) {
kfree((void*)(sg_list[sg_index])); if (rcode != -ETIME && rcode != -EINTR)
kfree((void*)(sg_list[sg_index]));
} }
} }
return rcode; return rcode;
...@@ -1876,7 +1913,7 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ...@@ -1876,7 +1913,7 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
int minor; int minor;
int error = 0; int error = 0;
adpt_hba* pHba; adpt_hba* pHba;
ulong flags; ulong flags = 0;
minor = iminor(inode); minor = iminor(inode);
if (minor >= DPTI_MAX_HBA){ if (minor >= DPTI_MAX_HBA){
...@@ -1942,9 +1979,11 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ...@@ -1942,9 +1979,11 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
break; break;
} }
case I2ORESETCMD: case I2ORESETCMD:
spin_lock_irqsave(pHba->host->host_lock, flags); if(pHba->host)
spin_lock_irqsave(pHba->host->host_lock, flags);
adpt_hba_reset(pHba); adpt_hba_reset(pHba);
spin_unlock_irqrestore(pHba->host->host_lock, flags); if(pHba->host)
spin_unlock_irqrestore(pHba->host->host_lock, flags);
break; break;
case I2ORESCANCMD: case I2ORESCANCMD:
adpt_rescan(pHba); adpt_rescan(pHba);
...@@ -1957,7 +1996,7 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ...@@ -1957,7 +1996,7 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
} }
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; Scsi_Cmnd* cmd;
adpt_hba* pHba = dev_id; adpt_hba* pHba = dev_id;
...@@ -1966,12 +2005,15 @@ static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -1966,12 +2005,15 @@ static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
u32 status=0; u32 status=0;
u32 context; u32 context;
ulong flags = 0; ulong flags = 0;
int handled = 0;
if (pHba == NULL ){ if (pHba == NULL){
printk(KERN_WARNING"adpt_isr: NULL dev_id\n"); printk(KERN_WARNING"adpt_isr: NULL dev_id\n");
return; return IRQ_NONE;
} }
spin_lock_irqsave(pHba->host->host_lock, flags); if(pHba->host)
spin_lock_irqsave(pHba->host->host_lock, flags);
while( readl(pHba->irq_mask) & I2O_INTERRUPT_PENDING_B) { while( readl(pHba->irq_mask) & I2O_INTERRUPT_PENDING_B) {
m = readl(pHba->reply_port); m = readl(pHba->reply_port);
if(m == EMPTY_QUEUE){ if(m == EMPTY_QUEUE){
...@@ -2036,7 +2078,10 @@ static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2036,7 +2078,10 @@ static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
wmb(); wmb();
rmb(); rmb();
} }
out: spin_unlock_irqrestore(pHba->host->host_lock, flags); handled = 1;
out: if(pHba->host)
spin_unlock_irqrestore(pHba->host->host_lock, flags);
return IRQ_RETVAL(handled);
} }
static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d) static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d)
...@@ -2111,15 +2156,19 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* ...@@ -2111,15 +2156,19 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device*
/* Now fill in the SGList and command */ /* Now fill in the SGList and command */
if(cmd->use_sg) { if(cmd->use_sg) {
struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer; struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
int sg_count = pci_map_sg(pHba->pDev, sg, cmd->use_sg,
scsi_to_pci_dma_dir(cmd->sc_data_direction));
len = 0; len = 0;
for(i = 0 ; i < cmd->use_sg; i++) { for(i = 0 ; i < sg_count; i++) {
*mptr++ = direction|0x10000000|sg->length; *mptr++ = direction|0x10000000|sg_dma_len(sg);
len+=sg->length; len+=sg_dma_len(sg);
*mptr++ = virt_to_bus(sg->address); *mptr++ = sg_dma_address(sg);
sg++; sg++;
} }
/* Make this an end of list */ /* Make this an end of list */
mptr[-2] = direction|0xD0000000|(sg-1)->length; mptr[-2] = direction|0xD0000000|sg_dma_len(sg-1);
reqlen = mptr - msg; reqlen = mptr - msg;
*lenptr = len; *lenptr = len;
...@@ -2133,7 +2182,10 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* ...@@ -2133,7 +2182,10 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device*
reqlen = 12; reqlen = 12;
} else { } else {
*mptr++ = 0xD0000000|direction|cmd->request_bufflen; *mptr++ = 0xD0000000|direction|cmd->request_bufflen;
*mptr++ = virt_to_bus(cmd->request_buffer); *mptr++ = pci_map_single(pHba->pDev,
cmd->request_buffer,
cmd->request_bufflen,
scsi_to_pci_dma_dir(cmd->sc_data_direction));
} }
} }
...@@ -2306,15 +2358,17 @@ static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd) ...@@ -2306,15 +2358,17 @@ static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd)
static s32 adpt_rescan(adpt_hba* pHba) static s32 adpt_rescan(adpt_hba* pHba)
{ {
s32 rcode; s32 rcode;
ulong flags; ulong flags = 0;
spin_lock_irqsave(pHba->host->host_lock, flags); if(pHba->host)
spin_lock_irqsave(pHba->host->host_lock, flags);
if ((rcode=adpt_i2o_lct_get(pHba)) < 0) if ((rcode=adpt_i2o_lct_get(pHba)) < 0)
goto out; goto out;
if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0) if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0)
goto out; goto out;
rcode = 0; rcode = 0;
out: spin_unlock_irqrestore(pHba->host->host_lock, flags); out: if(pHba->host)
spin_unlock_irqrestore(pHba->host->host_lock, flags);
return rcode; return rcode;
} }
...@@ -2596,6 +2650,8 @@ static s32 adpt_send_nop(adpt_hba*pHba,u32 m) ...@@ -2596,6 +2650,8 @@ static s32 adpt_send_nop(adpt_hba*pHba,u32 m)
printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name); printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
return 2; return 2;
} }
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} }
msg = (u32*)(pHba->msg_addr_virt + m); msg = (u32*)(pHba->msg_addr_virt + m);
writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]); writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
...@@ -2629,6 +2685,8 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) ...@@ -2629,6 +2685,8 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name); printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while(m == EMPTY_QUEUE); } while(m == EMPTY_QUEUE);
msg=(u32 *)(pHba->msg_addr_virt+m); msg=(u32 *)(pHba->msg_addr_virt+m);
...@@ -2664,9 +2722,10 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) ...@@ -2664,9 +2722,10 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
rmb(); rmb();
if(time_after(jiffies,timeout)){ if(time_after(jiffies,timeout)){
printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name); printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
kfree((void*)status);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while (1); } while (1);
// If the command was successful, fill the fifo with our reply // If the command was successful, fill the fifo with our reply
...@@ -2744,6 +2803,8 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba) ...@@ -2744,6 +2803,8 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
pHba->name); pHba->name);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} while(m==EMPTY_QUEUE); } while(m==EMPTY_QUEUE);
...@@ -2770,6 +2831,8 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba) ...@@ -2770,6 +2831,8 @@ static s32 adpt_i2o_status_get(adpt_hba* pHba)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
rmb(); rmb();
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
} }
// Set up our number of outbound and inbound messages // Set up our number of outbound and inbound messages
...@@ -3095,17 +3158,33 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid, ...@@ -3095,17 +3158,33 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
int group, int field, void *buf, int buflen) int group, int field, void *buf, int buflen)
{ {
u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field }; u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
u8 resblk[8+buflen]; /* 8 bytes for header */ u8 *resblk;
int size; int size;
/* 8 bytes for header */
resblk = kmalloc(sizeof(u8) * (8+buflen), GFP_KERNEL|ADDR32);
if (resblk == NULL) {
printk(KERN_CRIT "%s: query scalar failed; Out of memory.\n", pHba->name);
return -ENOMEM;
}
if (field == -1) /* whole group */ if (field == -1) /* whole group */
opblk[4] = -1; opblk[4] = -1;
size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid, size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid,
opblk, sizeof(opblk), resblk, sizeof(resblk)); opblk, sizeof(opblk), resblk, sizeof(u8)*(8+buflen));
if (size == -ETIME) {
printk(KERN_WARNING "%s: issue params failed; Timed out.\n", pHba->name);
return -ETIME;
} else if (size == -EINTR) {
printk(KERN_WARNING "%s: issue params failed; Interrupted.\n", pHba->name);
return -EINTR;
}
memcpy(buf, resblk+8, buflen); /* cut off header */ memcpy(buf, resblk+8, buflen); /* cut off header */
kfree(resblk);
if (size < 0) if (size < 0)
return size; return size;
...@@ -3139,6 +3218,7 @@ static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid, ...@@ -3139,6 +3218,7 @@ static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid,
msg[8] = virt_to_bus(resblk); msg[8] = virt_to_bus(resblk);
if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) { if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk);
return wait_status; /* -DetailedStatus */ return wait_status; /* -DetailedStatus */
} }
......
...@@ -65,7 +65,7 @@ static int adpt_device_reset(Scsi_Cmnd* cmd); ...@@ -65,7 +65,7 @@ static int adpt_device_reset(Scsi_Cmnd* cmd);
#include "dpt/dpti_i2o.h" #include "dpt/dpti_i2o.h"
#include "dpt/dpti_ioctl.h" #include "dpt/dpti_ioctl.h"
#define DPT_I2O_VERSION "2.4 Build 5" #define DPT_I2O_VERSION "2.4 Build 5go"
#define DPT_VERSION 2 #define DPT_VERSION 2
#define DPT_REVISION '4' #define DPT_REVISION '4'
#define DPT_SUBREVISION '5' #define DPT_SUBREVISION '5'
...@@ -272,7 +272,7 @@ struct sg_simple_element { ...@@ -272,7 +272,7 @@ struct sg_simple_element {
static void adpt_i2o_sys_shutdown(void); static void adpt_i2o_sys_shutdown(void);
static int adpt_init(void); static int adpt_init(void);
static int adpt_i2o_build_sys_table(void); static int adpt_i2o_build_sys_table(void);
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);
#ifdef REBOOT_NOTIFIER #ifdef REBOOT_NOTIFIER
static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p); static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p);
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment