]> err.no Git - linux-2.6/blobdiff - drivers/scsi/qla2xxx/qla_attr.c
Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6] / drivers / scsi / qla2xxx / qla_attr.c
index 612e3d0c7bd109be53a267cabc4274478c6ad34e..45e7dcb4b34d8b276edae17cf56a13c749317fa3 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/kthread.h>
 #include <linux/vmalloc.h>
+#include <linux/delay.h>
 
 static int qla24xx_vport_disable(struct fc_vport *, bool);
 
@@ -20,18 +21,12 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj,
 {
        struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
            struct device, kobj)));
-       char *rbuf = (char *)ha->fw_dump;
 
        if (ha->fw_dump_reading == 0)
                return 0;
-       if (off > ha->fw_dump_len)
-                return 0;
-       if (off + count > ha->fw_dump_len)
-               count = ha->fw_dump_len - off;
 
-       memcpy(buf, &rbuf[off], count);
-
-       return (count);
+       return memory_read_from_buffer(buf, count, &off, ha->fw_dump,
+                                       ha->fw_dump_len);
 }
 
 static ssize_t
@@ -94,20 +89,13 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj,
 {
        struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
            struct device, kobj)));
-       int             size = ha->nvram_size;
-       char            *nvram_cache = ha->nvram;
 
-       if (!capable(CAP_SYS_ADMIN) || off > size || count == 0)
+       if (!capable(CAP_SYS_ADMIN))
                return 0;
-       if (off + count > size) {
-               size -= off;
-               count = size;
-       }
 
        /* Read NVRAM data from cache. */
-       memcpy(buf, &nvram_cache[off], count);
-
-       return count;
+       return memory_read_from_buffer(buf, count, &off, ha->nvram,
+                                       ha->nvram_size);
 }
 
 static ssize_t
@@ -175,14 +163,9 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj,
 
        if (ha->optrom_state != QLA_SREADING)
                return 0;
-       if (off > ha->optrom_region_size)
-               return 0;
-       if (off + count > ha->optrom_region_size)
-               count = ha->optrom_region_size - off;
-
-       memcpy(buf, &ha->optrom_buffer[off], count);
 
-       return count;
+       return memory_read_from_buffer(buf, count, &off, ha->optrom_buffer,
+                                       ha->optrom_region_size);
 }
 
 static ssize_t
@@ -374,20 +357,12 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
 {
        struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj,
            struct device, kobj)));
-       int           size = ha->vpd_size;
-       char          *vpd_cache = ha->vpd;
 
-       if (!capable(CAP_SYS_ADMIN) || off > size || count == 0)
+       if (!capable(CAP_SYS_ADMIN))
                return 0;
-       if (off + count > size) {
-               size -= off;
-               count = size;
-       }
 
        /* Read NVRAM data from cache. */
-       memcpy(buf, &vpd_cache[off], count);
-
-       return count;
+       return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size);
 }
 
 static ssize_t
@@ -1018,6 +993,17 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
 {
        fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
 
+       /*
+        * At this point all fcport's software-states are cleared.  Perform any
+        * final cleanup of firmware resources (PCBs and XCBs).
+        */
+       if (fcport->loop_id != FC_NO_LOOP_ID) {
+               fcport->ha->isp_ops->fabric_logout(fcport->ha, fcport->loop_id,
+                   fcport->d_id.b.domain, fcport->d_id.b.area,
+                   fcport->d_id.b.al_pa);
+               fcport->loop_id = FC_NO_LOOP_ID;
+       }
+
        qla2x00_abort_fcport_cmds(fcport);
        scsi_target_unblock(&rport->dev);
 }
@@ -1203,6 +1189,11 @@ static int
 qla24xx_vport_delete(struct fc_vport *fc_vport)
 {
        scsi_qla_host_t *vha = fc_vport->dd_data;
+       scsi_qla_host_t *pha = to_qla_parent(vha);
+
+       while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
+           test_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags))
+               msleep(1000);
 
        qla24xx_disable_vp(vha);
        qla24xx_deallocate_vp_id(vha);