From: "erich" The "arcmsr" was modified,It had followed the all comments came from linux kernel members. This driver add firmware version check and notify function for ARECA hardware bug fix. 1.20.00.09 9/12/2005 Erich Chen bug fix with abort command handling,firmware version check and firmware update notify for hardware bug fix ARECA had found a hardware bug, this bug had mention in INTEL IOP331 errata. ("DMA engine may transfer error near below 4G position") This bug could hangup Linux system. But We miss attention with it. Our Firmware version "V1.37" had fixed this bug. Signed-off-by: Andrew Morton --- drivers/scsi/Kconfig | 2 drivers/scsi/arcmsr/arcmsr.c | 1061 ++++++++++++++++++++--------------------- drivers/scsi/arcmsr/arcmsr.h | 195 +------ drivers/scsi/arcmsr/arcmsr.txt | 10 4 files changed, 598 insertions(+), 670 deletions(-) diff -puN drivers/scsi/arcmsr/arcmsr.c~areca-raid-linux-scsi-driver-update drivers/scsi/arcmsr/arcmsr.c --- 25/drivers/scsi/arcmsr/arcmsr.c~areca-raid-linux-scsi-driver-update Tue Sep 20 15:47:57 2005 +++ 25-akpm/drivers/scsi/arcmsr/arcmsr.c Tue Sep 20 15:47:57 2005 @@ -67,50 +67,45 @@ ** 1.20.00.07 3/23/2005 Erich Chen bug fix with arcmsr_scsi_host_template_init ocur segmentation fault, ** if RAID adapter does not on PCI slot and modprobe/rmmod this driver twice. ** bug fix enormous stack usage (Adrian Bunk's comment) +** 1.20.00.08 6/23/2005 Erich Chen bug fix with abort command,in case of heavy loading when sata cable +** working on low quality connection +** 1.20.00.09 9/12/2005 Erich Chen bug fix with abort command handling,firmware version check +** and firmware update notify for hardware bug fix ****************************************************************************************** */ -#define ARCMSR_DEBUG 1 -/************************************/ -#if defined __KERNEL__ -#include -#if defined( CONFIG_MODVERSIONS ) && ! defined( MODVERSIONS ) -#define MODVERSIONS -#endif - /* modversions.h should be before should be before module.h */ -#if defined( MODVERSIONS ) -#include -#endif #include -#include - /* Now your module include files & source code follows */ +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include #include #include "arcmsr.h" + +MODULE_AUTHOR("Erich Chen"); +MODULE_DESCRIPTION("ARCMSR(ARC11xx/12xx) SATA RAID HOST Adapter"); + +#ifdef MODULE_LICENSE +MODULE_LICENSE("Dual BSD/GPL"); +#endif + +#ifndef msleep +#define arc_mdelay(msec) mdelay(msec) +#define arc_mdelay_int(msec) mdelay(msec) +#else +#define arc_mdelay(msec) msleep(msec) +#define arc_mdelay_int(msec) msleep_interruptible(msec) #endif /* ********************************************************************************** @@ -119,10 +114,9 @@ */ static u_int8_t arcmsr_adapterCnt = 0; static struct _HCBARC arcmsr_host_control_block; -static PHCBARC pHCBARC = &arcmsr_host_control_block; /* ********************************************************************************** -** notifier block to get a notify on system shutdown/halt/reboot +** ********************************************************************************** */ static int arcmsr_fops_ioctl(struct inode *inode, struct file *filep, @@ -131,8 +125,8 @@ static int arcmsr_fops_close(struct inod static int arcmsr_fops_open(struct inode *inode, struct file *filep); static int arcmsr_halt_notify(struct notifier_block *nb, unsigned long event, void *buf); -static int arcmsr_initialize(PACB pACB, struct pci_dev *pPCI_DEV); -static int arcmsr_iop_ioctlcmd(PACB pACB, int ioctl_cmd, void *arg); +static int arcmsr_initialize(struct _ACB *pACB, struct pci_dev *pPCI_DEV); +static int arcmsr_iop_ioctlcmd(struct _ACB *pACB, int ioctl_cmd, void *arg); static int arcmsr_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout); static int arcmsr_bios_param(struct scsi_device *sdev, @@ -147,13 +141,88 @@ static int arcmsr_ioctl(struct scsi_devi static int __devinit arcmsr_device_probe(struct pci_dev *pPCI_DEV, const struct pci_device_id *id); static void arcmsr_device_remove(struct pci_dev *pPCI_DEV); -static void arcmsr_pcidev_disattach(PACB pACB); -static void arcmsr_iop_init(PACB pACB); -static void arcmsr_free_ccb_pool(PACB pACB); -static irqreturn_t arcmsr_HwInterrupt(PACB pACB); -static u_int8_t arcmsr_wait_msgint_ready(PACB pACB); +static void arcmsr_pcidev_disattach(struct _ACB *pACB); +static void arcmsr_iop_init(struct _ACB *pACB); +static void arcmsr_free_ccb_pool(struct _ACB *pACB); +static irqreturn_t arcmsr_interrupt(struct _ACB *pACB); +static u_int8_t arcmsr_wait_msgint_ready(struct _ACB *pACB); static const char *arcmsr_info(struct Scsi_Host *); - +/* +********************************************************************************** +** +********************************************************************************** +*/ +static ssize_t arcmsr_show_firmware_info(struct class_device *dev, char *buf) +{ + struct Scsi_Host *host = class_to_shost(dev); + struct _ACB *pACB = (struct _ACB *)host->hostdata; + unsigned long flags = 0; + ssize_t len; + + spin_lock_irqsave(pACB->host->host_lock, flags); + len = snprintf(buf, PAGE_SIZE, + "Firmware Version: %s\n" + "Adapter Model: %s\n" + "Reguest Lenth: %4d\n" + "Numbers of Queue: %4d\n" + "SDRAM Size: %4d\n" + "IDE Channels: %4d\n", + pACB->firm_version, + pACB->firm_model, + pACB->firm_request_len, + pACB->firm_numbers_queue, + pACB->firm_sdram_size, pACB->firm_ide_channels); + spin_unlock_irqrestore(pACB->host->host_lock, flags); + return len; +} +static ssize_t arcmsr_show_current_state(struct class_device *dev, char *buf) +{ + struct Scsi_Host *host = class_to_shost(dev); + struct _ACB *pACB = (struct _ACB *)host->hostdata; + unsigned long flags = 0; + ssize_t len; + + spin_lock_irqsave(pACB->host->host_lock, flags); + len = snprintf(buf, PAGE_SIZE, + "ARCMSR:%s\n" + "Current commands posted: %4d\n" + "Max commands posted: %4d\n" + "Current pending commands: %4d\n" + "Max pending commands: %4d\n" + "Max sgl length: %4d\n" + "Max sector count: %4d\n" + "SCSI Host Resets: %4d\n" + "SCSI Aborts/Timeouts: %4d\n", + ARCMSR_DRIVER_VERSION, + atomic_read(&pACB->ccboutstandingcount), + ARCMSR_MAX_OUTSTANDING_CMD, + atomic_read(&pACB->ccbwait2gocount), + ARCMSR_MAX_FREECCB_NUM - ARCMSR_MAX_OUTSTANDING_CMD, + ARCMSR_MAX_SG_ENTRIES, + ARCMSR_MAX_XFER_SECTORS, + pACB->num_resets, pACB->num_aborts); + spin_unlock_irqrestore(pACB->host->host_lock, flags); + return len; +} +static struct class_device_attribute arcmsr_firmware_info_attr = { + .attr = { + .name = "firmware info", + .mode = S_IRUGO, + }, + .show = arcmsr_show_firmware_info, +}; +static struct class_device_attribute arcmsr_driver_state_attr = { + .attr = { + .name = "stats", + .mode = S_IRUGO, + }, + .show = arcmsr_show_current_state +}; +static struct class_device_attribute *arcmsr_host_attrs[] = { + &arcmsr_firmware_info_attr, + &arcmsr_driver_state_attr, + NULL +}; static struct scsi_host_template arcmsr_scsi_host_template = { .module = THIS_MODULE, .proc_name = "arcmsr", @@ -175,20 +244,22 @@ static struct scsi_host_template arcmsr_ .max_sectors = ARCMSR_MAX_XFER_SECTORS, .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN, .unchecked_isa_dma = 0, - .use_clustering = DISABLE_CLUSTERING, + .use_clustering = ENABLE_CLUSTERING, + .shost_attrs = arcmsr_host_attrs, }; /* ********************************************************************************** -** +** notifier block to get a notify on system shutdown/halt/reboot ********************************************************************************** */ static struct notifier_block arcmsr_event_notifier = { arcmsr_halt_notify, NULL, 0 }; static struct file_operations arcmsr_file_operations = { - ioctl:arcmsr_fops_ioctl, - open:arcmsr_fops_open, - release:arcmsr_fops_close + .owner = THIS_MODULE, + .ioctl = arcmsr_fops_ioctl, + .open = arcmsr_fops_open, + .release = arcmsr_fops_close, }; /* We do our own ID filtering. So, grab all SCSI storage class devices. */ @@ -228,31 +299,26 @@ static struct pci_driver arcmsr_pci_driv ********************************************************************* ********************************************************************* */ -static irqreturn_t arcmsr_doInterrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { irqreturn_t handle_state; - PACB pACB, pACBtmp; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; + struct _ACB *pACB; + struct _ACB *pACBtmp; int i = 0; -#if ARCMSR_DEBUG0 - printk("arcmsr_doInterrupt.................. 1\n"); -#endif - - pACB = (PACB) dev_id; + pACB = (struct _ACB *)dev_id; pACBtmp = pHCBARC->pACB[i]; while ((pACB != pACBtmp) && pACBtmp && (i < ARCMSR_MAX_ADAPTER)) { i++; pACBtmp = pHCBARC->pACB[i]; } if (!pACBtmp) { -#if ARCMSR_DEBUG0 - printk("arcmsr_doInterrupt: Invalid pACB=0x%p \n", pACB); -#endif return IRQ_NONE; } spin_lock_irq(&pACB->isr_lockunlock); - handle_state = arcmsr_HwInterrupt(pACB); + handle_state = arcmsr_interrupt(pACB); spin_unlock_irq(&pACB->isr_lockunlock); return (handle_state); } @@ -267,9 +333,6 @@ static int arcmsr_bios_param(struct scsi { int heads, sectors, cylinders, total_capacity; -#if ARCMSR_DEBUG0 - printk("arcmsr_bios_param.................. \n"); -#endif total_capacity = capacity; heads = 64; sectors = 32; @@ -292,34 +355,32 @@ static int arcmsr_bios_param(struct scsi static int __devinit arcmsr_device_probe(struct pci_dev *pPCI_DEV, const struct pci_device_id *id) { - struct Scsi_Host *psh; - PACB pACB; + struct Scsi_Host *host; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; + struct _ACB *pACB; -#if ARCMSR_DEBUG0 - printk("arcmsr_device_probe............................\n"); -#endif if (pci_enable_device(pPCI_DEV)) { printk ("arcmsr_device_probe: pci_enable_device error .....................\n"); return -ENODEV; } /* allocate scsi host information (includes out adapter) scsi_host_alloc==scsi_register */ - if ((psh = + if ((host = scsi_host_alloc(&arcmsr_scsi_host_template, sizeof(struct _ACB))) == 0) { printk ("arcmsr_device_probe: scsi_host_alloc error .....................\n"); return -ENODEV; } - if (!pci_set_dma_mask(pPCI_DEV, (dma_addr_t) 0xffffffffffffffffULL)) { /*64bit */ + if (!pci_set_dma_mask(pPCI_DEV, DMA_64BIT_MASK)) { /*64bit */ printk("ARECA RAID: 64BITS PCI BUS DMA ADDRESSING SUPPORTED\n"); - } else if (pci_set_dma_mask(pPCI_DEV, (dma_addr_t) 0x00000000ffffffffULL)) { /*32bit */ + } else if (pci_set_dma_mask(pPCI_DEV, DMA_32BIT_MASK)) { /*32bit */ printk ("ARECA RAID: 32BITS PCI BUS DMA ADDRESSING NOT SUPPORTED (ERROR)\n"); - scsi_host_put(psh); + scsi_host_put(host); return -ENODEV; } - pACB = (PACB) psh->hostdata; + pACB = (struct _ACB *)host->hostdata; memset(pACB, 0, sizeof(struct _ACB)); spin_lock_init(&pACB->isr_lockunlock); spin_lock_init(&pACB->wait2go_lockunlock); @@ -327,23 +388,23 @@ static int __devinit arcmsr_device_probe spin_lock_init(&pACB->ccb_doneindex_lockunlock); spin_lock_init(&pACB->ccb_startindex_lockunlock); pACB->pPCI_DEV = pPCI_DEV; - pACB->pScsiHost = psh; - psh->max_sectors = ARCMSR_MAX_XFER_SECTORS; - psh->max_lun = ARCMSR_MAX_TARGETLUN; - psh->max_id = ARCMSR_MAX_TARGETID; /*16:8 */ - psh->max_cmd_len = 16; /*this is issue of 64bit LBA ,over 2T byte */ - psh->sg_tablesize = ARCMSR_MAX_SG_ENTRIES; - psh->can_queue = ARCMSR_MAX_OUTSTANDING_CMD; /* max simultaneous cmds */ - psh->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN; - psh->this_id = ARCMSR_SCSI_INITIATOR_ID; - psh->io_port = 0; - psh->n_io_port = 0; - psh->irq = pPCI_DEV->irq; + pACB->host = host; + host->max_sectors = ARCMSR_MAX_XFER_SECTORS; + host->max_lun = ARCMSR_MAX_TARGETLUN; + host->max_id = ARCMSR_MAX_TARGETID; /*16:8 */ + host->max_cmd_len = 16; /*this is issue of 64bit LBA ,over 2T byte */ + host->sg_tablesize = ARCMSR_MAX_SG_ENTRIES; + host->can_queue = ARCMSR_MAX_OUTSTANDING_CMD; /* max simultaneous cmds */ + host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN; + host->this_id = ARCMSR_SCSI_INITIATOR_ID; + host->io_port = 0; + host->n_io_port = 0; + host->irq = pPCI_DEV->irq; pci_set_master(pPCI_DEV); if (arcmsr_initialize(pACB, pPCI_DEV)) { printk ("arcmsr: arcmsr_initialize got error...................\n"); - scsi_host_put(psh); + scsi_host_put(host); return -ENODEV; } if (pci_request_regions(pPCI_DEV, "arcmsr")) { @@ -353,11 +414,11 @@ static int __devinit arcmsr_device_probe pHCBARC->adapterCnt = arcmsr_adapterCnt; pHCBARC->pACB[pACB->adapter_index] = NULL; arcmsr_pcidev_disattach(pACB); - scsi_host_put(psh); + scsi_host_put(host); return -ENODEV; } if (request_irq - (pPCI_DEV->irq, arcmsr_doInterrupt, SA_INTERRUPT | SA_SHIRQ, + (pPCI_DEV->irq, arcmsr_do_interrupt, SA_INTERRUPT | SA_SHIRQ, "arcmsr", pACB)) { printk("arcmsr: pACB=0x%p register IRQ=%d error!\n", pACB, pPCI_DEV->irq); @@ -365,22 +426,22 @@ static int __devinit arcmsr_device_probe pHCBARC->adapterCnt = arcmsr_adapterCnt; pHCBARC->pACB[pACB->adapter_index] = NULL; arcmsr_pcidev_disattach(pACB); - scsi_host_put(psh); + scsi_host_put(host); return -ENODEV; } arcmsr_iop_init(pACB); - if (scsi_add_host(psh, &pPCI_DEV->dev)) { + if (scsi_add_host(host, &pPCI_DEV->dev)) { printk("arcmsr: scsi_add_host got error...................\n"); arcmsr_adapterCnt--; pHCBARC->adapterCnt = arcmsr_adapterCnt; pHCBARC->pACB[pACB->adapter_index] = NULL; arcmsr_pcidev_disattach(pACB); - scsi_host_put(psh); + scsi_host_put(host); return -ENODEV; } pHCBARC->adapterCnt = arcmsr_adapterCnt; - pci_set_drvdata(pPCI_DEV, psh); - scsi_scan_host(psh); + pci_set_drvdata(pPCI_DEV, host); + scsi_scan_host(host); return 0; } @@ -390,19 +451,17 @@ static int __devinit arcmsr_device_probe */ static void arcmsr_device_remove(struct pci_dev *pPCI_DEV) { - struct Scsi_Host *psh = pci_get_drvdata(pPCI_DEV); - PACB pACB = (PACB) psh->hostdata; + struct Scsi_Host *host = pci_get_drvdata(pPCI_DEV); + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; + struct _ACB *pACB = (struct _ACB *)host->hostdata; int i; -#if ARCMSR_DEBUG0 - printk("arcmsr_device_remove............................\n"); -#endif /* Flush cache to disk */ /* Free irq,otherwise extra interrupt is generated */ /* Issue a blocking(interrupts disabled) command to the card */ arcmsr_pcidev_disattach(pACB); - scsi_remove_host(psh); - scsi_host_put(psh); + scsi_remove_host(host); + scsi_host_put(host); pci_set_drvdata(pPCI_DEV, NULL); /*if this is last pACB */ for (i = 0; i < ARCMSR_MAX_ADAPTER; i++) { @@ -419,19 +478,19 @@ static void arcmsr_device_remove(struct ************************************************************************ ************************************************************************ */ -static int arcmsr_scsi_host_template_init(struct scsi_host_template *psht) +static int arcmsr_scsi_host_template_init(struct scsi_host_template + *host_template) { int error; -#if ARCMSR_DEBUG0 - printk("arcmsr_scsi_host_template_init..............\n"); -#endif + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; + /* ** register as a PCI hot-plug driver module */ memset(pHCBARC, 0, sizeof(struct _HCBARC)); error = pci_module_init(&arcmsr_pci_driver); if (pHCBARC->pACB[0] != NULL) { - psht->proc_name = "arcmsr"; + host_template->proc_name = "arcmsr"; register_reboot_notifier(&arcmsr_event_notifier); pHCBARC->arcmsr_major_number = register_chrdev(0, "arcmsr", &arcmsr_file_operations); @@ -468,9 +527,9 @@ module_exit(arcmsr_module_exit); ** ********************************************************************** */ -static void arcmsr_pci_unmap_dma(PCCB pCCB) +static void arcmsr_pci_unmap_dma(struct _CCB *pCCB) { - PACB pACB = pCCB->pACB; + struct _ACB *pACB = pCCB->pACB; struct scsi_cmnd *pcmd = pCCB->pcmd; if (pcmd->use_sg != 0) { @@ -496,7 +555,8 @@ static void arcmsr_pci_unmap_dma(PCCB pC static int arcmsr_fops_open(struct inode *inode, struct file *filep) { int i, minor; - PACB pACB; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; + struct _ACB *pACB; minor = MINOR(inode->i_rdev); if (minor >= pHCBARC->adapterCnt) { @@ -523,7 +583,8 @@ static int arcmsr_fops_open(struct inode static int arcmsr_fops_close(struct inode *inode, struct file *filep) { int i, minor; - PACB pACB; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; + struct _ACB *pACB; minor = MINOR(inode->i_rdev); if (minor >= pHCBARC->adapterCnt) { @@ -551,7 +612,8 @@ static int arcmsr_fops_ioctl(struct inod unsigned int ioctl_cmd, unsigned long arg) { int i, minor; - PACB pACB; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; + struct _ACB *pACB; minor = MINOR(inode->i_rdev); if (minor >= pHCBARC->adapterCnt) { @@ -576,31 +638,14 @@ static int arcmsr_fops_ioctl(struct inod } /* -********************************************************************** -** -** Linux scsi mid layer command complete -** -********************************************************************** -*/ -static void arcmsr_cmd_done(struct scsi_cmnd *pcmd) -{ - pcmd->scsi_done(pcmd); - return; -} - -/* ************************************************************************ ** ** ************************************************************************ */ -static void arcmsr_flush_adapter_cache(PACB pACB) +static void arcmsr_flush_adapter_cache(struct _ACB *pACB) { -#if ARCMSR_DEBUG0 - printk("arcmsr_flush_adapter_cache..............\n"); -#endif - CHIP_REG_WRITE32(&pACB->pmu->inbound_msgaddr0, - ARCMSR_INBOUND_MESG0_FLUSH_CACHE); + writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, &pACB->pmu->inbound_msgaddr0); return; } @@ -611,17 +656,12 @@ static void arcmsr_flush_adapter_cache(P ** ********************************************************************** */ -static void arcmsr_ccb_complete(PCCB pCCB) +static void arcmsr_ccb_complete(struct _CCB *pCCB) { unsigned long flag; - PACB pACB = pCCB->pACB; + struct _ACB *pACB = pCCB->pACB; struct scsi_cmnd *pcmd = pCCB->pcmd; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_ccb_complete:pCCB=0x%p ccb_doneindex=0x%x ccb_startindex=0x%x\n", - pCCB, pACB->ccb_doneindex, pACB->ccb_startindex); -#endif arcmsr_pci_unmap_dma(pCCB); spin_lock_irqsave(&pACB->ccb_doneindex_lockunlock, flag); atomic_dec(&pACB->ccboutstandingcount); @@ -631,7 +671,7 @@ static void arcmsr_ccb_complete(PCCB pCC pACB->ccb_doneindex++; pACB->ccb_doneindex %= ARCMSR_MAX_FREECCB_NUM; spin_unlock_irqrestore(&pACB->ccb_doneindex_lockunlock, flag); - arcmsr_cmd_done(pcmd); + pcmd->scsi_done(pcmd); return; } @@ -640,13 +680,11 @@ static void arcmsr_ccb_complete(PCCB pCC ** if scsi error do auto request sense ********************************************************************** */ -static void arcmsr_report_SenseInfoBuffer(PCCB pCCB) +static void arcmsr_report_sense_info(struct _CCB *pCCB) { struct scsi_cmnd *pcmd = pCCB->pcmd; - PSENSE_DATA psenseBuffer = (PSENSE_DATA) pcmd->sense_buffer; -#if ARCMSR_DEBUG0 - printk("arcmsr_report_SenseInfoBuffer...........\n"); -#endif + struct _SENSE_DATA *psenseBuffer = + (struct _SENSE_DATA *)pcmd->sense_buffer; pcmd->result = DID_OK << 16; if (psenseBuffer) { @@ -669,14 +707,10 @@ static void arcmsr_report_SenseInfoBuffe ** to insert pCCB into tail of pACB wait exec ccbQ ********************************************************************* */ -static void arcmsr_queue_wait2go_ccb(PACB pACB, PCCB pCCB) +static void arcmsr_queue_wait2go_ccb(struct _ACB *pACB, struct _CCB *pCCB) { unsigned long flag; int i = 0; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_qtail_wait2go_ccb:......................................... \n"); -#endif spin_lock_irqsave(&pACB->wait2go_lockunlock, flag); while (1) { @@ -697,35 +731,34 @@ static void arcmsr_queue_wait2go_ccb(PAC ** ********************************************************************* */ -static void arcmsr_abort_allcmd(PACB pACB) +static void arcmsr_abort_allcmd(struct _ACB *pACB) { - CHIP_REG_WRITE32(&pACB->pmu->inbound_msgaddr0, - ARCMSR_INBOUND_MESG0_ABORT_CMD); + printk + ("arcmsr_abort_allcmd: try to abort all outstanding command............\n"); + writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, &pACB->pmu->inbound_msgaddr0); return; } /* ********************************************************************** ** -** -** ********************************************************************** */ -static u_int8_t arcmsr_wait_msgint_ready(PACB pACB) +static u_int8_t arcmsr_wait_msgint_ready(struct _ACB *pACB) { uint32_t Index; uint8_t Retries = 0x00; do { - for (Index = 0; Index < 500000; Index++) { - if (CHIP_REG_READ32(&pACB->pmu->outbound_intstatus) & + for (Index = 0; Index < 100; Index++) { + if (readl(&pACB->pmu->outbound_intstatus) & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { - CHIP_REG_WRITE32(&pACB->pmu->outbound_intstatus, ARCMSR_MU_OUTBOUND_MESSAGE0_INT); /*clear interrupt */ + writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, &pACB->pmu->outbound_intstatus); /*clear interrupt */ return 0x00; } /* one us delay */ - udelay(10); - } /*max 5 seconds */ - } while (Retries++ < 24); /*max 2 minutes */ + arc_mdelay_int(10); + } /*max 1 seconds */ + } while (Retries++ < 20); /*max 20 sec */ return 0xff; } @@ -736,26 +769,17 @@ static u_int8_t arcmsr_wait_msgint_ready ** Return Value: Nothing. **************************************************************************** */ -static void arcmsr_iop_reset(PACB pACB) +static void arcmsr_iop_reset(struct _ACB *pACB) { - PCCB pCCB; + struct _CCB *pCCB; uint32_t intmask_org, mask; int i = 0; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_iop_reset: reset iop controller......................................\n"); -#endif if (atomic_read(&pACB->ccboutstandingcount) != 0) { -#if ARCMSR_DEBUG0 - printk("arcmsr_iop_reset: ccboutstandingcount=%d ...\n", - atomic_read(&pACB->ccboutstandingcount)); -#endif /* disable all outbound interrupt */ - intmask_org = CHIP_REG_READ32(&pACB->pmu->outbound_intmask); - CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask, - intmask_org | - ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE); + intmask_org = readl(&pACB->pmu->outbound_intmask); + writel(intmask_org | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, + &pACB->pmu->outbound_intmask); /* talk to iop 331 outstanding command aborted */ arcmsr_abort_allcmd(pACB); if (arcmsr_wait_msgint_ready(pACB)) { @@ -764,7 +788,7 @@ static void arcmsr_iop_reset(PACB pACB) } /*clear all outbound posted Q */ for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) { - CHIP_REG_READ32(&pACB->pmu->outbound_queueport); + readl(&pACB->pmu->outbound_queueport); } for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { pCCB = pACB->pccb_pool[i]; @@ -779,20 +803,13 @@ static void arcmsr_iop_reset(PACB pACB) ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE | ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE); - CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask, - intmask_org & mask); - atomic_set(&pACB->ccboutstandingcount, 0); + writel(intmask_org & mask, &pACB->pmu->outbound_intmask); /* post abort all outstanding command message to RAID controller */ } i = 0; while (atomic_read(&pACB->ccbwait2gocount) != 0) { pCCB = pACB->pccbwait2go[i]; if (pCCB != NULL) { -#if ARCMSR_DEBUG0 - printk - ("arcmsr_iop_reset:abort command... ccbwait2gocount=%d ...\n", - atomic_read(&pACB->ccbwait2gocount)); -#endif pACB->pccbwait2go[i] = NULL; pCCB->startdone = ARCMSR_CCB_ABORTED; pCCB->pcmd->result = DID_ABORT << 16; @@ -802,6 +819,7 @@ static void arcmsr_iop_reset(PACB pACB) i++; i %= ARCMSR_MAX_OUTSTANDING_CMD; } + atomic_set(&pACB->ccboutstandingcount, 0); return; } @@ -811,16 +829,15 @@ static void arcmsr_iop_reset(PACB pACB) ** PAGE_SIZE=4096 or 8192,PAGE_SHIFT=12 ********************************************************************** */ -static void arcmsr_build_ccb(PACB pACB, PCCB pCCB, struct scsi_cmnd *pcmd) +static void arcmsr_build_ccb(struct _ACB *pACB, struct _CCB *pCCB, + struct scsi_cmnd *pcmd) { - PARCMSR_CDB pARCMSR_CDB = (PARCMSR_CDB) & pCCB->arcmsr_cdb; + struct _ARCMSR_CDB *pARCMSR_CDB = + (struct _ARCMSR_CDB *)&pCCB->arcmsr_cdb; int8_t *psge = (int8_t *) & pARCMSR_CDB->u; uint32_t address_lo, address_hi; int arccdbsize = 0x30; -#if ARCMSR_DEBUG0 - printk("arcmsr_build_ccb........................... \n"); -#endif pCCB->pcmd = pcmd; memset(pARCMSR_CDB, 0, sizeof(struct _ARCMSR_CDB)); pARCMSR_CDB->Bus = 0; @@ -828,7 +845,7 @@ static void arcmsr_build_ccb(PACB pACB, pARCMSR_CDB->LUN = pcmd->device->lun; pARCMSR_CDB->Function = 1; pARCMSR_CDB->CdbLength = (uint8_t) pcmd->cmd_len; - pARCMSR_CDB->Context = (CPT2INT) pARCMSR_CDB; + pARCMSR_CDB->Context = (unsigned long)pARCMSR_CDB; memcpy(pARCMSR_CDB->Cdb, pcmd->cmnd, pcmd->cmd_len); if (pcmd->use_sg) { int length, sgcount, i, cdb_sgcount = 0; @@ -848,53 +865,22 @@ static void arcmsr_build_ccb(PACB pACB, address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sl))); if (address_hi == 0) { - PSG32ENTRY pdma_sg = (PSG32ENTRY) psge; + struct _SG32ENTRY *pdma_sg = + (struct _SG32ENTRY *)psge; pdma_sg->address = address_lo; pdma_sg->length = length; - psge += sizeof(SG32ENTRY); - arccdbsize += sizeof(SG32ENTRY); + psge += sizeof(struct _SG32ENTRY); + arccdbsize += sizeof(struct _SG32ENTRY); } else { - int sg64s_size = 0, tmplength = length; + struct _SG64ENTRY *pdma_sg = + (struct _SG64ENTRY *)psge; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_build_ccb: ..........address_hi=0x%x.... \n", - address_hi); -#endif - - while (1) { - int64_t span4G, length0; - PSG64ENTRY pdma_sg = (PSG64ENTRY) psge; - - span4G = - (int64_t) address_lo + tmplength; - pdma_sg->addresshigh = address_hi; - pdma_sg->address = address_lo; - if (span4G > 0x100000000ULL) { - /*see if cross 4G boundary */ - length0 = - 0x100000000ULL - address_lo; - pdma_sg->length = - (uint32_t) length0 | - IS_SG64_ADDR; - address_hi = address_hi + 1; - address_lo = 0; - tmplength = - tmplength - - (int32_t) length0; - sg64s_size += sizeof(SG64ENTRY); - psge += sizeof(SG64ENTRY); - cdb_sgcount++; - } else { - pdma_sg->length = - tmplength | IS_SG64_ADDR; - sg64s_size += sizeof(SG64ENTRY); - psge += sizeof(SG64ENTRY); - break; - } - } - arccdbsize += sg64s_size; + pdma_sg->addresshigh = address_hi; + pdma_sg->address = address_lo; + pdma_sg->length = length | IS_SG64_ADDR; + psge += sizeof(struct _SG64ENTRY *); + arccdbsize += sizeof(struct _SG64ENTRY); } sl++; cdb_sgcount++; @@ -914,11 +900,11 @@ static void arcmsr_build_ccb(PACB pACB, address_lo = cpu_to_le32(dma_addr_lo32(dma_addr)); address_hi = cpu_to_le32(dma_addr_hi32(dma_addr)); if (address_hi == 0) { - PSG32ENTRY pdma_sg = (PSG32ENTRY) psge; + struct _SG32ENTRY *pdma_sg = (struct _SG32ENTRY *)psge; pdma_sg->address = address_lo; pdma_sg->length = pcmd->request_bufflen; } else { - PSG64ENTRY pdma_sg = (PSG64ENTRY) psge; + struct _SG64ENTRY *pdma_sg = (struct _SG64ENTRY *)psge; pdma_sg->addresshigh = address_hi; pdma_sg->address = address_lo; pdma_sg->length = pcmd->request_bufflen | IS_SG64_ADDR; @@ -930,12 +916,6 @@ static void arcmsr_build_ccb(PACB pACB, pARCMSR_CDB->Flags |= ARCMSR_CDB_FLAG_WRITE; pCCB->ccb_flags |= CCB_FLAG_WRITE; } -#if ARCMSR_DEBUG0 - printk - ("arcmsr_build_ccb: pCCB=0x%p cmd=0x%x xferlength=%d arccdbsize=%d sgcount=%d\n", - pCCB, pcmd->cmnd[0], pARCMSR_CDB->DataLength, arccdbsize, - pARCMSR_CDB->sgcount); -#endif return; } @@ -952,25 +932,19 @@ static void arcmsr_build_ccb(PACB pACB, ** ************************************************************************** */ -static void arcmsr_post_ccb(PACB pACB, PCCB pCCB) +static void arcmsr_post_ccb(struct _ACB *pACB, struct _CCB *pCCB) { uint32_t cdb_shifted_phyaddr = pCCB->cdb_shifted_phyaddr; - PARCMSR_CDB pARCMSR_CDB = (PARCMSR_CDB) & pCCB->arcmsr_cdb; + struct _ARCMSR_CDB *pARCMSR_CDB = + (struct _ARCMSR_CDB *)&pCCB->arcmsr_cdb; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_post_ccb: pCCB=0x%p cdb_shifted_phyaddr=0x%x pCCB->pACB=0x%p \n", - pCCB, cdb_shifted_phyaddr, pCCB->pACB); -#endif atomic_inc(&pACB->ccboutstandingcount); pCCB->startdone = ARCMSR_CCB_START; if (pARCMSR_CDB->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) { - CHIP_REG_WRITE32(&pACB->pmu->inbound_queueport, - cdb_shifted_phyaddr | - ARCMSR_CCBPOST_FLAG_SGL_BSIZE); + writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE, + &pACB->pmu->inbound_queueport); } else { - CHIP_REG_WRITE32(&pACB->pmu->inbound_queueport, - cdb_shifted_phyaddr); + writel(cdb_shifted_phyaddr, &pACB->pmu->inbound_queueport); } return; } @@ -981,17 +955,12 @@ static void arcmsr_post_ccb(PACB pACB, P ** ************************************************************************** */ -static void arcmsr_post_wait2go_ccb(PACB pACB) +static void arcmsr_post_wait2go_ccb(struct _ACB *pACB) { unsigned long flag; - PCCB pCCB; + struct _CCB *pCCB; int i = 0; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_post_wait2go_ccb:ccbwait2gocount=%d ccboutstandingcount=%d\n", - atomic_read(&pACB->ccbwait2gocount), - atomic_read(&pACB->ccboutstandingcount)); -#endif + spin_lock_irqsave(&pACB->wait2go_lockunlock, flag); while ((atomic_read(&pACB->ccbwait2gocount) > 0) && (atomic_read(&pACB->ccboutstandingcount) < @@ -1015,7 +984,7 @@ static void arcmsr_post_wait2go_ccb(PACB ** Output: ********************************************************************** */ -static void arcmsr_post_Qbuffer(PACB pACB) +static void arcmsr_post_Qbuffer(struct _ACB *pACB) { uint8_t *pQbuffer; PQBUFFER pwbuffer = (PQBUFFER) & pACB->pmu->ioctl_wbuffer; @@ -1035,8 +1004,8 @@ static void arcmsr_post_Qbuffer(PACB pAC /* ** push inbound doorbell and wait reply at hwinterrupt routine for next Qbuffer post */ - CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, - ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK); + writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK, + &pACB->pmu->inbound_doorbell); return; } @@ -1046,15 +1015,11 @@ static void arcmsr_post_Qbuffer(PACB pAC ** ************************************************************************ */ -static void arcmsr_stop_adapter_bgrb(PACB pACB) +static void arcmsr_stop_adapter_bgrb(struct _ACB *pACB) { -#if ARCMSR_DEBUG0 - printk("arcmsr_stop_adapter_bgrb..............\n"); -#endif pACB->acb_flags |= ACB_F_MSG_STOP_BGRB; pACB->acb_flags &= ~ACB_F_MSG_START_BGRB; - CHIP_REG_WRITE32(&pACB->pmu->inbound_msgaddr0, - ARCMSR_INBOUND_MESG0_STOP_BGRB); + writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, &pACB->pmu->inbound_msgaddr0); return; } @@ -1064,7 +1029,7 @@ static void arcmsr_stop_adapter_bgrb(PAC ** ************************************************************************ */ -static void arcmsr_free_ccb_pool(PACB pACB) +static void arcmsr_free_ccb_pool(struct _ACB *pACB) { dma_free_coherent(&pACB->pPCI_DEV->dev, ARCMSR_MAX_FREECCB_NUM * sizeof(struct _CCB) + 0x20, @@ -1074,7 +1039,7 @@ static void arcmsr_free_ccb_pool(PACB pA /* ********************************************************************** -** Function: arcmsr_HwInterrupt +** Function: arcmsr_interrupt ** Output: void ** DID_OK 0x00 // NO error ** DID_NO_CONNECT 0x01 // Couldn't connect before timeout period @@ -1091,13 +1056,10 @@ static void arcmsr_free_ccb_pool(PACB pA ** DRIVER_OK 0x00 // Driver status ********************************************************************** */ -static irqreturn_t arcmsr_HwInterrupt(PACB pACB) +static irqreturn_t arcmsr_interrupt(struct _ACB *pACB) { - PCCB pCCB; + struct _CCB *pCCB; uint32_t flag_ccb, outbound_intstatus, outbound_doorbell; -#if ARCMSR_DEBUG0 - printk("arcmsr_HwInterrupt...................................\n"); -#endif /* ********************************************* @@ -1105,22 +1067,16 @@ static irqreturn_t arcmsr_HwInterrupt(PA ********************************************* */ outbound_intstatus = - CHIP_REG_READ32(&pACB->pmu->outbound_intstatus) & pACB-> - outbound_int_enable; - CHIP_REG_WRITE32(&pACB->pmu->outbound_intstatus, outbound_intstatus); /*clear interrupt */ + readl(&pACB->pmu->outbound_intstatus) & pACB->outbound_int_enable; + writel(outbound_intstatus, &pACB->pmu->outbound_intstatus); /*clear interrupt */ if (outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) { -#if ARCMSR_DEBUG0 - printk - ("arcmsr_HwInterrupt:..........ARCMSR_MU_OUTBOUND_DOORBELL_INT\n"); -#endif /* ********************************************* ** DOORBELL 叮噹! 是否有郵件要簽收 ********************************************* */ - outbound_doorbell = - CHIP_REG_READ32(&pACB->pmu->outbound_doorbell); - CHIP_REG_WRITE32(&pACB->pmu->outbound_doorbell, outbound_doorbell); /*clear interrupt */ + outbound_doorbell = readl(&pACB->pmu->outbound_doorbell); + writel(outbound_doorbell, &pACB->pmu->outbound_doorbell); /*clear interrupt */ if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) { PQBUFFER prbuffer = (PQBUFFER) & pACB->pmu->ioctl_rbuffer; @@ -1147,12 +1103,8 @@ static irqreturn_t arcmsr_HwInterrupt(PA iop_data++; iop_len--; } - CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK); /*signature, let IOP331 know data has been readed */ + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, &pACB->pmu->inbound_doorbell); /*signature, let IOP331 know data has been readed */ } else { -#if ARCMSR_DEBUG0 - printk - ("arcmsr_HwInterrupt: this iop data overflow my rqbuffer.....\n"); -#endif pACB->acb_flags |= ACB_F_IOPDATA_OVERFLOW; } } @@ -1185,8 +1137,8 @@ static irqreturn_t arcmsr_HwInterrupt(PA /* ** push inbound doorbell tell iop driver data write ok and wait reply on next hwinterrupt for next Qbuffer post */ - CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, - ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK); + writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK, + &pACB->pmu->inbound_doorbell); } else { pACB->acb_flags |= ACB_F_IOCTL_WQBUFFER_CLEARED; } @@ -1200,45 +1152,34 @@ static irqreturn_t arcmsr_HwInterrupt(PA */ while (1) { if ((flag_ccb = - CHIP_REG_READ32(&pACB->pmu->outbound_queueport)) == + readl(&pACB->pmu->outbound_queueport)) == 0xFFFFFFFF) { break; /*chip FIFO no ccb for completion already */ } /* check if command done with no error */ - pCCB = (PCCB) (pACB->vir2phy_offset + (flag_ccb << 5)); /*frame must be 32 bytes aligned */ + pCCB = (struct _CCB *)(pACB->vir2phy_offset + (flag_ccb << 5)); /*frame must be 32 bytes aligned */ if ((pCCB->pACB != pACB) || (pCCB->startdone != ARCMSR_CCB_START)) { if (pCCB->startdone == ARCMSR_CCB_ABORTED) { pCCB->pcmd->result = DID_ABORT << 16; arcmsr_ccb_complete(pCCB); - break; + } else { + printk + ("arcmsr_interrupt:got an illegal ccb command done ...acb=0x%p pCCB=0x%p ccbacb=0x%p startdone=0x%x ccboutstandingcount=%d \n", + pACB, pCCB, pCCB->pACB, + pCCB->startdone, + atomic_read(&pACB-> + ccboutstandingcount)); } - printk - ("arcmsr_HwInterrupt:got an illegal ccb command done ...pACB=0x%p pCCB=0x%p ccboutstandingcount=%d .....\n", - pACB, pCCB, - atomic_read(&pACB->ccboutstandingcount)); - break; + continue; } -#if ARCMSR_DEBUG0 - printk("pCCB=0x%p .....................done\n", pCCB); -#endif if ((flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR) == 0) { -#if ARCMSR_DEBUG0 - printk - ("pCCB=0x%p scsi cmd=0x%x................... GOOD ..............done\n", - pCCB, pCCB->pcmd->cmnd[0]); -#endif pCCB->pcmd->result = DID_OK << 16; arcmsr_ccb_complete(pCCB); } else { switch (pCCB->arcmsr_cdb.DeviceStatus) { case ARCMSR_DEV_SELECT_TIMEOUT: { -#if ARCMSR_DEBUG0 - printk - ("pCCB=0x%p ......ARCMSR_DEV_SELECT_TIMEOUT\n", - pCCB); -#endif pCCB->pcmd->result = DID_TIME_OUT << 16; arcmsr_ccb_complete(pCCB); @@ -1246,11 +1187,6 @@ static irqreturn_t arcmsr_HwInterrupt(PA break; case ARCMSR_DEV_ABORTED: { -#if ARCMSR_DEBUG0 - printk - ("pCCB=0x%p ......ARCMSR_DEV_ABORTED\n", - pCCB); -#endif pCCB->pcmd->result = DID_NO_CONNECT << 16; arcmsr_ccb_complete(pCCB); @@ -1258,11 +1194,6 @@ static irqreturn_t arcmsr_HwInterrupt(PA break; case ARCMSR_DEV_INIT_FAIL: { -#if ARCMSR_DEBUG0 - printk - ("pCCB=0x%p .....ARCMSR_DEV_INIT_FAIL\n", - pCCB); -#endif pCCB->pcmd->result = DID_BAD_TARGET << 16; arcmsr_ccb_complete(pCCB); @@ -1270,22 +1201,19 @@ static irqreturn_t arcmsr_HwInterrupt(PA break; case SCSISTAT_CHECK_CONDITION: { -#if ARCMSR_DEBUG0 - printk - ("pCCB=0x%p .....SCSISTAT_CHECK_CONDITION\n", - pCCB); -#endif - arcmsr_report_SenseInfoBuffer - (pCCB); + arcmsr_report_sense_info(pCCB); arcmsr_ccb_complete(pCCB); } break; default: /* error occur Q all error ccb to errorccbpending Q */ printk - ("arcmsr_HwInterrupt:command error done ......but got unknow DeviceStatus=0x%x....\n", - pCCB->arcmsr_cdb.DeviceStatus); - pCCB->pcmd->result = DID_PARITY << 16; /*unknow error or crc error just for retry */ + ("arcmsr_interrupt:id=%d command error done ......but got unknow DeviceStatus=0x%x....ccboutstandingcount=%d\n", + pCCB->pcmd->device->id, + pCCB->arcmsr_cdb.DeviceStatus, + atomic_read(&pACB-> + ccboutstandingcount)); + pCCB->pcmd->result = DID_NO_CONNECT << 16; /*unknow error or crc error just for retry */ arcmsr_ccb_complete(pCCB); break; } @@ -1294,10 +1222,6 @@ static irqreturn_t arcmsr_HwInterrupt(PA } if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) { /*it must be share irq */ -#if ARCMSR_DEBUG0 - printk - ("arcmsr_HwInterrupt..........FALSE....................share irq.....\n"); -#endif return IRQ_NONE; } if (atomic_read(&pACB->ccbwait2gocount) != 0) { @@ -1311,16 +1235,13 @@ static irqreturn_t arcmsr_HwInterrupt(PA ** ************************************************************************ */ -static int arcmsr_iop_ioctlcmd(PACB pACB, int ioctl_cmd, void *arg) +static int arcmsr_iop_ioctlcmd(struct _ACB *pACB, int ioctl_cmd, void *arg) { - PCMD_IOCTL_FIELD pcmdioctlfld; + struct _CMD_IOCTL_FIELD *pcmdioctlfld; dma_addr_t cmd_handle; int retvalue = 0; /* Only let one of these through at a time */ -#if ARCMSR_DEBUG0 - printk("arcmsr_iop_ioctlcmd.......................................\n"); -#endif pcmdioctlfld = pci_alloc_consistent(pACB->pPCI_DEV, sizeof(struct _CMD_IOCTL_FIELD), &cmd_handle); @@ -1345,10 +1266,6 @@ static int arcmsr_iop_ioctlcmd(PACB pACB uint8_t *pQbuffer, *ptmpQbuffer; int32_t allxfer_len = 0; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_iop_ioctlcmd: ARCMSR_IOCTL_READ_RQBUFFER..... \n"); -#endif ver_addr = pci_alloc_consistent(pACB->pPCI_DEV, 1032, &buf_handle); @@ -1389,7 +1306,7 @@ static int arcmsr_iop_ioctlcmd(PACB pACB iop_data++; iop_len--; } - CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK); /*signature, let IOP331 know data has been readed */ + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, &pACB->pmu->inbound_doorbell); /*signature, let IOP331 know data has been readed */ } spin_unlock_irqrestore(&pACB->qbuffer_lockunlock, flag); memcpy(pcmdioctlfld->ioctldatabuffer, @@ -1415,10 +1332,6 @@ static int arcmsr_iop_ioctlcmd(PACB pACB wqbuf_lastindex; uint8_t *pQbuffer, *ptmpuserbuffer; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_iop_ioctlcmd: ARCMSR_IOCTL_WRITE_WQBUFFER..... \n"); -#endif ver_addr = pci_alloc_consistent(pACB->pPCI_DEV, 1032, &buf_handle); @@ -1459,10 +1372,6 @@ static int arcmsr_iop_ioctlcmd(PACB pACB pcmdioctlfld->cmdioctl.ReturnCode = ARCMSR_IOCTL_RETURNCODE_OK; } else { -#if ARCMSR_DEBUG0 - printk - ("arcmsr_iop_ioctlcmd:invalid data xfer ............qbuffer full............ \n"); -#endif pcmdioctlfld->cmdioctl.ReturnCode = ARCMSR_IOCTL_RETURNCODE_ERROR; } @@ -1480,13 +1389,10 @@ static int arcmsr_iop_ioctlcmd(PACB pACB { unsigned long flag; uint8_t *pQbuffer = pACB->rqbuffer; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_iop_ioctlcmd: ARCMSR_IOCTL_CLEAR_RQBUFFER..... \n"); -#endif + if (pACB->acb_flags & ACB_F_IOPDATA_OVERFLOW) { pACB->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; - CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK); /*signature, let IOP331 know data has been readed */ + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, &pACB->pmu->inbound_doorbell); /*signature, let IOP331 know data has been readed */ } pACB->acb_flags |= ACB_F_IOCTL_RQBUFFER_CLEARED; spin_lock_irqsave(&pACB->qbuffer_lockunlock, flag); @@ -1508,14 +1414,10 @@ static int arcmsr_iop_ioctlcmd(PACB pACB { unsigned long flag; uint8_t *pQbuffer = pACB->wqbuffer; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_iop_ioctlcmd: ARCMSR_IOCTL_CLEAR_WQBUFFER..... \n"); -#endif if (pACB->acb_flags & ACB_F_IOPDATA_OVERFLOW) { pACB->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; - CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK); /*signature, let IOP331 know data has been readed */ + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, &pACB->pmu->inbound_doorbell); /*signature, let IOP331 know data has been readed */ } pACB->acb_flags |= ACB_F_IOCTL_WQBUFFER_CLEARED; spin_lock_irqsave(&pACB->qbuffer_lockunlock, flag); @@ -1537,13 +1439,10 @@ static int arcmsr_iop_ioctlcmd(PACB pACB { unsigned long flag; uint8_t *pQbuffer; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_iop_ioctlcmd: ARCMSR_IOCTL_CLEAR_ALLQBUFFER..... \n"); -#endif + if (pACB->acb_flags & ACB_F_IOPDATA_OVERFLOW) { pACB->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; - CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, ARCMSR_INBOUND_DRIVER_DATA_READ_OK); /*signature, let IOP331 know data has been readed */ + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, &pACB->pmu->inbound_doorbell); /*signature, let IOP331 know data has been readed */ } pACB->acb_flags |= (ACB_F_IOCTL_WQBUFFER_CLEARED | @@ -1570,10 +1469,6 @@ static int arcmsr_iop_ioctlcmd(PACB pACB break; case ARCMSR_IOCTL_RETURN_CODE_3F: { -#if ARCMSR_DEBUG0 - printk - ("arcmsr_iop_ioctlcmd: ARCMSR_IOCTL_RETURNCODE_3F..... \n"); -#endif pcmdioctlfld->cmdioctl.ReturnCode = ARCMSR_IOCTL_RETURNCODE_3F; if (copy_to_user @@ -1586,10 +1481,7 @@ static int arcmsr_iop_ioctlcmd(PACB pACB case ARCMSR_IOCTL_SAY_HELLO: { int8_t *hello_string = "Hello! I am ARCMSR"; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_iop_ioctlcmd: ARCMSR_IOCTL_SAY_HELLO..... \n"); -#endif + memcpy(pcmdioctlfld->ioctldatabuffer, hello_string, (int16_t) strlen(hello_string)); pcmdioctlfld->cmdioctl.ReturnCode = @@ -1690,17 +1582,13 @@ static int arcmsr_iop_ioctlcmd(PACB pACB */ static int arcmsr_ioctl(struct scsi_device *dev, int ioctl_cmd, void *arg) { - PACB pACB; + struct _ACB *pACB; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; int32_t match = 0x55AA, i; -#if ARCMSR_DEBUG0 - printk - ("arcmsr_ioctl..................................................... \n"); -#endif - for (i = 0; i < ARCMSR_MAX_ADAPTER; i++) { if ((pACB = pHCBARC->pACB[i]) != NULL) { - if (pACB->pScsiHost == dev->host) { + if (pACB->host == dev->host) { match = i; break; } @@ -1720,16 +1608,12 @@ static int arcmsr_ioctl(struct scsi_devi ** ************************************************************************** */ -static PCCB arcmsr_get_freeccb(PACB pACB) +static struct _CCB *arcmsr_get_freeccb(struct _ACB *pACB) { - PCCB pCCB; + struct _CCB *pCCB; unsigned long flag; int ccb_startindex, ccb_doneindex; -#if ARCMSR_DEBUG0 - printk("arcmsr_get_freeccb: ccb_startindex=%d ccb_doneindex=%d\n", - pACB->ccb_startindex, pACB->ccb_doneindex); -#endif spin_lock_irqsave(&pACB->ccb_startindex_lockunlock, flag); ccb_doneindex = pACB->ccb_doneindex; ccb_startindex = pACB->ccb_startindex; @@ -1896,20 +1780,40 @@ static int arcmsr_queue_command(struct s void (*done) (struct scsi_cmnd *)) { struct Scsi_Host *host = cmd->device->host; - PACB pACB = (PACB) host->hostdata; - PCCB pCCB; + struct _ACB *pACB = (struct _ACB *)host->hostdata; + struct _CCB *pCCB; + int target = cmd->device->id; + int lun = cmd->device->lun; -#if ARCMSR_DEBUG0 - printk("arcmsr_queue_command:Cmd=%2x,TargetId=%d,Lun=%d \n", - cmd->cmnd[0], cmd->device->id, cmd->device->lun); -#endif cmd->scsi_done = done; cmd->host_scribble = NULL; cmd->result = 0; - if (cmd->cmnd[0] == SYNCHRONIZE_CACHE) { /* 0x35 avoid synchronizing disk cache cmd during .remove : arcmsr_device_remove (linux bug) */ + if (cmd->cmnd[0] == SYNCHRONIZE_CACHE) { /* 0x35 avoid synchronizing disk cache cmd after .remove : arcmsr_device_remove (linux bug) */ + if (pACB->devstate[target][lun] == ARECA_RAID_GONE) { + cmd->result = (DID_NO_CONNECT << 16); + } + cmd->scsi_done(cmd); + return (0); + } + if (pACB->acb_flags & ACB_F_BUS_RESET) { + printk("arcmsr_queue_command: bus reset return busy .......\n"); + cmd->result = (DID_BUS_BUSY << 16); cmd->scsi_done(cmd); return (0); } + if (pACB->devstate[target][lun] == ARECA_RAID_GONE) { + uint8_t block_cmd; + + printk + ("arcmsr_queue_command:block ARECA_RAID_GONE Cmd=%2x,TargetId=%d,Lun=%d \n", + cmd->cmnd[0], target, lun); + block_cmd = cmd->cmnd[0] & 0x0f; + if (block_cmd == 0x08 || block_cmd == 0x0a) { + cmd->result = (DID_NO_CONNECT << 16); + cmd->scsi_done(cmd); + return (0); + } + } if ((pCCB = arcmsr_get_freeccb(pACB)) != NULL) { arcmsr_build_ccb(pACB, pCCB, cmd); if (atomic_read(&pACB->ccboutstandingcount) < @@ -1929,8 +1833,8 @@ static int arcmsr_queue_command(struct s arcmsr_queue_wait2go_ccb(pACB, pCCB); } } else { - printk("ARCMSR SCSI ID%d-LUN%d: invalid CCB in start\n", - cmd->device->id, cmd->device->lun); + printk("ARCMSR SCSI ID%d-LUN%d: invalid CCB in start\n", target, + lun); cmd->result = (DID_BUS_BUSY << 16); cmd->scsi_done(cmd); } @@ -1940,20 +1844,167 @@ static int arcmsr_queue_command(struct s /* ********************************************************************** ** +** get firmware miscellaneous data +** +********************************************************************** +*/ +static void arcmsr_get_firmware_spec(struct _ACB *pACB) +{ + char *acb_firm_model = pACB->firm_model; + char *acb_firm_version = pACB->firm_version; + char *iop_firm_model = (char *)(&pACB->pmu->message_rbuffer[15]); /*firm_model,15,60-67 */ + char *iop_firm_version = (char *)(&pACB->pmu->message_rbuffer[17]); /*firm_version,17,68-83 */ + int count; + + writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, &pACB->pmu->inbound_msgaddr0); + if (arcmsr_wait_msgint_ready(pACB)) { + printk + ("arcmsr_get_firmware_spec: wait 'get adapter firmware miscellaneous data' timeout................ \n"); + } + count = 8; + while (count) { + *acb_firm_model = readb(iop_firm_model); + acb_firm_model++; + iop_firm_model++; + count--; + } + count = 16; + while (count) { + *acb_firm_version = readb(iop_firm_version); + acb_firm_version++; + iop_firm_version++; + count--; + } + printk("ARECA FIRMWARE VERSION: %s \n", pACB->firm_version); + if (strncmp(pACB->firm_version, "V1.37", 5) < 0) { + printk + ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + printk + ("!!!!!! PLEASE UPDATE RAID FIRMWARE VERSION EQUAL OR MORE THAN 'V1.37' !!!!!!\n"); + printk + ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + } + pACB->firm_request_len = readl(&pACB->pmu->message_rbuffer[1]); /*firm_request_len,1,04-07 */ + pACB->firm_numbers_queue = readl(&pACB->pmu->message_rbuffer[2]); /*firm_numbers_queue,2,08-11 */ + pACB->firm_sdram_size = readl(&pACB->pmu->message_rbuffer[3]); /*firm_sdram_size,3,12-15 */ + pACB->firm_ide_channels = readl(&pACB->pmu->message_rbuffer[4]); /*firm_ide_channels,4,16-19 */ + return; +} + +/* +********************************************************************** +** ** start background rebulid ** ********************************************************************** */ -static void arcmsr_start_adapter_bgrb(PACB pACB) +static void arcmsr_start_adapter_bgrb(struct _ACB *pACB) { -#if ARCMSR_DEBUG0 - printk - ("arcmsr_start_adapter_bgrb.................................. \n"); -#endif pACB->acb_flags |= ACB_F_MSG_START_BGRB; pACB->acb_flags &= ~ACB_F_MSG_STOP_BGRB; - CHIP_REG_WRITE32(&pACB->pmu->inbound_msgaddr0, - ARCMSR_INBOUND_MESG0_START_BGRB); + writel(ARCMSR_INBOUND_MESG0_START_BGRB, &pACB->pmu->inbound_msgaddr0); + return; +} + +/* +********************************************************************** +** +** +********************************************************************** +*/ +static void arcmsr_polling_ccbdone(struct _ACB *pACB, struct _CCB *poll_ccb) +{ + struct _CCB *pCCB; + uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = + 0; + int id, lun; + + polling_ccb_retry: + poll_count++; + outbound_intstatus = + readl(&pACB->pmu->outbound_intstatus) & pACB->outbound_int_enable; + writel(outbound_intstatus, &pACB->pmu->outbound_intstatus); /*clear interrupt */ + while (1) { + if ((flag_ccb = + readl(&pACB->pmu->outbound_queueport)) == 0xFFFFFFFF) { + if (poll_ccb_done) { + break; /*chip FIFO no ccb for completion already */ + } else { + arc_mdelay(25); + if (poll_count > 100) { + break; + } + goto polling_ccb_retry; + } + } + /* check ifcommand done with no error */ + pCCB = (struct _CCB *)(pACB->vir2phy_offset + (flag_ccb << 5)); /*frame must be 32 bytes aligned */ + if ((pCCB->pACB != pACB) + || (pCCB->startdone != ARCMSR_CCB_START)) { + if ((pCCB->startdone == ARCMSR_CCB_ABORTED) + && (pCCB == poll_ccb)) { + printk + ("arcmsr_polling_ccbdone: ccb='0x%p' command abort successfully \n", + pCCB); + pCCB->pcmd->result = DID_ABORT << 16; + arcmsr_ccb_complete(pCCB); + poll_ccb_done = 1; + continue; + } + printk + ("arcmsr_polling_ccbdone:got an illegal ccb command done ...pACB=0x%p pCCB=0x%p ccboutstandingcount=%d \n", + pACB, pCCB, + atomic_read(&pACB->ccboutstandingcount)); + continue; + } + id = pCCB->pcmd->device->id; + lun = pCCB->pcmd->device->lun; + if ((flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR) == 0) { + if (pACB->devstate[id][lun] == ARECA_RAID_GONE) { + pACB->devstate[id][lun] = ARECA_RAID_GOOD; + } + pCCB->pcmd->result = DID_OK << 16; + arcmsr_ccb_complete(pCCB); + } else { + switch (pCCB->arcmsr_cdb.DeviceStatus) { + case ARCMSR_DEV_SELECT_TIMEOUT: + { + pACB->devstate[id][lun] = + ARECA_RAID_GONE; + pCCB->pcmd->result = DID_TIME_OUT << 16; + arcmsr_ccb_complete(pCCB); + } + break; + case ARCMSR_DEV_ABORTED: + case ARCMSR_DEV_INIT_FAIL: + { + pACB->devstate[id][lun] = + ARECA_RAID_GONE; + pCCB->pcmd->result = + DID_BAD_TARGET << 16; + arcmsr_ccb_complete(pCCB); + } + break; + case SCSISTAT_CHECK_CONDITION: + { + pACB->devstate[id][lun] = + ARECA_RAID_GOOD; + arcmsr_report_sense_info(pCCB); + arcmsr_ccb_complete(pCCB); + } + break; + default: + /* error occur Q all error ccb to errorccbpending Q */ + printk + ("arcmsr_polling_ccbdone:command error done ......but got unknow DeviceStatus=0x%x \n", + pCCB->arcmsr_cdb.DeviceStatus); + pACB->devstate[id][lun] = ARECA_RAID_GONE; + pCCB->pcmd->result = DID_BAD_TARGET << 16; /*unknow error or crc error just for retry */ + arcmsr_ccb_complete(pCCB); + break; + } + } + } /*drain reply FIFO */ return; } @@ -1964,17 +2015,15 @@ static void arcmsr_start_adapter_bgrb(PA ** ********************************************************************** */ -static void arcmsr_iop_init(PACB pACB) +static void arcmsr_iop_init(struct _ACB *pACB) { uint32_t intmask_org, mask, outbound_doorbell, firmware_state = 0; -#if ARCMSR_DEBUG0 - printk("arcmsr_iop_init.................................. \n"); -#endif do { - firmware_state = CHIP_REG_READ32(&pACB->pmu->outbound_msgaddr1); + firmware_state = readl(&pACB->pmu->outbound_msgaddr1); } while ((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0); - intmask_org = CHIP_REG_READ32(&pACB->pmu->outbound_intmask); /*change "disable iop interrupt" to arcmsr_initialize */ + intmask_org = readl(&pACB->pmu->outbound_intmask); /*change "disable iop interrupt" to arcmsr_initialize */ + arcmsr_get_firmware_spec(pACB); /*start background rebuild */ arcmsr_start_adapter_bgrb(pACB); if (arcmsr_wait_msgint_ready(pACB)) { @@ -1982,18 +2031,18 @@ static void arcmsr_iop_init(PACB pACB) ("arcmsr_iop_init: wait 'start adapter background rebulid' timeout................ \n"); } /* clear Qbuffer if door bell ringed */ - outbound_doorbell = CHIP_REG_READ32(&pACB->pmu->outbound_doorbell); + outbound_doorbell = readl(&pACB->pmu->outbound_doorbell); if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) { - CHIP_REG_WRITE32(&pACB->pmu->outbound_doorbell, outbound_doorbell); /*clear interrupt */ - CHIP_REG_WRITE32(&pACB->pmu->inbound_doorbell, - ARCMSR_INBOUND_DRIVER_DATA_READ_OK); + writel(outbound_doorbell, &pACB->pmu->outbound_doorbell); /*clear interrupt */ + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, + &pACB->pmu->inbound_doorbell); } /* enable outbound Post Queue,outbound message0,outbell doorbell Interrupt */ mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE | ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE); - CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask, intmask_org & mask); + writel(intmask_org & mask, &pACB->pmu->outbound_intmask); pACB->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff; pACB->acb_flags |= ACB_F_IOP_INITED; return; @@ -2006,13 +2055,21 @@ static void arcmsr_iop_init(PACB pACB) */ static int arcmsr_bus_reset(struct scsi_cmnd *cmd) { - PACB pACB; + struct _ACB *pACB; + int retry = 0; -#if ARCMSR_DEBUG0 printk("arcmsr_bus_reset.......................... \n"); -#endif - pACB = (PACB) cmd->device->host->hostdata; + pACB = (struct _ACB *)cmd->device->host->hostdata; + pACB->num_resets++; + pACB->acb_flags |= ACB_F_BUS_RESET; + while (atomic_read(&pACB->ccboutstandingcount) != 0 && retry < 400) { + printk + ("arcmsr_bus_reset..........................pACB->ccboutstandingcount!=0 \n"); + arc_mdelay_int(25); + retry++; + } arcmsr_iop_reset(pACB); + pACB->acb_flags &= ~ACB_F_BUS_RESET; return SUCCESS; } @@ -2023,40 +2080,48 @@ static int arcmsr_bus_reset(struct scsi_ */ static int arcmsr_seek_cmd2abort(struct scsi_cmnd *pabortcmd) { - PACB pACB = (PACB) pabortcmd->device->host->hostdata; - PCCB pCCB; + struct _ACB *pACB = (struct _ACB *)pabortcmd->device->host->hostdata; + struct _CCB *pCCB; uint32_t intmask_org, mask; int i = 0; -#if ARCMSR_DEBUG0 - printk("arcmsr_seek_cmd2abort.................. \n"); -#endif + pACB->num_aborts++; /* + ***************************************************************************** ** It is the upper layer do abort command this lock just prior to calling us. ** First determine if we currently own this command. ** Start by searching the device queue. If not found ** at all,and the system wanted us to just abort the ** command return success. + ***************************************************************************** */ if (atomic_read(&pACB->ccboutstandingcount) != 0) { for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { pCCB = pACB->pccb_pool[i]; if (pCCB->startdone == ARCMSR_CCB_START) { if (pCCB->pcmd == pabortcmd) { + pCCB->startdone = ARCMSR_CCB_ABORTED; + printk + ("arcmsr abort ccb '0x%p' outstanding command............... \n", + pCCB); goto abort_outstanding_cmd; } } } } /* + ********************************************************** ** seek this command at our command list ** if command found then remove,abort it and free this CCB + ********************************************************** */ if (atomic_read(&pACB->ccbwait2gocount) != 0) { for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) { pCCB = pACB->pccbwait2go[i]; if (pCCB != NULL) { if (pCCB->pcmd == pabortcmd) { + printk + ("arcmsr abort ccb wait to go command............... \n"); pACB->pccbwait2go[i] = NULL; pCCB->startdone = ARCMSR_CCB_ABORTED; pCCB->pcmd->result = DID_ABORT << 16; @@ -2070,33 +2135,17 @@ static int arcmsr_seek_cmd2abort(struct return (SUCCESS); abort_outstanding_cmd: /* disable all outbound interrupt */ - intmask_org = CHIP_REG_READ32(&pACB->pmu->outbound_intmask); - CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask, - intmask_org | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE); - /* talk to iop 331 outstanding command aborted */ - arcmsr_abort_allcmd(pACB); - if (arcmsr_wait_msgint_ready(pACB)) { - printk - ("arcmsr_seek_cmd2abort: wait 'abort all outstanding command' timeout................. \n"); - } - /*clear all outbound posted Q */ - for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) { - CHIP_REG_READ32(&pACB->pmu->outbound_queueport); - } - for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { - pCCB = pACB->pccb_pool[i]; - if (pCCB->startdone == ARCMSR_CCB_START) { - pCCB->startdone = ARCMSR_CCB_ABORTED; - pCCB->pcmd->result = DID_ABORT << 16; - arcmsr_ccb_complete(pCCB); - } - } + intmask_org = readl(&pACB->pmu->outbound_intmask); + writel(intmask_org | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, + &pACB->pmu->outbound_intmask); + /* do not talk to iop 331 abort command */ + arcmsr_polling_ccbdone(pACB, pCCB); /* enable all outbound interrupt */ mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE | ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE); - CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask, intmask_org & mask); + writel(intmask_org & mask, &pACB->pmu->outbound_intmask); atomic_set(&pACB->ccboutstandingcount, 0); return (SUCCESS); } @@ -2110,9 +2159,13 @@ static int arcmsr_cmd_abort(struct scsi_ { int error; -#if ARCMSR_DEBUG0 printk("arcmsr_cmd_abort.................. \n"); -#endif + /* + ************************************************ + ** the all interrupt service routine is locked + ** we need to handle it as soon as possible and exit + ************************************************ + */ error = arcmsr_seek_cmd2abort(cmd); if (error != SUCCESS) { printk("arcmsr_cmd_abort: returns FAILED\n"); @@ -2173,13 +2226,10 @@ static int arcmsr_cmd_abort(struct scsi_ static const char *arcmsr_info(struct Scsi_Host *host) { static char buf[256]; - PACB pACB; + struct _ACB *pACB; uint16_t device_id; -#if ARCMSR_DEBUG0 - printk("arcmsr_info.............\n"); -#endif - pACB = (PACB) host->hostdata; + pACB = (struct _ACB *)host->hostdata; device_id = pACB->pPCI_DEV->device; switch (device_id) { case PCIDeviceIDARC1110: @@ -2261,19 +2311,17 @@ static const char *arcmsr_info(struct Sc ** ************************************************************************ */ -static int arcmsr_initialize(PACB pACB, struct pci_dev *pPCI_DEV) +static int arcmsr_initialize(struct _ACB *pACB, struct pci_dev *pPCI_DEV) { uint32_t intmask_org, page_base, page_offset, mem_base_start; dma_addr_t dma_coherent_handle, dma_addr; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; uint8_t pcicmd; void *dma_coherent; void *page_remapped; - int i, rc = 0; - PCCB pccb_tmp; + int i; + struct _CCB *pccb_tmp; -#if ARCMSR_DEBUG0 - printk("arcmsr_initialize....................................\n"); -#endif /* Enable Busmaster/Mem */ pci_read_config_byte(pPCI_DEV, PCI_COMMAND, &pcicmd); pci_write_config_byte(pPCI_DEV, PCI_COMMAND, @@ -2286,10 +2334,9 @@ static int arcmsr_initialize(PACB pACB, if (page_remapped == NULL) { printk ("arcmsr_initialize: memory mapping region fail............\n"); - free_irq(pPCI_DEV->irq, pACB); return (ENXIO); } - pACB->pmu = (PMU) (page_remapped + page_offset); + pACB->pmu = (struct _MU *)(page_remapped + page_offset); pACB->acb_flags |= (ACB_F_IOCTL_WQBUFFER_CLEARED | ACB_F_IOCTL_RQBUFFER_CLEARED); pACB->acb_flags &= ~ACB_F_SCSISTOPADAPTER; @@ -2328,7 +2375,6 @@ static int arcmsr_initialize(PACB pACB, ** the consistent allocate ****************************************************************************** */ - rc = pci_set_dma_mask(pPCI_DEV, (dma_addr_t) 0x00000000ffffffffULL); /*32bit */ /* Attempt to claim larger area for request queue pCCB). */ dma_coherent = dma_alloc_coherent(&pPCI_DEV->dev, @@ -2343,16 +2389,17 @@ static int arcmsr_initialize(PACB pACB, pACB->dma_coherent_handle = dma_coherent_handle; memset(dma_coherent, 0, ARCMSR_MAX_FREECCB_NUM * sizeof(struct _CCB) + 0x20); - if (((CPT2INT) dma_coherent & 0x1F) != 0) { /*ccb address must 32 (0x20) boundary */ + if (((unsigned long)dma_coherent & 0x1F) != 0) { /*ccb address must 32 (0x20) boundary */ dma_coherent = - dma_coherent + (0x20 - ((CPT2INT) dma_coherent & 0x1F)); + dma_coherent + (0x20 - + ((unsigned long)dma_coherent & 0x1F)); dma_coherent_handle = dma_coherent_handle + (0x20 - - ((CPT2INT) dma_coherent_handle & + ((unsigned long)dma_coherent_handle & 0x1F)); } dma_addr = dma_coherent_handle; - pccb_tmp = (PCCB) dma_coherent; + pccb_tmp = (struct _CCB *)dma_coherent; for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { pccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5; pccb_tmp->pACB = pACB; @@ -2360,20 +2407,20 @@ static int arcmsr_initialize(PACB pACB, dma_addr = dma_addr + sizeof(struct _CCB); pccb_tmp++; } - pACB->vir2phy_offset = (CPT2INT) pccb_tmp - (CPT2INT) dma_addr; + pACB->vir2phy_offset = + (unsigned long)pccb_tmp - (unsigned long)dma_addr; /* ******************************************************************** ** here we need to tell iop 331 our pccb_tmp.HighPart ** if pccb_tmp.HighPart is not zero ******************************************************************** */ - rc = pci_set_dma_mask(pPCI_DEV, (dma_addr_t) 0xffffffffffffffffULL); /*set dma 64bit again if could */ pACB->adapter_index = arcmsr_adapterCnt; pHCBARC->pACB[arcmsr_adapterCnt] = pACB; /* disable iop all outbound interrupt */ - intmask_org = CHIP_REG_READ32(&pACB->pmu->outbound_intmask); - CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask, - intmask_org | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE); + intmask_org = readl(&pACB->pmu->outbound_intmask); + writel(intmask_org | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, + &pACB->pmu->outbound_intmask); arcmsr_adapterCnt++; return (0); } @@ -2384,9 +2431,6 @@ static int arcmsr_initialize(PACB pACB, */ static int arcmsr_set_info(char *buffer, int length) { -#if ARCMSR_DEBUG0 - printk("arcmsr_set_info.............\n"); -#endif return (0); } @@ -2395,18 +2439,17 @@ static int arcmsr_set_info(char *buffer, ** ********************************************************************* */ -static void arcmsr_pcidev_disattach(PACB pACB) +static void arcmsr_pcidev_disattach(struct _ACB *pACB) { - PCCB pCCB; + struct _CCB *pCCB; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; uint32_t intmask_org, mask; int i = 0; -#if ARCMSR_DEBUG0 - printk("arcmsr_pcidev_disattach.................. \n"); -#endif + /* disable all outbound interrupt */ - intmask_org = CHIP_REG_READ32(&pACB->pmu->outbound_intmask); - CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask, - intmask_org | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE); + intmask_org = readl(&pACB->pmu->outbound_intmask); + writel(intmask_org | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, + &pACB->pmu->outbound_intmask); /* stop adapter background rebuild */ arcmsr_stop_adapter_bgrb(pACB); if (arcmsr_wait_msgint_ready(pACB)) { @@ -2422,15 +2465,10 @@ static void arcmsr_pcidev_disattach(PACB pACB->acb_flags |= ACB_F_SCSISTOPADAPTER; pACB->acb_flags &= ~ACB_F_IOP_INITED; if (atomic_read(&pACB->ccboutstandingcount) != 0) { -#if ARCMSR_DEBUG0 - printk - ("arcmsr_pcidev_disattach: .....pACB->ccboutstandingcount!=0 \n"); -#endif /* disable all outbound interrupt */ - intmask_org = CHIP_REG_READ32(&pACB->pmu->outbound_intmask); - CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask, - intmask_org | - ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE); + intmask_org = readl(&pACB->pmu->outbound_intmask); + writel(intmask_org | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, + &pACB->pmu->outbound_intmask); /* talk to iop 331 outstanding command aborted */ arcmsr_abort_allcmd(pACB); if (arcmsr_wait_msgint_ready(pACB)) { @@ -2439,14 +2477,12 @@ static void arcmsr_pcidev_disattach(PACB } /*clear all outbound posted Q */ for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) { - CHIP_REG_READ32(&pACB->pmu->outbound_queueport); + readl(&pACB->pmu->outbound_queueport); } for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { pCCB = pACB->pccb_pool[i]; if (pCCB->startdone == ARCMSR_CCB_START) { pCCB->startdone = ARCMSR_CCB_ABORTED; - pCCB->pcmd->result = DID_ABORT << 16; - arcmsr_ccb_complete(pCCB); } } /* enable all outbound interrupt */ @@ -2454,8 +2490,7 @@ static void arcmsr_pcidev_disattach(PACB ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE | ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE); - CHIP_REG_WRITE32(&pACB->pmu->outbound_intmask, - intmask_org & mask); + writel(intmask_org & mask, &pACB->pmu->outbound_intmask); atomic_set(&pACB->ccboutstandingcount, 0); } if (atomic_read(&pACB->ccbwait2gocount) != 0) { /*remove first wait2go ccb and abort it */ @@ -2486,13 +2521,11 @@ static void arcmsr_pcidev_disattach(PACB static int arcmsr_halt_notify(struct notifier_block *nb, unsigned long event, void *buf) { - PACB pACB; - struct Scsi_Host *psh; + struct _ACB *pACB; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; + struct Scsi_Host *host; int i; -#if ARCMSR_DEBUG0 - printk("arcmsr_halt_notify............................1 \n"); -#endif if ((event != SYS_RESTART) && (event != SYS_HALT) && (event != SYS_POWER_OFF)) { return NOTIFY_DONE; @@ -2505,10 +2538,10 @@ static int arcmsr_halt_notify(struct not /* Flush cache to disk */ /* Free irq,otherwise extra interrupt is generated */ /* Issue a blocking(interrupts disabled) command to the card */ - psh = pACB->pScsiHost; + host = pACB->host; arcmsr_pcidev_disattach(pACB); - scsi_remove_host(psh); - scsi_host_put(psh); + scsi_remove_host(host); + scsi_host_put(host); } unregister_chrdev(pHCBARC->arcmsr_major_number, "arcmsr"); unregister_reboot_notifier(&arcmsr_event_notifier); @@ -2529,12 +2562,10 @@ static int arcmsr_proc_info(struct Scsi_ off_t offset, int length, int inout) { uint8_t i; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; char *pos = buffer; - PACB pACB; + struct _ACB *pACB; -#if ARCMSR_DEBUG0 - printk("arcmsr_proc_info.............\n"); -#endif if (inout) { return (arcmsr_set_info(buffer, length)); } @@ -2566,16 +2597,14 @@ static int arcmsr_proc_info(struct Scsi_ */ static int arcmsr_release(struct Scsi_Host *host) { - PACB pACB; + struct _ACB *pACB; + struct _HCBARC *pHCBARC = &arcmsr_host_control_block; uint8_t match = 0xff, i; -#if ARCMSR_DEBUG0 - printk("arcmsr_release...........................\n"); -#endif if (host == NULL) { return -ENXIO; } - pACB = (PACB) host->hostdata; + pACB = (struct _ACB *)host->hostdata; if (pACB == NULL) { return -ENXIO; } @@ -2602,9 +2631,3 @@ static int arcmsr_release(struct Scsi_Ho unregister_reboot_notifier(&arcmsr_event_notifier); return (0); } - -MODULE_AUTHOR("Erich Chen"); -MODULE_DESCRIPTION("ARCMSR(ARC11xx/12xx) SATA RAID HOST Adapter"); -#ifdef MODULE_LICENSE -MODULE_LICENSE("Dual BSD/GPL"); -#endif diff -puN drivers/scsi/arcmsr/arcmsr.h~areca-raid-linux-scsi-driver-update drivers/scsi/arcmsr/arcmsr.h --- 25/drivers/scsi/arcmsr/arcmsr.h~areca-raid-linux-scsi-driver-update Tue Sep 20 15:47:57 2005 +++ 25-akpm/drivers/scsi/arcmsr/arcmsr.h Tue Sep 20 15:47:57 2005 @@ -44,18 +44,6 @@ */ #include #include - -#if defined(__SMP__) && !defined(CONFIG_SMP) -# define CONFIG_SMP -#endif -/* -********************************************************************* -*/ -#if BITS_PER_LONG == 64 -typedef uint64_t CPT2INT, *PCPT2INT; -#else -typedef uint32_t CPT2INT, *PCPT2INT; -#endif /* ********************************************************************************** ** @@ -63,7 +51,7 @@ typedef uint32_t CPT2INT, *PCPT2INT; */ #define ARCMSR_MAX_OUTSTANDING_CMD 256 #define ARCMSR_MAX_FREECCB_NUM 320 -#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.07" +#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.09" #define ARCMSR_SCSI_INITIATOR_ID 16 #define ARCMSR_DEV_SECTOR_SIZE 512 #define ARCMSR_MAX_XFER_SECTORS 256 @@ -81,17 +69,6 @@ typedef uint32_t CPT2INT, *PCPT2INT; ** ********************************************************************************** */ -#define CHIP_REG_READ8(a) (uint8_t)(readb((uint8_t *)(a))) -#define CHIP_REG_READ16(a) (uint16_t)(readw((uint16_t *)(a))) -#define CHIP_REG_READ32(a) (uint32_t)(readl((uint32_t *)(a))) -#define CHIP_REG_WRITE8(a,d) writeb((uint8_t)(d),(uint8_t *)(a)) -#define CHIP_REG_WRITE16(a,d) writew((uint16_t)(d),(uint16_t *)(a)) -#define CHIP_REG_WRITE32(a,d) writel((uint32_t)(d),(uint32_t *)(a)) -/* -********************************************************************************** -** -********************************************************************************** -*/ #define PCIVendorIDARECA 0x17D3 /* Vendor ID */ #define PCIDeviceIDARC1110 0x1110 /* Device ID */ #define PCIDeviceIDARC1120 0x1120 /* Device ID */ @@ -105,11 +82,11 @@ typedef uint32_t CPT2INT, *PCPT2INT; #define PCIDeviceIDARC1270 0x1270 /* Device ID */ /* ********************************************************************************** -** +**((unsigned long)addr & 0xffff) ********************************************************************************** */ -#define dma_addr_hi32(a) ((uint32_t) (0xffffffff & (((uint64_t)(a))>>32))) -#define dma_addr_lo32(a) ((uint32_t) (0xffffffff & (((uint64_t)(a))))) +#define dma_addr_hi32(addr) (uint32_t) ((addr>>16)>>16) +#define dma_addr_lo32(addr) (uint32_t) (addr & 0xffffffff) #ifndef pci_resource_start # define arcget_pcicfg_base(pdev,n) pdev->base_address[n] & PCI_BASE_ADDRESS_MEM_MASK @@ -119,100 +96,6 @@ typedef uint32_t CPT2INT, *PCPT2INT; /* ************************************************************************ ** IOCTL CONTROL CODE -** =================== -** IOCtl definitions -** =================== -** Define the various device type values. Note that values used by Microsoft -** Corporation are in the range 0x0000 - 0x7FFF, and 0x8000 - 0xFFFF are -** reserved for use by customers. -** -** #define IOCTL_SCSI_MINIPORT_IO_CONTROL 0x8001 -** -** Macro definition for defining IOCTL and FSCTL function control codes. -** Note that function codes 0x000 - 0x7FF are reserved for Microsoft -** Corporation, and 0x800 - 0xFFF are reserved for customers. -** -** #define RETURNCODE0x0000003F 0x850 -** #define SMP_RETURN_3F CTL_CODE(IOCTL_SCSI_MINIPORT_IO_CONTROL, RETURNCODE0x0000003F, METHOD_BUFFERED, FILE_ANY_ACCESS) -** #define SMP_PRINT_STRING 0x80000001 -**--------------- -** #define IOCTL_Device_Function CTL_CODE(DeviceType, Function, Method, Access) -**--------------- -** _31_ _30..16_ ___15_14___ _13_ _12...2_ _1_0_ -** Common DeviceType Required Access Custom FunctionCode TransferType -** -**--------------- -**DeviceType -** Identifies the device type. -** This value must match the value that is set in the DeviceType member of the driver's DEVICE_OBJECT structure. -** (See Specifying Device Types). -** Values of less than 0x8000 are reserved for Microsoft. -** Values of 0x8000 and higher can be used by vendors. -** Note that the vendor-assigned values set the Common bit. -**--------------- -**FunctionCode -** Identifies the function to be performed by the driver. -** Values of less than 0x800 are reserved for Microsoft. -** Values of 0x800 and higher can be used by vendors. -** Note that the vendor-assigned values set the Custom bit. -**--------------- -**TransferType -** Indicates how the system will pass data between the caller of DeviceIoControl -** (or IoBuildDeviceIoControlRequest) and the driver that handles the IRP. -** Use one of the following system-defined constants: -** METHOD_BUFFERED -** Specifies the buffered I/O method, which is typically used for transferring small amounts of data per request. -** Most I/O control codes for device and intermediate drivers use this TransferType value. -** For information about how the system specifies data buffers for METHOD_BUFFERED I/O control codes, -** see Buffer Descriptions for I/O Control Codes. -** For more information about buffered I/O, see Using Buffered I/O. -** METHOD_IN_DIRECT or METHOD_OUT_DIRECT -** Specifies the direct I/O method, which is typically used for reading or writing large amounts of data, -** using DMA or PIO, that must be transferred quickly. -** Specify METHOD_IN_DIRECT if the caller of DeviceIoControl or IoBuildDeviceIoControlRequest will pass data to the driver. -** Specify METHOD_OUT_DIRECT if the caller of DeviceIoControl or IoBuildDeviceIoControlRequest will receive data from the driver. -** For information about how the system specifies data buffers for METHOD_IN_DIRECT and METHOD_OUT_DIRECT I/O control codes, -** see Buffer Descriptions for I/O Control Codes. -** For more information about direct I/O, see Using Direct I/O. -** METHOD_NEITHER -** Specifies neither buffered nor direct I/O. -** The I/O manager does not provide any system buffers or MDLs. -** The IRP supplies the user-mode virtual addresses of the input and output buffers -** that were specified to DeviceIoControl or IoBuildDeviceIoControlRequest,without validating or mapping them. -** For information about how the system specifies data buffers for METHOD_NEITHER I/O control codes, -** see Buffer Descriptions for I/O Control Codes. -** This method can be used only if the driver can be guaranteed to be running in the context -** of the thread that originated the I/O control request. -** Only a highest-level kernel-mode driver is guaranteed to meet this condition, -** so METHOD_NEITHER is seldom used for the I/O control codes that are passed to low-level device drivers. -** With this method, the highest-level driver must determine whether to set up buffered -** or direct access to user data on receipt of the request, -** possibly must lock down the user buffer, -** and must wrap its access to the user buffer in a structured exception handler (see Handling Exceptions). -** Otherwise, the originating user-mode caller might change the buffered data before the driver can use it, -** or the caller could be swapped out just as the driver is accessing the user buffer. -** For more information, see Using Neither Buffered Nor Direct I/O. -**------------------- -**RequiredAccess -** Indicates the type of access that a caller must request -** when opening the file object that represents the device (see IRP_MJ_CREATE). -** The I/O Manager will create IRPs and call the driver with a particular I/O control code -** only if the caller has requested the specified access rights. -** RequiredAccess is specified by using the following system-defined constants: -** FILE_ANY_ACCESS -** The I/O Manager sends the IRP for any caller that has a handle to the file object -** that represents the target device object. -** FILE_READ_DATA -** The I/O Manager sends the IRP only for a caller with read access rights, -** allowing the underlying device driver to transfer data from the device to system memory. -** FILE_WRITE_DATA -** The I/O Manager sends the IRP only for a caller with write access rights, -** allowing the underlying device driver to transfer data from system memory to its device. -** FILE_READ_DATA and FILE_WRITE_DATA can be OR'ed together -** if the caller must have both read and write access rights. -** Some system-defined I/O control codes have a RequiredAccess value of FILE_ANY_ACCESS. -** This is especially true for I/O control codes that are sent to drivers of exclusive devices, -** and for those that specify buffered I/O. ************************************************************************ */ typedef struct _CMD_IO_CONTROL { @@ -334,6 +217,22 @@ typedef struct _QBUFFER { } QBUFFER, *PQBUFFER; /* ************************************************************************************************ +** FIRMWARE INFO +************************************************************************************************ +*/ +typedef struct _FIRMWARE_INFO { + uint32_t signature; /*0,00-03 */ + uint32_t request_len; /*1,04-07 */ + uint32_t numbers_queue; /*2,08-11 */ + uint32_t sdram_size; /*3,12-15 */ + uint32_t ide_channels; /*4,16-19 */ + char vendor[40]; /*5,20-59 */ + char model[8]; /*15,60-67 */ + char firmware_ver[16]; /*17,68-83 */ + char device_map[16]; /*21,84-99 */ +} FIRMWARE_INFO, *PFIRMWARE_INFO; +/* +************************************************************************************************ ** ARECA FIRMWARE SPEC ************************************************************************************************ ** Usage of IOP331 adapter @@ -347,8 +246,8 @@ typedef struct _QBUFFER { ** 3. Index Memory Usage ** offset 0xf00 : for RS232 out (request buffer) ** offset 0xe00 : for RS232 in (scratch buffer) -** offset 0xa00 : for inbound message code message_wbuffer (driver to IOP331) -** offset 0x800 : for outbound message code message_rbuffer (IOP331 to driver) +** offset 0x800 : for inbound message code message_wbuffer (driver send to IOP331) +** offset 0xa00 : for outbound message code message_rbuffer (IOP331 to driver) ** 4. RS-232 emulation ** Currently 128 byte buffer is used ** 1st uint32_t : Data length (1--124) @@ -387,19 +286,20 @@ typedef struct _QBUFFER { ** 8. Message1 Out - Diag Status Code (????) ** 9. Message0 message code : ** 0x00 : NOP -** 0x01 : Get Config ->offset 0xa00 :for outbound message code message_rbuffer (IOP331 to driver) -** Signature 0x87974060(4) -** Request len 0x00000200(4) -** # of queue 0x00000100(4) -** SDRAM Size 0x00000100(4)-->256 MB -** IDE Channels 0x00000008(4) -** vendor 40 bytes char -** model 8 bytes char -** FirmVer 16 bytes char -** Device Map 16 Bytes +** 0x01 : Get Config ->offset 0xa00 :for outbound message code message_rbuffer (IOP331 send to driver) +** Signature 0x87974060(4) +** Request len 0x00000200(4) +** numbers of queue 0x00000100(4) +** SDRAM Size 0x00000100(4)-->256 MB +** IDE Channels 0x00000008(4) +** vendor 40 bytes char +** model 8 bytes char +** FirmVer 16 bytes char +** Device Map 16 bytes char +** ** FirmwareVersion DWORD <== Added for checking of new firmware capability -** 0x02 : Set Config ->offset 0xa00 : for inbound message code message_wbuffer (driver to IOP331) -** Signature 0x87974063(4) +** 0x02 : Set Config ->offset 0x800 : for inbound message code message_wbuffer (driver send to IOP331) +** Signature 0x87974063(4) ** UPPER32 of Request Frame (4)-->Driver Only ** 0x03 : Reset (Abort all queued Command) ** 0x04 : Stop Background Activity @@ -571,8 +471,8 @@ typedef struct _MU { uint32_t outbound_queueport; /*0044 0047 */ uint32_t reserved2[2]; /*0048 004F */ uint32_t reserved3[492]; /*0050 07FF ......local_buffer 492 */ - uint32_t message_rbuffer[128]; /*0800 09FF 128 */ - uint32_t message_wbuffer[256]; /*0a00 0DFF 256 */ + uint32_t message_wbuffer[128]; /*0800 09FF 128 */ + uint32_t message_rbuffer[256]; /*0a00 0DFF 256 */ uint32_t ioctl_wbuffer[32]; /*0E00 0E7F 32 */ uint32_t reserved4[32]; /*0E80 0EFF 32 */ uint32_t ioctl_rbuffer[32]; /*0F00 0F7F 32 */ @@ -586,12 +486,8 @@ typedef struct _MU { */ typedef struct _ACB { struct pci_dev *pPCI_DEV; - struct Scsi_Host *pScsiHost; -#if BITS_PER_LONG == 64 - uint64_t vir2phy_offset; /* Offset is used in making arc cdb physical to virtual calculations */ -#else - uint32_t vir2phy_offset; /* Offset is used in making arc cdb physical to virtual calculations */ -#endif + struct Scsi_Host *host; + unsigned long vir2phy_offset; /* Offset is used in making arc cdb physical to virtual calculations */ uint32_t outbound_int_enable; struct _MU *pmu; /* message unit ATU inbound base address0 */ @@ -605,7 +501,7 @@ typedef struct _ACB { #define ACB_F_IOPDATA_OVERFLOW 0x0008 /* iop ioctl data rqbuffer overflow */ #define ACB_F_IOCTL_WQBUFFER_CLEARED 0x0010 /* ioctl clear wqbuffer */ #define ACB_F_IOCTL_RQBUFFER_CLEARED 0x0020 /* ioctl clear rqbuffer */ -#define ACB_F_IOCTL_OPEN 0x0040 +#define ACB_F_BUS_RESET 0x0040 #define ACB_F_IOP_INITED 0x0080 /* iop init */ struct _CCB *pccbwait2go[ARCMSR_MAX_OUTSTANDING_CMD]; @@ -632,6 +528,17 @@ typedef struct _ACB { spinlock_t qbuffer_lockunlock; spinlock_t ccb_doneindex_lockunlock; spinlock_t ccb_startindex_lockunlock; + uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; /* id0 ..... id15,lun0...lun7 */ +#define ARECA_RAID_GONE 0x55 +#define ARECA_RAID_GOOD 0xaa + uint32_t num_resets; + uint32_t num_aborts; + uint32_t firm_request_len; /*1,04-07 */ + uint32_t firm_numbers_queue; /*2,08-11 */ + uint32_t firm_sdram_size; /*3,12-15 */ + uint32_t firm_ide_channels; /*4,16-19 */ + char firm_model[12]; /*15,60-67 */ + char firm_version[20]; /*17,68-83 */ } ACB, *PACB; /* HW_DEVICE_EXTENSION */ /* ********************************************************************* diff -puN drivers/scsi/arcmsr/arcmsr.txt~areca-raid-linux-scsi-driver-update drivers/scsi/arcmsr/arcmsr.txt --- 25/drivers/scsi/arcmsr/arcmsr.txt~areca-raid-linux-scsi-driver-update Tue Sep 20 15:47:57 2005 +++ 25-akpm/drivers/scsi/arcmsr/arcmsr.txt Tue Sep 20 15:47:57 2005 @@ -23,13 +23,15 @@ History 1.20.00.06 3/12/2005 Erich Chen fix with arcmsr_pci_unmap_dma "unsigned long" cast, modify PCCB POOL allocated by "dma_alloc_coherent" (Kornel Wieliczek's comment) - 1.20.00.07 3/23/2005 Erich Chen bug fix with arcmsr_scsi_host_template_init ocur segmentation fault, if RAID adapter does not on PCI slot and modprobe/rmmod this driver twice. bug fix enormous stack usage (Adrian Bunk's comment) + 1.20.00.08 6/23/2005 Erich Chen bug fix with abort command,in case of heavy loading when sata cable + working on low quality connection + 1.20.00.09 9/12/2005 Erich Chen bug fix with abort command handling,firmware version check + and firmware update notify for hardware bug fix ===================================================================================================== Support: - Linux SCSI RAID driver technical support mail address: erich@areca.com.tw @@ -42,13 +44,10 @@ Support: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ... .... - obj-$(CONFIG_SCSI_ARCMSR) += arcmsr/ - .... ... @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - /usr/src/linux/drivers/scsi/Kconfig @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ... @@ -66,7 +65,6 @@ config SCSI_ARCMSR To compile this driver as a module, choose M here: the module will be called arcmsr (modprobe arcmsr) . - .... ... @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ diff -puN drivers/scsi/Kconfig~areca-raid-linux-scsi-driver-update drivers/scsi/Kconfig --- 25/drivers/scsi/Kconfig~areca-raid-linux-scsi-driver-update Tue Sep 20 15:48:03 2005 +++ 25-akpm/drivers/scsi/Kconfig Tue Sep 20 15:48:38 2005 @@ -320,7 +320,7 @@ config SCSI_ARCMSR This driver supports all of ARECA's SATA RAID controllers cards. This is an ARECA maintained driver by Erich Chen. If you have any problems, please mail to: < erich@areca.com.tw > - Areca have suport Linux RAID config tools + Areca have support Linux RAID config tools < http://www.areca.com.tw > _