From: "erich" I had modified some incorrect code about Arjan van de Ven comment. And change this driver version to 1.20.00.11 . 1.20.00.10 9/23/2005 enhance sysfs function for change driver's max tag Q number. add DMA_64BIT_MASK for backward compatible with all 2.6.x add some useful message for abort command add ioctl code 'ARCMSR_IOCTL_FLUSH_ADAPTER_CACHE' customer can send this command for sync raid volume data 1.20.00.11 9/29/2005 by comment of Arjan van de Ven fix incorrect msleep redefine cast off sizeof(dma_addr_t) condition for 64bit pci_set_dma_mask Signed-off-by: Andrew Morton --- drivers/scsi/Kconfig | 28 +- drivers/scsi/arcmsr/arcmsr.c | 384 ++++++++++++++++++++++++----------------- drivers/scsi/arcmsr/arcmsr.h | 19 +- drivers/scsi/arcmsr/arcmsr.txt | 13 + 4 files changed, 269 insertions(+), 175 deletions(-) diff -puN drivers/scsi/arcmsr/arcmsr.c~areca-raid-linux-scsi-driver-update-2 drivers/scsi/arcmsr/arcmsr.c --- devel/drivers/scsi/arcmsr/arcmsr.c~areca-raid-linux-scsi-driver-update-2 2005-09-29 02:47:00.000000000 -0700 +++ devel-akpm/drivers/scsi/arcmsr/arcmsr.c 2005-09-29 02:47:00.000000000 -0700 @@ -71,6 +71,13 @@ ** 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 +** 1.20.00.10 9/23/2005 Erich Chen enhance sysfs function for change driver's max tag Q number. +** add DMA_64BIT_MASK for backward compatible with all 2.6.x +** add some useful message for abort command +** add ioctl code 'ARCMSR_IOCTL_FLUSH_ADAPTER_CACHE' +** customer can send this command for sync raid volume data +** 1.20.00.11 9/29/2005 Erich Chen by comment of Arjan van de Ven fix incorrect msleep redefine +** cast off sizeof(dma_addr_t) condition for 64bit pci_set_dma_mask ****************************************************************************************** */ #include @@ -90,33 +97,22 @@ #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_AUTHOR("Erich Chen "); +MODULE_DESCRIPTION("ARECA (ARC11xx/12xx) SATA RAID HOST Adapter"); 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 /* ********************************************************************************** -** ********************************************************************************** */ static u_int8_t arcmsr_adapterCnt = 0; static struct _HCBARC arcmsr_host_control_block; /* ********************************************************************************** -** ********************************************************************************** */ static int arcmsr_fops_ioctl(struct inode *inode, struct file *filep, @@ -161,21 +157,26 @@ static ssize_t arcmsr_show_firmware_info 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", + "=================================\n" + "Firmware Version: %s\n" + "%s" + "Adapter Model: %s\n" + "Reguest Lenth: %4d\n" + "Numbers of Queue: %4d\n" + "SDRAM Size: %4d\n" + "IDE Channels: %4d\n" + "=================================\n", pACB->firm_version, - pACB->firm_model, - pACB->firm_request_len, - pACB->firm_numbers_queue, - pACB->firm_sdram_size, pACB->firm_ide_channels); + (strncmp(pACB->firm_version, "V1.37", 5) < + 0) ? + " PLEASE UPDATE RAID FIRMWARE VERSION EQUAL OR MORE THAN 'V1.37'\n" + : "", 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) +static ssize_t arcmsr_show_driver_state(struct class_device *dev, char *buf) { struct Scsi_Host *host = class_to_shost(dev); struct _ACB *pACB = (struct _ACB *)host->hostdata; @@ -184,15 +185,17 @@ static ssize_t arcmsr_show_current_state 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", + "=================================\n" + "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" + "=================================\n", ARCMSR_DRIVER_VERSION, atomic_read(&pACB->ccboutstandingcount), ARCMSR_MAX_OUTSTANDING_CMD, @@ -206,23 +209,46 @@ static ssize_t arcmsr_show_current_state } static struct class_device_attribute arcmsr_firmware_info_attr = { .attr = { - .name = "firmware info", + .name = "firmware_info", .mode = S_IRUGO, }, .show = arcmsr_show_firmware_info, }; static struct class_device_attribute arcmsr_driver_state_attr = { .attr = { - .name = "stats", + .name = "driver_state", .mode = S_IRUGO, }, - .show = arcmsr_show_current_state + .show = arcmsr_show_driver_state }; -static struct class_device_attribute *arcmsr_host_attrs[] = { +static struct class_device_attribute *arcmsr_scsi_host_attr[] = { &arcmsr_firmware_info_attr, &arcmsr_driver_state_attr, NULL }; +static ssize_t arcmsr_adjust_queue_depth(struct device *dev, const char *buf, + size_t count) +{ + int queue_depth; + struct scsi_device *sdev = to_scsi_device(dev); + + queue_depth = simple_strtoul(buf, NULL, 0); + if (queue_depth > ARCMSR_MAX_CMD_PERLUN) + return -EINVAL; + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth); + return count; +} +static struct device_attribute arcmsr_queue_depth_attr = { + .attr = { + .name = "queue_depth", + .mode = S_IRUSR | S_IWUSR, + }, + .store = arcmsr_adjust_queue_depth +}; +static struct device_attribute *arcmsr_scsi_device_attr[] = { + &arcmsr_queue_depth_attr, + NULL, +}; static struct scsi_host_template arcmsr_scsi_host_template = { .module = THIS_MODULE, .proc_name = "arcmsr", @@ -245,7 +271,8 @@ static struct scsi_host_template arcmsr_ .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN, .unchecked_isa_dma = 0, .use_clustering = ENABLE_CLUSTERING, - .shost_attrs = arcmsr_host_attrs, + .shost_attrs = arcmsr_scsi_host_attr, + .sdev_attrs = arcmsr_scsi_device_attr, }; /* @@ -358,28 +385,38 @@ static int __devinit arcmsr_device_probe struct Scsi_Host *host; struct _HCBARC *pHCBARC = &arcmsr_host_control_block; struct _ACB *pACB; + uint8_t bus, dev_fun; if (pci_enable_device(pPCI_DEV)) { - printk - ("arcmsr_device_probe: pci_enable_device error .....................\n"); + printk("arcmsr%d adapter probe: pci_enable_device error \n", + arcmsr_adapterCnt); return -ENODEV; } /* allocate scsi host information (includes out adapter) scsi_host_alloc==scsi_register */ if ((host = scsi_host_alloc(&arcmsr_scsi_host_template, sizeof(struct _ACB))) == 0) { - printk - ("arcmsr_device_probe: scsi_host_alloc error .....................\n"); + printk("arcmsr%d adapter probe: scsi_host_alloc error \n", + arcmsr_adapterCnt); return -ENODEV; } - 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_32BIT_MASK)) { /*32bit */ + if (!pci_set_dma_mask(pPCI_DEV, DMA_64BIT_MASK) + && !pci_set_consistent_dma_mask(pPCI_DEV, DMA_64BIT_MASK)) { printk - ("ARECA RAID: 32BITS PCI BUS DMA ADDRESSING NOT SUPPORTED (ERROR)\n"); - scsi_host_put(host); - return -ENODEV; + ("ARECA RAID ADAPTER%d: 64BITS PCI BUS DMA ADDRESSING SUPPORTED 'USING DAC'\n", + arcmsr_adapterCnt); + } else if (!pci_set_dma_mask(pPCI_DEV, DMA_32BIT_MASK) + && !pci_set_consistent_dma_mask(pPCI_DEV, DMA_32BIT_MASK)) { + printk + ("ARECA RAID ADAPTER%d: 32BITS PCI BUS DMA ADDRESSING SUPPORTED \n", + arcmsr_adapterCnt); + } else { + printk("ARECA RAID ADAPTER%d: No suitable DMA available.\n", + arcmsr_adapterCnt); + return -ENOMEM; } + bus = pPCI_DEV->bus->number; + dev_fun = pPCI_DEV->devfn; pACB = (struct _ACB *)host->hostdata; memset(pACB, 0, sizeof(struct _ACB)); spin_lock_init(&pACB->isr_lockunlock); @@ -397,22 +434,22 @@ static int __devinit arcmsr_device_probe 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->unique_id = (bus << 8) | dev_fun; 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"); + printk("arcmsr%d initialize got error \n", arcmsr_adapterCnt--); + pHCBARC->adapterCnt = arcmsr_adapterCnt; + pHCBARC->pACB[arcmsr_adapterCnt] = NULL; scsi_host_put(host); return -ENODEV; } if (pci_request_regions(pPCI_DEV, "arcmsr")) { - printk - ("arcmsr_device_probe: pci_request_regions.............!\n"); - arcmsr_adapterCnt--; + printk("arcmsr%d adapter probe: pci_request_regions failed \n", + arcmsr_adapterCnt--); pHCBARC->adapterCnt = arcmsr_adapterCnt; - pHCBARC->pACB[pACB->adapter_index] = NULL; arcmsr_pcidev_disattach(pACB); scsi_host_put(host); return -ENODEV; @@ -420,21 +457,18 @@ static int __devinit arcmsr_device_probe if (request_irq (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); - arcmsr_adapterCnt--; + printk("arcmsr%d request IRQ=%d failed !\n", + arcmsr_adapterCnt--, pPCI_DEV->irq); pHCBARC->adapterCnt = arcmsr_adapterCnt; - pHCBARC->pACB[pACB->adapter_index] = NULL; arcmsr_pcidev_disattach(pACB); scsi_host_put(host); return -ENODEV; } arcmsr_iop_init(pACB); if (scsi_add_host(host, &pPCI_DEV->dev)) { - printk("arcmsr: scsi_add_host got error...................\n"); - arcmsr_adapterCnt--; + printk("arcmsr%d 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(host); return -ENODEV; @@ -523,8 +557,6 @@ module_init(arcmsr_module_init); module_exit(arcmsr_module_exit); /* ********************************************************************** -** -** ********************************************************************** */ static void arcmsr_pci_unmap_dma(struct _CCB *pCCB) @@ -549,7 +581,6 @@ static void arcmsr_pci_unmap_dma(struct /* ********************************************************************************** -** ********************************************************************************** */ static int arcmsr_fops_open(struct inode *inode, struct file *filep) @@ -577,7 +608,6 @@ static int arcmsr_fops_open(struct inode /* ********************************************************************************** -** ********************************************************************************** */ static int arcmsr_fops_close(struct inode *inode, struct file *filep) @@ -605,7 +635,6 @@ static int arcmsr_fops_close(struct inod /* ********************************************************************************** -** ********************************************************************************** */ static int arcmsr_fops_ioctl(struct inode *inode, struct file *filep, @@ -639,8 +668,6 @@ static int arcmsr_fops_ioctl(struct inod /* ************************************************************************ -** -** ************************************************************************ */ static void arcmsr_flush_adapter_cache(struct _ACB *pACB) @@ -651,9 +678,7 @@ static void arcmsr_flush_adapter_cache(s /* ********************************************************************** -** ** Q back this CCB into ACB ArrayCCB -** ********************************************************************** */ static void arcmsr_ccb_complete(struct _CCB *pCCB) @@ -728,7 +753,6 @@ static void arcmsr_queue_wait2go_ccb(str /* ********************************************************************* -** ********************************************************************* */ static void arcmsr_abort_allcmd(struct _ACB *pACB) @@ -741,7 +765,6 @@ static void arcmsr_abort_allcmd(struct _ /* ********************************************************************** -** ********************************************************************** */ static u_int8_t arcmsr_wait_msgint_ready(struct _ACB *pACB) @@ -755,8 +778,7 @@ static u_int8_t arcmsr_wait_msgint_ready writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, &pACB->pmu->outbound_intstatus); /*clear interrupt */ return 0x00; } - /* one us delay */ - arc_mdelay_int(10); + msleep_interruptible(10); } /*max 1 seconds */ } while (Retries++ < 20); /*max 20 sec */ return 0xff; @@ -825,8 +847,6 @@ static void arcmsr_iop_reset(struct _ACB /* ********************************************************************** -** -** PAGE_SIZE=4096 or 8192,PAGE_SHIFT=12 ********************************************************************** */ static void arcmsr_build_ccb(struct _ACB *pACB, struct _CCB *pCCB, @@ -921,7 +941,6 @@ static void arcmsr_build_ccb(struct _ACB /* ************************************************************************** -** ** arcmsr_post_ccb - Send a protocol specific ARC send postcard to a AIOC . ** handle: Handle of registered ARC protocol driver ** adapter_id: AIOC unique identifier(integer) @@ -929,7 +948,6 @@ static void arcmsr_build_ccb(struct _ACB ** ** This routine posts a ARC send postcard to the request post FIFO of a ** specific ARC adapter. -** ************************************************************************** */ static void arcmsr_post_ccb(struct _ACB *pACB, struct _CCB *pCCB) @@ -951,8 +969,6 @@ static void arcmsr_post_ccb(struct _ACB /* ************************************************************************** -** -** ************************************************************************** */ static void arcmsr_post_wait2go_ccb(struct _ACB *pACB) @@ -1011,8 +1027,6 @@ static void arcmsr_post_Qbuffer(struct _ /* ************************************************************************ -** -** ************************************************************************ */ static void arcmsr_stop_adapter_bgrb(struct _ACB *pACB) @@ -1025,8 +1039,6 @@ static void arcmsr_stop_adapter_bgrb(str /* ************************************************************************ -** -** ************************************************************************ */ static void arcmsr_free_ccb_pool(struct _ACB *pACB) @@ -1145,6 +1157,7 @@ static irqreturn_t arcmsr_interrupt(stru } } if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) { + int id, lun; /* ***************************************************************************** ** areca cdb command done @@ -1161,39 +1174,47 @@ static irqreturn_t arcmsr_interrupt(stru if ((pCCB->pACB != pACB) || (pCCB->startdone != ARCMSR_CCB_START)) { if (pCCB->startdone == ARCMSR_CCB_ABORTED) { + printk + ("arcmsr%d scsi id=%d lun=%d ccb='0x%p' isr command abort successfully \n", + pACB->adapter_index, + pCCB->pcmd->device->id, + pCCB->pcmd->device->lun, pCCB); pCCB->pcmd->result = DID_ABORT << 16; arcmsr_ccb_complete(pCCB); - } 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)); + continue; } + printk + ("arcmsr%d isr and getting an illegal ccb command done acb='0x%p' ccb='0x%p' ccbacb='0x%p' startdone=0x%x ccboutstandingcount=%d \n", + pACB->adapter_index, pACB, pCCB, + pCCB->pACB, pCCB->startdone, + 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: - { - pCCB->pcmd->result = - DID_NO_CONNECT << 16; - arcmsr_ccb_complete(pCCB); - } - break; case ARCMSR_DEV_INIT_FAIL: { + pACB->devstate[id][lun] = + ARECA_RAID_GONE; pCCB->pcmd->result = DID_BAD_TARGET << 16; arcmsr_ccb_complete(pCCB); @@ -1201,6 +1222,8 @@ static irqreturn_t arcmsr_interrupt(stru break; case SCSISTAT_CHECK_CONDITION: { + pACB->devstate[id][lun] = + ARECA_RAID_GOOD; arcmsr_report_sense_info(pCCB); arcmsr_ccb_complete(pCCB); } @@ -1208,11 +1231,11 @@ static irqreturn_t arcmsr_interrupt(stru default: /* error occur Q all error ccb to errorccbpending Q */ printk - ("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)); + ("arcmsr%d scsi id=%d lun=%d isr get command error done, but got unknow DeviceStatus=0x%x \n", + pACB->adapter_index, id, lun, + pCCB->arcmsr_cdb.DeviceStatus); + pACB->devstate[id][lun] = + ARECA_RAID_GONE; pCCB->pcmd->result = DID_NO_CONNECT << 16; /*unknow error or crc error just for retry */ arcmsr_ccb_complete(pCCB); break; @@ -1231,8 +1254,33 @@ static irqreturn_t arcmsr_interrupt(stru } /* +******************************************************************************* +******************************************************************************* +*/ +static void arcmsr_iop_parking(struct _ACB *pACB) +{ + if (pACB != NULL) { + /* stop adapter background rebuild */ + if (pACB->acb_flags & ACB_F_MSG_START_BGRB) { + pACB->acb_flags &= ~ACB_F_MSG_START_BGRB; + arcmsr_stop_adapter_bgrb(pACB); + if (arcmsr_wait_msgint_ready(pACB)) { + printk + ("arcmsr%d wait 'stop adapter rebulid' timeout \n", + pACB->adapter_index); + } + arcmsr_flush_adapter_cache(pACB); + if (arcmsr_wait_msgint_ready(pACB)) { + printk + ("arcmsr%d wait 'stop adapter rebulid' timeout \n", + pACB->adapter_index); + } + } + } +} + +/* *********************************************************************** -** ************************************************************************ */ static int arcmsr_iop_ioctlcmd(struct _ACB *pACB, int ioctl_cmd, void *arg) @@ -1493,6 +1541,21 @@ static int arcmsr_iop_ioctlcmd(struct _A } } break; + case ARCMSR_IOCTL_SAY_GOODBYE: + { + arcmsr_iop_parking(pACB); + } + break; + case ARCMSR_IOCTL_FLUSH_ADAPTER_CACHE: + { + arcmsr_flush_adapter_cache(pACB); + if (arcmsr_wait_msgint_ready(pACB)) { + printk + ("arcmsr%d ioctl flush cache wait 'flush adapter cache' timeout \n", + pACB->adapter_index); + } + } + break; default: retvalue = -EFAULT; } @@ -1605,7 +1668,6 @@ static int arcmsr_ioctl(struct scsi_devi /* ************************************************************************** -** ************************************************************************** */ static struct _CCB *arcmsr_get_freeccb(struct _ACB *pACB) @@ -1796,7 +1858,8 @@ static int arcmsr_queue_command(struct s return (0); } if (pACB->acb_flags & ACB_F_BUS_RESET) { - printk("arcmsr_queue_command: bus reset return busy .......\n"); + printk("arcmsr%d bus reset and return busy \n", + pACB->adapter_index); cmd->result = (DID_BUS_BUSY << 16); cmd->scsi_done(cmd); return (0); @@ -1804,11 +1867,11 @@ static int arcmsr_queue_command(struct s 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) { + printk + ("arcmsr%d block 'read/write' command with gone raid volume Cmd=%2x,TargetId=%d,Lun=%d \n", + pACB->adapter_index, cmd->cmnd[0], target, lun); cmd->result = (DID_NO_CONNECT << 16); cmd->scsi_done(cmd); return (0); @@ -1833,8 +1896,11 @@ 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", target, - lun); + printk + ("arcmsr%d 'out of ccbs resource' ccb outstanding=%d pending=%d \n", + pACB->adapter_index, + atomic_read(&pACB->ccboutstandingcount), + atomic_read(&pACB->ccbwait2gocount)); cmd->result = (DID_BUS_BUSY << 16); cmd->scsi_done(cmd); } @@ -1843,9 +1909,7 @@ static int arcmsr_queue_command(struct s /* ********************************************************************** -** ** get firmware miscellaneous data -** ********************************************************************** */ static void arcmsr_get_firmware_spec(struct _ACB *pACB) @@ -1859,7 +1923,8 @@ static void arcmsr_get_firmware_spec(str 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"); + ("arcmsr%d wait 'get adapter firmware miscellaneous data' timeout \n", + pACB->adapter_index); } count = 8; while (count) { @@ -1875,7 +1940,8 @@ static void arcmsr_get_firmware_spec(str iop_firm_version++; count--; } - printk("ARECA FIRMWARE VERSION: %s \n", pACB->firm_version); + printk("ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", + pACB->adapter_index, pACB->firm_version); if (strncmp(pACB->firm_version, "V1.37", 5) < 0) { printk ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); @@ -1893,9 +1959,7 @@ static void arcmsr_get_firmware_spec(str /* ********************************************************************** -** ** start background rebulid -** ********************************************************************** */ static void arcmsr_start_adapter_bgrb(struct _ACB *pACB) @@ -1908,8 +1972,6 @@ static void arcmsr_start_adapter_bgrb(st /* ********************************************************************** -** -** ********************************************************************** */ static void arcmsr_polling_ccbdone(struct _ACB *pACB, struct _CCB *poll_ccb) @@ -1930,7 +1992,7 @@ static void arcmsr_polling_ccbdone(struc if (poll_ccb_done) { break; /*chip FIFO no ccb for completion already */ } else { - arc_mdelay(25); + msleep(25); if (poll_count > 100) { break; } @@ -1944,16 +2006,18 @@ static void arcmsr_polling_ccbdone(struc if ((pCCB->startdone == ARCMSR_CCB_ABORTED) && (pCCB == poll_ccb)) { printk - ("arcmsr_polling_ccbdone: ccb='0x%p' command abort successfully \n", - pCCB); + ("arcmsr%d scsi id=%d lun=%d ccb='0x%p' poll command abort successfully \n", + pACB->adapter_index, + pCCB->pcmd->device->id, + pCCB->pcmd->device->lun, 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, + ("arcmsr%d polling and getting an illegal ccb command done ccb='0x%p' ccboutstandingcount=%d \n", + pACB->adapter_index, pCCB, atomic_read(&pACB->ccboutstandingcount)); continue; } @@ -1996,7 +2060,8 @@ static void arcmsr_polling_ccbdone(struc default: /* error occur Q all error ccb to errorccbpending Q */ printk - ("arcmsr_polling_ccbdone:command error done ......but got unknow DeviceStatus=0x%x \n", + ("arcmsr%d scsi id=%d lun=%d polling and getting command error done, but got unknow DeviceStatus=0x%x \n", + pACB->adapter_index, id, lun, 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 */ @@ -2010,9 +2075,7 @@ static void arcmsr_polling_ccbdone(struc /* ********************************************************************** -** ** start background rebulid -** ********************************************************************** */ static void arcmsr_iop_init(struct _ACB *pACB) @@ -2028,7 +2091,8 @@ static void arcmsr_iop_init(struct _ACB arcmsr_start_adapter_bgrb(pACB); if (arcmsr_wait_msgint_ready(pACB)) { printk - ("arcmsr_iop_init: wait 'start adapter background rebulid' timeout................ \n"); + ("arcmsr%d wait 'start adapter background rebulid' timeout \n", + pACB->adapter_index); } /* clear Qbuffer if door bell ringed */ outbound_doorbell = readl(&pACB->pmu->outbound_doorbell); @@ -2050,7 +2114,6 @@ static void arcmsr_iop_init(struct _ACB /* **************************************************************************** -** **************************************************************************** */ static int arcmsr_bus_reset(struct scsi_cmnd *cmd) @@ -2058,14 +2121,15 @@ static int arcmsr_bus_reset(struct scsi_ struct _ACB *pACB; int retry = 0; - printk("arcmsr_bus_reset.......................... \n"); pACB = (struct _ACB *)cmd->device->host->hostdata; + printk("arcmsr%d bus reset ..... \n", pACB->adapter_index); 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); + ("arcmsr%d bus reset wait ccb outstanding command count equal to zero \n", + pACB->adapter_index); + msleep_interruptible(25); retry++; } arcmsr_iop_reset(pACB); @@ -2075,7 +2139,6 @@ static int arcmsr_bus_reset(struct scsi_ /* ***************************************************************************************** -** ***************************************************************************************** */ static int arcmsr_seek_cmd2abort(struct scsi_cmnd *pabortcmd) @@ -2102,8 +2165,10 @@ static int arcmsr_seek_cmd2abort(struct if (pCCB->pcmd == pabortcmd) { pCCB->startdone = ARCMSR_CCB_ABORTED; printk - ("arcmsr abort ccb '0x%p' outstanding command............... \n", - pCCB); + ("arcmsr%d scsi id=%d lun=%d abort ccb '0x%p' outstanding command \n", + pACB->adapter_index, + pabortcmd->device->id, + pabortcmd->device->lun, pCCB); goto abort_outstanding_cmd; } } @@ -2121,7 +2186,10 @@ static int arcmsr_seek_cmd2abort(struct if (pCCB != NULL) { if (pCCB->pcmd == pabortcmd) { printk - ("arcmsr abort ccb wait to go command............... \n"); + ("arcmsr%d scsi id=%d lun=%d abort ccb '0x%p' pending command \n", + pACB->adapter_index, + pabortcmd->device->id, + pabortcmd->device->lun, pCCB); pACB->pccbwait2go[i] = NULL; pCCB->startdone = ARCMSR_CCB_ABORTED; pCCB->pcmd->result = DID_ABORT << 16; @@ -2152,14 +2220,15 @@ static int arcmsr_seek_cmd2abort(struct /* ***************************************************************************************** -** ***************************************************************************************** */ static int arcmsr_cmd_abort(struct scsi_cmnd *cmd) { + struct _ACB *pACB = (struct _ACB *)cmd->device->host->hostdata; int error; - printk("arcmsr_cmd_abort.................. \n"); + printk("arcmsr%d abort device command of scsi id=%d lun=%d \n", + pACB->adapter_index, cmd->device->id, cmd->device->lun); /* ************************************************ ** the all interrupt service routine is locked @@ -2168,7 +2237,8 @@ static int arcmsr_cmd_abort(struct scsi_ */ error = arcmsr_seek_cmd2abort(cmd); if (error != SUCCESS) { - printk("arcmsr_cmd_abort: returns FAILED\n"); + printk("arcmsr%d abort command failed scsi id=%d lun=%d \n", + pACB->adapter_index, cmd->device->id, cmd->device->lun); } return (error); } @@ -2308,7 +2378,6 @@ static const char *arcmsr_info(struct Sc /* ************************************************************************ -** ************************************************************************ */ static int arcmsr_initialize(struct _ACB *pACB, struct pci_dev *pPCI_DEV) @@ -2319,7 +2388,7 @@ static int arcmsr_initialize(struct _ACB uint8_t pcicmd; void *dma_coherent; void *page_remapped; - int i; + int i, j; struct _CCB *pccb_tmp; /* Enable Busmaster/Mem */ @@ -2327,13 +2396,13 @@ static int arcmsr_initialize(struct _ACB pci_write_config_byte(pPCI_DEV, PCI_COMMAND, pcicmd | PCI_COMMAND_INVALIDATE | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); - mem_base_start = (uint32_t) arcget_pcicfg_base(pPCI_DEV, 0); + mem_base_start = (uint32_t) pci_resource_start(pPCI_DEV, 0); page_base = mem_base_start & PAGE_MASK; page_offset = mem_base_start - page_base; page_remapped = ioremap(page_base, page_offset + 0x1FFF); if (page_remapped == NULL) { - printk - ("arcmsr_initialize: memory mapping region fail............\n"); + printk("arcmsr%d memory mapping region fail \n", + arcmsr_adapterCnt); return (ENXIO); } pACB->pmu = (struct _MU *)(page_remapped + page_offset); @@ -2381,8 +2450,8 @@ static int arcmsr_initialize(struct _ACB ARCMSR_MAX_FREECCB_NUM * sizeof(struct _CCB) + 0x20, &dma_coherent_handle, GFP_KERNEL); if (dma_coherent == NULL) { - printk - ("arcmsr_initialize:dma_alloc_coherent got error.......... \n"); + printk("arcmsr%d dma_alloc_coherent got error \n", + arcmsr_adapterCnt); return -ENOMEM; } pACB->dma_coherent = dma_coherent; @@ -2411,6 +2480,16 @@ static int arcmsr_initialize(struct _ACB (unsigned long)pccb_tmp - (unsigned long)dma_addr; /* ******************************************************************** + ** init raid volume state + ******************************************************************** + */ + for (i = 0; i < ARCMSR_MAX_TARGETID; i++) { + for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) { + pACB->devstate[i][j] = ARECA_RAID_GOOD; + } + } + /* + ******************************************************************** ** here we need to tell iop 331 our pccb_tmp.HighPart ** if pccb_tmp.HighPart is not zero ******************************************************************** @@ -2436,7 +2515,6 @@ static int arcmsr_set_info(char *buffer, /* ********************************************************************* -** ********************************************************************* */ static void arcmsr_pcidev_disattach(struct _ACB *pACB) @@ -2454,12 +2532,14 @@ static void arcmsr_pcidev_disattach(stru arcmsr_stop_adapter_bgrb(pACB); if (arcmsr_wait_msgint_ready(pACB)) { printk - ("arcmsr_pcidev_disattach: wait 'stop adapter rebulid' timeout.... \n"); + ("arcmsr%d pcidev disattach wait 'stop adapter rebulid' timeout \n", + pACB->adapter_index); } arcmsr_flush_adapter_cache(pACB); if (arcmsr_wait_msgint_ready(pACB)) { printk - ("arcmsr_pcidev_disattach: wait 'flush adapter cache' timeout.... \n"); + ("arcmsr%d pcidev disattach wait 'flush adapter cache' timeout \n", + pACB->adapter_index); } /* abort all outstanding command */ pACB->acb_flags |= ACB_F_SCSISTOPADAPTER; @@ -2473,7 +2553,8 @@ static void arcmsr_pcidev_disattach(stru arcmsr_abort_allcmd(pACB); if (arcmsr_wait_msgint_ready(pACB)) { printk - ("arcmsr_pcidev_disattach: wait 'abort all outstanding command' timeout................. \n"); + ("arcmsr%d pcidev disattach wait 'abort all outstanding command' timeout \n", + pACB->adapter_index); } /*clear all outbound posted Q */ for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) { @@ -2590,9 +2671,6 @@ static int arcmsr_proc_info(struct Scsi_ /* ************************************************************************ -** arcmsr -** arcmsr_release -** ************************************************************************ */ static int arcmsr_release(struct Scsi_Host *host) diff -puN drivers/scsi/arcmsr/arcmsr.h~areca-raid-linux-scsi-driver-update-2 drivers/scsi/arcmsr/arcmsr.h --- devel/drivers/scsi/arcmsr/arcmsr.h~areca-raid-linux-scsi-driver-update-2 2005-09-29 02:47:00.000000000 -0700 +++ devel-akpm/drivers/scsi/arcmsr/arcmsr.h 2005-09-29 02:47:00.000000000 -0700 @@ -51,7 +51,7 @@ */ #define ARCMSR_MAX_OUTSTANDING_CMD 256 #define ARCMSR_MAX_FREECCB_NUM 320 -#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.09" +#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.11" #define ARCMSR_SCSI_INITIATOR_ID 16 #define ARCMSR_DEV_SECTOR_SIZE 512 #define ARCMSR_MAX_XFER_SECTORS 256 @@ -85,13 +85,12 @@ **((unsigned long)addr & 0xffff) ********************************************************************************** */ -#define dma_addr_hi32(addr) (uint32_t) ((addr>>16)>>16) -#define dma_addr_lo32(addr) (uint32_t) (addr & 0xffffffff) +#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 -#else -# define arcget_pcicfg_base(pdev,n) pci_resource_start(pdev,n) +#ifndef DMA_64BIT_MASK +#define DMA_64BIT_MASK 0xffffffffffffffffULL +#define DMA_32BIT_MASK 0x00000000ffffffffULL #endif /* ************************************************************************ @@ -137,6 +136,8 @@ typedef struct _CMD_IOCTL_FIELD { #define FUNCTION_CLEAR_ALLQBUFFER 0x0805 #define FUNCTION_RETURN_CODE_3F 0x0806 #define FUNCTION_SAY_HELLO 0x0807 +#define FUNCTION_SAY_GOODBYE 0x0808 +#define FUNCTION_FLUSH_ADAPTER_CACHE 0x0809 /* ARECA IO CONTROL CODE*/ #define ARCMSR_IOCTL_READ_RQBUFFER ARECA_SATA_RAID | FUNCTION_READ_RQBUFFER #define ARCMSR_IOCTL_WRITE_WQBUFFER ARECA_SATA_RAID | FUNCTION_WRITE_WQBUFFER @@ -145,6 +146,8 @@ typedef struct _CMD_IOCTL_FIELD { #define ARCMSR_IOCTL_CLEAR_ALLQBUFFER ARECA_SATA_RAID | FUNCTION_CLEAR_ALLQBUFFER #define ARCMSR_IOCTL_RETURN_CODE_3F ARECA_SATA_RAID | FUNCTION_RETURN_CODE_3F #define ARCMSR_IOCTL_SAY_HELLO ARECA_SATA_RAID | FUNCTION_SAY_HELLO +#define ARCMSR_IOCTL_SAY_GOODBYE ARECA_SATA_RAID | FUNCTION_SAY_GOODBYE +#define ARCMSR_IOCTL_FLUSH_ADAPTER_CACHE ARECA_SATA_RAID | FUNCTION_FLUSH_ADAPTER_CACHE /* ARECA IOCTL ReturnCode */ #define ARCMSR_IOCTL_RETURNCODE_OK 0x00000001 #define ARCMSR_IOCTL_RETURNCODE_ERROR 0x00000006 @@ -247,7 +250,7 @@ typedef struct _FIRMWARE_INFO { ** offset 0xf00 : for RS232 out (request buffer) ** offset 0xe00 : for RS232 in (scratch buffer) ** offset 0x800 : for inbound message code message_wbuffer (driver send to IOP331) -** offset 0xa00 : for outbound message code message_rbuffer (IOP331 to driver) +** offset 0xa00 : for outbound message code message_rbuffer (IOP331 send to driver) ** 4. RS-232 emulation ** Currently 128 byte buffer is used ** 1st uint32_t : Data length (1--124) diff -puN drivers/scsi/arcmsr/arcmsr.txt~areca-raid-linux-scsi-driver-update-2 drivers/scsi/arcmsr/arcmsr.txt --- devel/drivers/scsi/arcmsr/arcmsr.txt~areca-raid-linux-scsi-driver-update-2 2005-09-29 02:47:00.000000000 -0700 +++ devel-akpm/drivers/scsi/arcmsr/arcmsr.txt 2005-09-29 02:47:00.000000000 -0700 @@ -23,6 +23,7 @@ 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) @@ -30,8 +31,16 @@ History 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 + 1.20.00.10 9/23/2005 Erich Chen enhance sysfs function for change driver's max tag Q number. + add DMA_64BIT_MASK for backward compatible with all 2.6.x + add some useful message for abort command + add ioctl code 'ARCMSR_IOCTL_FLUSH_ADAPTER_CACHE' + customer can send this command for sync raid volume data + 1.20.00.11 9/29/2005 Erich Chen by comment of Arjan van de Ven fix incorrect msleep redefine + cast off sizeof(dma_addr_t) condition for 64bit pci_set_dma_mask ===================================================================================================== Support: + Linux SCSI RAID driver technical support mail address: erich@areca.com.tw @@ -44,10 +53,13 @@ Support: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ... .... + obj-$(CONFIG_SCSI_ARCMSR) += arcmsr/ + .... ... @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + /usr/src/linux/drivers/scsi/Kconfig @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ... @@ -65,6 +77,7 @@ 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-2 drivers/scsi/Kconfig --- devel/drivers/scsi/Kconfig~areca-raid-linux-scsi-driver-update-2 2005-09-29 02:47:00.000000000 -0700 +++ devel-akpm/drivers/scsi/Kconfig 2005-09-29 02:47:00.000000000 -0700 @@ -289,6 +289,20 @@ config SCSI_DECSII tristate "DEC SII Scsi Driver" depends on MACH_DECSTATION && SCSI && 32BIT +config SCSI_ARCMSR + tristate "ARECA ARC11X0[PCI-X]/ARC12X0[PCI-EXPRESS] SATA-RAID support" + depends on PCI && SCSI + help + 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 + + < http://www.areca.com.tw > + + To compile this driver as a module, choose M here: the + module will be called arcmsr (modprobe arcmsr) . + config BLK_DEV_3W_XXXX_RAID tristate "3ware 5/6/7/8xxx ATA-RAID support" depends on PCI && SCSI @@ -313,20 +327,6 @@ config SCSI_3W_9XXX Please read the comments at the top of . -config SCSI_ARCMSR - tristate "ARECA ARC11X0[PCI-X]/ARC12X0[PCI-EXPRESS] SATA-RAID support" - depends on PCI && SCSI - help - 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 support Linux RAID config tools - - < http://www.areca.com.tw > - - To compile this driver as a module, choose M here: the - module will be called arcmsr (modprobe arcmsr) . - config SCSI_7000FASST tristate "7000FASST SCSI support" depends on ISA && SCSI && ISA_DMA_API _