diff -u b/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c --- b/drivers/scsi/3w-xxxx.c 2004-09-15 20:41:38 -07:00 +++ b/drivers/scsi/3w-xxxx.c 2004-09-15 20:42:17 -07:00 @@ -207,7 +207,7 @@ #include "3w-xxxx.h" /* Globals */ -#define TW_DRIVER_VERSION "1.26.02.000" +static const char *tw_driver_version="1.26.02.000"; static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT]; static int tw_device_extension_count = 0; static int twe_major = -1; @@ -216,7 +216,6 @@ MODULE_AUTHOR("AMCC"); MODULE_DESCRIPTION("3ware Storage Controller Linux Driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(TW_DRIVER_VERSION); /* Function prototypes */ static int tw_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset); @@ -224,7 +223,7 @@ /* Functions */ /* This function will check the status register for unexpected bits */ -static int tw_check_bits(u32 status_reg_value) +int tw_check_bits(u32 status_reg_value) { if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) { dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value); @@ -493,7 +492,7 @@ "Max sector count: %4d\n" "SCSI Host Resets: %4d\n" "AEN's: %4d\n", - TW_DRIVER_VERSION, + tw_driver_version, tw_dev->posted_request_count, tw_dev->max_posted_request_count, tw_dev->pending_request_count, @@ -885,7 +884,7 @@ /* This function handles ioctl for the character device */ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int request_id; + int error, request_id; dma_addr_t dma_handle; unsigned short tw_aen_code; unsigned long flags; @@ -906,7 +905,8 @@ return -EINTR; /* First copy down the buffer length */ - if (copy_from_user(&data_buffer_length, argp, sizeof(unsigned int))) + error = copy_from_user(&data_buffer_length, argp, sizeof(unsigned int)); + if (error) goto out; /* Check size */ @@ -919,7 +919,7 @@ data_buffer_length_adjusted = (data_buffer_length + 511) & ~511; /* Now allocate ioctl buf memory */ - cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle, GFP_KERNEL); + cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle); if (cpu_addr == NULL) { retval = -ENOMEM; goto out; @@ -928,7 +928,8 @@ tw_ioctl = (TW_New_Ioctl *)cpu_addr; /* Now copy down the entire ioctl */ - if (copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1)) + error = copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1); + if (error) goto out2; passthru = (TW_Passthru *)&tw_ioctl->firmware_command; @@ -1041,12 +1042,12 @@ } /* Now copy the response to userspace */ - if (copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1)) - goto out2; - retval = 0; + error = copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1); + if (error == 0) + retval = 0; out2: /* Now free ioctl buf memory */ - dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle); + pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle); out: up(&tw_dev->ioctl_sem); return retval; @@ -1543,7 +1544,7 @@ request_buffer[4] = 31; /* Additional length */ memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */ sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id); - memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3); + memcpy(&request_buffer[32], tw_driver_version, 3); param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; if (param == NULL) { @@ -2483,7 +2484,7 @@ /* This function is called on driver initialization */ static int __init tw_init(void) { - printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION); + printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version); return pci_module_init(&tw_driver); } /* End tw_init() */ reverted: --- b/drivers/scsi/aacraid/aachba.c 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/aacraid/aachba.c 2004-09-15 20:41:38 -07:00 @@ -193,80 +193,6 @@ static int nondasd = -1; static int dacmode = -1; -static int commit = -1; - -/** - * aac_get_config_status - check the adapter configuration - * @common: adapter to query - * - * Query config status, and commit the configuration if needed. - */ -int aac_get_config_status(struct aac_dev *dev) -{ - int status = 0; - struct fib * fibptr; - - if (!(fibptr = fib_alloc(dev))) - return -ENOMEM; - - fib_init(fibptr); - { - struct aac_get_config_status *dinfo; - dinfo = (struct aac_get_config_status *) fib_data(fibptr); - - dinfo->command = cpu_to_le32(VM_ContainerConfig); - dinfo->type = cpu_to_le32(CT_GET_CONFIG_STATUS); - dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data)); - } - - status = fib_send(ContainerCommand, - fibptr, - sizeof (struct aac_get_config_status), - FsaNormal, - 1, 1, - NULL, NULL); - if (status < 0 ) { - printk(KERN_WARNING "aac_get_config_status: SendFIB failed.\n"); - } else { - struct aac_get_config_status_resp *reply - = (struct aac_get_config_status_resp *) fib_data(fibptr); - dprintk((KERN_WARNING - "aac_get_config_status: response=%d status=%d action=%d\n", - reply->response, reply->status, reply->data.action)); - if ((reply->response != ST_OK) - || (reply->status != CT_OK) - || (reply->data.action > CFACT_PAUSE)) { - printk(KERN_WARNING "aac_get_config_status: Will not issue the Commit Configuration\n"); - status = -EINVAL; - } - } - fib_complete(fibptr); - /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ - if (status >= 0) { - if (commit == 1) { - struct aac_commit_config * dinfo; - fib_init(fibptr); - dinfo = (struct aac_commit_config *) fib_data(fibptr); - - dinfo->command = cpu_to_le32(VM_ContainerConfig); - dinfo->type = cpu_to_le32(CT_COMMIT_CONFIG); - - status = fib_send(ContainerCommand, - fibptr, - sizeof (struct aac_commit_config), - FsaNormal, - 1, 1, - NULL, NULL); - fib_complete(fibptr); - } else if (commit == 0) { - printk(KERN_WARNING - "aac_get_config_status: Foreign device configurations are being ignored\n"); - } - } - fib_free(fibptr); - return status; -} - /** * aac_get_containers - list containers * @common: adapter to probe reverted: --- b/drivers/scsi/aacraid/aacraid.h 2004-09-15 20:41:37 -07:00 +++ a/drivers/scsi/aacraid/aacraid.h 2004-09-15 20:41:37 -07:00 @@ -57,7 +57,6 @@ #define CT_VOLUME_OF_MIRRORS 12 /* volume of mirror */ #define CT_PSEUDO_RAID 13 /* really raid4 */ #define CT_LAST_VOLUME_TYPE 14 -#define CT_OK 218 /* * Types of objects addressable in some fashion by the client. @@ -1170,52 +1169,6 @@ }; /* - * Query for Container Configuration Status - */ - -#define CT_GET_CONFIG_STATUS 147 -struct aac_get_config_status { - u32 command; /* VM_ContainerConfig */ - u32 type; /* CT_GET_CONFIG_STATUS */ - u32 parm1; - u32 parm2; - u32 parm3; - u32 parm4; - u32 parm5; - u32 count; /* sizeof(((struct aac_get_config_status_resp *)NULL)->data) */ -}; - -#define CFACT_CONTINUE 0 -#define CFACT_PAUSE 1 -#define CFACT_ABORT 2 -struct aac_get_config_status_resp { - u32 response; /* ST_OK */ - u32 dummy0; - u32 status; /* CT_OK */ - u32 parm1; - u32 parm2; - u32 parm3; - u32 parm4; - u32 parm5; - struct { - u32 action; /* CFACT_CONTINUE, CFACT_PAUSE or CFACT_ABORT */ - u16 flags; - s16 count; - } data; -}; - -/* - * Accept the configuration as-is - */ - -#define CT_COMMIT_CONFIG 152 - -struct aac_commit_config { - u32 command; /* VM_ContainerConfig */ - u32 type; /* CT_COMMIT_CONFIG */ -}; - -/* * Query for "mountable" objects, ie, objects that are typically * associated with a drive letter on the client (host) side. */ @@ -1490,7 +1443,6 @@ int fib_complete(struct fib * context); #define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) struct aac_dev *aac_init_adapter(struct aac_dev *dev); -int aac_get_config_status(struct aac_dev *dev); int aac_get_containers(struct aac_dev *dev); int aac_scsi_cmd(struct scsi_cmnd *cmd); int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg); reverted: --- b/drivers/scsi/aacraid/linit.c 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/aacraid/linit.c 2004-09-15 20:41:38 -07:00 @@ -589,7 +589,6 @@ else shost->max_channel = 1; - aac_get_config_status(aac); aac_get_containers(aac); aac_devices[aac_count-1] = aac; reverted: --- b/drivers/scsi/advansys.c 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/advansys.c 2004-09-15 20:41:38 -07:00 @@ -796,7 +796,6 @@ #include #include -#include #include #include #include "advansys.h" diff -u b/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c --- b/drivers/scsi/qla2xxx/qla_os.c 2004-09-15 20:41:38 -07:00 +++ b/drivers/scsi/qla2xxx/qla_os.c 2004-09-15 20:42:17 -07:00 @@ -2892,19 +2892,6 @@ continue; } - /* get consistent memory allocated for init control block */ - ha->init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, - &ha->init_cb_dma); - if (ha->init_cb == NULL) { - qla_printk(KERN_WARNING, ha, - "Memory Allocation failed - init_cb\n"); - - qla2x00_mem_free(ha); - msleep(100); - - continue; - } - memset(ha->init_cb, 0, sizeof(init_cb_t)); /* Get consistent memory allocated for Get Port Database cmd */ ha->iodesc_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, @@ -2996,6 +2983,21 @@ memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); } + /* Get consistent memory allocated for Get Port Database cmd */ + ha->iodesc_pd = pci_alloc_consistent(ha->pdev, + PORT_DATABASE_SIZE, &ha->iodesc_pd_dma); + if (ha->iodesc_pd == NULL) { + /* error */ + qla_printk(KERN_WARNING, ha, + "Memory Allocation failed - iodesc_pd\n"); + + qla2x00_mem_free(ha); + msleep(100); + + continue; + } + memset(ha->iodesc_pd, 0, PORT_DATABASE_SIZE); + /* Done all allocations without any error. */ status = 0; diff -u b/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c --- b/drivers/scsi/scsi_lib.c 2004-09-15 20:41:38 -07:00 +++ b/drivers/scsi/scsi_lib.c 2004-09-15 20:42:16 -07:00 @@ -365,7 +365,7 @@ unsigned long flags; spin_lock_irqsave(shost->host_lock, flags); - current_sdev->sdev_target->starget_sdev_user = NULL; + scsi_target(current_sdev)->starget_sdev_user = NULL; spin_unlock_irqrestore(shost->host_lock, flags); /* @@ -377,7 +377,7 @@ blk_run_queue(current_sdev->request_queue); spin_lock_irqsave(shost->host_lock, flags); - if (current_sdev->sdev_target->starget_sdev_user) + if (scsi_target(current_sdev)->starget_sdev_user) goto out; list_for_each_entry_safe(sdev, tmp, ¤t_sdev->same_target_siblings, same_target_siblings) { @@ -1253,10 +1253,10 @@ if (!scsi_host_queue_ready(q, shost, sdev)) goto not_ready; if (sdev->single_lun) { - if (sdev->sdev_target->starget_sdev_user && - sdev->sdev_target->starget_sdev_user != sdev) + if (scsi_target(sdev)->starget_sdev_user && + scsi_target(sdev)->starget_sdev_user != sdev) goto not_ready; - sdev->sdev_target->starget_sdev_user = sdev; + scsi_target(sdev)->starget_sdev_user = sdev; } shost->host_busy++; @@ -1753,0 +1754,28 @@ + +static int +device_quiesce_fn(struct device *dev, void *data) +{ + scsi_device_quiesce(to_scsi_device(dev)); + return 0; +} + +void +scsi_target_quiesce(struct scsi_target *starget) +{ + device_for_each_child(&starget->dev, NULL, device_quiesce_fn); +} +EXPORT_SYMBOL(scsi_target_quiesce); + +static int +device_resume_fn(struct device *dev, void *data) +{ + scsi_device_resume(to_scsi_device(dev)); + return 0; +} + +void +scsi_target_resume(struct scsi_target *starget) +{ + device_for_each_child(&starget->dev, NULL, device_resume_fn); +} +EXPORT_SYMBOL(scsi_target_resume); reverted: --- b/drivers/scsi/sym53c8xx_2/sym53c8xx.h 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym53c8xx.h 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM53C8XX_H reverted: --- b/drivers/scsi/sym53c8xx_2/sym_conf.h 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_conf.h 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_CONF_H reverted: --- b/drivers/scsi/sym53c8xx_2/sym_defs.h 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_defs.h 2004-09-15 20:41:38 -07:00 @@ -22,25 +22,38 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_DEFS_H #define SYM_DEFS_H +#define SYM_VERSION "2.1.18j" -#define SYM_VERSION "2.1.18k" #define SYM_DRIVER_NAME "sym-" SYM_VERSION /* reverted: --- b/drivers/scsi/sym53c8xx_2/sym_fw.c 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_fw.c 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef __FreeBSD__ @@ -398,6 +411,7 @@ if (opcode == 0) { printf ("%s: ERROR0 IN SCRIPT at %d.\n", sym_name(np), (int) (cur-start)); + MDELAY (10000); ++cur; continue; }; @@ -441,6 +455,7 @@ if ((tmp1 ^ tmp2) & 3) { printf ("%s: ERROR1 IN SCRIPT at %d.\n", sym_name(np), (int) (cur-start)); + MDELAY (10000); } /* * If PREFETCH feature not enabled, remove reverted: --- b/drivers/scsi/sym53c8xx_2/sym_fw.h 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_fw.h 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_FW_H reverted: --- b/drivers/scsi/sym53c8xx_2/sym_fw1.h 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_fw1.h 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* reverted: --- b/drivers/scsi/sym53c8xx_2/sym_fw2.h 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_fw2.h 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* diff -u b/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c --- b/drivers/scsi/sym53c8xx_2/sym_glue.c 2004-09-15 20:41:38 -07:00 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c 2004-09-15 20:42:17 -07:00 @@ -3,7 +3,6 @@ * of PCI-SCSI IO processors. * * Copyright (C) 1999-2001 Gerard Roudier - * Copyright (c) 2003-2004 Matthew Wilcox * * This driver is derived from the Linux sym53c8xx driver. * Copyright (C) 1998-2000 Gerard Roudier @@ -23,19 +22,32 @@ * *----------------------------------------------------------------------------- * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #define SYM_GLUE_C @@ -561,6 +573,7 @@ switch (cp->cdb_buf[0]) { case 0x0A: case 0x2A: case 0xAA: panic("XXXXXXXXXXXXX WRITE NOT YET ALLOWED XXXXXXXXXXXXXX\n"); + MDELAY(10000); break; default: break; @@ -1083,7 +1096,8 @@ lp->s.scdev_depth = depth_to_use; sym_tune_dev_queuing(np, device->id, device->lun, reqtags); - spi_dv_device(device); + if (!spi_initial_dv(device->sdev_target)) + spi_dv_device(device); return 0; } @@ -1966,14 +1980,39 @@ __setup("sym53c8xx=", sym53c8xx_setup); #endif -static int __devinit sym_check_supported(struct sym_device *device) +/* + * Read and check the PCI configuration for any detected NCR + * boards and save data for attaching after all boards have + * been detected. + */ +static int __devinit +sym53c8xx_pci_init(struct pci_dev *pdev, struct sym_device *device) { struct sym_pci_chip *chip; - struct pci_dev *pdev = device->pdev; - u_char revision; - unsigned long io_port = device->s.io_port; - unsigned long base = device->s.base; + u_long base, base_2; + u_long base_c, base_2_c, io_port; int i; + u_short device_id, status_reg; + u_char revision; + + /* Choose some short name for this device */ + sprintf(device->s.inst_name, "sym.%d.%d.%d", pdev->bus->number, + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); + + device_id = pdev->device; + + io_port = pdev->resource[0].start; + + base_c = pdev->resource[1].start; + i = pci_get_base_address(pdev, 1, &base); + + base_2_c = pdev->resource[i].start; + pci_get_base_address(pdev, i, &base_2); + + base &= PCI_BASE_ADDRESS_MEM_MASK; + base_2 &= PCI_BASE_ADDRESS_MEM_MASK; + + pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); /* * If user excluded this chip, do not initialize it. @@ -1981,11 +2020,20 @@ if (io_port) { for (i = 0 ; i < 8 ; i++) { if (sym_driver_setup.excludes[i] == io_port) - return -ENODEV; + return -1; } } /* + * Check if the chip is supported. + */ + chip = sym_lookup_pci_chip_table(device_id, revision); + if (!chip) { + printf_info("%s: device not supported\n", sym_name(device)); + return -1; + } + + /* * Check if the chip has been assigned resources we need. * XXX: can this still happen with Linux 2.6's PCI layer? */ @@ -1993,84 +2041,66 @@ if (!io_port) { printf_info("%s: IO base address disabled.\n", sym_name(device)); - return -ENODEV; + return -1; } #else if (!base) { printf_info("%s: MMIO base address disabled.\n", sym_name(device)); - return -ENODEV; + return -1; } #endif /* - * Check if the chip is supported. Then copy the chip description - * to our device structure so we can make it match the actual device - * and options. + * Ignore Symbios chips controlled by various RAID controllers. + * These controllers set value 0x52414944 at RAM end - 16. */ - pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); - chip = sym_lookup_pci_chip_table(pdev->device, revision); - if (!chip) { - printf_info("%s: device not supported\n", sym_name(device)); - return -ENODEV; +#if defined(__i386__) + if (base_2_c) { + unsigned int ram_size, ram_val; + void *ram_ptr; + + if (chip->features & FE_RAM8K) + ram_size = 8192; + else + ram_size = 4096; + + ram_ptr = ioremap(base_2_c, ram_size); + if (ram_ptr) { + ram_val = readl_raw(ram_ptr + ram_size - 16); + iounmap(ram_ptr); + if (ram_val == 0x52414944) { + printf_info("%s: not initializing, " + "driven by RAID controller.\n", + sym_name(device)); + return -1; + } + } } +#endif /* i386 and PCI MEMORY accessible */ + + /* + * Copy the chip description to our device structure, + * so we can make it match the actual device and options. + */ memcpy(&device->chip, chip, sizeof(device->chip)); device->chip.revision_id = revision; - return 0; -} - -/* - * Ignore Symbios chips controlled by various RAID controllers. - * These controllers set value 0x52414944 at RAM end - 16. - */ -static int __devinit sym_check_raid(struct sym_device *device) -{ - unsigned long base_2_c = device->s.base_2_c; - unsigned int ram_size, ram_val; - void *ram_ptr; - - if (!base_2_c) - return 0; - - if (device->chip.features & FE_RAM8K) - ram_size = 8192; - else - ram_size = 4096; - - ram_ptr = ioremap(base_2_c, ram_size); - if (!ram_ptr) - return 0; - - ram_val = readl(ram_ptr + ram_size - 16); - iounmap(ram_ptr); - if (ram_val != 0x52414944) - return 0; - - printf_info("%s: not initializing, driven by RAID controller.\n", - sym_name(device)); - return -ENODEV; -} - -static int __devinit sym_set_workarounds(struct sym_device *device) -{ - struct sym_pci_chip *chip = &device->chip; - struct pci_dev *pdev = device->pdev; - u_short status_reg; - /* + * Some features are required to be enabled in order to + * work around some chip problems. :) ;) * (ITEM 12 of a DEL about the 896 I haven't yet). * We must ensure the chip will use WRITE AND INVALIDATE. * The revision number limit is for now arbitrary. */ - if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && chip->revision_id < 0x4) { + if (device_id == PCI_DEVICE_ID_NCR_53C896 && revision < 0x4) { chip->features |= (FE_WRIE | FE_CLSE); } /* If the chip can do Memory Write Invalidate, enable it */ if (chip->features & FE_WRIE) { if (pci_set_mwi(pdev)) - return -ENODEV; + return -1; } /* @@ -2096,36 +2126,18 @@ } } - return 0; -} - -/* - * Read and check the PCI configuration for any detected NCR - * boards and save data for attaching after all boards have - * been detected. - */ -static void __devinit -sym_init_device(struct pci_dev *pdev, struct sym_device *device) -{ - unsigned long base, base_2; - int i; - - device->pdev = pdev; - device->s.irq = pdev->irq; - - /* Choose some short name for this device */ - sprintf(device->s.inst_name, "sym.%d.%d.%d", pdev->bus->number, - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); - - device->s.io_port = pdev->resource[0].start; - - device->s.base_c = pdev->resource[1].start; - i = pci_get_base_address(pdev, 1, &base); - device->s.base = base & PCI_BASE_ADDRESS_MEM_MASK; + /* + * Initialise device structure with items required by sym_attach. + */ + device->pdev = pdev; + device->s.base = base; + device->s.base_2 = base_2; + device->s.base_c = base_c; + device->s.base_2_c = base_2_c; + device->s.io_port = io_port; + device->s.irq = pdev->irq; - device->s.base_2_c = pdev->resource[i].start; - pci_get_base_address(pdev, i, &base_2); - device->s.base_2 = base_2 & PCI_BASE_ADDRESS_MEM_MASK; + return 0; } /* @@ -2204,7 +2216,7 @@ return 1; } -MODULE_LICENSE("GPL"); +MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(SYM_VERSION); /* @@ -2241,7 +2253,7 @@ memset(&nvram, 0, sizeof(nvram)); if (pci_enable_device(pdev)) - goto leave; + return -ENODEV; pci_set_master(pdev); @@ -2249,15 +2261,7 @@ goto disable; sym_dev.host_id = SYM_SETUP_HOST_ID; - - sym_init_device(pdev, &sym_dev); - if (sym_check_supported(&sym_dev)) - goto free; - - if (sym_check_raid(&sym_dev)) - goto leave; /* Don't disable the device */ - - if (sym_set_workarounds(&sym_dev)) + if (sym53c8xx_pci_init(pdev, &sym_dev)) goto free; sym_config_pqs(pdev, &sym_dev); @@ -2282,7 +2286,6 @@ pci_release_regions(pdev); disable: pci_disable_device(pdev); - leave: return -ENODEV; } @@ -2302,35 +2305,61 @@ attach_count--; } -static void sym2_get_offset(struct scsi_device *sdev) +static void sym2_get_signalling(struct Scsi_Host *shost) +{ + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + enum spi_signal_type type; + + switch (np->scsi_mode) { + case SMODE_SE: + type = SPI_SIGNAL_SE; + break; + case SMODE_LVD: + type = SPI_SIGNAL_LVD; + break; + case SMODE_HVD: + type = SPI_SIGNAL_HVD; + break; + default: + type = SPI_SIGNAL_UNKNOWN; + break; + } + spi_signalling(shost) = type; +} + +static void sym2_get_offset(struct scsi_target *starget) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; - spi_offset(sdev) = tp->tinfo.curr.offset; + spi_offset(starget) = tp->tinfo.curr.offset; } -static void sym2_set_offset(struct scsi_device *sdev, int offset) +static void sym2_set_offset(struct scsi_target *starget, int offset) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; tp->tinfo.goal.offset = offset; } -static void sym2_get_period(struct scsi_device *sdev) +static void sym2_get_period(struct scsi_target *starget) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; - spi_period(sdev) = tp->tinfo.curr.period; + spi_period(starget) = tp->tinfo.curr.period; } -static void sym2_set_period(struct scsi_device *sdev, int period) +static void sym2_set_period(struct scsi_target *starget, int period) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; /* have to have DT for these transfers */ if (period <= np->minsync) @@ -2339,18 +2368,20 @@ tp->tinfo.goal.period = period; } -static void sym2_get_width(struct scsi_device *sdev) +static void sym2_get_width(struct scsi_target *starget) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; - spi_width(sdev) = tp->tinfo.curr.width ? 1 : 0; + spi_width(starget) = tp->tinfo.curr.width ? 1 : 0; } -static void sym2_set_width(struct scsi_device *sdev, int width) +static void sym2_set_width(struct scsi_target *starget, int width) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; /* It is illegal to have DT set on narrow transfers */ if (width == 0) @@ -2359,18 +2390,20 @@ tp->tinfo.goal.width = width; } -static void sym2_get_dt(struct scsi_device *sdev) +static void sym2_get_dt(struct scsi_target *starget) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; - spi_dt(sdev) = (tp->tinfo.curr.options & PPR_OPT_DT) ? 1 : 0; + spi_dt(starget) = (tp->tinfo.curr.options & PPR_OPT_DT) ? 1 : 0; } -static void sym2_set_dt(struct scsi_device *sdev, int dt) +static void sym2_set_dt(struct scsi_target *starget, int dt) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; if (dt) tp->tinfo.goal.options |= PPR_OPT_DT; @@ -2392,6 +2425,7 @@ .get_dt = sym2_get_dt, .set_dt = sym2_set_dt, .show_dt = 1, + .get_signalling = sym2_get_signalling, }; static struct pci_device_id sym2_id_table[] __devinitdata = { reverted: --- b/drivers/scsi/sym53c8xx_2/sym_glue.h 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_glue.h 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_GLUE_H @@ -76,6 +89,7 @@ #define SYM_OPT_HANDLE_DIR_UNKNOWN #define SYM_OPT_HANDLE_DEVICE_QUEUEING +#define SYM_OPT_NVRAM_PRE_READ #define SYM_OPT_LIMIT_COMMAND_REORDERING #define SYM_OPT_ANNOUNCE_TRANSFER_RATE @@ -93,9 +107,10 @@ #define printf(args...) printk(args) /* + * Insert a delay in micro-seconds and milli-seconds. - * Insert a delay in micro-seconds */ #define sym_udelay(us) udelay(us) +#define sym_mdelay(ms) mdelay(ms) /* * A 'read barrier' flushes any data that have been prefetched reverted: --- b/drivers/scsi/sym53c8xx_2/sym_hipd.c 2004-09-15 20:41:37 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_hipd.c 2004-09-15 20:41:37 -07:00 @@ -3,7 +3,6 @@ * of PCI-SCSI IO processors. * * Copyright (C) 1999-2001 Gerard Roudier - * Copyright (c) 2003-2004 Matthew Wilcox * * This driver is derived from the Linux sym53c8xx driver. * Copyright (C) 1998-2000 Gerard Roudier @@ -23,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sym_glue.h" #include "sym_nvram.h" @@ -287,6 +299,7 @@ } out: OUTB (nc_scntl1, 0); + /* MDELAY(100); */ return retv; } @@ -1942,7 +1955,7 @@ if (np->features & (FE_ULTRA2|FE_ULTRA3)) { OUTONW (nc_sien, SBMC); if (reason == 0) { + MDELAY(100); - mdelay(100); INW (nc_sist); } np->scsi_mode = INB (nc_stest4) & SMODE; @@ -5505,6 +5518,7 @@ printf ("CCB=%lx STAT=%x/%x/%x DEV=%d/%d\n", (unsigned long)cp, cp->host_status, cp->ssss_status, cp->host_flags, cp->target, cp->lun); + MDELAY(100); } /* @@ -5732,8 +5746,15 @@ /* * Soft-attach the controller. */ +#ifdef SYM_OPT_NVRAM_PRE_READ int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram) +#else +int sym_hcb_attach(hcb_p np, struct sym_fw *fw) +#endif { +#ifndef SYM_OPT_NVRAM_PRE_READ + struct sym_nvram nvram_buf, *nvram = &nvram_buf; +#endif int i; /* @@ -5758,6 +5779,13 @@ * if the chip is currently active. */ sym_chip_reset (np); + + /* + * Try to read the user set-up. + */ +#ifndef SYM_OPT_NVRAM_PRE_READ + (void) sym_read_nvram(np, nvram); +#endif /* * Prepare controller and devices settings, according reverted: --- b/drivers/scsi/sym53c8xx_2/sym_hipd.h 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_hipd.h 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_HIPD_H @@ -1108,7 +1121,12 @@ int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out); int sym_reset_scsi_target(hcb_p np, int target); void sym_hcb_free(hcb_p np); + +#ifdef SYM_OPT_NVRAM_PRE_READ int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram); +#else +int sym_hcb_attach(hcb_p np, struct sym_fw *fw); +#endif /* * Optionnaly, the driver may handle IO timeouts. @@ -1332,6 +1350,7 @@ #define PRINT_ADDR sym_print_addr #define PRINT_TARGET sym_print_target #define PRINT_LUN sym_print_lun +#define MDELAY sym_mdelay #define UDELAY sym_udelay #endif /* SYM_HIPD_H */ reverted: --- b/drivers/scsi/sym53c8xx_2/sym_malloc.c 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_malloc.c 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef __FreeBSD__ reverted: --- b/drivers/scsi/sym53c8xx_2/sym_misc.c 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_misc.c 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef __FreeBSD__ reverted: --- b/drivers/scsi/sym53c8xx_2/sym_misc.h 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_misc.h 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_MISC_H reverted: --- b/drivers/scsi/sym53c8xx_2/sym_nvram.c 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_nvram.c 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sym_glue.h" reverted: --- b/drivers/scsi/sym53c8xx_2/sym_nvram.h 2004-09-15 20:41:38 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_nvram.h 2004-09-15 20:41:38 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_NVRAM_H diff -u b/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c --- b/drivers/scsi/tmscsim.c 2004-09-15 20:41:38 -07:00 +++ b/drivers/scsi/tmscsim.c 2004-09-15 20:42:17 -07:00 @@ -388,6 +388,22 @@ * Lists are managed using two pointers and eventually a counter */ +/* Return next free SRB */ +static __inline__ struct dc390_srb* dc390_Free_get ( struct dc390_acb* pACB ) +{ + struct dc390_srb* pSRB; + + pSRB = pACB->pFreeSRB; + DEBUG0(printk ("DC390: Get Free SRB %p\n", pSRB)); + if( pSRB ) + { + pACB->pFreeSRB = pSRB->pNextSRB; + pSRB->pNextSRB = NULL; + } + + return( pSRB ); +} + /* Insert SRB oin top of free list */ static __inline__ void dc390_Free_insert (struct dc390_acb* pACB, struct dc390_srb* pSRB) { @@ -409,6 +425,21 @@ } +/* Queue SRB to waiting list */ +static __inline__ void dc390_Waiting_append ( struct dc390_dcb* pDCB, struct dc390_srb* pSRB) +{ + DEBUG0(printk ("DC390: Append pSRB %p cmd %li to Waiting\n", pSRB, pSRB->pcmd->pid)); + if( pDCB->pWaitingSRB ) + pDCB->pWaitLast->pNextSRB = pSRB; + else + pDCB->pWaitingSRB = pSRB; + + pDCB->pWaitLast = pSRB; + pSRB->pNextSRB = NULL; + pDCB->WaitSRBCnt++; + pDCB->pDCBACB->CmdInQ++; +} + static __inline__ void dc390_Going_append (struct dc390_dcb* pDCB, struct dc390_srb* pSRB) { pDCB->GoingSRBCnt++; @@ -528,6 +559,47 @@ spin_unlock_irqrestore(pACB->pScsiHost->host_lock, iflags); } +/*********************************************************************** + * Function: static void dc390_SendSRB (struct dc390_acb* pACB, struct dc390_srb* pSRB) + * + * Purpose: Send SCSI Request Block (pSRB) to adapter (pACB) + * + ***********************************************************************/ + +static void dc390_SendSRB( struct dc390_acb* pACB, struct dc390_srb* pSRB ) +{ + struct dc390_dcb* pDCB; + + pDCB = pSRB->pSRBDCB; + if( (pDCB->MaxCommand <= pDCB->GoingSRBCnt) || (pACB->pActiveDCB) || + (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV)) ) + { + dc390_Waiting_append (pDCB, pSRB); + dc390_Waiting_process (pACB); + return; + } + +#if 0 + if( pDCB->pWaitingSRB ) + { + dc390_Waiting_append (pDCB, pSRB); +/* pSRB = GetWaitingSRB(pDCB); */ /* non-existent */ + pSRB = pDCB->pWaitingSRB; + /* Remove from waiting list */ + pDCB->pWaitingSRB = pSRB->pNextSRB; + pSRB->pNextSRB = NULL; + if (!pDCB->pWaitingSRB) pDCB->pWaitLast = NULL; + } +#endif + + if (!dc390_StartSCSI(pACB, pDCB, pSRB)) + dc390_Going_append (pDCB, pSRB); + else { + dc390_Waiting_insert (pDCB, pSRB); + dc390_waiting_timer (pACB, HZ/5); + } +} + static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length) { memset(sg, 0, sizeof(struct scatterlist)); @@ -603,72 +675,86 @@ } } -static int DC390_queuecommand(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) -{ - struct scsi_device *sdev = cmd->device; - struct dc390_acb *acb = (struct dc390_acb *)sdev->host->hostdata; - struct dc390_dcb *dcb = sdev->hostdata; - struct dc390_srb *srb; - - if (dcb->pWaitingSRB) - goto device_busy; - if (dcb->MaxCommand <= dcb->GoingSRBCnt) - goto device_busy; - if (acb->pActiveDCB) - goto host_busy; - if (acb->ACBFlag & (RESET_DETECT|RESET_DONE|RESET_DEV)) - goto host_busy; - - srb = acb->pFreeSRB; - if (unlikely(srb == NULL)) - goto host_busy; - - cmd->scsi_done = done; - cmd->result = 0; - acb->Cmds++; - acb->pFreeSRB = srb->pNextSRB; - srb->pNextSRB = NULL; +/*********************************************************************** + * Function: static void dc390_BuildSRB (Scsi_Cmd *pcmd, struct dc390_dcb* pDCB, + * struct dc390_srb* pSRB) + * + * Purpose: Prepare SRB for being sent to Device DCB w/ command *pcmd + * + ***********************************************************************/ - srb->pSRBDCB = dcb; - srb->pcmd = cmd; +static void dc390_BuildSRB (struct scsi_cmnd *pcmd, struct dc390_dcb* pDCB, struct dc390_srb* pSRB) +{ + pSRB->pSRBDCB = pDCB; + pSRB->pcmd = pcmd; - srb->SGIndex = 0; - srb->AdaptStatus = 0; - srb->TargetStatus = 0; - srb->MsgCnt = 0; - if (dcb->DevType == TYPE_TAPE) - srb->RetryCnt = 0; - else - srb->RetryCnt = 1; - srb->SRBStatus = 0; - srb->SRBFlag = 0; - srb->SRBState = 0; - srb->TotalXferredLen = 0; - srb->SGBusAddr = 0; - srb->SGToBeXferLen = 0; - srb->ScsiPhase = 0; - srb->EndMessage = 0; - srb->TagNumber = 255; - - if (dc390_StartSCSI(acb, dcb, srb)) { - dc390_Waiting_insert(dcb, srb); - dc390_waiting_timer(acb, HZ/5); - goto done; - } + pSRB->SGIndex = 0; + pSRB->AdaptStatus = 0; + pSRB->TargetStatus = 0; + pSRB->MsgCnt = 0; + if( pDCB->DevType != TYPE_TAPE ) + pSRB->RetryCnt = 1; + else + pSRB->RetryCnt = 0; + pSRB->SRBStatus = 0; + pSRB->SRBFlag = 0; + pSRB->SRBState = 0; + pSRB->TotalXferredLen = 0; + pSRB->SGBusAddr = 0; + pSRB->SGToBeXferLen = 0; + pSRB->ScsiPhase = 0; + pSRB->EndMessage = 0; + pSRB->TagNumber = 255; + /* KG: deferred PCI mapping to dc390_StartSCSI */ +} - dc390_Going_append(dcb, srb); - done: - return 0; +/*********************************************************************** + * Function : static int DC390_queue_command (struct scsi_cmnd *cmd, + * void (*done)(struct scsi_cmnd *)) + * + * Purpose : enqueues a SCSI command + * + * Inputs : cmd - SCSI command, done - callback function called on + * completion, with a pointer to the command descriptor. + * + * Returns : (depending on kernel version) + * 2.0.x: always return 0 + * 2.1.x: old model: (use_new_eh_code == 0): like 2.0.x + * TO BE DONE: + * new model: return 0 if successful, or must not be re-queued + * return 1 if command cannot be queued (queue full) + * command will be inserted in midlevel queue then ... + * + ***********************************************************************/ + +static int DC390_queue_command(struct scsi_cmnd *cmd, + void (* done)(struct scsi_cmnd *)) +{ + struct dc390_dcb* pDCB = (struct dc390_dcb*) cmd->device->hostdata; + struct dc390_srb* pSRB; + struct dc390_acb* pACB = (struct dc390_acb*) cmd->device->host->hostdata; + + pACB->Cmds++; + cmd->scsi_done = done; + cmd->result = 0; + + pSRB = dc390_Free_get(pACB); + if (!pSRB) + goto requeue; + + dc390_BuildSRB(cmd, pDCB, pSRB); + if (pDCB->pWaitingSRB) { + dc390_Waiting_append(pDCB, pSRB); + dc390_Waiting_process(pACB); + } else + dc390_SendSRB(pACB, pSRB); + + DEBUG1(printk (KERN_DEBUG " ... command (pid %li) queued successfully.\n", cmd->pid)); + return(0); - host_busy: - dc390_Waiting_process(acb); - return SCSI_MLQUEUE_HOST_BUSY; - - device_busy: - dc390_Waiting_process(acb); - return SCSI_MLQUEUE_DEVICE_BUSY; + requeue: + return 1; } static void dc390_dumpinfo (struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB) @@ -979,7 +1065,7 @@ .slave_alloc = dc390_slave_alloc, .slave_configure = dc390_slave_configure, .slave_destroy = dc390_slave_destroy, - .queuecommand = DC390_queuecommand, + .queuecommand = DC390_queue_command, .eh_abort_handler = DC390_abort, .eh_bus_reset_handler = DC390_bus_reset, .can_queue = 42, @@ -989,7 +1075,7 @@ .use_clustering = DISABLE_CLUSTERING, }; -static void __devinit dc390_eeprom_prepare_read(struct pci_dev *pdev, u8 cmd) +static void __devinit dc390_eeprom_prepare_read(struct pci_dev *pdev, u8 cd) { u8 carryFlag = 1, j = 0x80, i, bval, regval; only in patch2: unchanged: --- a/drivers/scsi/53c700.c 2004-09-15 20:42:16 -07:00 +++ b/drivers/scsi/53c700.c 2004-09-15 20:42:16 -07:00 @@ -287,8 +287,9 @@ struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; - return NCR_700_offset_period_to_sxfer(hostdata, spi_offset(SDp), - spi_period(SDp)); + return NCR_700_offset_period_to_sxfer(hostdata, + spi_offset(SDp->sdev_target), + spi_period(SDp->sdev_target)); } struct Scsi_Host * @@ -403,6 +404,8 @@ (hostdata->fast ? "53c700-66" : "53c700"), hostdata->rev, hostdata->differential ? "(Differential)" : ""); + spi_signalling(host) = hostdata->differential ? SPI_SIGNAL_HVD : + SPI_SIGNAL_SE; /* reset the chip */ NCR_700_chip_reset(host); @@ -803,7 +806,7 @@ } if(NCR_700_is_flag_set(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION)) { - if(spi_offset(SCp->device) != 0) + if(spi_offset(SCp->device->sdev_target) != 0) printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n", host->host_no, pun, lun, offset, period*4); @@ -813,8 +816,8 @@ NCR_700_clear_flag(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION); } - spi_offset(SCp->device) = offset; - spi_period(SCp->device) = period; + spi_offset(SCp->device->sdev_target) = offset; + spi_period(SCp->device->sdev_target) = period; NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); @@ -894,7 +897,8 @@ case A_REJECT_MSG: if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) { /* Rejected our sync negotiation attempt */ - spi_period(SCp->device) = spi_offset(SCp->device) = 0; + spi_period(SCp->device->sdev_target) = + spi_offset(SCp->device->sdev_target) = 0; NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } else if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) { @@ -1420,8 +1424,8 @@ NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) { memcpy(&hostdata->msgout[count], NCR_700_SDTR_msg, sizeof(NCR_700_SDTR_msg)); - hostdata->msgout[count+3] = spi_period(SCp->device); - hostdata->msgout[count+4] = spi_offset(SCp->device); + hostdata->msgout[count+3] = spi_period(SCp->device->sdev_target); + hostdata->msgout[count+4] = spi_offset(SCp->device->sdev_target); count += sizeof(NCR_700_SDTR_msg); NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } @@ -1999,10 +2003,11 @@ } STATIC void -NCR_700_set_period(struct scsi_device *SDp, int period) +NCR_700_set_period(struct scsi_target *STp, int period) { + struct Scsi_Host *SHp = dev_to_shost(STp->dev.parent); struct NCR_700_Host_Parameters *hostdata = - (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; + (struct NCR_700_Host_Parameters *)SHp->hostdata[0]; if(!hostdata->fast) return; @@ -2010,17 +2015,18 @@ if(period < hostdata->min_period) period = hostdata->min_period; - spi_period(SDp) = period; - NCR_700_clear_flag(SDp, NCR_700_DEV_NEGOTIATED_SYNC); - NCR_700_clear_flag(SDp, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); - NCR_700_set_flag(SDp, NCR_700_DEV_PRINT_SYNC_NEGOTIATION); + spi_period(STp) = period; + spi_flags(STp) &= ~(NCR_700_DEV_NEGOTIATED_SYNC | + NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); + spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; } STATIC void -NCR_700_set_offset(struct scsi_device *SDp, int offset) +NCR_700_set_offset(struct scsi_target *STp, int offset) { + struct Scsi_Host *SHp = dev_to_shost(STp->dev.parent); struct NCR_700_Host_Parameters *hostdata = - (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; + (struct NCR_700_Host_Parameters *)SHp->hostdata[0]; int max_offset = hostdata->chip710 ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET; @@ -2031,14 +2037,14 @@ offset = max_offset; /* if we're currently async, make sure the period is reasonable */ - if(spi_offset(SDp) == 0 && (spi_period(SDp) < hostdata->min_period || - spi_period(SDp) > 0xff)) - spi_period(SDp) = hostdata->min_period; - - spi_offset(SDp) = offset; - NCR_700_clear_flag(SDp, NCR_700_DEV_NEGOTIATED_SYNC); - NCR_700_clear_flag(SDp, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); - NCR_700_set_flag(SDp, NCR_700_DEV_PRINT_SYNC_NEGOTIATION); + if(spi_offset(STp) == 0 && (spi_period(STp) < hostdata->min_period || + spi_period(STp) > 0xff)) + spi_period(STp) = hostdata->min_period; + + spi_offset(STp) = offset; + spi_flags(STp) &= ~(NCR_700_DEV_NEGOTIATED_SYNC | + NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); + spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; } @@ -2058,10 +2064,11 @@ } if(hostdata->fast) { /* Find the correct offset and period via domain validation */ - spi_dv_device(SDp); + if (!spi_initial_dv(SDp->sdev_target)) + spi_dv_device(SDp); } else { - spi_offset(SDp) = 0; - spi_period(SDp) = 0; + spi_offset(SDp->sdev_target) = 0; + spi_period(SDp->sdev_target) = 0; } return 0; } only in patch2: unchanged: --- a/drivers/scsi/53c700.h 2004-09-15 20:42:16 -07:00 +++ b/drivers/scsi/53c700.h 2004-09-15 20:42:16 -07:00 @@ -121,22 +121,22 @@ static inline int NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag) { - return (((unsigned long)SDp->hostdata) & flag) == flag; + return (spi_flags(SDp->sdev_target) & flag) == flag; } static inline int NCR_700_is_flag_clear(struct scsi_device *SDp, __u32 flag) { - return (((unsigned long)SDp->hostdata) & flag) == 0; + return (spi_flags(SDp->sdev_target) & flag) == 0; } static inline void NCR_700_set_flag(struct scsi_device *SDp, __u32 flag) { - SDp->hostdata = (void *)((long)SDp->hostdata | (flag & 0xffff0000)); + spi_flags(SDp->sdev_target) |= flag; } static inline void NCR_700_clear_flag(struct scsi_device *SDp, __u32 flag) { - SDp->hostdata = (void *)((long)SDp->hostdata & ~(flag & 0xffff0000)); + spi_flags(SDp->sdev_target) &= ~flag; } struct NCR_700_command_slot { only in patch2: unchanged: --- a/drivers/scsi/NCR_D700.c 2004-09-15 20:42:16 -07:00 +++ b/drivers/scsi/NCR_D700.c 2004-09-15 20:42:16 -07:00 @@ -99,6 +99,9 @@ #include #include #include +#include +#include +#include #include "53c700.h" #include "NCR_D700.h" only in patch2: unchanged: --- a/drivers/scsi/hosts.c 2004-09-15 20:42:16 -07:00 +++ b/drivers/scsi/hosts.c 2004-09-15 20:42:16 -07:00 @@ -82,6 +82,8 @@ set_bit(SHOST_DEL, &shost->shost_state); class_device_unregister(&shost->shost_classdev); + if (shost->transport_classdev.class) + class_device_unregister(&shost->transport_classdev); device_del(&shost->shost_gendev); } @@ -154,6 +156,7 @@ scsi_proc_hostdir_rm(shost->hostt); scsi_destroy_command_freelist(shost); + kfree(shost->shost_data); /* * Some drivers (eg aha1542) do scsi_register()/scsi_unregister() @@ -278,15 +281,26 @@ snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d", shost->host_no); + if (shost->transportt->host_size && + (shost->shost_data = kmalloc(shost->transportt->host_size, + GFP_KERNEL)) == NULL) + goto fail_destroy_freelist; + + if (shost->transportt->host_setup) + shost->transportt->host_setup(shost); + shost->eh_notify = &complete; rval = kernel_thread(scsi_error_handler, shost, 0); if (rval < 0) - goto fail_destroy_freelist; + goto fail_free_shost_data; wait_for_completion(&complete); shost->eh_notify = NULL; + scsi_proc_hostdir_add(shost->hostt); return shost; + fail_free_shost_data: + kfree(shost->shost_data); fail_destroy_freelist: scsi_destroy_command_freelist(shost); fail_kfree: only in patch2: unchanged: --- a/drivers/scsi/lasi700.c 2004-09-15 20:42:16 -07:00 +++ b/drivers/scsi/lasi700.c 2004-09-15 20:42:16 -07:00 @@ -50,6 +50,9 @@ #include #include +#include +#include +#include #include "lasi700.h" #include "53c700.h" only in patch2: unchanged: --- a/drivers/scsi/scsi_priv.h 2004-09-15 20:42:17 -07:00 +++ b/drivers/scsi/scsi_priv.h 2004-09-15 20:42:17 -07:00 @@ -58,16 +58,6 @@ */ #define SCAN_WILD_CARD ~0 -/* - * scsi_target: representation of a scsi target, for now, this is only - * used for single_lun devices. If no one has active IO to the target, - * starget_sdev_user is NULL, else it points to the active sdev. - */ -struct scsi_target { - struct scsi_device *starget_sdev_user; - unsigned int starget_refcnt; -}; - /* hosts.c */ extern int scsi_init_hosts(void); extern void scsi_exit_hosts(void); @@ -156,6 +146,8 @@ extern int scsi_sysfs_add_host(struct Scsi_Host *); extern int scsi_sysfs_register(void); extern void scsi_sysfs_unregister(void); +extern int scsi_sysfs_device_initialize(struct scsi_device *); +extern int scsi_sysfs_target_initialize(struct scsi_device *); extern struct scsi_transport_template blank_transport_template; extern struct class sdev_class; only in patch2: unchanged: --- a/drivers/scsi/scsi_scan.c 2004-09-15 20:42:17 -07:00 +++ b/drivers/scsi/scsi_scan.c 2004-09-15 20:42:17 -07:00 @@ -202,10 +202,11 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, uint id, uint lun, void *hostdata) { - struct scsi_device *sdev, *device; + struct scsi_device *sdev; unsigned long flags; - sdev = kmalloc(sizeof(*sdev) + shost->transportt->size, GFP_ATOMIC); + sdev = kmalloc(sizeof(*sdev) + shost->transportt->device_size, + GFP_ATOMIC); if (!sdev) goto out; @@ -256,67 +257,28 @@ goto out_free_queue; } - if (shost->transportt->setup) { - if (shost->transportt->setup(sdev)) + if (shost->transportt->device_setup) { + if (shost->transportt->device_setup(sdev)) goto out_cleanup_slave; } - if (get_device(&sdev->host->shost_gendev)) { - - device_initialize(&sdev->sdev_gendev); - sdev->sdev_gendev.parent = &sdev->host->shost_gendev; - sdev->sdev_gendev.bus = &scsi_bus_type; - sdev->sdev_gendev.release = scsi_device_dev_release; - sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d", - sdev->host->host_no, sdev->channel, sdev->id, - sdev->lun); - - class_device_initialize(&sdev->sdev_classdev); - sdev->sdev_classdev.dev = &sdev->sdev_gendev; - sdev->sdev_classdev.class = &sdev_class; - snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE, - "%d:%d:%d:%d", sdev->host->host_no, - sdev->channel, sdev->id, sdev->lun); - - class_device_initialize(&sdev->transport_classdev); - sdev->transport_classdev.dev = &sdev->sdev_gendev; - sdev->transport_classdev.class = sdev->host->transportt->class; - snprintf(sdev->transport_classdev.class_id, BUS_ID_SIZE, - "%d:%d:%d:%d", sdev->host->host_no, - sdev->channel, sdev->id, sdev->lun); - } else - goto out_cleanup_transport; + if (get_device(&sdev->host->shost_gendev) == NULL || + scsi_sysfs_device_initialize(sdev) != 0) + goto out_cleanup_slave; - /* - * If there are any same target siblings, add this to the - * sibling list - */ - spin_lock_irqsave(shost->host_lock, flags); - list_for_each_entry(device, &shost->__devices, siblings) { - if (device->id == sdev->id && - device->channel == sdev->channel) { - list_add_tail(&sdev->same_target_siblings, - &device->same_target_siblings); - sdev->scsi_level = device->scsi_level; - break; - } - } - /* - * If there wasn't another lun already configured at this - * target, then default this device to SCSI_2 until we - * know better - */ - if (!sdev->scsi_level) - sdev->scsi_level = SCSI_2; + /* NOTE: this target initialisation code depends critically on + * lun scanning being sequential. */ + if (scsi_sysfs_target_initialize(sdev)) + goto out_remove_siblings; - list_add_tail(&sdev->siblings, &shost->__devices); - spin_unlock_irqrestore(shost->host_lock, flags); return sdev; -out_cleanup_transport: - if (shost->transportt->cleanup) - shost->transportt->cleanup(sdev); +out_remove_siblings: + spin_lock_irqsave(shost->host_lock, flags); + list_del(&sdev->siblings); + list_del(&sdev->same_target_siblings); + spin_unlock_irqrestore(shost->host_lock, flags); out_cleanup_slave: if (shost->hostt->slave_destroy) shost->hostt->slave_destroy(sdev); @@ -500,10 +462,6 @@ **/ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) { - struct scsi_device *sdev_sibling; - struct scsi_target *starget; - unsigned long flags; - /* * XXX do not save the inquiry, since it can change underneath us, * save just vendor/model/rev. @@ -612,40 +570,9 @@ if (*bflags & BLIST_NOSTARTONADD) sdev->no_start_on_add = 1; - /* - * If we need to allow I/O to only one of the luns attached to - * this target id at a time set single_lun, and allocate or modify - * sdev_target. - */ - if (*bflags & BLIST_SINGLELUN) { + if (*bflags & BLIST_SINGLELUN) sdev->single_lun = 1; - spin_lock_irqsave(sdev->host->host_lock, flags); - starget = NULL; - /* - * Search for an existing target for this sdev. - */ - list_for_each_entry(sdev_sibling, &sdev->same_target_siblings, - same_target_siblings) { - if (sdev_sibling->sdev_target != NULL) { - starget = sdev_sibling->sdev_target; - break; - } - } - if (!starget) { - starget = kmalloc(sizeof(*starget), GFP_ATOMIC); - if (!starget) { - printk(ALLOC_FAILURE_MSG, __FUNCTION__); - spin_unlock_irqrestore(sdev->host->host_lock, - flags); - return SCSI_SCAN_NO_RESPONSE; - } - starget->starget_refcnt = 0; - starget->starget_sdev_user = NULL; - } - starget->starget_refcnt++; - sdev->sdev_target = starget; - spin_unlock_irqrestore(sdev->host->host_lock, flags); - } + sdev->use_10_for_rw = 1; @@ -785,8 +712,6 @@ } else { if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); - if (sdev->host->transportt->cleanup) - sdev->host->transportt->cleanup(sdev); put_device(&sdev->sdev_gendev); } out: @@ -1345,7 +1270,5 @@ if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); - if (sdev->host->transportt->cleanup) - sdev->host->transportt->cleanup(sdev); put_device(&sdev->sdev_gendev); } only in patch2: unchanged: --- a/drivers/scsi/scsi_sysfs.c 2004-09-15 20:42:16 -07:00 +++ b/drivers/scsi/scsi_sysfs.c 2004-09-15 20:42:16 -07:00 @@ -153,25 +153,36 @@ struct scsi_device *sdev; struct device *parent; unsigned long flags; + int delete; parent = dev->parent; sdev = to_scsi_device(dev); spin_lock_irqsave(sdev->host->host_lock, flags); + /* If we're the last LUN on the target, destroy the target */ + delete = list_empty(&sdev->same_target_siblings); list_del(&sdev->siblings); list_del(&sdev->same_target_siblings); list_del(&sdev->starved_entry); - if (sdev->single_lun && --sdev->sdev_target->starget_refcnt == 0) - kfree(sdev->sdev_target); spin_unlock_irqrestore(sdev->host->host_lock, flags); + if (delete) { + struct scsi_target *starget = to_scsi_target(parent); + if (!starget->create) { + device_del(parent); + if (starget->transport_classdev.class) + class_device_unregister(&starget->transport_classdev); + } + put_device(parent); + } if (sdev->request_queue) scsi_free_queue(sdev->request_queue); kfree(sdev->inquiry); kfree(sdev); - put_device(parent); + if (parent) + put_device(parent); } struct class sdev_class = { @@ -430,6 +441,14 @@ return device_create_file(dev, attr); } +static void scsi_target_dev_release(struct device *dev) +{ + struct scsi_target *starget = to_scsi_target(dev); + struct device *parent = dev->parent; + kfree(starget); + put_device(parent); +} + /** * scsi_sysfs_add_sdev - add scsi device to sysfs * @sdev: scsi_device to add @@ -440,13 +459,55 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) { struct class_device_attribute **attrs; - int error, i; + struct scsi_target *starget = sdev->sdev_target; + struct Scsi_Host *shost = sdev->host; + int error, i, create; + unsigned long flags; + + spin_lock_irqsave(shost->host_lock, flags); + create = starget->create; + starget->create = 0; + spin_unlock_irqrestore(shost->host_lock, flags); + + if (create) { + error = device_add(&starget->dev); + if (error) { + printk(KERN_ERR "Target device_add failed\n"); + return error; + } + if (starget->transport_classdev.class) { + int i; + struct class_device_attribute **attrs = + sdev->host->transportt->target_attrs; + + error = class_device_add(&starget->transport_classdev); + if (error) { + dev_printk(KERN_ERR, &starget->dev, + "Target transport add failed\n"); + return error; + } + + /* take a reference for the transport_classdev; this + * is released by the transport_class .release */ + get_device(&starget->dev); + for (i = 0; attrs[i]; i++) { + error = class_device_create_file(&starget->transport_classdev, + attrs[i]); + if (error) { + dev_printk(KERN_ERR, &starget->dev, + "Target transport attr add failed\n"); + return error; + } + } + } + } if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0) return error; error = device_add(&sdev->sdev_gendev); if (error) { + put_device(sdev->sdev_gendev.parent); printk(KERN_INFO "error 1\n"); return error; } @@ -459,7 +520,6 @@ /* take a reference for the sdev_classdev; this is * released by the sdev_class .release */ get_device(&sdev->sdev_gendev); - if (sdev->transport_classdev.class) { error = class_device_add(&sdev->transport_classdev); if (error) @@ -494,7 +554,7 @@ } if (sdev->transport_classdev.class) { - attrs = sdev->host->transportt->attrs; + attrs = sdev->host->transportt->device_attrs; for (i = 0; attrs[i]; i++) { error = class_device_create_file(&sdev->transport_classdev, attrs[i]); @@ -538,8 +598,6 @@ scsi_device_set_state(sdev, SDEV_DEL); if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); - if (sdev->host->transportt->cleanup) - sdev->host->transportt->cleanup(sdev); put_device(&sdev->sdev_gendev); out: @@ -626,6 +684,120 @@ } } + class_device_initialize(&shost->transport_classdev); + shost->transport_classdev.class = shost->transportt->host_class; + shost->transport_classdev.dev = &shost->shost_gendev; + snprintf(shost->transport_classdev.class_id, BUS_ID_SIZE, + "host%d", shost->host_no); + + if (shost->transport_classdev.class) { + struct class_device_attribute **attrs = + shost->transportt->host_attrs; + error = class_device_add(&shost->transport_classdev); + if (error) + return error; + /* take a reference for the transport_classdev; this + * is released by the transport_class .release */ + get_device(&shost->shost_gendev); + for (i = 0; attrs[i]; i++) { + error = class_device_create_file(&shost->transport_classdev, + attrs[i]); + if (error) + return error; + } + } + + return 0; +} + +int scsi_sysfs_device_initialize(struct scsi_device *sdev) +{ + device_initialize(&sdev->sdev_gendev); + sdev->sdev_gendev.bus = &scsi_bus_type; + sdev->sdev_gendev.release = scsi_device_dev_release; + sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d", + sdev->host->host_no, sdev->channel, sdev->id, + sdev->lun); + + class_device_initialize(&sdev->sdev_classdev); + sdev->sdev_classdev.dev = &sdev->sdev_gendev; + sdev->sdev_classdev.class = &sdev_class; + snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE, + "%d:%d:%d:%d", sdev->host->host_no, + sdev->channel, sdev->id, sdev->lun); + + class_device_initialize(&sdev->transport_classdev); + sdev->transport_classdev.dev = &sdev->sdev_gendev; + sdev->transport_classdev.class = sdev->host->transportt->device_class; + snprintf(sdev->transport_classdev.class_id, BUS_ID_SIZE, + "%d:%d:%d:%d", sdev->host->host_no, + sdev->channel, sdev->id, sdev->lun); + return 0; +} + +int scsi_sysfs_target_initialize(struct scsi_device *sdev) +{ + struct scsi_target *starget = NULL; + struct Scsi_Host *shost = sdev->host; + struct scsi_device *device; + struct device *dev = NULL; + unsigned long flags; + int create = 0; + + spin_lock_irqsave(shost->host_lock, flags); + /* + * Search for an existing target for this sdev. + */ + list_for_each_entry(device, &shost->__devices, siblings) { + if (device->id == sdev->id && + device->channel == sdev->channel) { + list_add_tail(&sdev->same_target_siblings, + &device->same_target_siblings); + sdev->scsi_level = device->scsi_level; + starget = device->sdev_target; + break; + } + } + + if (!starget) { + const int size = sizeof(*starget) + + shost->transportt->target_size; + starget = kmalloc(size, GFP_ATOMIC); + if (!starget) { + printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); + spin_unlock_irqrestore(shost->host_lock, + flags); + return -ENOMEM; + } + memset(starget, 0, size); + dev = &starget->dev; + device_initialize(dev); + dev->parent = &shost->shost_gendev; + dev->release = scsi_target_dev_release; + sprintf(dev->bus_id, "target%d:%d:%d", + shost->host_no, sdev->channel, sdev->id); + class_device_initialize(&starget->transport_classdev); + starget->transport_classdev.dev = &starget->dev; + starget->transport_classdev.class = shost->transportt->target_class; + snprintf(starget->transport_classdev.class_id, BUS_ID_SIZE, + "target%d:%d:%d", + shost->host_no, sdev->channel, sdev->id); + starget->id = sdev->id; + create = starget->create = 1; + /* + * If there wasn't another lun already configured at + * this target, then default this device to SCSI_2 + * until we know better + */ + sdev->scsi_level = SCSI_2; + } + get_device(&starget->dev); + sdev->sdev_gendev.parent = &starget->dev; + sdev->sdev_target = starget; + list_add_tail(&sdev->siblings, &shost->__devices); + spin_unlock_irqrestore(shost->host_lock, flags); + if (create && shost->transportt->target_setup) + shost->transportt->target_setup(starget); return 0; } only in patch2: unchanged: --- a/drivers/scsi/scsi_transport_fc.c 2004-09-15 20:42:16 -07:00 +++ b/drivers/scsi/scsi_transport_fc.c 2004-09-15 20:42:16 -07:00 @@ -84,7 +84,7 @@ struct scsi_device *sdev = transport_class_to_sdev(cdev); \ struct fc_transport_attrs *tp; \ struct fc_internal *i = to_fc_internal(sdev->host->transportt); \ - tp = (struct fc_transport_attrs *)&sdev->transport_data; \ + tp = (struct fc_transport_attrs *)&sdev->sdev_data; \ if (i->f->get_##field) \ i->f->get_##field(sdev); \ return snprintf(buf, 20, format_string, cast tp->field); \ @@ -156,10 +156,10 @@ memset(i, 0, sizeof(struct fc_internal)); - i->t.attrs = &i->attrs[0]; - i->t.class = &fc_transport_class; - i->t.setup = &fc_setup_transport_attrs; - i->t.size = sizeof(struct fc_transport_attrs); + i->t.device_attrs = &i->attrs[0]; + i->t.device_class = &fc_transport_class; + i->t.device_setup = &fc_setup_transport_attrs; + i->t.device_size = sizeof(struct fc_transport_attrs); i->f = ft; SETUP_ATTRIBUTE_RD(port_id); only in patch2: unchanged: --- a/drivers/scsi/scsi_transport_spi.c 2004-09-15 20:42:16 -07:00 +++ b/drivers/scsi/scsi_transport_spi.c 2004-09-15 20:42:16 -07:00 @@ -27,25 +27,28 @@ #include #include #include +#include "scsi_priv.h" #include #include #include #include #include -#define SPI_PRINTK(x, l, f, a...) printk(l "scsi(%d:%d:%d:%d): " f, (x)->host->host_no, (x)->channel, (x)->id, (x)->lun , ##a) +#define SPI_PRINTK(x, l, f, a...) dev_printk(l, &(x)->dev, f , ##a) static void transport_class_release(struct class_device *class_dev); +static void host_class_release(struct class_device *class_dev); #define SPI_NUM_ATTRS 10 /* increase this if you add attributes */ #define SPI_OTHER_ATTRS 1 /* Increase this if you add "always * on" attributes */ +#define SPI_HOST_ATTRS 1 #define SPI_MAX_ECHO_BUFFER_SIZE 4096 /* Private data accessors (keep these out of the header file) */ -#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->transport_data)->dv_pending) -#define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->transport_data)->dv_sem) +#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending) +#define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_sem) struct spi_internal { struct scsi_transport_template t; @@ -55,6 +58,8 @@ /* The array of null terminated pointers to attributes * needed by scsi_sysfs.c */ struct class_device_attribute *attrs[SPI_NUM_ATTRS + SPI_OTHER_ATTRS + 1]; + struct class_device_attribute private_host_attrs[SPI_HOST_ATTRS]; + struct class_device_attribute *host_attrs[SPI_HOST_ATTRS + 1]; }; #define to_spi_internal(tmpl) container_of(tmpl, struct spi_internal, t) @@ -80,43 +85,100 @@ * by 4 */ #define SPI_STATIC_PPR 0x0c +static struct { + enum spi_signal_type value; + char *name; +} signal_types[] = { + { SPI_SIGNAL_UNKNOWN, "unknown" }, + { SPI_SIGNAL_SE, "SE" }, + { SPI_SIGNAL_LVD, "LVD" }, + { SPI_SIGNAL_HVD, "HVD" }, +}; + +static inline const char *spi_signal_to_string(enum spi_signal_type type) +{ + int i; + + for (i = 0; i < sizeof(signal_types)/sizeof(signal_types[0]); i++) { + if (type == signal_types[i].value) + return signal_types[i].name; + } + return NULL; +} +static inline enum spi_signal_type spi_signal_to_value(const char *name) +{ + int i, len; + + for (i = 0; i < sizeof(signal_types)/sizeof(signal_types[0]); i++) { + len = strlen(signal_types[i].name); + if (strncmp(name, signal_types[i].name, len) == 0 && + (name[len] == '\n' || name[len] == '\0')) + return signal_types[i].value; + } + return SPI_SIGNAL_UNKNOWN; +} + + struct class spi_transport_class = { .name = "spi_transport", .release = transport_class_release, }; +struct class spi_host_class = { + .name = "spi_host", + .release = host_class_release, +}; + static __init int spi_transport_init(void) { + int error = class_register(&spi_host_class); + if (error) + return error; return class_register(&spi_transport_class); } static void __exit spi_transport_exit(void) { class_unregister(&spi_transport_class); + class_unregister(&spi_host_class); +} + +static int spi_setup_host_attrs(struct Scsi_Host *shost) +{ + spi_signalling(shost) = SPI_SIGNAL_UNKNOWN; + + return 0; } -static int spi_setup_transport_attrs(struct scsi_device *sdev) +static int spi_setup_transport_attrs(struct scsi_target *starget) { - spi_period(sdev) = -1; /* illegal value */ - spi_offset(sdev) = 0; /* async */ - spi_width(sdev) = 0; /* narrow */ - spi_iu(sdev) = 0; /* no IU */ - spi_dt(sdev) = 0; /* ST */ - spi_qas(sdev) = 0; - spi_wr_flow(sdev) = 0; - spi_rd_strm(sdev) = 0; - spi_rti(sdev) = 0; - spi_pcomp_en(sdev) = 0; - spi_dv_pending(sdev) = 0; - init_MUTEX(&spi_dv_sem(sdev)); + spi_period(starget) = -1; /* illegal value */ + spi_offset(starget) = 0; /* async */ + spi_width(starget) = 0; /* narrow */ + spi_iu(starget) = 0; /* no IU */ + spi_dt(starget) = 0; /* ST */ + spi_qas(starget) = 0; + spi_wr_flow(starget) = 0; + spi_rd_strm(starget) = 0; + spi_rti(starget) = 0; + spi_pcomp_en(starget) = 0; + spi_dv_pending(starget) = 0; + spi_initial_dv(starget) = 0; + init_MUTEX(&spi_dv_sem(starget)); return 0; } static void transport_class_release(struct class_device *class_dev) { - struct scsi_device *sdev = transport_class_to_sdev(class_dev); - put_device(&sdev->sdev_gendev); + struct scsi_target *starget = transport_class_to_starget(class_dev); + put_device(&starget->dev); +} + +static void host_class_release(struct class_device *class_dev) +{ + struct Scsi_Host *shost = transport_class_to_shost(class_dev); + put_device(&shost->shost_gendev); } #define spi_transport_show_function(field, format_string) \ @@ -124,12 +186,13 @@ static ssize_t \ show_spi_transport_##field(struct class_device *cdev, char *buf) \ { \ - struct scsi_device *sdev = transport_class_to_sdev(cdev); \ + struct scsi_target *starget = transport_class_to_starget(cdev); \ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ struct spi_transport_attrs *tp; \ - struct spi_internal *i = to_spi_internal(sdev->host->transportt); \ - tp = (struct spi_transport_attrs *)&sdev->transport_data; \ + struct spi_internal *i = to_spi_internal(shost->transportt); \ + tp = (struct spi_transport_attrs *)&starget->starget_data; \ if (i->f->get_##field) \ - i->f->get_##field(sdev); \ + i->f->get_##field(starget); \ return snprintf(buf, 20, format_string, tp->field); \ } @@ -139,11 +202,12 @@ size_t count) \ { \ int val; \ - struct scsi_device *sdev = transport_class_to_sdev(cdev); \ - struct spi_internal *i = to_spi_internal(sdev->host->transportt); \ + struct scsi_target *starget = transport_class_to_starget(cdev); \ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ + struct spi_internal *i = to_spi_internal(shost->transportt); \ \ val = simple_strtoul(buf, NULL, 0); \ - i->f->set_##field(sdev, val); \ + i->f->set_##field(starget, val); \ return count; \ } @@ -168,8 +232,13 @@ static ssize_t store_spi_revalidate(struct class_device *cdev, const char *buf, size_t count) { - struct scsi_device *sdev = transport_class_to_sdev(cdev); + struct scsi_target *starget = transport_class_to_starget(cdev); + /* FIXME: we're relying on an awful lot of device internals + * here. We really need a function to get the first available + * child */ + struct device *dev = container_of(starget->dev.children.next, struct device, node); + struct scsi_device *sdev = to_scsi_device(dev); spi_dv_device(sdev); return count; } @@ -180,15 +249,16 @@ static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf) { - struct scsi_device *sdev = transport_class_to_sdev(cdev); + struct scsi_target *starget = transport_class_to_starget(cdev); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct spi_transport_attrs *tp; const char *str; - struct spi_internal *i = to_spi_internal(sdev->host->transportt); + struct spi_internal *i = to_spi_internal(shost->transportt); - tp = (struct spi_transport_attrs *)&sdev->transport_data; + tp = (struct spi_transport_attrs *)&starget->starget_data; if (i->f->get_period) - i->f->get_period(sdev); + i->f->get_period(starget); switch(tp->period) { @@ -212,8 +282,9 @@ store_spi_transport_period(struct class_device *cdev, const char *buf, size_t count) { - struct scsi_device *sdev = transport_class_to_sdev(cdev); - struct spi_internal *i = to_spi_internal(sdev->host->transportt); + struct scsi_target *starget = transport_class_to_starget(cdev); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct spi_internal *i = to_spi_internal(shost->transportt); int j, period = -1; for (j = 0; j < SPI_STATIC_PPR; j++) { @@ -246,7 +317,7 @@ if (period > 0xff) period = 0xff; - i->f->set_period(sdev, period); + i->f->set_period(starget, period); return count; } @@ -255,9 +326,36 @@ show_spi_transport_period, store_spi_transport_period); +static ssize_t show_spi_host_signalling(struct class_device *cdev, char *buf) +{ + struct Scsi_Host *shost = transport_class_to_shost(cdev); + struct spi_internal *i = to_spi_internal(shost->transportt); + + if (i->f->get_signalling) + i->f->get_signalling(shost); + + return sprintf(buf, "%s\n", spi_signal_to_string(spi_signalling(shost))); +} +static ssize_t store_spi_host_signalling(struct class_device *cdev, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = transport_class_to_shost(cdev); + struct spi_internal *i = to_spi_internal(shost->transportt); + enum spi_signal_type type = spi_signal_to_value(buf); + + if (type != SPI_SIGNAL_UNKNOWN) + return count; + + i->f->set_signalling(shost, type); + return count; +} +static CLASS_DEVICE_ATTR(signalling, S_IRUGO | S_IWUSR, + show_spi_host_signalling, + store_spi_host_signalling); + #define DV_SET(x, y) \ if(i->f->set_##x) \ - i->f->set_##x(sdev, y) + i->f->set_##x(sdev->sdev_target, y) #define DV_LOOPS 3 #define DV_TIMEOUT (10*HZ) @@ -325,7 +423,7 @@ DV_TIMEOUT, DV_RETRIES); if(sreq->sr_result || !scsi_device_online(sdev)) { scsi_device_set_state(sdev, SDEV_QUIESCE); - SPI_PRINTK(sdev, KERN_ERR, "Write Buffer failure %x\n", sreq->sr_result); + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Write Buffer failure %x\n", sreq->sr_result); return 0; } @@ -401,8 +499,8 @@ /* OK, retrain, fallback */ if (i->f->get_period) - i->f->get_period(sdev); - newperiod = spi_period(sdev); + i->f->get_period(sdev->sdev_target); + newperiod = spi_period(sdev->sdev_target); period = newperiod > period ? newperiod : period; if (period < 0x0d) period++; @@ -411,11 +509,11 @@ if (unlikely(period > 0xff || period == prevperiod)) { /* Total failure; set to async and return */ - SPI_PRINTK(sdev, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n"); + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n"); DV_SET(offset, 0); return 0; } - SPI_PRINTK(sdev, KERN_ERR, "Domain Validation detected failure, dropping back\n"); + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation detected failure, dropping back\n"); DV_SET(period, period); prevperiod = period; } @@ -486,20 +584,20 @@ DV_SET(width, 0); if (!spi_dv_device_compare_inquiry(sreq, buffer, buffer, DV_LOOPS)) { - SPI_PRINTK(sdev, KERN_ERR, "Domain Validation Initial Inquiry Failed\n"); + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation Initial Inquiry Failed\n"); /* FIXME: should probably offline the device here? */ return; } /* test width */ if (i->f->set_width && sdev->wdtr) { - i->f->set_width(sdev, 1); + i->f->set_width(sdev->sdev_target, 1); if (!spi_dv_device_compare_inquiry(sreq, buffer, buffer + len, DV_LOOPS)) { - SPI_PRINTK(sdev, KERN_ERR, "Wide Transfers Fail\n"); - i->f->set_width(sdev, 0); + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Wide Transfers Fail\n"); + i->f->set_width(sdev->sdev_target, 0); } } @@ -521,11 +619,11 @@ * test, now try an echo buffer test (if the device allows it) */ if ((len = spi_dv_device_get_echo_buffer(sreq, buffer)) == 0) { - SPI_PRINTK(sdev, KERN_INFO, "Domain Validation skipping write tests\n"); + SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n"); return; } if (len > SPI_MAX_ECHO_BUFFER_SIZE) { - SPI_PRINTK(sdev, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE); + SPI_PRINTK(sdev->sdev_target, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE); len = SPI_MAX_ECHO_BUFFER_SIZE; } @@ -547,6 +645,7 @@ spi_dv_device(struct scsi_device *sdev) { struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL); + struct scsi_target *starget = sdev->sdev_target; u8 *buffer; const int len = SPI_MAX_ECHO_BUFFER_SIZE*2; @@ -563,22 +662,28 @@ memset(buffer, 0, len); + /* We need to verify that the actual device will quiesce; the + * later target quiesce is just a nice to have */ if (unlikely(scsi_device_quiesce(sdev))) goto out_free; - spi_dv_pending(sdev) = 1; - down(&spi_dv_sem(sdev)); + scsi_target_quiesce(starget); + + spi_dv_pending(starget) = 1; + down(&spi_dv_sem(starget)); - SPI_PRINTK(sdev, KERN_INFO, "Beginning Domain Validation\n"); + SPI_PRINTK(starget, KERN_INFO, "Beginning Domain Validation\n"); spi_dv_device_internal(sreq, buffer); - SPI_PRINTK(sdev, KERN_INFO, "Ending Domain Validation\n"); + SPI_PRINTK(starget, KERN_INFO, "Ending Domain Validation\n"); - up(&spi_dv_sem(sdev)); - spi_dv_pending(sdev) = 0; + up(&spi_dv_sem(starget)); + spi_dv_pending(starget) = 0; - scsi_device_resume(sdev); + scsi_target_resume(starget); + + spi_initial_dv(starget) = 1; out_free: kfree(buffer); @@ -602,7 +707,7 @@ kfree(wqw); spi_dv_device(sdev); - spi_dv_pending(sdev) = 0; + spi_dv_pending(sdev->sdev_target) = 0; scsi_device_put(sdev); } @@ -625,15 +730,15 @@ if (unlikely(!wqw)) return; - if (unlikely(spi_dv_pending(sdev))) { + if (unlikely(spi_dv_pending(sdev->sdev_target))) { kfree(wqw); return; } /* Set pending early (dv_device doesn't check it, only sets it) */ - spi_dv_pending(sdev) = 1; + spi_dv_pending(sdev->sdev_target) = 1; if (unlikely(scsi_device_get(sdev))) { kfree(wqw); - spi_dv_pending(sdev) = 0; + spi_dv_pending(sdev->sdev_target) = 0; return; } @@ -654,6 +759,15 @@ if (i->f->show_##field) \ count++ +#define SETUP_HOST_ATTRIBUTE(field) \ + i->private_host_attrs[count] = class_device_attr_##field; \ + if (!i->f->set_##field) { \ + i->private_host_attrs[count].attr.mode = S_IRUGO; \ + i->private_host_attrs[count].store = NULL; \ + } \ + i->host_attrs[count] = &i->private_host_attrs[count]; \ + count++ + struct scsi_transport_template * spi_attach_transport(struct spi_function_template *ft) { @@ -666,10 +780,14 @@ memset(i, 0, sizeof(struct spi_internal)); - i->t.attrs = &i->attrs[0]; - i->t.class = &spi_transport_class; - i->t.setup = &spi_setup_transport_attrs; - i->t.size = sizeof(struct spi_transport_attrs); + i->t.target_attrs = &i->attrs[0]; + i->t.target_class = &spi_transport_class; + i->t.target_setup = &spi_setup_transport_attrs; + i->t.target_size = sizeof(struct spi_transport_attrs); + i->t.host_attrs = &i->host_attrs[0]; + i->t.host_class = &spi_host_class; + i->t.host_setup = &spi_setup_host_attrs; + i->t.host_size = sizeof(struct spi_host_attrs); i->f = ft; SETUP_ATTRIBUTE(period); @@ -688,6 +806,13 @@ BUG_ON(count > SPI_NUM_ATTRS); i->attrs[count++] = &class_device_attr_revalidate; + + i->attrs[count] = NULL; + + count = 0; + SETUP_HOST_ATTRIBUTE(signalling); + + BUG_ON(count > SPI_HOST_ATTRS); i->attrs[count] = NULL; only in patch2: unchanged: --- a/drivers/scsi/sim710.c 2004-09-15 20:42:17 -07:00 +++ b/drivers/scsi/sim710.c 2004-09-15 20:42:17 -07:00 @@ -36,6 +36,9 @@ #include #include #include +#include +#include +#include #include "53c700.h" only in patch2: unchanged: --- a/include/scsi/scsi_device.h 2004-09-15 20:42:16 -07:00 +++ b/include/scsi/scsi_device.h 2004-09-15 20:42:16 -07:00 @@ -120,7 +120,7 @@ struct class_device transport_classdev; enum scsi_device_state sdev_state; - unsigned long transport_data[0]; + unsigned long sdev_data[0]; } __attribute__((aligned(sizeof(unsigned long)))); #define to_scsi_device(d) \ container_of(d, struct scsi_device, sdev_gendev) @@ -129,6 +129,29 @@ #define transport_class_to_sdev(class_dev) \ container_of(class_dev, struct scsi_device, transport_classdev) +/* + * scsi_target: representation of a scsi target, for now, this is only + * used for single_lun devices. If no one has active IO to the target, + * starget_sdev_user is NULL, else it points to the active sdev. + */ +struct scsi_target { + struct scsi_device *starget_sdev_user; + struct device dev; + unsigned int id; /* target id ... replace + * scsi_device.id eventually */ + struct class_device transport_classdev; + unsigned long create:1; /* signal that it needs to be added */ + unsigned long starget_data[0]; +} __attribute__((aligned(sizeof(unsigned long)))); + +#define to_scsi_target(d) container_of(d, struct scsi_target, dev) +static inline struct scsi_target *scsi_target(struct scsi_device *sdev) +{ + return to_scsi_target(sdev->sdev_gendev.parent); +} +#define transport_class_to_starget(class_dev) \ + container_of(class_dev, struct scsi_target, transport_classdev) + extern struct scsi_device *__scsi_add_device(struct Scsi_Host *, uint, uint, uint, void *hostdata); #define scsi_add_device(host, channel, target, lun) \ @@ -191,6 +214,8 @@ enum scsi_device_state state); extern int scsi_device_quiesce(struct scsi_device *sdev); extern void scsi_device_resume(struct scsi_device *sdev); +extern void scsi_target_quiesce(struct scsi_target *); +extern void scsi_target_resume(struct scsi_target *); extern const char *scsi_device_state_name(enum scsi_device_state); static inline int scsi_device_online(struct scsi_device *sdev) { only in patch2: unchanged: --- a/include/scsi/scsi_host.h 2004-09-15 20:42:16 -07:00 +++ b/include/scsi/scsi_host.h 2004-09-15 20:42:16 -07:00 @@ -511,6 +511,13 @@ struct list_head sht_legacy_list; /* + * Points to the transport data (if any) which is allocated + * separately + */ + void *shost_data; + struct class_device transport_classdev; + + /* * We should ensure that this is aligned, both for better performance * and also because some compilers (m68k) don't automatically force * alignment to a long boundary. @@ -522,6 +529,9 @@ container_of(d, struct Scsi_Host, shost_gendev) #define class_to_shost(d) \ container_of(d, struct Scsi_Host, shost_classdev) +#define transport_class_to_shost(class_dev) \ + container_of(class_dev, struct Scsi_Host, transport_classdev) + extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int); extern int scsi_add_host(struct Scsi_Host *, struct device *); only in patch2: unchanged: --- a/include/scsi/scsi_transport.h 2004-09-15 20:42:17 -07:00 +++ b/include/scsi/scsi_transport.h 2004-09-15 20:42:17 -07:00 @@ -24,18 +24,27 @@ /* The NULL terminated list of transport attributes * that should be exported. */ - struct class_device_attribute **attrs; + struct class_device_attribute **device_attrs; + struct class_device_attribute **target_attrs; + struct class_device_attribute **host_attrs; + /* The transport class that the device is in */ - struct class *class; + struct class *device_class; + struct class *target_class; + struct class *host_class; + + /* Constructor functions */ + int (*device_setup)(struct scsi_device *); + int (*target_setup)(struct scsi_target *); + int (*host_setup)(struct Scsi_Host *); - /* Constructor/Destructor functions */ - int (* setup)(struct scsi_device *); - void (* cleanup)(struct scsi_device *); /* The size of the specific transport attribute structure (a * space of this size will be left at the end of the - * scsi_device structure */ - int size; + * scsi_* structure */ + int device_size; + int target_size; + int host_size; }; #endif /* SCSI_TRANSPORT_H */ only in patch2: unchanged: --- a/include/scsi/scsi_transport_fc.h 2004-09-15 20:42:16 -07:00 +++ b/include/scsi/scsi_transport_fc.h 2004-09-15 20:42:16 -07:00 @@ -31,9 +31,9 @@ }; /* accessor functions */ -#define fc_port_id(x) (((struct fc_transport_attrs *)&(x)->transport_data)->port_id) -#define fc_node_name(x) (((struct fc_transport_attrs *)&(x)->transport_data)->node_name) -#define fc_port_name(x) (((struct fc_transport_attrs *)&(x)->transport_data)->port_name) +#define fc_port_id(x) (((struct fc_transport_attrs *)&(x)->sdev_data)->port_id) +#define fc_node_name(x) (((struct fc_transport_attrs *)&(x)->sdev_data)->node_name) +#define fc_port_name(x) (((struct fc_transport_attrs *)&(x)->sdev_data)->port_name) /* The functions by which the transport class and the driver communicate */ struct fc_function_template { only in patch2: unchanged: --- a/include/scsi/scsi_transport_spi.h 2004-09-15 20:42:16 -07:00 +++ b/include/scsi/scsi_transport_spi.h 2004-09-15 20:42:16 -07:00 @@ -35,45 +35,63 @@ unsigned int rd_strm:1; /* Read streaming enabled */ unsigned int rti:1; /* Retain Training Information */ unsigned int pcomp_en:1;/* Precompensation enabled */ + unsigned int initial_dv:1; /* DV done to this target yet */ + unsigned long flags; /* flags field for drivers to use */ /* Private Fields */ unsigned int dv_pending:1; /* Internal flag */ struct semaphore dv_sem; /* semaphore to serialise dv */ }; +enum spi_signal_type { + SPI_SIGNAL_UNKNOWN = 1, + SPI_SIGNAL_SE, + SPI_SIGNAL_LVD, + SPI_SIGNAL_HVD, +}; + +struct spi_host_attrs { + enum spi_signal_type signalling; +}; + /* accessor functions */ -#define spi_period(x) (((struct spi_transport_attrs *)&(x)->transport_data)->period) -#define spi_offset(x) (((struct spi_transport_attrs *)&(x)->transport_data)->offset) -#define spi_width(x) (((struct spi_transport_attrs *)&(x)->transport_data)->width) -#define spi_iu(x) (((struct spi_transport_attrs *)&(x)->transport_data)->iu) -#define spi_dt(x) (((struct spi_transport_attrs *)&(x)->transport_data)->dt) -#define spi_qas(x) (((struct spi_transport_attrs *)&(x)->transport_data)->qas) -#define spi_wr_flow(x) (((struct spi_transport_attrs *)&(x)->transport_data)->wr_flow) -#define spi_rd_strm(x) (((struct spi_transport_attrs *)&(x)->transport_data)->rd_strm) -#define spi_rti(x) (((struct spi_transport_attrs *)&(x)->transport_data)->rti) -#define spi_pcomp_en(x) (((struct spi_transport_attrs *)&(x)->transport_data)->pcomp_en) +#define spi_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->period) +#define spi_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->offset) +#define spi_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->width) +#define spi_iu(x) (((struct spi_transport_attrs *)&(x)->starget_data)->iu) +#define spi_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dt) +#define spi_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->qas) +#define spi_wr_flow(x) (((struct spi_transport_attrs *)&(x)->starget_data)->wr_flow) +#define spi_rd_strm(x) (((struct spi_transport_attrs *)&(x)->starget_data)->rd_strm) +#define spi_rti(x) (((struct spi_transport_attrs *)&(x)->starget_data)->rti) +#define spi_pcomp_en(x) (((struct spi_transport_attrs *)&(x)->starget_data)->pcomp_en) +#define spi_initial_dv(x) (((struct spi_transport_attrs *)&(x)->starget_data)->initial_dv) +#define spi_flags(x) (((struct spi_transport_attrs *)&(x)->starget_data)->flags) +#define spi_signalling(h) (((struct spi_host_attrs *)&(h)->shost_data)->signalling) /* The functions by which the transport class and the driver communicate */ struct spi_function_template { - void (*get_period)(struct scsi_device *); - void (*set_period)(struct scsi_device *, int); - void (*get_offset)(struct scsi_device *); - void (*set_offset)(struct scsi_device *, int); - void (*get_width)(struct scsi_device *); - void (*set_width)(struct scsi_device *, int); - void (*get_iu)(struct scsi_device *); - void (*set_iu)(struct scsi_device *, int); - void (*get_dt)(struct scsi_device *); - void (*set_dt)(struct scsi_device *, int); - void (*get_qas)(struct scsi_device *); - void (*set_qas)(struct scsi_device *, int); - void (*get_wr_flow)(struct scsi_device *); - void (*set_wr_flow)(struct scsi_device *, int); - void (*get_rd_strm)(struct scsi_device *); - void (*set_rd_strm)(struct scsi_device *, int); - void (*get_rti)(struct scsi_device *); - void (*set_rti)(struct scsi_device *, int); - void (*get_pcomp_en)(struct scsi_device *); - void (*set_pcomp_en)(struct scsi_device *, int); + void (*get_period)(struct scsi_target *); + void (*set_period)(struct scsi_target *, int); + void (*get_offset)(struct scsi_target *); + void (*set_offset)(struct scsi_target *, int); + void (*get_width)(struct scsi_target *); + void (*set_width)(struct scsi_target *, int); + void (*get_iu)(struct scsi_target *); + void (*set_iu)(struct scsi_target *, int); + void (*get_dt)(struct scsi_target *); + void (*set_dt)(struct scsi_target *, int); + void (*get_qas)(struct scsi_target *); + void (*set_qas)(struct scsi_target *, int); + void (*get_wr_flow)(struct scsi_target *); + void (*set_wr_flow)(struct scsi_target *, int); + void (*get_rd_strm)(struct scsi_target *); + void (*set_rd_strm)(struct scsi_target *, int); + void (*get_rti)(struct scsi_target *); + void (*set_rti)(struct scsi_target *, int); + void (*get_pcomp_en)(struct scsi_target *); + void (*set_pcomp_en)(struct scsi_target *, int); + void (*get_signalling)(struct Scsi_Host *); + void (*set_signalling)(struct Scsi_Host *, enum spi_signal_type); /* The driver sets these to tell the transport class it * wants the attributes displayed in sysfs. If the show_ flag * is not set, the attribute will be private to the transport