diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 14:25:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 14:25:31 -0400 |
commit | 2cca775baecbfede2fec20c99add709232311fe7 (patch) | |
tree | b0eefe80881d263ba7976174144ae4e9cf238425 | |
parent | eddeb0e2d863e3941d8768e70cb50c6120e61fa0 (diff) | |
parent | 94795b61e84994a3b058f92d041d1fb3d869c7d5 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (137 commits)
[SCSI] iscsi: bidi support for iscsi_tcp
[SCSI] iscsi: bidi support at the generic libiscsi level
[SCSI] iscsi: extended cdb support
[SCSI] zfcp: Fix error handling for blocked unit for send FCP command
[SCSI] zfcp: Remove zfcp_erp_wait from slave destory handler to fix deadlock
[SCSI] zfcp: fix 31 bit compile warnings
[SCSI] bsg: no need to set BSG_F_BLOCK bit in bsg_complete_all_commands
[SCSI] bsg: remove minor in struct bsg_device
[SCSI] bsg: use better helper list functions
[SCSI] bsg: replace kobject_get with blk_get_queue
[SCSI] bsg: takes a ref to struct device in fops->open
[SCSI] qla1280: remove version check
[SCSI] libsas: fix endianness bug in sas_ata
[SCSI] zfcp: fix compiler warning caused by poking inside new semaphore (linux-next)
[SCSI] aacraid: Do not describe check_reset parameter with its value
[SCSI] aacraid: Fix down_interruptible() to check the return value
[SCSI] sun3_scsi_vme: add MODULE_LICENSE
[SCSI] st: rename flush_write_buffer()
[SCSI] tgt: use KMEM_CACHE macro
[SCSI] initio: fix big endian problems for auto request sense
...
133 files changed, 4873 insertions, 4389 deletions
diff --git a/Documentation/scsi/st.txt b/Documentation/scsi/st.txt index b7be95b5bd24..40752602c050 100644 --- a/Documentation/scsi/st.txt +++ b/Documentation/scsi/st.txt | |||
@@ -2,7 +2,7 @@ This file contains brief information about the SCSI tape driver. | |||
2 | The driver is currently maintained by Kai Mäkisara (email | 2 | The driver is currently maintained by Kai Mäkisara (email |
3 | Kai.Makisara@kolumbus.fi) | 3 | Kai.Makisara@kolumbus.fi) |
4 | 4 | ||
5 | Last modified: Mon Mar 7 21:14:44 2005 by kai.makisara | 5 | Last modified: Sun Feb 24 21:59:07 2008 by kai.makisara |
6 | 6 | ||
7 | 7 | ||
8 | BASICS | 8 | BASICS |
@@ -133,6 +133,11 @@ the defaults set by the user. The value -1 means the default is not set. The | |||
133 | file 'dev' contains the device numbers corresponding to this device. The links | 133 | file 'dev' contains the device numbers corresponding to this device. The links |
134 | 'device' and 'driver' point to the SCSI device and driver entries. | 134 | 'device' and 'driver' point to the SCSI device and driver entries. |
135 | 135 | ||
136 | Each directory also contains the entry 'options' which shows the currently | ||
137 | enabled driver and mode options. The value in the file is a bit mask where the | ||
138 | bit definitions are the same as those used with MTSETDRVBUFFER in setting the | ||
139 | options. | ||
140 | |||
136 | A link named 'tape' is made from the SCSI device directory to the class | 141 | A link named 'tape' is made from the SCSI device directory to the class |
137 | directory corresponding to the mode 0 auto-rewind device (e.g., st0). | 142 | directory corresponding to the mode 0 auto-rewind device (e.g., st0). |
138 | 143 | ||
@@ -372,6 +377,11 @@ MTSETDRVBUFFER | |||
372 | MT_ST_SYSV sets the SYSV semantics (mode) | 377 | MT_ST_SYSV sets the SYSV semantics (mode) |
373 | MT_ST_NOWAIT enables immediate mode (i.e., don't wait for | 378 | MT_ST_NOWAIT enables immediate mode (i.e., don't wait for |
374 | the command to finish) for some commands (e.g., rewind) | 379 | the command to finish) for some commands (e.g., rewind) |
380 | MT_ST_SILI enables setting the SILI bit in SCSI commands when | ||
381 | reading in variable block mode to enhance performance when | ||
382 | reading blocks shorter than the byte count; set this only | ||
383 | if you are sure that the drive supports SILI and the HBA | ||
384 | correctly returns transfer residuals | ||
375 | MT_ST_DEBUGGING debugging (global; debugging must be | 385 | MT_ST_DEBUGGING debugging (global; debugging must be |
376 | compiled into the driver) | 386 | compiled into the driver) |
377 | MT_ST_SETBOOLEANS | 387 | MT_ST_SETBOOLEANS |
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c index 7661bb065fa5..3a078ad3aa44 100644 --- a/arch/ia64/hp/sim/simscsi.c +++ b/arch/ia64/hp/sim/simscsi.c | |||
@@ -201,22 +201,6 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode) | |||
201 | simscsi_sg_readwrite(sc, mode, offset); | 201 | simscsi_sg_readwrite(sc, mode, offset); |
202 | } | 202 | } |
203 | 203 | ||
204 | static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len) | ||
205 | { | ||
206 | |||
207 | int i; | ||
208 | unsigned thislen; | ||
209 | struct scatterlist *slp; | ||
210 | |||
211 | scsi_for_each_sg(sc, slp, scsi_sg_count(sc), i) { | ||
212 | if (!len) | ||
213 | break; | ||
214 | thislen = min(len, slp->length); | ||
215 | memcpy(sg_virt(slp), buf, thislen); | ||
216 | len -= thislen; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | static int | 204 | static int |
221 | simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | 205 | simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) |
222 | { | 206 | { |
@@ -258,7 +242,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
258 | buf[6] = 0; /* reserved */ | 242 | buf[6] = 0; /* reserved */ |
259 | buf[7] = 0; /* various flags */ | 243 | buf[7] = 0; /* various flags */ |
260 | memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28); | 244 | memcpy(buf + 8, "HP SIMULATED DISK 0.00", 28); |
261 | simscsi_fillresult(sc, buf, 36); | 245 | scsi_sg_copy_from_buffer(sc, buf, 36); |
262 | sc->result = GOOD; | 246 | sc->result = GOOD; |
263 | break; | 247 | break; |
264 | 248 | ||
@@ -306,14 +290,15 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
306 | buf[5] = 0; | 290 | buf[5] = 0; |
307 | buf[6] = 2; | 291 | buf[6] = 2; |
308 | buf[7] = 0; | 292 | buf[7] = 0; |
309 | simscsi_fillresult(sc, buf, 8); | 293 | scsi_sg_copy_from_buffer(sc, buf, 8); |
310 | sc->result = GOOD; | 294 | sc->result = GOOD; |
311 | break; | 295 | break; |
312 | 296 | ||
313 | case MODE_SENSE: | 297 | case MODE_SENSE: |
314 | case MODE_SENSE_10: | 298 | case MODE_SENSE_10: |
315 | /* sd.c uses this to determine whether disk does write-caching. */ | 299 | /* sd.c uses this to determine whether disk does write-caching. */ |
316 | simscsi_fillresult(sc, (char *)empty_zero_page, scsi_bufflen(sc)); | 300 | scsi_sg_copy_from_buffer(sc, (char *)empty_zero_page, |
301 | PAGE_SIZE); | ||
317 | sc->result = GOOD; | 302 | sc->result = GOOD; |
318 | break; | 303 | break; |
319 | 304 | ||
diff --git a/block/bsg.c b/block/bsg.c index 8917c5174dc2..302ac1f5af39 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -37,7 +37,6 @@ struct bsg_device { | |||
37 | struct list_head done_list; | 37 | struct list_head done_list; |
38 | struct hlist_node dev_list; | 38 | struct hlist_node dev_list; |
39 | atomic_t ref_count; | 39 | atomic_t ref_count; |
40 | int minor; | ||
41 | int queued_cmds; | 40 | int queued_cmds; |
42 | int done_cmds; | 41 | int done_cmds; |
43 | wait_queue_head_t wq_done; | 42 | wait_queue_head_t wq_done; |
@@ -368,7 +367,7 @@ static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd) | |||
368 | 367 | ||
369 | spin_lock_irq(&bd->lock); | 368 | spin_lock_irq(&bd->lock); |
370 | if (bd->done_cmds) { | 369 | if (bd->done_cmds) { |
371 | bc = list_entry(bd->done_list.next, struct bsg_command, list); | 370 | bc = list_first_entry(&bd->done_list, struct bsg_command, list); |
372 | list_del(&bc->list); | 371 | list_del(&bc->list); |
373 | bd->done_cmds--; | 372 | bd->done_cmds--; |
374 | } | 373 | } |
@@ -468,8 +467,6 @@ static int bsg_complete_all_commands(struct bsg_device *bd) | |||
468 | 467 | ||
469 | dprintk("%s: entered\n", bd->name); | 468 | dprintk("%s: entered\n", bd->name); |
470 | 469 | ||
471 | set_bit(BSG_F_BLOCK, &bd->flags); | ||
472 | |||
473 | /* | 470 | /* |
474 | * wait for all commands to complete | 471 | * wait for all commands to complete |
475 | */ | 472 | */ |
@@ -705,6 +702,7 @@ static struct bsg_device *bsg_alloc_device(void) | |||
705 | static int bsg_put_device(struct bsg_device *bd) | 702 | static int bsg_put_device(struct bsg_device *bd) |
706 | { | 703 | { |
707 | int ret = 0; | 704 | int ret = 0; |
705 | struct device *dev = bd->queue->bsg_dev.dev; | ||
708 | 706 | ||
709 | mutex_lock(&bsg_mutex); | 707 | mutex_lock(&bsg_mutex); |
710 | 708 | ||
@@ -730,6 +728,7 @@ static int bsg_put_device(struct bsg_device *bd) | |||
730 | kfree(bd); | 728 | kfree(bd); |
731 | out: | 729 | out: |
732 | mutex_unlock(&bsg_mutex); | 730 | mutex_unlock(&bsg_mutex); |
731 | put_device(dev); | ||
733 | return ret; | 732 | return ret; |
734 | } | 733 | } |
735 | 734 | ||
@@ -738,22 +737,26 @@ static struct bsg_device *bsg_add_device(struct inode *inode, | |||
738 | struct file *file) | 737 | struct file *file) |
739 | { | 738 | { |
740 | struct bsg_device *bd; | 739 | struct bsg_device *bd; |
740 | int ret; | ||
741 | #ifdef BSG_DEBUG | 741 | #ifdef BSG_DEBUG |
742 | unsigned char buf[32]; | 742 | unsigned char buf[32]; |
743 | #endif | 743 | #endif |
744 | ret = blk_get_queue(rq); | ||
745 | if (ret) | ||
746 | return ERR_PTR(-ENXIO); | ||
744 | 747 | ||
745 | bd = bsg_alloc_device(); | 748 | bd = bsg_alloc_device(); |
746 | if (!bd) | 749 | if (!bd) { |
750 | blk_put_queue(rq); | ||
747 | return ERR_PTR(-ENOMEM); | 751 | return ERR_PTR(-ENOMEM); |
752 | } | ||
748 | 753 | ||
749 | bd->queue = rq; | 754 | bd->queue = rq; |
750 | kobject_get(&rq->kobj); | ||
751 | bsg_set_block(bd, file); | 755 | bsg_set_block(bd, file); |
752 | 756 | ||
753 | atomic_set(&bd->ref_count, 1); | 757 | atomic_set(&bd->ref_count, 1); |
754 | bd->minor = iminor(inode); | ||
755 | mutex_lock(&bsg_mutex); | 758 | mutex_lock(&bsg_mutex); |
756 | hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(bd->minor)); | 759 | hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode))); |
757 | 760 | ||
758 | strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1); | 761 | strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1); |
759 | dprintk("bound to <%s>, max queue %d\n", | 762 | dprintk("bound to <%s>, max queue %d\n", |
@@ -763,23 +766,21 @@ static struct bsg_device *bsg_add_device(struct inode *inode, | |||
763 | return bd; | 766 | return bd; |
764 | } | 767 | } |
765 | 768 | ||
766 | static struct bsg_device *__bsg_get_device(int minor) | 769 | static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q) |
767 | { | 770 | { |
768 | struct bsg_device *bd = NULL; | 771 | struct bsg_device *bd; |
769 | struct hlist_node *entry; | 772 | struct hlist_node *entry; |
770 | 773 | ||
771 | mutex_lock(&bsg_mutex); | 774 | mutex_lock(&bsg_mutex); |
772 | 775 | ||
773 | hlist_for_each(entry, bsg_dev_idx_hash(minor)) { | 776 | hlist_for_each_entry(bd, entry, bsg_dev_idx_hash(minor), dev_list) { |
774 | bd = hlist_entry(entry, struct bsg_device, dev_list); | 777 | if (bd->queue == q) { |
775 | if (bd->minor == minor) { | ||
776 | atomic_inc(&bd->ref_count); | 778 | atomic_inc(&bd->ref_count); |
777 | break; | 779 | goto found; |
778 | } | 780 | } |
779 | |||
780 | bd = NULL; | ||
781 | } | 781 | } |
782 | 782 | bd = NULL; | |
783 | found: | ||
783 | mutex_unlock(&bsg_mutex); | 784 | mutex_unlock(&bsg_mutex); |
784 | return bd; | 785 | return bd; |
785 | } | 786 | } |
@@ -789,21 +790,27 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file) | |||
789 | struct bsg_device *bd; | 790 | struct bsg_device *bd; |
790 | struct bsg_class_device *bcd; | 791 | struct bsg_class_device *bcd; |
791 | 792 | ||
792 | bd = __bsg_get_device(iminor(inode)); | ||
793 | if (bd) | ||
794 | return bd; | ||
795 | |||
796 | /* | 793 | /* |
797 | * find the class device | 794 | * find the class device |
798 | */ | 795 | */ |
799 | mutex_lock(&bsg_mutex); | 796 | mutex_lock(&bsg_mutex); |
800 | bcd = idr_find(&bsg_minor_idr, iminor(inode)); | 797 | bcd = idr_find(&bsg_minor_idr, iminor(inode)); |
798 | if (bcd) | ||
799 | get_device(bcd->dev); | ||
801 | mutex_unlock(&bsg_mutex); | 800 | mutex_unlock(&bsg_mutex); |
802 | 801 | ||
803 | if (!bcd) | 802 | if (!bcd) |
804 | return ERR_PTR(-ENODEV); | 803 | return ERR_PTR(-ENODEV); |
805 | 804 | ||
806 | return bsg_add_device(inode, bcd->queue, file); | 805 | bd = __bsg_get_device(iminor(inode), bcd->queue); |
806 | if (bd) | ||
807 | return bd; | ||
808 | |||
809 | bd = bsg_add_device(inode, bcd->queue, file); | ||
810 | if (IS_ERR(bd)) | ||
811 | put_device(bcd->dev); | ||
812 | |||
813 | return bd; | ||
807 | } | 814 | } |
808 | 815 | ||
809 | static int bsg_open(struct inode *inode, struct file *file) | 816 | static int bsg_open(struct inode *inode, struct file *file) |
@@ -942,7 +949,6 @@ void bsg_unregister_queue(struct request_queue *q) | |||
942 | class_device_unregister(bcd->class_dev); | 949 | class_device_unregister(bcd->class_dev); |
943 | put_device(bcd->dev); | 950 | put_device(bcd->dev); |
944 | bcd->class_dev = NULL; | 951 | bcd->class_dev = NULL; |
945 | bcd->dev = NULL; | ||
946 | mutex_unlock(&bsg_mutex); | 952 | mutex_unlock(&bsg_mutex); |
947 | } | 953 | } |
948 | EXPORT_SYMBOL_GPL(bsg_unregister_queue); | 954 | EXPORT_SYMBOL_GPL(bsg_unregister_queue); |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index c16e3cea1d28..f3c69a8c1103 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -2332,11 +2332,7 @@ void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) | |||
2332 | { | 2332 | { |
2333 | cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | 2333 | cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; |
2334 | 2334 | ||
2335 | cmd->sense_buffer[0] = 0x70; /* fixed format, current */ | 2335 | scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq); |
2336 | cmd->sense_buffer[2] = sk; | ||
2337 | cmd->sense_buffer[7] = 18 - 8; /* additional sense length */ | ||
2338 | cmd->sense_buffer[12] = asc; | ||
2339 | cmd->sense_buffer[13] = ascq; | ||
2340 | } | 2336 | } |
2341 | 2337 | ||
2342 | /** | 2338 | /** |
diff --git a/drivers/base/transport_class.c b/drivers/base/transport_class.c index 40bca48abc12..cabd0edf2156 100644 --- a/drivers/base/transport_class.c +++ b/drivers/base/transport_class.c | |||
@@ -108,7 +108,8 @@ EXPORT_SYMBOL_GPL(anon_transport_class_register); | |||
108 | */ | 108 | */ |
109 | void anon_transport_class_unregister(struct anon_transport_class *atc) | 109 | void anon_transport_class_unregister(struct anon_transport_class *atc) |
110 | { | 110 | { |
111 | attribute_container_unregister(&atc->container); | 111 | if (unlikely(attribute_container_unregister(&atc->container))) |
112 | BUG(); | ||
112 | } | 113 | } |
113 | EXPORT_SYMBOL_GPL(anon_transport_class_unregister); | 114 | EXPORT_SYMBOL_GPL(anon_transport_class_unregister); |
114 | 115 | ||
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index c6be6eba7dc3..db3c892f87fb 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -79,7 +79,7 @@ MODULE_VERSION(my_VERSION); | |||
79 | /* | 79 | /* |
80 | * cmd line parameters | 80 | * cmd line parameters |
81 | */ | 81 | */ |
82 | static int mpt_msi_enable; | 82 | static int mpt_msi_enable = -1; |
83 | module_param(mpt_msi_enable, int, 0); | 83 | module_param(mpt_msi_enable, int, 0); |
84 | MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); | 84 | MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); |
85 | 85 | ||
@@ -1686,6 +1686,11 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1686 | ioc->bus_type = SAS; | 1686 | ioc->bus_type = SAS; |
1687 | } | 1687 | } |
1688 | 1688 | ||
1689 | if (ioc->bus_type == SAS && mpt_msi_enable == -1) | ||
1690 | ioc->msi_enable = 1; | ||
1691 | else | ||
1692 | ioc->msi_enable = mpt_msi_enable; | ||
1693 | |||
1689 | if (ioc->errata_flag_1064) | 1694 | if (ioc->errata_flag_1064) |
1690 | pci_disable_io_access(pdev); | 1695 | pci_disable_io_access(pdev); |
1691 | 1696 | ||
@@ -1831,7 +1836,7 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1831 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); | 1836 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); |
1832 | 1837 | ||
1833 | free_irq(ioc->pci_irq, ioc); | 1838 | free_irq(ioc->pci_irq, ioc); |
1834 | if (mpt_msi_enable) | 1839 | if (ioc->msi_enable) |
1835 | pci_disable_msi(ioc->pcidev); | 1840 | pci_disable_msi(ioc->pcidev); |
1836 | ioc->pci_irq = -1; | 1841 | ioc->pci_irq = -1; |
1837 | pci_save_state(pdev); | 1842 | pci_save_state(pdev); |
@@ -2057,15 +2062,17 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
2057 | if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { | 2062 | if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { |
2058 | ioc->pci_irq = -1; | 2063 | ioc->pci_irq = -1; |
2059 | if (ioc->pcidev->irq) { | 2064 | if (ioc->pcidev->irq) { |
2060 | if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev)) | 2065 | if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev)) |
2061 | printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", | 2066 | printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", |
2062 | ioc->name); | 2067 | ioc->name); |
2068 | else | ||
2069 | ioc->msi_enable = 0; | ||
2063 | rc = request_irq(ioc->pcidev->irq, mpt_interrupt, | 2070 | rc = request_irq(ioc->pcidev->irq, mpt_interrupt, |
2064 | IRQF_SHARED, ioc->name, ioc); | 2071 | IRQF_SHARED, ioc->name, ioc); |
2065 | if (rc < 0) { | 2072 | if (rc < 0) { |
2066 | printk(MYIOC_s_ERR_FMT "Unable to allocate " | 2073 | printk(MYIOC_s_ERR_FMT "Unable to allocate " |
2067 | "interrupt %d!\n", ioc->name, ioc->pcidev->irq); | 2074 | "interrupt %d!\n", ioc->name, ioc->pcidev->irq); |
2068 | if (mpt_msi_enable) | 2075 | if (ioc->msi_enable) |
2069 | pci_disable_msi(ioc->pcidev); | 2076 | pci_disable_msi(ioc->pcidev); |
2070 | return -EBUSY; | 2077 | return -EBUSY; |
2071 | } | 2078 | } |
@@ -2173,7 +2180,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
2173 | /* | 2180 | /* |
2174 | * Initalize link list for inactive raid volumes. | 2181 | * Initalize link list for inactive raid volumes. |
2175 | */ | 2182 | */ |
2176 | init_MUTEX(&ioc->raid_data.inactive_list_mutex); | 2183 | mutex_init(&ioc->raid_data.inactive_list_mutex); |
2177 | INIT_LIST_HEAD(&ioc->raid_data.inactive_list); | 2184 | INIT_LIST_HEAD(&ioc->raid_data.inactive_list); |
2178 | 2185 | ||
2179 | if (ioc->bus_type == SAS) { | 2186 | if (ioc->bus_type == SAS) { |
@@ -2261,7 +2268,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
2261 | out: | 2268 | out: |
2262 | if ((ret != 0) && irq_allocated) { | 2269 | if ((ret != 0) && irq_allocated) { |
2263 | free_irq(ioc->pci_irq, ioc); | 2270 | free_irq(ioc->pci_irq, ioc); |
2264 | if (mpt_msi_enable) | 2271 | if (ioc->msi_enable) |
2265 | pci_disable_msi(ioc->pcidev); | 2272 | pci_disable_msi(ioc->pcidev); |
2266 | } | 2273 | } |
2267 | return ret; | 2274 | return ret; |
@@ -2443,7 +2450,7 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) | |||
2443 | 2450 | ||
2444 | if (ioc->pci_irq != -1) { | 2451 | if (ioc->pci_irq != -1) { |
2445 | free_irq(ioc->pci_irq, ioc); | 2452 | free_irq(ioc->pci_irq, ioc); |
2446 | if (mpt_msi_enable) | 2453 | if (ioc->msi_enable) |
2447 | pci_disable_msi(ioc->pcidev); | 2454 | pci_disable_msi(ioc->pcidev); |
2448 | ioc->pci_irq = -1; | 2455 | ioc->pci_irq = -1; |
2449 | } | 2456 | } |
@@ -5159,13 +5166,13 @@ mpt_inactive_raid_list_free(MPT_ADAPTER *ioc) | |||
5159 | if (list_empty(&ioc->raid_data.inactive_list)) | 5166 | if (list_empty(&ioc->raid_data.inactive_list)) |
5160 | return; | 5167 | return; |
5161 | 5168 | ||
5162 | down(&ioc->raid_data.inactive_list_mutex); | 5169 | mutex_lock(&ioc->raid_data.inactive_list_mutex); |
5163 | list_for_each_entry_safe(component_info, pNext, | 5170 | list_for_each_entry_safe(component_info, pNext, |
5164 | &ioc->raid_data.inactive_list, list) { | 5171 | &ioc->raid_data.inactive_list, list) { |
5165 | list_del(&component_info->list); | 5172 | list_del(&component_info->list); |
5166 | kfree(component_info); | 5173 | kfree(component_info); |
5167 | } | 5174 | } |
5168 | up(&ioc->raid_data.inactive_list_mutex); | 5175 | mutex_unlock(&ioc->raid_data.inactive_list_mutex); |
5169 | } | 5176 | } |
5170 | 5177 | ||
5171 | /** | 5178 | /** |
@@ -5224,7 +5231,7 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id) | |||
5224 | if (!handle_inactive_volumes) | 5231 | if (!handle_inactive_volumes) |
5225 | goto out; | 5232 | goto out; |
5226 | 5233 | ||
5227 | down(&ioc->raid_data.inactive_list_mutex); | 5234 | mutex_lock(&ioc->raid_data.inactive_list_mutex); |
5228 | for (i = 0; i < buffer->NumPhysDisks; i++) { | 5235 | for (i = 0; i < buffer->NumPhysDisks; i++) { |
5229 | if(mpt_raid_phys_disk_pg0(ioc, | 5236 | if(mpt_raid_phys_disk_pg0(ioc, |
5230 | buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0) | 5237 | buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0) |
@@ -5244,7 +5251,7 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id) | |||
5244 | list_add_tail(&component_info->list, | 5251 | list_add_tail(&component_info->list, |
5245 | &ioc->raid_data.inactive_list); | 5252 | &ioc->raid_data.inactive_list); |
5246 | } | 5253 | } |
5247 | up(&ioc->raid_data.inactive_list_mutex); | 5254 | mutex_unlock(&ioc->raid_data.inactive_list_mutex); |
5248 | 5255 | ||
5249 | out: | 5256 | out: |
5250 | if (buffer) | 5257 | if (buffer) |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index caadc68c3000..a8f617447d22 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -51,6 +51,7 @@ | |||
51 | 51 | ||
52 | #include <linux/kernel.h> | 52 | #include <linux/kernel.h> |
53 | #include <linux/pci.h> | 53 | #include <linux/pci.h> |
54 | #include <linux/mutex.h> | ||
54 | 55 | ||
55 | #include "lsi/mpi_type.h" | 56 | #include "lsi/mpi_type.h" |
56 | #include "lsi/mpi.h" /* Fusion MPI(nterface) basic defs */ | 57 | #include "lsi/mpi.h" /* Fusion MPI(nterface) basic defs */ |
@@ -531,7 +532,7 @@ struct inactive_raid_component_info { | |||
531 | typedef struct _RaidCfgData { | 532 | typedef struct _RaidCfgData { |
532 | IOCPage2_t *pIocPg2; /* table of Raid Volumes */ | 533 | IOCPage2_t *pIocPg2; /* table of Raid Volumes */ |
533 | IOCPage3_t *pIocPg3; /* table of physical disks */ | 534 | IOCPage3_t *pIocPg3; /* table of physical disks */ |
534 | struct semaphore inactive_list_mutex; | 535 | struct mutex inactive_list_mutex; |
535 | struct list_head inactive_list; /* link list for physical | 536 | struct list_head inactive_list; /* link list for physical |
536 | disk that belong in | 537 | disk that belong in |
537 | inactive volumes */ | 538 | inactive volumes */ |
@@ -630,6 +631,7 @@ typedef struct _MPT_ADAPTER | |||
630 | int mtrr_reg; | 631 | int mtrr_reg; |
631 | struct pci_dev *pcidev; /* struct pci_dev pointer */ | 632 | struct pci_dev *pcidev; /* struct pci_dev pointer */ |
632 | int bars; /* bitmask of BAR's that must be configured */ | 633 | int bars; /* bitmask of BAR's that must be configured */ |
634 | int msi_enable; | ||
633 | u8 __iomem *memmap; /* mmap address */ | 635 | u8 __iomem *memmap; /* mmap address */ |
634 | struct Scsi_Host *sh; /* Scsi Host pointer */ | 636 | struct Scsi_Host *sh; /* Scsi Host pointer */ |
635 | SpiCfgData spi_data; /* Scsi config. data */ | 637 | SpiCfgData spi_data; /* Scsi config. data */ |
@@ -693,7 +695,6 @@ typedef struct _MPT_ADAPTER | |||
693 | struct mutex sas_discovery_mutex; | 695 | struct mutex sas_discovery_mutex; |
694 | u8 sas_discovery_runtime; | 696 | u8 sas_discovery_runtime; |
695 | u8 sas_discovery_ignore_events; | 697 | u8 sas_discovery_ignore_events; |
696 | u16 handle; | ||
697 | int sas_index; /* index refrencing */ | 698 | int sas_index; /* index refrencing */ |
698 | MPT_SAS_MGMT sas_mgmt; | 699 | MPT_SAS_MGMT sas_mgmt; |
699 | struct work_struct sas_persist_task; | 700 | struct work_struct sas_persist_task; |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 78734e25edd5..468480771f13 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -230,6 +230,20 @@ static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy) | |||
230 | return ((MPT_SCSI_HOST *)shost->hostdata)->ioc; | 230 | return ((MPT_SCSI_HOST *)shost->hostdata)->ioc; |
231 | } | 231 | } |
232 | 232 | ||
233 | static struct mptsas_portinfo * | ||
234 | mptsas_get_hba_portinfo(MPT_ADAPTER *ioc) | ||
235 | { | ||
236 | struct list_head *head = &ioc->sas_topology; | ||
237 | struct mptsas_portinfo *pi = NULL; | ||
238 | |||
239 | /* always the first entry on sas_topology list */ | ||
240 | |||
241 | if (!list_empty(head)) | ||
242 | pi = list_entry(head->next, struct mptsas_portinfo, list); | ||
243 | |||
244 | return pi; | ||
245 | } | ||
246 | |||
233 | /* | 247 | /* |
234 | * mptsas_find_portinfo_by_handle | 248 | * mptsas_find_portinfo_by_handle |
235 | * | 249 | * |
@@ -1290,7 +1304,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, | |||
1290 | struct mptsas_portinfo *port_info; | 1304 | struct mptsas_portinfo *port_info; |
1291 | 1305 | ||
1292 | mutex_lock(&ioc->sas_topology_mutex); | 1306 | mutex_lock(&ioc->sas_topology_mutex); |
1293 | port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle); | 1307 | port_info = mptsas_get_hba_portinfo(ioc); |
1294 | if (port_info && port_info->phy_info) | 1308 | if (port_info && port_info->phy_info) |
1295 | sas_address = | 1309 | sas_address = |
1296 | port_info->phy_info[0].phy->identify.sas_address; | 1310 | port_info->phy_info[0].phy->identify.sas_address; |
@@ -2028,8 +2042,7 @@ static int mptsas_probe_one_phy(struct device *dev, | |||
2028 | int i; | 2042 | int i; |
2029 | 2043 | ||
2030 | mutex_lock(&ioc->sas_topology_mutex); | 2044 | mutex_lock(&ioc->sas_topology_mutex); |
2031 | port_info = mptsas_find_portinfo_by_handle(ioc, | 2045 | port_info = mptsas_get_hba_portinfo(ioc); |
2032 | ioc->handle); | ||
2033 | mutex_unlock(&ioc->sas_topology_mutex); | 2046 | mutex_unlock(&ioc->sas_topology_mutex); |
2034 | 2047 | ||
2035 | for (i = 0; i < port_info->num_phys; i++) | 2048 | for (i = 0; i < port_info->num_phys; i++) |
@@ -2099,8 +2112,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) | |||
2099 | 2112 | ||
2100 | mptsas_sas_io_unit_pg1(ioc); | 2113 | mptsas_sas_io_unit_pg1(ioc); |
2101 | mutex_lock(&ioc->sas_topology_mutex); | 2114 | mutex_lock(&ioc->sas_topology_mutex); |
2102 | ioc->handle = hba->phy_info[0].handle; | 2115 | port_info = mptsas_get_hba_portinfo(ioc); |
2103 | port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle); | ||
2104 | if (!port_info) { | 2116 | if (!port_info) { |
2105 | port_info = hba; | 2117 | port_info = hba; |
2106 | list_add_tail(&port_info->list, &ioc->sas_topology); | 2118 | list_add_tail(&port_info->list, &ioc->sas_topology); |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index c207bda6723b..89c63147a15d 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -2304,14 +2304,14 @@ mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id) | |||
2304 | if (list_empty(&ioc->raid_data.inactive_list)) | 2304 | if (list_empty(&ioc->raid_data.inactive_list)) |
2305 | goto out; | 2305 | goto out; |
2306 | 2306 | ||
2307 | down(&ioc->raid_data.inactive_list_mutex); | 2307 | mutex_lock(&ioc->raid_data.inactive_list_mutex); |
2308 | list_for_each_entry(component_info, &ioc->raid_data.inactive_list, | 2308 | list_for_each_entry(component_info, &ioc->raid_data.inactive_list, |
2309 | list) { | 2309 | list) { |
2310 | if ((component_info->d.PhysDiskID == id) && | 2310 | if ((component_info->d.PhysDiskID == id) && |
2311 | (component_info->d.PhysDiskBus == channel)) | 2311 | (component_info->d.PhysDiskBus == channel)) |
2312 | rc = 1; | 2312 | rc = 1; |
2313 | } | 2313 | } |
2314 | up(&ioc->raid_data.inactive_list_mutex); | 2314 | mutex_unlock(&ioc->raid_data.inactive_list_mutex); |
2315 | 2315 | ||
2316 | out: | 2316 | out: |
2317 | return rc; | 2317 | return rc; |
@@ -2341,14 +2341,14 @@ mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id) | |||
2341 | if (list_empty(&ioc->raid_data.inactive_list)) | 2341 | if (list_empty(&ioc->raid_data.inactive_list)) |
2342 | goto out; | 2342 | goto out; |
2343 | 2343 | ||
2344 | down(&ioc->raid_data.inactive_list_mutex); | 2344 | mutex_lock(&ioc->raid_data.inactive_list_mutex); |
2345 | list_for_each_entry(component_info, &ioc->raid_data.inactive_list, | 2345 | list_for_each_entry(component_info, &ioc->raid_data.inactive_list, |
2346 | list) { | 2346 | list) { |
2347 | if ((component_info->d.PhysDiskID == id) && | 2347 | if ((component_info->d.PhysDiskID == id) && |
2348 | (component_info->d.PhysDiskBus == channel)) | 2348 | (component_info->d.PhysDiskBus == channel)) |
2349 | rc = component_info->d.PhysDiskNum; | 2349 | rc = component_info->d.PhysDiskNum; |
2350 | } | 2350 | } |
2351 | up(&ioc->raid_data.inactive_list_mutex); | 2351 | mutex_unlock(&ioc->raid_data.inactive_list_mutex); |
2352 | 2352 | ||
2353 | out: | 2353 | out: |
2354 | return rc; | 2354 | return rc; |
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 874b55ed00a3..8c7e2b778ef1 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -1030,10 +1030,10 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
1030 | 1030 | ||
1031 | /* initialize debug locks */ | 1031 | /* initialize debug locks */ |
1032 | 1032 | ||
1033 | spin_lock_init(&adapter->erp_dbf_lock); | ||
1034 | spin_lock_init(&adapter->hba_dbf_lock); | 1033 | spin_lock_init(&adapter->hba_dbf_lock); |
1035 | spin_lock_init(&adapter->san_dbf_lock); | 1034 | spin_lock_init(&adapter->san_dbf_lock); |
1036 | spin_lock_init(&adapter->scsi_dbf_lock); | 1035 | spin_lock_init(&adapter->scsi_dbf_lock); |
1036 | spin_lock_init(&adapter->rec_dbf_lock); | ||
1037 | 1037 | ||
1038 | retval = zfcp_adapter_debug_register(adapter); | 1038 | retval = zfcp_adapter_debug_register(adapter); |
1039 | if (retval) | 1039 | if (retval) |
@@ -1325,10 +1325,10 @@ zfcp_nameserver_enqueue(struct zfcp_adapter *adapter) | |||
1325 | 1325 | ||
1326 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_FC | 1326 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_FC |
1327 | 1327 | ||
1328 | static void | 1328 | static void zfcp_fsf_incoming_els_rscn(struct zfcp_fsf_req *fsf_req) |
1329 | zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter, | ||
1330 | struct fsf_status_read_buffer *status_buffer) | ||
1331 | { | 1329 | { |
1330 | struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data; | ||
1331 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
1332 | struct fcp_rscn_head *fcp_rscn_head; | 1332 | struct fcp_rscn_head *fcp_rscn_head; |
1333 | struct fcp_rscn_element *fcp_rscn_element; | 1333 | struct fcp_rscn_element *fcp_rscn_element; |
1334 | struct zfcp_port *port; | 1334 | struct zfcp_port *port; |
@@ -1375,7 +1375,8 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter, | |||
1375 | ZFCP_LOG_INFO("incoming RSCN, trying to open " | 1375 | ZFCP_LOG_INFO("incoming RSCN, trying to open " |
1376 | "port 0x%016Lx\n", port->wwpn); | 1376 | "port 0x%016Lx\n", port->wwpn); |
1377 | zfcp_erp_port_reopen(port, | 1377 | zfcp_erp_port_reopen(port, |
1378 | ZFCP_STATUS_COMMON_ERP_FAILED); | 1378 | ZFCP_STATUS_COMMON_ERP_FAILED, |
1379 | 82, fsf_req); | ||
1379 | continue; | 1380 | continue; |
1380 | } | 1381 | } |
1381 | 1382 | ||
@@ -1406,10 +1407,10 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter, | |||
1406 | } | 1407 | } |
1407 | } | 1408 | } |
1408 | 1409 | ||
1409 | static void | 1410 | static void zfcp_fsf_incoming_els_plogi(struct zfcp_fsf_req *fsf_req) |
1410 | zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter, | ||
1411 | struct fsf_status_read_buffer *status_buffer) | ||
1412 | { | 1411 | { |
1412 | struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data; | ||
1413 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
1413 | struct fsf_plogi *els_plogi; | 1414 | struct fsf_plogi *els_plogi; |
1414 | struct zfcp_port *port; | 1415 | struct zfcp_port *port; |
1415 | unsigned long flags; | 1416 | unsigned long flags; |
@@ -1428,14 +1429,14 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter, | |||
1428 | status_buffer->d_id, | 1429 | status_buffer->d_id, |
1429 | zfcp_get_busid_by_adapter(adapter)); | 1430 | zfcp_get_busid_by_adapter(adapter)); |
1430 | } else { | 1431 | } else { |
1431 | zfcp_erp_port_forced_reopen(port, 0); | 1432 | zfcp_erp_port_forced_reopen(port, 0, 83, fsf_req); |
1432 | } | 1433 | } |
1433 | } | 1434 | } |
1434 | 1435 | ||
1435 | static void | 1436 | static void zfcp_fsf_incoming_els_logo(struct zfcp_fsf_req *fsf_req) |
1436 | zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter, | ||
1437 | struct fsf_status_read_buffer *status_buffer) | ||
1438 | { | 1437 | { |
1438 | struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data; | ||
1439 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
1439 | struct fcp_logo *els_logo = (struct fcp_logo *) status_buffer->payload; | 1440 | struct fcp_logo *els_logo = (struct fcp_logo *) status_buffer->payload; |
1440 | struct zfcp_port *port; | 1441 | struct zfcp_port *port; |
1441 | unsigned long flags; | 1442 | unsigned long flags; |
@@ -1453,7 +1454,7 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter, | |||
1453 | status_buffer->d_id, | 1454 | status_buffer->d_id, |
1454 | zfcp_get_busid_by_adapter(adapter)); | 1455 | zfcp_get_busid_by_adapter(adapter)); |
1455 | } else { | 1456 | } else { |
1456 | zfcp_erp_port_forced_reopen(port, 0); | 1457 | zfcp_erp_port_forced_reopen(port, 0, 84, fsf_req); |
1457 | } | 1458 | } |
1458 | } | 1459 | } |
1459 | 1460 | ||
@@ -1480,12 +1481,12 @@ zfcp_fsf_incoming_els(struct zfcp_fsf_req *fsf_req) | |||
1480 | 1481 | ||
1481 | zfcp_san_dbf_event_incoming_els(fsf_req); | 1482 | zfcp_san_dbf_event_incoming_els(fsf_req); |
1482 | if (els_type == LS_PLOGI) | 1483 | if (els_type == LS_PLOGI) |
1483 | zfcp_fsf_incoming_els_plogi(adapter, status_buffer); | 1484 | zfcp_fsf_incoming_els_plogi(fsf_req); |
1484 | else if (els_type == LS_LOGO) | 1485 | else if (els_type == LS_LOGO) |
1485 | zfcp_fsf_incoming_els_logo(adapter, status_buffer); | 1486 | zfcp_fsf_incoming_els_logo(fsf_req); |
1486 | else if ((els_type & 0xffff0000) == LS_RSCN) | 1487 | else if ((els_type & 0xffff0000) == LS_RSCN) |
1487 | /* we are only concerned with the command, not the length */ | 1488 | /* we are only concerned with the command, not the length */ |
1488 | zfcp_fsf_incoming_els_rscn(adapter, status_buffer); | 1489 | zfcp_fsf_incoming_els_rscn(fsf_req); |
1489 | else | 1490 | else |
1490 | zfcp_fsf_incoming_els_unknown(adapter, status_buffer); | 1491 | zfcp_fsf_incoming_els_unknown(adapter, status_buffer); |
1491 | } | 1492 | } |
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index edc5015e920d..66d3b88844b0 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c | |||
@@ -170,9 +170,10 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device) | |||
170 | BUG_ON(!zfcp_reqlist_isempty(adapter)); | 170 | BUG_ON(!zfcp_reqlist_isempty(adapter)); |
171 | adapter->req_no = 0; | 171 | adapter->req_no = 0; |
172 | 172 | ||
173 | zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING, | 173 | zfcp_erp_modify_adapter_status(adapter, 10, NULL, |
174 | ZFCP_SET); | 174 | ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); |
175 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED); | 175 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 85, |
176 | NULL); | ||
176 | zfcp_erp_wait(adapter); | 177 | zfcp_erp_wait(adapter); |
177 | goto out; | 178 | goto out; |
178 | 179 | ||
@@ -197,7 +198,7 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device) | |||
197 | 198 | ||
198 | down(&zfcp_data.config_sema); | 199 | down(&zfcp_data.config_sema); |
199 | adapter = dev_get_drvdata(&ccw_device->dev); | 200 | adapter = dev_get_drvdata(&ccw_device->dev); |
200 | zfcp_erp_adapter_shutdown(adapter, 0); | 201 | zfcp_erp_adapter_shutdown(adapter, 0, 86, NULL); |
201 | zfcp_erp_wait(adapter); | 202 | zfcp_erp_wait(adapter); |
202 | zfcp_erp_thread_kill(adapter); | 203 | zfcp_erp_thread_kill(adapter); |
203 | up(&zfcp_data.config_sema); | 204 | up(&zfcp_data.config_sema); |
@@ -223,24 +224,21 @@ zfcp_ccw_notify(struct ccw_device *ccw_device, int event) | |||
223 | case CIO_GONE: | 224 | case CIO_GONE: |
224 | ZFCP_LOG_NORMAL("adapter %s: device gone\n", | 225 | ZFCP_LOG_NORMAL("adapter %s: device gone\n", |
225 | zfcp_get_busid_by_adapter(adapter)); | 226 | zfcp_get_busid_by_adapter(adapter)); |
226 | debug_text_event(adapter->erp_dbf,1,"dev_gone"); | 227 | zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL); |
227 | zfcp_erp_adapter_shutdown(adapter, 0); | ||
228 | break; | 228 | break; |
229 | case CIO_NO_PATH: | 229 | case CIO_NO_PATH: |
230 | ZFCP_LOG_NORMAL("adapter %s: no path\n", | 230 | ZFCP_LOG_NORMAL("adapter %s: no path\n", |
231 | zfcp_get_busid_by_adapter(adapter)); | 231 | zfcp_get_busid_by_adapter(adapter)); |
232 | debug_text_event(adapter->erp_dbf,1,"no_path"); | 232 | zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL); |
233 | zfcp_erp_adapter_shutdown(adapter, 0); | ||
234 | break; | 233 | break; |
235 | case CIO_OPER: | 234 | case CIO_OPER: |
236 | ZFCP_LOG_NORMAL("adapter %s: operational again\n", | 235 | ZFCP_LOG_NORMAL("adapter %s: operational again\n", |
237 | zfcp_get_busid_by_adapter(adapter)); | 236 | zfcp_get_busid_by_adapter(adapter)); |
238 | debug_text_event(adapter->erp_dbf,1,"dev_oper"); | 237 | zfcp_erp_modify_adapter_status(adapter, 11, NULL, |
239 | zfcp_erp_modify_adapter_status(adapter, | ||
240 | ZFCP_STATUS_COMMON_RUNNING, | 238 | ZFCP_STATUS_COMMON_RUNNING, |
241 | ZFCP_SET); | 239 | ZFCP_SET); |
242 | zfcp_erp_adapter_reopen(adapter, | 240 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, |
243 | ZFCP_STATUS_COMMON_ERP_FAILED); | 241 | 89, NULL); |
244 | break; | 242 | break; |
245 | } | 243 | } |
246 | zfcp_erp_wait(adapter); | 244 | zfcp_erp_wait(adapter); |
@@ -272,7 +270,7 @@ zfcp_ccw_shutdown(struct ccw_device *cdev) | |||
272 | 270 | ||
273 | down(&zfcp_data.config_sema); | 271 | down(&zfcp_data.config_sema); |
274 | adapter = dev_get_drvdata(&cdev->dev); | 272 | adapter = dev_get_drvdata(&cdev->dev); |
275 | zfcp_erp_adapter_shutdown(adapter, 0); | 273 | zfcp_erp_adapter_shutdown(adapter, 0, 90, NULL); |
276 | zfcp_erp_wait(adapter); | 274 | zfcp_erp_wait(adapter); |
277 | up(&zfcp_data.config_sema); | 275 | up(&zfcp_data.config_sema); |
278 | } | 276 | } |
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 701046c9bb33..37b85c67b11d 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
@@ -31,123 +31,128 @@ MODULE_PARM_DESC(dbfsize, | |||
31 | 31 | ||
32 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER | 32 | #define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER |
33 | 33 | ||
34 | static int | 34 | static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len, |
35 | zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck) | 35 | int level, char *from, int from_len) |
36 | { | ||
37 | int offset; | ||
38 | struct zfcp_dbf_dump *dump = to; | ||
39 | int room = to_len - sizeof(*dump); | ||
40 | |||
41 | for (offset = 0; offset < from_len; offset += dump->size) { | ||
42 | memset(to, 0, to_len); | ||
43 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); | ||
44 | dump->total_size = from_len; | ||
45 | dump->offset = offset; | ||
46 | dump->size = min(from_len - offset, room); | ||
47 | memcpy(dump->data, from + offset, dump->size); | ||
48 | debug_event(dbf, level, dump, dump->size); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | /* FIXME: this duplicate this code in s390 debug feature */ | ||
53 | static void zfcp_dbf_timestamp(unsigned long long stck, struct timespec *time) | ||
36 | { | 54 | { |
37 | unsigned long long sec; | 55 | unsigned long long sec; |
38 | struct timespec dbftime; | ||
39 | int len = 0; | ||
40 | 56 | ||
41 | stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); | 57 | stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); |
42 | sec = stck >> 12; | 58 | sec = stck >> 12; |
43 | do_div(sec, 1000000); | 59 | do_div(sec, 1000000); |
44 | dbftime.tv_sec = sec; | 60 | time->tv_sec = sec; |
45 | stck -= (sec * 1000000) << 12; | 61 | stck -= (sec * 1000000) << 12; |
46 | dbftime.tv_nsec = ((stck * 1000) >> 12); | 62 | time->tv_nsec = ((stck * 1000) >> 12); |
47 | len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n", | ||
48 | label, dbftime.tv_sec, dbftime.tv_nsec); | ||
49 | |||
50 | return len; | ||
51 | } | 63 | } |
52 | 64 | ||
53 | static int zfcp_dbf_tag(char *out_buf, const char *label, const char *tag) | 65 | static void zfcp_dbf_tag(char **p, const char *label, const char *tag) |
54 | { | 66 | { |
55 | int len = 0, i; | 67 | int i; |
56 | 68 | ||
57 | len += sprintf(out_buf + len, "%-24s", label); | 69 | *p += sprintf(*p, "%-24s", label); |
58 | for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++) | 70 | for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++) |
59 | len += sprintf(out_buf + len, "%c", tag[i]); | 71 | *p += sprintf(*p, "%c", tag[i]); |
60 | len += sprintf(out_buf + len, "\n"); | 72 | *p += sprintf(*p, "\n"); |
73 | } | ||
61 | 74 | ||
62 | return len; | 75 | static void zfcp_dbf_outs(char **buf, const char *s1, const char *s2) |
76 | { | ||
77 | *buf += sprintf(*buf, "%-24s%s\n", s1, s2); | ||
63 | } | 78 | } |
64 | 79 | ||
65 | static int | 80 | static void zfcp_dbf_out(char **buf, const char *s, const char *format, ...) |
66 | zfcp_dbf_view(char *out_buf, const char *label, const char *format, ...) | ||
67 | { | 81 | { |
68 | va_list arg; | 82 | va_list arg; |
69 | int len = 0; | ||
70 | 83 | ||
71 | len += sprintf(out_buf + len, "%-24s", label); | 84 | *buf += sprintf(*buf, "%-24s", s); |
72 | va_start(arg, format); | 85 | va_start(arg, format); |
73 | len += vsprintf(out_buf + len, format, arg); | 86 | *buf += vsprintf(*buf, format, arg); |
74 | va_end(arg); | 87 | va_end(arg); |
75 | len += sprintf(out_buf + len, "\n"); | 88 | *buf += sprintf(*buf, "\n"); |
76 | |||
77 | return len; | ||
78 | } | 89 | } |
79 | 90 | ||
80 | static int | 91 | static void zfcp_dbf_outd(char **p, const char *label, char *buffer, |
81 | zfcp_dbf_view_dump(char *out_buf, const char *label, | 92 | int buflen, int offset, int total_size) |
82 | char *buffer, int buflen, int offset, int total_size) | ||
83 | { | 93 | { |
84 | int len = 0; | 94 | if (!offset) |
85 | 95 | *p += sprintf(*p, "%-24s ", label); | |
86 | if (offset == 0) | ||
87 | len += sprintf(out_buf + len, "%-24s ", label); | ||
88 | |||
89 | while (buflen--) { | 96 | while (buflen--) { |
90 | if (offset > 0) { | 97 | if (offset > 0) { |
91 | if ((offset % 32) == 0) | 98 | if ((offset % 32) == 0) |
92 | len += sprintf(out_buf + len, "\n%-24c ", ' '); | 99 | *p += sprintf(*p, "\n%-24c ", ' '); |
93 | else if ((offset % 4) == 0) | 100 | else if ((offset % 4) == 0) |
94 | len += sprintf(out_buf + len, " "); | 101 | *p += sprintf(*p, " "); |
95 | } | 102 | } |
96 | len += sprintf(out_buf + len, "%02x", *buffer++); | 103 | *p += sprintf(*p, "%02x", *buffer++); |
97 | if (++offset == total_size) { | 104 | if (++offset == total_size) { |
98 | len += sprintf(out_buf + len, "\n"); | 105 | *p += sprintf(*p, "\n"); |
99 | break; | 106 | break; |
100 | } | 107 | } |
101 | } | 108 | } |
102 | 109 | if (!total_size) | |
103 | if (total_size == 0) | 110 | *p += sprintf(*p, "\n"); |
104 | len += sprintf(out_buf + len, "\n"); | ||
105 | |||
106 | return len; | ||
107 | } | 111 | } |
108 | 112 | ||
109 | static int | 113 | static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view, |
110 | zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area, | 114 | int area, debug_entry_t *entry, char *out_buf) |
111 | debug_entry_t * entry, char *out_buf) | ||
112 | { | 115 | { |
113 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry); | 116 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry); |
114 | int len = 0; | 117 | struct timespec t; |
118 | char *p = out_buf; | ||
115 | 119 | ||
116 | if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) { | 120 | if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) { |
117 | len += zfcp_dbf_stck(out_buf + len, "timestamp", | 121 | zfcp_dbf_timestamp(entry->id.stck, &t); |
118 | entry->id.stck); | 122 | zfcp_dbf_out(&p, "timestamp", "%011lu:%06lu", |
119 | len += zfcp_dbf_view(out_buf + len, "cpu", "%02i", | 123 | t.tv_sec, t.tv_nsec); |
120 | entry->id.fields.cpuid); | 124 | zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid); |
121 | } else { | 125 | } else { |
122 | len += zfcp_dbf_view_dump(out_buf + len, NULL, | 126 | zfcp_dbf_outd(&p, NULL, dump->data, dump->size, dump->offset, |
123 | dump->data, | 127 | dump->total_size); |
124 | dump->size, | ||
125 | dump->offset, dump->total_size); | ||
126 | if ((dump->offset + dump->size) == dump->total_size) | 128 | if ((dump->offset + dump->size) == dump->total_size) |
127 | len += sprintf(out_buf + len, "\n"); | 129 | p += sprintf(p, "\n"); |
128 | } | 130 | } |
129 | 131 | return p - out_buf; | |
130 | return len; | ||
131 | } | 132 | } |
132 | 133 | ||
134 | /** | ||
135 | * zfcp_hba_dbf_event_fsf_response - trace event for request completion | ||
136 | * @fsf_req: request that has been completed | ||
137 | */ | ||
133 | void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) | 138 | void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) |
134 | { | 139 | { |
135 | struct zfcp_adapter *adapter = fsf_req->adapter; | 140 | struct zfcp_adapter *adapter = fsf_req->adapter; |
136 | struct fsf_qtcb *qtcb = fsf_req->qtcb; | 141 | struct fsf_qtcb *qtcb = fsf_req->qtcb; |
137 | union fsf_prot_status_qual *prot_status_qual = | 142 | union fsf_prot_status_qual *prot_status_qual = |
138 | &qtcb->prefix.prot_status_qual; | 143 | &qtcb->prefix.prot_status_qual; |
139 | union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual; | 144 | union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual; |
140 | struct scsi_cmnd *scsi_cmnd; | 145 | struct scsi_cmnd *scsi_cmnd; |
141 | struct zfcp_port *port; | 146 | struct zfcp_port *port; |
142 | struct zfcp_unit *unit; | 147 | struct zfcp_unit *unit; |
143 | struct zfcp_send_els *send_els; | 148 | struct zfcp_send_els *send_els; |
144 | struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; | 149 | struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; |
145 | struct zfcp_hba_dbf_record_response *response = &rec->type.response; | 150 | struct zfcp_hba_dbf_record_response *response = &rec->u.response; |
146 | int level; | 151 | int level; |
147 | unsigned long flags; | 152 | unsigned long flags; |
148 | 153 | ||
149 | spin_lock_irqsave(&adapter->hba_dbf_lock, flags); | 154 | spin_lock_irqsave(&adapter->hba_dbf_lock, flags); |
150 | memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); | 155 | memset(rec, 0, sizeof(*rec)); |
151 | strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE); | 156 | strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE); |
152 | 157 | ||
153 | if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && | 158 | if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && |
@@ -161,6 +166,9 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) | |||
161 | (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) { | 166 | (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) { |
162 | strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE); | 167 | strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE); |
163 | level = 4; | 168 | level = 4; |
169 | } else if (qtcb->header.log_length) { | ||
170 | strncpy(rec->tag2, "qtcb", ZFCP_DBF_TAG_SIZE); | ||
171 | level = 5; | ||
164 | } else { | 172 | } else { |
165 | strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE); | 173 | strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE); |
166 | level = 6; | 174 | level = 6; |
@@ -188,11 +196,9 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) | |||
188 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) | 196 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) |
189 | break; | 197 | break; |
190 | scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; | 198 | scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; |
191 | if (scsi_cmnd != NULL) { | 199 | if (scsi_cmnd) { |
192 | response->data.send_fcp.scsi_cmnd | 200 | response->u.fcp.cmnd = (unsigned long)scsi_cmnd; |
193 | = (unsigned long)scsi_cmnd; | 201 | response->u.fcp.serial = scsi_cmnd->serial_number; |
194 | response->data.send_fcp.scsi_serial | ||
195 | = scsi_cmnd->serial_number; | ||
196 | } | 202 | } |
197 | break; | 203 | break; |
198 | 204 | ||
@@ -200,25 +206,25 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) | |||
200 | case FSF_QTCB_CLOSE_PORT: | 206 | case FSF_QTCB_CLOSE_PORT: |
201 | case FSF_QTCB_CLOSE_PHYSICAL_PORT: | 207 | case FSF_QTCB_CLOSE_PHYSICAL_PORT: |
202 | port = (struct zfcp_port *)fsf_req->data; | 208 | port = (struct zfcp_port *)fsf_req->data; |
203 | response->data.port.wwpn = port->wwpn; | 209 | response->u.port.wwpn = port->wwpn; |
204 | response->data.port.d_id = port->d_id; | 210 | response->u.port.d_id = port->d_id; |
205 | response->data.port.port_handle = qtcb->header.port_handle; | 211 | response->u.port.port_handle = qtcb->header.port_handle; |
206 | break; | 212 | break; |
207 | 213 | ||
208 | case FSF_QTCB_OPEN_LUN: | 214 | case FSF_QTCB_OPEN_LUN: |
209 | case FSF_QTCB_CLOSE_LUN: | 215 | case FSF_QTCB_CLOSE_LUN: |
210 | unit = (struct zfcp_unit *)fsf_req->data; | 216 | unit = (struct zfcp_unit *)fsf_req->data; |
211 | port = unit->port; | 217 | port = unit->port; |
212 | response->data.unit.wwpn = port->wwpn; | 218 | response->u.unit.wwpn = port->wwpn; |
213 | response->data.unit.fcp_lun = unit->fcp_lun; | 219 | response->u.unit.fcp_lun = unit->fcp_lun; |
214 | response->data.unit.port_handle = qtcb->header.port_handle; | 220 | response->u.unit.port_handle = qtcb->header.port_handle; |
215 | response->data.unit.lun_handle = qtcb->header.lun_handle; | 221 | response->u.unit.lun_handle = qtcb->header.lun_handle; |
216 | break; | 222 | break; |
217 | 223 | ||
218 | case FSF_QTCB_SEND_ELS: | 224 | case FSF_QTCB_SEND_ELS: |
219 | send_els = (struct zfcp_send_els *)fsf_req->data; | 225 | send_els = (struct zfcp_send_els *)fsf_req->data; |
220 | response->data.send_els.d_id = qtcb->bottom.support.d_id; | 226 | response->u.els.d_id = qtcb->bottom.support.d_id; |
221 | response->data.send_els.ls_code = send_els->ls_code >> 24; | 227 | response->u.els.ls_code = send_els->ls_code >> 24; |
222 | break; | 228 | break; |
223 | 229 | ||
224 | case FSF_QTCB_ABORT_FCP_CMND: | 230 | case FSF_QTCB_ABORT_FCP_CMND: |
@@ -230,39 +236,54 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) | |||
230 | break; | 236 | break; |
231 | } | 237 | } |
232 | 238 | ||
233 | debug_event(adapter->hba_dbf, level, | 239 | debug_event(adapter->hba_dbf, level, rec, sizeof(*rec)); |
234 | rec, sizeof(struct zfcp_hba_dbf_record)); | 240 | |
241 | /* have fcp channel microcode fixed to use as little as possible */ | ||
242 | if (fsf_req->fsf_command != FSF_QTCB_FCP_CMND) { | ||
243 | /* adjust length skipping trailing zeros */ | ||
244 | char *buf = (char *)qtcb + qtcb->header.log_start; | ||
245 | int len = qtcb->header.log_length; | ||
246 | for (; len && !buf[len - 1]; len--); | ||
247 | zfcp_dbf_hexdump(adapter->hba_dbf, rec, sizeof(*rec), level, | ||
248 | buf, len); | ||
249 | } | ||
250 | |||
235 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); | 251 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); |
236 | } | 252 | } |
237 | 253 | ||
238 | void | 254 | /** |
239 | zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, | 255 | * zfcp_hba_dbf_event_fsf_unsol - trace event for an unsolicited status buffer |
240 | struct fsf_status_read_buffer *status_buffer) | 256 | * @tag: tag indicating which kind of unsolicited status has been received |
257 | * @adapter: adapter that has issued the unsolicited status buffer | ||
258 | * @status_buffer: buffer containing payload of unsolicited status | ||
259 | */ | ||
260 | void zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, | ||
261 | struct fsf_status_read_buffer *status_buffer) | ||
241 | { | 262 | { |
242 | struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; | 263 | struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; |
243 | unsigned long flags; | 264 | unsigned long flags; |
244 | 265 | ||
245 | spin_lock_irqsave(&adapter->hba_dbf_lock, flags); | 266 | spin_lock_irqsave(&adapter->hba_dbf_lock, flags); |
246 | memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); | 267 | memset(rec, 0, sizeof(*rec)); |
247 | strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE); | 268 | strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE); |
248 | strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE); | 269 | strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE); |
249 | 270 | ||
250 | rec->type.status.failed = adapter->status_read_failed; | 271 | rec->u.status.failed = adapter->status_read_failed; |
251 | if (status_buffer != NULL) { | 272 | if (status_buffer != NULL) { |
252 | rec->type.status.status_type = status_buffer->status_type; | 273 | rec->u.status.status_type = status_buffer->status_type; |
253 | rec->type.status.status_subtype = status_buffer->status_subtype; | 274 | rec->u.status.status_subtype = status_buffer->status_subtype; |
254 | memcpy(&rec->type.status.queue_designator, | 275 | memcpy(&rec->u.status.queue_designator, |
255 | &status_buffer->queue_designator, | 276 | &status_buffer->queue_designator, |
256 | sizeof(struct fsf_queue_designator)); | 277 | sizeof(struct fsf_queue_designator)); |
257 | 278 | ||
258 | switch (status_buffer->status_type) { | 279 | switch (status_buffer->status_type) { |
259 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: | 280 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: |
260 | rec->type.status.payload_size = | 281 | rec->u.status.payload_size = |
261 | ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL; | 282 | ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL; |
262 | break; | 283 | break; |
263 | 284 | ||
264 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: | 285 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: |
265 | rec->type.status.payload_size = | 286 | rec->u.status.payload_size = |
266 | ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD; | 287 | ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD; |
267 | break; | 288 | break; |
268 | 289 | ||
@@ -270,119 +291,101 @@ zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, | |||
270 | switch (status_buffer->status_subtype) { | 291 | switch (status_buffer->status_subtype) { |
271 | case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: | 292 | case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: |
272 | case FSF_STATUS_READ_SUB_FDISC_FAILED: | 293 | case FSF_STATUS_READ_SUB_FDISC_FAILED: |
273 | rec->type.status.payload_size = | 294 | rec->u.status.payload_size = |
274 | sizeof(struct fsf_link_down_info); | 295 | sizeof(struct fsf_link_down_info); |
275 | } | 296 | } |
276 | break; | 297 | break; |
277 | 298 | ||
278 | case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: | 299 | case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: |
279 | rec->type.status.payload_size = | 300 | rec->u.status.payload_size = |
280 | ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT; | 301 | ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT; |
281 | break; | 302 | break; |
282 | } | 303 | } |
283 | memcpy(&rec->type.status.payload, | 304 | memcpy(&rec->u.status.payload, |
284 | &status_buffer->payload, rec->type.status.payload_size); | 305 | &status_buffer->payload, rec->u.status.payload_size); |
285 | } | 306 | } |
286 | 307 | ||
287 | debug_event(adapter->hba_dbf, 2, | 308 | debug_event(adapter->hba_dbf, 2, rec, sizeof(*rec)); |
288 | rec, sizeof(struct zfcp_hba_dbf_record)); | ||
289 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); | 309 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); |
290 | } | 310 | } |
291 | 311 | ||
292 | void | 312 | /** |
293 | zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status, | 313 | * zfcp_hba_dbf_event_qdio - trace event for QDIO related failure |
294 | unsigned int qdio_error, unsigned int siga_error, | 314 | * @adapter: adapter affected by this QDIO related event |
295 | int sbal_index, int sbal_count) | 315 | * @status: as passed by qdio module |
316 | * @qdio_error: as passed by qdio module | ||
317 | * @siga_error: as passed by qdio module | ||
318 | * @sbal_index: first buffer with error condition, as passed by qdio module | ||
319 | * @sbal_count: number of buffers affected, as passed by qdio module | ||
320 | */ | ||
321 | void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status, | ||
322 | unsigned int qdio_error, unsigned int siga_error, | ||
323 | int sbal_index, int sbal_count) | ||
296 | { | 324 | { |
297 | struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; | 325 | struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf; |
298 | unsigned long flags; | 326 | unsigned long flags; |
299 | 327 | ||
300 | spin_lock_irqsave(&adapter->hba_dbf_lock, flags); | 328 | spin_lock_irqsave(&adapter->hba_dbf_lock, flags); |
301 | memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); | 329 | memset(r, 0, sizeof(*r)); |
302 | strncpy(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE); | 330 | strncpy(r->tag, "qdio", ZFCP_DBF_TAG_SIZE); |
303 | rec->type.qdio.status = status; | 331 | r->u.qdio.status = status; |
304 | rec->type.qdio.qdio_error = qdio_error; | 332 | r->u.qdio.qdio_error = qdio_error; |
305 | rec->type.qdio.siga_error = siga_error; | 333 | r->u.qdio.siga_error = siga_error; |
306 | rec->type.qdio.sbal_index = sbal_index; | 334 | r->u.qdio.sbal_index = sbal_index; |
307 | rec->type.qdio.sbal_count = sbal_count; | 335 | r->u.qdio.sbal_count = sbal_count; |
308 | debug_event(adapter->hba_dbf, 0, | 336 | debug_event(adapter->hba_dbf, 0, r, sizeof(*r)); |
309 | rec, sizeof(struct zfcp_hba_dbf_record)); | ||
310 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); | 337 | spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); |
311 | } | 338 | } |
312 | 339 | ||
313 | static int | 340 | static void zfcp_hba_dbf_view_response(char **p, |
314 | zfcp_hba_dbf_view_response(char *out_buf, | 341 | struct zfcp_hba_dbf_record_response *r) |
315 | struct zfcp_hba_dbf_record_response *rec) | 342 | { |
316 | { | 343 | struct timespec t; |
317 | int len = 0; | 344 | |
318 | 345 | zfcp_dbf_out(p, "fsf_command", "0x%08x", r->fsf_command); | |
319 | len += zfcp_dbf_view(out_buf + len, "fsf_command", "0x%08x", | 346 | zfcp_dbf_out(p, "fsf_reqid", "0x%0Lx", r->fsf_reqid); |
320 | rec->fsf_command); | 347 | zfcp_dbf_out(p, "fsf_seqno", "0x%08x", r->fsf_seqno); |
321 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", | 348 | zfcp_dbf_timestamp(r->fsf_issued, &t); |
322 | rec->fsf_reqid); | 349 | zfcp_dbf_out(p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec); |
323 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", | 350 | zfcp_dbf_out(p, "fsf_prot_status", "0x%08x", r->fsf_prot_status); |
324 | rec->fsf_seqno); | 351 | zfcp_dbf_out(p, "fsf_status", "0x%08x", r->fsf_status); |
325 | len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued); | 352 | zfcp_dbf_outd(p, "fsf_prot_status_qual", r->fsf_prot_status_qual, |
326 | len += zfcp_dbf_view(out_buf + len, "fsf_prot_status", "0x%08x", | 353 | FSF_PROT_STATUS_QUAL_SIZE, 0, FSF_PROT_STATUS_QUAL_SIZE); |
327 | rec->fsf_prot_status); | 354 | zfcp_dbf_outd(p, "fsf_status_qual", r->fsf_status_qual, |
328 | len += zfcp_dbf_view(out_buf + len, "fsf_status", "0x%08x", | 355 | FSF_STATUS_QUALIFIER_SIZE, 0, FSF_STATUS_QUALIFIER_SIZE); |
329 | rec->fsf_status); | 356 | zfcp_dbf_out(p, "fsf_req_status", "0x%08x", r->fsf_req_status); |
330 | len += zfcp_dbf_view_dump(out_buf + len, "fsf_prot_status_qual", | 357 | zfcp_dbf_out(p, "sbal_first", "0x%02x", r->sbal_first); |
331 | rec->fsf_prot_status_qual, | 358 | zfcp_dbf_out(p, "sbal_curr", "0x%02x", r->sbal_curr); |
332 | FSF_PROT_STATUS_QUAL_SIZE, | 359 | zfcp_dbf_out(p, "sbal_last", "0x%02x", r->sbal_last); |
333 | 0, FSF_PROT_STATUS_QUAL_SIZE); | 360 | zfcp_dbf_out(p, "pool", "0x%02x", r->pool); |
334 | len += zfcp_dbf_view_dump(out_buf + len, "fsf_status_qual", | 361 | |
335 | rec->fsf_status_qual, | 362 | switch (r->fsf_command) { |
336 | FSF_STATUS_QUALIFIER_SIZE, | ||
337 | 0, FSF_STATUS_QUALIFIER_SIZE); | ||
338 | len += zfcp_dbf_view(out_buf + len, "fsf_req_status", "0x%08x", | ||
339 | rec->fsf_req_status); | ||
340 | len += zfcp_dbf_view(out_buf + len, "sbal_first", "0x%02x", | ||
341 | rec->sbal_first); | ||
342 | len += zfcp_dbf_view(out_buf + len, "sbal_curr", "0x%02x", | ||
343 | rec->sbal_curr); | ||
344 | len += zfcp_dbf_view(out_buf + len, "sbal_last", "0x%02x", | ||
345 | rec->sbal_last); | ||
346 | len += zfcp_dbf_view(out_buf + len, "pool", "0x%02x", rec->pool); | ||
347 | |||
348 | switch (rec->fsf_command) { | ||
349 | case FSF_QTCB_FCP_CMND: | 363 | case FSF_QTCB_FCP_CMND: |
350 | if (rec->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) | 364 | if (r->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) |
351 | break; | 365 | break; |
352 | len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx", | 366 | zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); |
353 | rec->data.send_fcp.scsi_cmnd); | 367 | zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); |
354 | len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx", | ||
355 | rec->data.send_fcp.scsi_serial); | ||
356 | break; | 368 | break; |
357 | 369 | ||
358 | case FSF_QTCB_OPEN_PORT_WITH_DID: | 370 | case FSF_QTCB_OPEN_PORT_WITH_DID: |
359 | case FSF_QTCB_CLOSE_PORT: | 371 | case FSF_QTCB_CLOSE_PORT: |
360 | case FSF_QTCB_CLOSE_PHYSICAL_PORT: | 372 | case FSF_QTCB_CLOSE_PHYSICAL_PORT: |
361 | len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx", | 373 | zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.port.wwpn); |
362 | rec->data.port.wwpn); | 374 | zfcp_dbf_out(p, "d_id", "0x%06x", r->u.port.d_id); |
363 | len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", | 375 | zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.port.port_handle); |
364 | rec->data.port.d_id); | ||
365 | len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x", | ||
366 | rec->data.port.port_handle); | ||
367 | break; | 376 | break; |
368 | 377 | ||
369 | case FSF_QTCB_OPEN_LUN: | 378 | case FSF_QTCB_OPEN_LUN: |
370 | case FSF_QTCB_CLOSE_LUN: | 379 | case FSF_QTCB_CLOSE_LUN: |
371 | len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx", | 380 | zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.unit.wwpn); |
372 | rec->data.unit.wwpn); | 381 | zfcp_dbf_out(p, "fcp_lun", "0x%016Lx", r->u.unit.fcp_lun); |
373 | len += zfcp_dbf_view(out_buf + len, "fcp_lun", "0x%016Lx", | 382 | zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.unit.port_handle); |
374 | rec->data.unit.fcp_lun); | 383 | zfcp_dbf_out(p, "lun_handle", "0x%08x", r->u.unit.lun_handle); |
375 | len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x", | ||
376 | rec->data.unit.port_handle); | ||
377 | len += zfcp_dbf_view(out_buf + len, "lun_handle", "0x%08x", | ||
378 | rec->data.unit.lun_handle); | ||
379 | break; | 384 | break; |
380 | 385 | ||
381 | case FSF_QTCB_SEND_ELS: | 386 | case FSF_QTCB_SEND_ELS: |
382 | len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", | 387 | zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id); |
383 | rec->data.send_els.d_id); | 388 | zfcp_dbf_out(p, "ls_code", "0x%02x", r->u.els.ls_code); |
384 | len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x", | ||
385 | rec->data.send_els.ls_code); | ||
386 | break; | 389 | break; |
387 | 390 | ||
388 | case FSF_QTCB_ABORT_FCP_CMND: | 391 | case FSF_QTCB_ABORT_FCP_CMND: |
@@ -393,74 +396,52 @@ zfcp_hba_dbf_view_response(char *out_buf, | |||
393 | case FSF_QTCB_UPLOAD_CONTROL_FILE: | 396 | case FSF_QTCB_UPLOAD_CONTROL_FILE: |
394 | break; | 397 | break; |
395 | } | 398 | } |
396 | |||
397 | return len; | ||
398 | } | 399 | } |
399 | 400 | ||
400 | static int | 401 | static void zfcp_hba_dbf_view_status(char **p, |
401 | zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec) | 402 | struct zfcp_hba_dbf_record_status *r) |
402 | { | 403 | { |
403 | int len = 0; | 404 | zfcp_dbf_out(p, "failed", "0x%02x", r->failed); |
404 | 405 | zfcp_dbf_out(p, "status_type", "0x%08x", r->status_type); | |
405 | len += zfcp_dbf_view(out_buf + len, "failed", "0x%02x", rec->failed); | 406 | zfcp_dbf_out(p, "status_subtype", "0x%08x", r->status_subtype); |
406 | len += zfcp_dbf_view(out_buf + len, "status_type", "0x%08x", | 407 | zfcp_dbf_outd(p, "queue_designator", (char *)&r->queue_designator, |
407 | rec->status_type); | 408 | sizeof(struct fsf_queue_designator), 0, |
408 | len += zfcp_dbf_view(out_buf + len, "status_subtype", "0x%08x", | 409 | sizeof(struct fsf_queue_designator)); |
409 | rec->status_subtype); | 410 | zfcp_dbf_outd(p, "payload", (char *)&r->payload, r->payload_size, 0, |
410 | len += zfcp_dbf_view_dump(out_buf + len, "queue_designator", | 411 | r->payload_size); |
411 | (char *)&rec->queue_designator, | ||
412 | sizeof(struct fsf_queue_designator), | ||
413 | 0, sizeof(struct fsf_queue_designator)); | ||
414 | len += zfcp_dbf_view_dump(out_buf + len, "payload", | ||
415 | (char *)&rec->payload, | ||
416 | rec->payload_size, 0, rec->payload_size); | ||
417 | |||
418 | return len; | ||
419 | } | 412 | } |
420 | 413 | ||
421 | static int | 414 | static void zfcp_hba_dbf_view_qdio(char **p, struct zfcp_hba_dbf_record_qdio *r) |
422 | zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec) | ||
423 | { | 415 | { |
424 | int len = 0; | 416 | zfcp_dbf_out(p, "status", "0x%08x", r->status); |
425 | 417 | zfcp_dbf_out(p, "qdio_error", "0x%08x", r->qdio_error); | |
426 | len += zfcp_dbf_view(out_buf + len, "status", "0x%08x", rec->status); | 418 | zfcp_dbf_out(p, "siga_error", "0x%08x", r->siga_error); |
427 | len += zfcp_dbf_view(out_buf + len, "qdio_error", "0x%08x", | 419 | zfcp_dbf_out(p, "sbal_index", "0x%02x", r->sbal_index); |
428 | rec->qdio_error); | 420 | zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count); |
429 | len += zfcp_dbf_view(out_buf + len, "siga_error", "0x%08x", | ||
430 | rec->siga_error); | ||
431 | len += zfcp_dbf_view(out_buf + len, "sbal_index", "0x%02x", | ||
432 | rec->sbal_index); | ||
433 | len += zfcp_dbf_view(out_buf + len, "sbal_count", "0x%02x", | ||
434 | rec->sbal_count); | ||
435 | |||
436 | return len; | ||
437 | } | 421 | } |
438 | 422 | ||
439 | static int | 423 | static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view, |
440 | zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view, | 424 | char *out_buf, const char *in_buf) |
441 | char *out_buf, const char *in_buf) | ||
442 | { | 425 | { |
443 | struct zfcp_hba_dbf_record *rec = (struct zfcp_hba_dbf_record *)in_buf; | 426 | struct zfcp_hba_dbf_record *r = (struct zfcp_hba_dbf_record *)in_buf; |
444 | int len = 0; | 427 | char *p = out_buf; |
445 | 428 | ||
446 | if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | 429 | if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) |
447 | return 0; | 430 | return 0; |
448 | 431 | ||
449 | len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); | 432 | zfcp_dbf_tag(&p, "tag", r->tag); |
450 | if (isalpha(rec->tag2[0])) | 433 | if (isalpha(r->tag2[0])) |
451 | len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2); | 434 | zfcp_dbf_tag(&p, "tag2", r->tag2); |
452 | if (strncmp(rec->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0) | ||
453 | len += zfcp_hba_dbf_view_response(out_buf + len, | ||
454 | &rec->type.response); | ||
455 | else if (strncmp(rec->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0) | ||
456 | len += zfcp_hba_dbf_view_status(out_buf + len, | ||
457 | &rec->type.status); | ||
458 | else if (strncmp(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0) | ||
459 | len += zfcp_hba_dbf_view_qdio(out_buf + len, &rec->type.qdio); | ||
460 | 435 | ||
461 | len += sprintf(out_buf + len, "\n"); | 436 | if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0) |
437 | zfcp_hba_dbf_view_response(&p, &r->u.response); | ||
438 | else if (strncmp(r->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0) | ||
439 | zfcp_hba_dbf_view_status(&p, &r->u.status); | ||
440 | else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0) | ||
441 | zfcp_hba_dbf_view_qdio(&p, &r->u.qdio); | ||
462 | 442 | ||
463 | return len; | 443 | p += sprintf(p, "\n"); |
444 | return p - out_buf; | ||
464 | } | 445 | } |
465 | 446 | ||
466 | static struct debug_view zfcp_hba_dbf_view = { | 447 | static struct debug_view zfcp_hba_dbf_view = { |
@@ -472,219 +453,570 @@ static struct debug_view zfcp_hba_dbf_view = { | |||
472 | NULL | 453 | NULL |
473 | }; | 454 | }; |
474 | 455 | ||
475 | static void | 456 | static const char *zfcp_rec_dbf_tags[] = { |
476 | _zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req, | 457 | [ZFCP_REC_DBF_ID_THREAD] = "thread", |
477 | u32 s_id, u32 d_id, void *buffer, int buflen) | 458 | [ZFCP_REC_DBF_ID_TARGET] = "target", |
459 | [ZFCP_REC_DBF_ID_TRIGGER] = "trigger", | ||
460 | [ZFCP_REC_DBF_ID_ACTION] = "action", | ||
461 | }; | ||
462 | |||
463 | static const char *zfcp_rec_dbf_ids[] = { | ||
464 | [1] = "new", | ||
465 | [2] = "ready", | ||
466 | [3] = "kill", | ||
467 | [4] = "down sleep", | ||
468 | [5] = "down wakeup", | ||
469 | [6] = "down sleep ecd", | ||
470 | [7] = "down wakeup ecd", | ||
471 | [8] = "down sleep epd", | ||
472 | [9] = "down wakeup epd", | ||
473 | [10] = "online", | ||
474 | [11] = "operational", | ||
475 | [12] = "scsi slave destroy", | ||
476 | [13] = "propagate failed adapter", | ||
477 | [14] = "propagate failed port", | ||
478 | [15] = "block adapter", | ||
479 | [16] = "unblock adapter", | ||
480 | [17] = "block port", | ||
481 | [18] = "unblock port", | ||
482 | [19] = "block unit", | ||
483 | [20] = "unblock unit", | ||
484 | [21] = "unit recovery failed", | ||
485 | [22] = "port recovery failed", | ||
486 | [23] = "adapter recovery failed", | ||
487 | [24] = "qdio queues down", | ||
488 | [25] = "p2p failed", | ||
489 | [26] = "nameserver lookup failed", | ||
490 | [27] = "nameserver port failed", | ||
491 | [28] = "link up", | ||
492 | [29] = "link down", | ||
493 | [30] = "link up status read", | ||
494 | [31] = "open port failed", | ||
495 | [32] = "open port failed", | ||
496 | [33] = "close port", | ||
497 | [34] = "open unit failed", | ||
498 | [35] = "exclusive open unit failed", | ||
499 | [36] = "shared open unit failed", | ||
500 | [37] = "link down", | ||
501 | [38] = "link down status read no link", | ||
502 | [39] = "link down status read fdisc login", | ||
503 | [40] = "link down status read firmware update", | ||
504 | [41] = "link down status read unknown reason", | ||
505 | [42] = "link down ecd incomplete", | ||
506 | [43] = "link down epd incomplete", | ||
507 | [44] = "sysfs adapter recovery", | ||
508 | [45] = "sysfs port recovery", | ||
509 | [46] = "sysfs unit recovery", | ||
510 | [47] = "port boxed abort", | ||
511 | [48] = "unit boxed abort", | ||
512 | [49] = "port boxed ct", | ||
513 | [50] = "port boxed close physical", | ||
514 | [51] = "port boxed open unit", | ||
515 | [52] = "port boxed close unit", | ||
516 | [53] = "port boxed fcp", | ||
517 | [54] = "unit boxed fcp", | ||
518 | [55] = "port access denied ct", | ||
519 | [56] = "port access denied els", | ||
520 | [57] = "port access denied open port", | ||
521 | [58] = "port access denied close physical", | ||
522 | [59] = "unit access denied open unit", | ||
523 | [60] = "shared unit access denied open unit", | ||
524 | [61] = "unit access denied fcp", | ||
525 | [62] = "request timeout", | ||
526 | [63] = "adisc link test reject or timeout", | ||
527 | [64] = "adisc link test d_id changed", | ||
528 | [65] = "adisc link test failed", | ||
529 | [66] = "recovery out of memory", | ||
530 | [67] = "adapter recovery repeated after state change", | ||
531 | [68] = "port recovery repeated after state change", | ||
532 | [69] = "unit recovery repeated after state change", | ||
533 | [70] = "port recovery follow-up after successful adapter recovery", | ||
534 | [71] = "adapter recovery escalation after failed adapter recovery", | ||
535 | [72] = "port recovery follow-up after successful physical port " | ||
536 | "recovery", | ||
537 | [73] = "adapter recovery escalation after failed physical port " | ||
538 | "recovery", | ||
539 | [74] = "unit recovery follow-up after successful port recovery", | ||
540 | [75] = "physical port recovery escalation after failed port " | ||
541 | "recovery", | ||
542 | [76] = "port recovery escalation after failed unit recovery", | ||
543 | [77] = "recovery opening nameserver port", | ||
544 | [78] = "duplicate request id", | ||
545 | [79] = "link down", | ||
546 | [80] = "exclusive read-only unit access unsupported", | ||
547 | [81] = "shared read-write unit access unsupported", | ||
548 | [82] = "incoming rscn", | ||
549 | [83] = "incoming plogi", | ||
550 | [84] = "incoming logo", | ||
551 | [85] = "online", | ||
552 | [86] = "offline", | ||
553 | [87] = "ccw device gone", | ||
554 | [88] = "ccw device no path", | ||
555 | [89] = "ccw device operational", | ||
556 | [90] = "ccw device shutdown", | ||
557 | [91] = "sysfs port addition", | ||
558 | [92] = "sysfs port removal", | ||
559 | [93] = "sysfs adapter recovery", | ||
560 | [94] = "sysfs unit addition", | ||
561 | [95] = "sysfs unit removal", | ||
562 | [96] = "sysfs port recovery", | ||
563 | [97] = "sysfs unit recovery", | ||
564 | [98] = "sequence number mismatch", | ||
565 | [99] = "link up", | ||
566 | [100] = "error state", | ||
567 | [101] = "status read physical port closed", | ||
568 | [102] = "link up status read", | ||
569 | [103] = "too many failed status read buffers", | ||
570 | [104] = "port handle not valid abort", | ||
571 | [105] = "lun handle not valid abort", | ||
572 | [106] = "port handle not valid ct", | ||
573 | [107] = "port handle not valid close port", | ||
574 | [108] = "port handle not valid close physical port", | ||
575 | [109] = "port handle not valid open unit", | ||
576 | [110] = "port handle not valid close unit", | ||
577 | [111] = "lun handle not valid close unit", | ||
578 | [112] = "port handle not valid fcp", | ||
579 | [113] = "lun handle not valid fcp", | ||
580 | [114] = "handle mismatch fcp", | ||
581 | [115] = "lun not valid fcp", | ||
582 | [116] = "qdio send failed", | ||
583 | [117] = "version mismatch", | ||
584 | [118] = "incompatible qtcb type", | ||
585 | [119] = "unknown protocol status", | ||
586 | [120] = "unknown fsf command", | ||
587 | [121] = "no recommendation for status qualifier", | ||
588 | [122] = "status read physical port closed in error", | ||
589 | [123] = "fc service class not supported ct", | ||
590 | [124] = "fc service class not supported els", | ||
591 | [125] = "need newer zfcp", | ||
592 | [126] = "need newer microcode", | ||
593 | [127] = "arbitrated loop not supported", | ||
594 | [128] = "unknown topology", | ||
595 | [129] = "qtcb size mismatch", | ||
596 | [130] = "unknown fsf status ecd", | ||
597 | [131] = "fcp request too big", | ||
598 | [132] = "fc service class not supported fcp", | ||
599 | [133] = "data direction not valid fcp", | ||
600 | [134] = "command length not valid fcp", | ||
601 | [135] = "status read act update", | ||
602 | [136] = "status read cfdc update", | ||
603 | [137] = "hbaapi port open", | ||
604 | [138] = "hbaapi unit open", | ||
605 | [139] = "hbaapi unit shutdown", | ||
606 | [140] = "qdio error", | ||
607 | [141] = "scsi host reset", | ||
608 | [142] = "dismissing fsf request for recovery action", | ||
609 | [143] = "recovery action timed out", | ||
610 | [144] = "recovery action gone", | ||
611 | [145] = "recovery action being processed", | ||
612 | [146] = "recovery action ready for next step", | ||
613 | }; | ||
614 | |||
615 | static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view, | ||
616 | char *buf, const char *_rec) | ||
617 | { | ||
618 | struct zfcp_rec_dbf_record *r = (struct zfcp_rec_dbf_record *)_rec; | ||
619 | char *p = buf; | ||
620 | |||
621 | zfcp_dbf_outs(&p, "tag", zfcp_rec_dbf_tags[r->id]); | ||
622 | zfcp_dbf_outs(&p, "hint", zfcp_rec_dbf_ids[r->id2]); | ||
623 | zfcp_dbf_out(&p, "id", "%d", r->id2); | ||
624 | switch (r->id) { | ||
625 | case ZFCP_REC_DBF_ID_THREAD: | ||
626 | zfcp_dbf_out(&p, "total", "%d", r->u.thread.total); | ||
627 | zfcp_dbf_out(&p, "ready", "%d", r->u.thread.ready); | ||
628 | zfcp_dbf_out(&p, "running", "%d", r->u.thread.running); | ||
629 | break; | ||
630 | case ZFCP_REC_DBF_ID_TARGET: | ||
631 | zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.target.ref); | ||
632 | zfcp_dbf_out(&p, "status", "0x%08x", r->u.target.status); | ||
633 | zfcp_dbf_out(&p, "erp_count", "%d", r->u.target.erp_count); | ||
634 | zfcp_dbf_out(&p, "d_id", "0x%06x", r->u.target.d_id); | ||
635 | zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.target.wwpn); | ||
636 | zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.target.fcp_lun); | ||
637 | break; | ||
638 | case ZFCP_REC_DBF_ID_TRIGGER: | ||
639 | zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.trigger.ref); | ||
640 | zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.trigger.action); | ||
641 | zfcp_dbf_out(&p, "requested", "%d", r->u.trigger.want); | ||
642 | zfcp_dbf_out(&p, "executed", "%d", r->u.trigger.need); | ||
643 | zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.trigger.wwpn); | ||
644 | zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.trigger.fcp_lun); | ||
645 | zfcp_dbf_out(&p, "adapter_status", "0x%08x", r->u.trigger.as); | ||
646 | zfcp_dbf_out(&p, "port_status", "0x%08x", r->u.trigger.ps); | ||
647 | zfcp_dbf_out(&p, "unit_status", "0x%08x", r->u.trigger.us); | ||
648 | break; | ||
649 | case ZFCP_REC_DBF_ID_ACTION: | ||
650 | zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.action.action); | ||
651 | zfcp_dbf_out(&p, "fsf_req", "0x%016Lx", r->u.action.fsf_req); | ||
652 | zfcp_dbf_out(&p, "status", "0x%08Lx", r->u.action.status); | ||
653 | zfcp_dbf_out(&p, "step", "0x%08Lx", r->u.action.step); | ||
654 | break; | ||
655 | } | ||
656 | p += sprintf(p, "\n"); | ||
657 | return p - buf; | ||
658 | } | ||
659 | |||
660 | static struct debug_view zfcp_rec_dbf_view = { | ||
661 | "structured", | ||
662 | NULL, | ||
663 | &zfcp_dbf_view_header, | ||
664 | &zfcp_rec_dbf_view_format, | ||
665 | NULL, | ||
666 | NULL | ||
667 | }; | ||
668 | |||
669 | /** | ||
670 | * zfcp_rec_dbf_event_thread - trace event related to recovery thread operation | ||
671 | * @id2: identifier for event | ||
672 | * @adapter: adapter | ||
673 | * @lock: non-zero value indicates that erp_lock has not yet been acquired | ||
674 | */ | ||
675 | void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter, int lock) | ||
676 | { | ||
677 | struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf; | ||
678 | unsigned long flags = 0; | ||
679 | struct list_head *entry; | ||
680 | unsigned ready = 0, running = 0, total; | ||
681 | |||
682 | if (lock) | ||
683 | read_lock_irqsave(&adapter->erp_lock, flags); | ||
684 | list_for_each(entry, &adapter->erp_ready_head) | ||
685 | ready++; | ||
686 | list_for_each(entry, &adapter->erp_running_head) | ||
687 | running++; | ||
688 | total = adapter->erp_total_count; | ||
689 | if (lock) | ||
690 | read_unlock_irqrestore(&adapter->erp_lock, flags); | ||
691 | |||
692 | spin_lock_irqsave(&adapter->rec_dbf_lock, flags); | ||
693 | memset(r, 0, sizeof(*r)); | ||
694 | r->id = ZFCP_REC_DBF_ID_THREAD; | ||
695 | r->id2 = id2; | ||
696 | r->u.thread.total = total; | ||
697 | r->u.thread.ready = ready; | ||
698 | r->u.thread.running = running; | ||
699 | debug_event(adapter->rec_dbf, 5, r, sizeof(*r)); | ||
700 | spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags); | ||
701 | } | ||
702 | |||
703 | static void zfcp_rec_dbf_event_target(u8 id2, void *ref, | ||
704 | struct zfcp_adapter *adapter, | ||
705 | atomic_t *status, atomic_t *erp_count, | ||
706 | u64 wwpn, u32 d_id, u64 fcp_lun) | ||
707 | { | ||
708 | struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf; | ||
709 | unsigned long flags; | ||
710 | |||
711 | spin_lock_irqsave(&adapter->rec_dbf_lock, flags); | ||
712 | memset(r, 0, sizeof(*r)); | ||
713 | r->id = ZFCP_REC_DBF_ID_TARGET; | ||
714 | r->id2 = id2; | ||
715 | r->u.target.ref = (unsigned long)ref; | ||
716 | r->u.target.status = atomic_read(status); | ||
717 | r->u.target.wwpn = wwpn; | ||
718 | r->u.target.d_id = d_id; | ||
719 | r->u.target.fcp_lun = fcp_lun; | ||
720 | r->u.target.erp_count = atomic_read(erp_count); | ||
721 | debug_event(adapter->rec_dbf, 3, r, sizeof(*r)); | ||
722 | spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags); | ||
723 | } | ||
724 | |||
725 | /** | ||
726 | * zfcp_rec_dbf_event_adapter - trace event for adapter state change | ||
727 | * @id: identifier for trigger of state change | ||
728 | * @ref: additional reference (e.g. request) | ||
729 | * @adapter: adapter | ||
730 | */ | ||
731 | void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *adapter) | ||
732 | { | ||
733 | zfcp_rec_dbf_event_target(id, ref, adapter, &adapter->status, | ||
734 | &adapter->erp_counter, 0, 0, 0); | ||
735 | } | ||
736 | |||
737 | /** | ||
738 | * zfcp_rec_dbf_event_port - trace event for port state change | ||
739 | * @id: identifier for trigger of state change | ||
740 | * @ref: additional reference (e.g. request) | ||
741 | * @port: port | ||
742 | */ | ||
743 | void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port) | ||
478 | { | 744 | { |
479 | struct zfcp_send_ct *send_ct = (struct zfcp_send_ct *)fsf_req->data; | ||
480 | struct zfcp_port *port = send_ct->port; | ||
481 | struct zfcp_adapter *adapter = port->adapter; | 745 | struct zfcp_adapter *adapter = port->adapter; |
482 | struct ct_hdr *header = (struct ct_hdr *)buffer; | 746 | |
483 | struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf; | 747 | zfcp_rec_dbf_event_target(id, ref, adapter, &port->status, |
484 | struct zfcp_san_dbf_record_ct *ct = &rec->type.ct; | 748 | &port->erp_counter, port->wwpn, port->d_id, |
749 | 0); | ||
750 | } | ||
751 | |||
752 | /** | ||
753 | * zfcp_rec_dbf_event_unit - trace event for unit state change | ||
754 | * @id: identifier for trigger of state change | ||
755 | * @ref: additional reference (e.g. request) | ||
756 | * @unit: unit | ||
757 | */ | ||
758 | void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit) | ||
759 | { | ||
760 | struct zfcp_port *port = unit->port; | ||
761 | struct zfcp_adapter *adapter = port->adapter; | ||
762 | |||
763 | zfcp_rec_dbf_event_target(id, ref, adapter, &unit->status, | ||
764 | &unit->erp_counter, port->wwpn, port->d_id, | ||
765 | unit->fcp_lun); | ||
766 | } | ||
767 | |||
768 | /** | ||
769 | * zfcp_rec_dbf_event_trigger - trace event for triggered error recovery | ||
770 | * @id2: identifier for error recovery trigger | ||
771 | * @ref: additional reference (e.g. request) | ||
772 | * @want: originally requested error recovery action | ||
773 | * @need: error recovery action actually initiated | ||
774 | * @action: address of error recovery action struct | ||
775 | * @adapter: adapter | ||
776 | * @port: port | ||
777 | * @unit: unit | ||
778 | */ | ||
779 | void zfcp_rec_dbf_event_trigger(u8 id2, void *ref, u8 want, u8 need, | ||
780 | void *action, struct zfcp_adapter *adapter, | ||
781 | struct zfcp_port *port, struct zfcp_unit *unit) | ||
782 | { | ||
783 | struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf; | ||
485 | unsigned long flags; | 784 | unsigned long flags; |
486 | 785 | ||
487 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); | 786 | spin_lock_irqsave(&adapter->rec_dbf_lock, flags); |
488 | memset(rec, 0, sizeof(struct zfcp_san_dbf_record)); | 787 | memset(r, 0, sizeof(*r)); |
489 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); | 788 | r->id = ZFCP_REC_DBF_ID_TRIGGER; |
490 | rec->fsf_reqid = (unsigned long)fsf_req; | 789 | r->id2 = id2; |
491 | rec->fsf_seqno = fsf_req->seq_no; | 790 | r->u.trigger.ref = (unsigned long)ref; |
492 | rec->s_id = s_id; | 791 | r->u.trigger.want = want; |
493 | rec->d_id = d_id; | 792 | r->u.trigger.need = need; |
494 | if (strncmp(tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { | 793 | r->u.trigger.action = (unsigned long)action; |
495 | ct->type.request.cmd_req_code = header->cmd_rsp_code; | 794 | r->u.trigger.as = atomic_read(&adapter->status); |
496 | ct->type.request.revision = header->revision; | 795 | if (port) { |
497 | ct->type.request.gs_type = header->gs_type; | 796 | r->u.trigger.ps = atomic_read(&port->status); |
498 | ct->type.request.gs_subtype = header->gs_subtype; | 797 | r->u.trigger.wwpn = port->wwpn; |
499 | ct->type.request.options = header->options; | ||
500 | ct->type.request.max_res_size = header->max_res_size; | ||
501 | } else if (strncmp(tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { | ||
502 | ct->type.response.cmd_rsp_code = header->cmd_rsp_code; | ||
503 | ct->type.response.revision = header->revision; | ||
504 | ct->type.response.reason_code = header->reason_code; | ||
505 | ct->type.response.reason_code_expl = header->reason_code_expl; | ||
506 | ct->type.response.vendor_unique = header->vendor_unique; | ||
507 | } | 798 | } |
508 | ct->payload_size = | 799 | if (unit) { |
509 | min(buflen - (int)sizeof(struct ct_hdr), ZFCP_DBF_CT_PAYLOAD); | 800 | r->u.trigger.us = atomic_read(&unit->status); |
510 | memcpy(ct->payload, buffer + sizeof(struct ct_hdr), ct->payload_size); | 801 | r->u.trigger.fcp_lun = unit->fcp_lun; |
511 | debug_event(adapter->san_dbf, 3, | 802 | } |
512 | rec, sizeof(struct zfcp_san_dbf_record)); | 803 | debug_event(adapter->rec_dbf, action ? 1 : 4, r, sizeof(*r)); |
513 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); | 804 | spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags); |
514 | } | 805 | } |
515 | 806 | ||
807 | /** | ||
808 | * zfcp_rec_dbf_event_action - trace event showing progress of recovery action | ||
809 | * @id2: identifier | ||
810 | * @erp_action: error recovery action struct pointer | ||
811 | */ | ||
812 | void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action) | ||
813 | { | ||
814 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
815 | struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf; | ||
816 | unsigned long flags; | ||
817 | |||
818 | spin_lock_irqsave(&adapter->rec_dbf_lock, flags); | ||
819 | memset(r, 0, sizeof(*r)); | ||
820 | r->id = ZFCP_REC_DBF_ID_ACTION; | ||
821 | r->id2 = id2; | ||
822 | r->u.action.action = (unsigned long)erp_action; | ||
823 | r->u.action.status = erp_action->status; | ||
824 | r->u.action.step = erp_action->step; | ||
825 | r->u.action.fsf_req = (unsigned long)erp_action->fsf_req; | ||
826 | debug_event(adapter->rec_dbf, 4, r, sizeof(*r)); | ||
827 | spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags); | ||
828 | } | ||
829 | |||
830 | /** | ||
831 | * zfcp_san_dbf_event_ct_request - trace event for issued CT request | ||
832 | * @fsf_req: request containing issued CT data | ||
833 | */ | ||
516 | void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) | 834 | void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) |
517 | { | 835 | { |
518 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; | 836 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; |
519 | struct zfcp_port *port = ct->port; | 837 | struct zfcp_port *port = ct->port; |
520 | struct zfcp_adapter *adapter = port->adapter; | 838 | struct zfcp_adapter *adapter = port->adapter; |
839 | struct ct_hdr *hdr = zfcp_sg_to_address(ct->req); | ||
840 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; | ||
841 | struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req; | ||
842 | unsigned long flags; | ||
521 | 843 | ||
522 | _zfcp_san_dbf_event_common_ct("octc", fsf_req, | 844 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); |
523 | fc_host_port_id(adapter->scsi_host), | 845 | memset(r, 0, sizeof(*r)); |
524 | port->d_id, zfcp_sg_to_address(ct->req), | 846 | strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE); |
525 | ct->req->length); | 847 | r->fsf_reqid = (unsigned long)fsf_req; |
848 | r->fsf_seqno = fsf_req->seq_no; | ||
849 | r->s_id = fc_host_port_id(adapter->scsi_host); | ||
850 | r->d_id = port->d_id; | ||
851 | oct->cmd_req_code = hdr->cmd_rsp_code; | ||
852 | oct->revision = hdr->revision; | ||
853 | oct->gs_type = hdr->gs_type; | ||
854 | oct->gs_subtype = hdr->gs_subtype; | ||
855 | oct->options = hdr->options; | ||
856 | oct->max_res_size = hdr->max_res_size; | ||
857 | oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr), | ||
858 | ZFCP_DBF_CT_PAYLOAD); | ||
859 | memcpy(oct->payload, (void *)hdr + sizeof(struct ct_hdr), oct->len); | ||
860 | debug_event(adapter->san_dbf, 3, r, sizeof(*r)); | ||
861 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); | ||
526 | } | 862 | } |
527 | 863 | ||
864 | /** | ||
865 | * zfcp_san_dbf_event_ct_response - trace event for completion of CT request | ||
866 | * @fsf_req: request containing CT response | ||
867 | */ | ||
528 | void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) | 868 | void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) |
529 | { | 869 | { |
530 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; | 870 | struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; |
531 | struct zfcp_port *port = ct->port; | 871 | struct zfcp_port *port = ct->port; |
532 | struct zfcp_adapter *adapter = port->adapter; | 872 | struct zfcp_adapter *adapter = port->adapter; |
873 | struct ct_hdr *hdr = zfcp_sg_to_address(ct->resp); | ||
874 | struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; | ||
875 | struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp; | ||
876 | unsigned long flags; | ||
533 | 877 | ||
534 | _zfcp_san_dbf_event_common_ct("rctc", fsf_req, port->d_id, | 878 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); |
535 | fc_host_port_id(adapter->scsi_host), | 879 | memset(r, 0, sizeof(*r)); |
536 | zfcp_sg_to_address(ct->resp), | 880 | strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE); |
537 | ct->resp->length); | 881 | r->fsf_reqid = (unsigned long)fsf_req; |
882 | r->fsf_seqno = fsf_req->seq_no; | ||
883 | r->s_id = port->d_id; | ||
884 | r->d_id = fc_host_port_id(adapter->scsi_host); | ||
885 | rct->cmd_rsp_code = hdr->cmd_rsp_code; | ||
886 | rct->revision = hdr->revision; | ||
887 | rct->reason_code = hdr->reason_code; | ||
888 | rct->expl = hdr->reason_code_expl; | ||
889 | rct->vendor_unique = hdr->vendor_unique; | ||
890 | rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr), | ||
891 | ZFCP_DBF_CT_PAYLOAD); | ||
892 | memcpy(rct->payload, (void *)hdr + sizeof(struct ct_hdr), rct->len); | ||
893 | debug_event(adapter->san_dbf, 3, r, sizeof(*r)); | ||
894 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); | ||
538 | } | 895 | } |
539 | 896 | ||
540 | static void | 897 | static void zfcp_san_dbf_event_els(const char *tag, int level, |
541 | _zfcp_san_dbf_event_common_els(const char *tag, int level, | 898 | struct zfcp_fsf_req *fsf_req, u32 s_id, |
542 | struct zfcp_fsf_req *fsf_req, u32 s_id, | 899 | u32 d_id, u8 ls_code, void *buffer, |
543 | u32 d_id, u8 ls_code, void *buffer, int buflen) | 900 | int buflen) |
544 | { | 901 | { |
545 | struct zfcp_adapter *adapter = fsf_req->adapter; | 902 | struct zfcp_adapter *adapter = fsf_req->adapter; |
546 | struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf; | 903 | struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf; |
547 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; | ||
548 | unsigned long flags; | 904 | unsigned long flags; |
549 | int offset = 0; | ||
550 | 905 | ||
551 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); | 906 | spin_lock_irqsave(&adapter->san_dbf_lock, flags); |
552 | do { | 907 | memset(rec, 0, sizeof(*rec)); |
553 | memset(rec, 0, sizeof(struct zfcp_san_dbf_record)); | 908 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); |
554 | if (offset == 0) { | 909 | rec->fsf_reqid = (unsigned long)fsf_req; |
555 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); | 910 | rec->fsf_seqno = fsf_req->seq_no; |
556 | rec->fsf_reqid = (unsigned long)fsf_req; | 911 | rec->s_id = s_id; |
557 | rec->fsf_seqno = fsf_req->seq_no; | 912 | rec->d_id = d_id; |
558 | rec->s_id = s_id; | 913 | rec->u.els.ls_code = ls_code; |
559 | rec->d_id = d_id; | 914 | debug_event(adapter->san_dbf, level, rec, sizeof(*rec)); |
560 | rec->type.els.ls_code = ls_code; | 915 | zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level, |
561 | buflen = min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD); | 916 | buffer, min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD)); |
562 | rec->type.els.payload_size = buflen; | ||
563 | memcpy(rec->type.els.payload, | ||
564 | buffer, min(buflen, ZFCP_DBF_ELS_PAYLOAD)); | ||
565 | offset += min(buflen, ZFCP_DBF_ELS_PAYLOAD); | ||
566 | } else { | ||
567 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); | ||
568 | dump->total_size = buflen; | ||
569 | dump->offset = offset; | ||
570 | dump->size = min(buflen - offset, | ||
571 | (int)sizeof(struct zfcp_san_dbf_record) | ||
572 | - (int)sizeof(struct zfcp_dbf_dump)); | ||
573 | memcpy(dump->data, buffer + offset, dump->size); | ||
574 | offset += dump->size; | ||
575 | } | ||
576 | debug_event(adapter->san_dbf, level, | ||
577 | rec, sizeof(struct zfcp_san_dbf_record)); | ||
578 | } while (offset < buflen); | ||
579 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); | 917 | spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); |
580 | } | 918 | } |
581 | 919 | ||
920 | /** | ||
921 | * zfcp_san_dbf_event_els_request - trace event for issued ELS | ||
922 | * @fsf_req: request containing issued ELS | ||
923 | */ | ||
582 | void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req) | 924 | void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req) |
583 | { | 925 | { |
584 | struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; | 926 | struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; |
585 | 927 | ||
586 | _zfcp_san_dbf_event_common_els("oels", 2, fsf_req, | 928 | zfcp_san_dbf_event_els("oels", 2, fsf_req, |
587 | fc_host_port_id(els->adapter->scsi_host), | 929 | fc_host_port_id(els->adapter->scsi_host), |
588 | els->d_id, | 930 | els->d_id, *(u8 *) zfcp_sg_to_address(els->req), |
589 | *(u8 *) zfcp_sg_to_address(els->req), | 931 | zfcp_sg_to_address(els->req), els->req->length); |
590 | zfcp_sg_to_address(els->req), | ||
591 | els->req->length); | ||
592 | } | 932 | } |
593 | 933 | ||
934 | /** | ||
935 | * zfcp_san_dbf_event_els_response - trace event for completed ELS | ||
936 | * @fsf_req: request containing ELS response | ||
937 | */ | ||
594 | void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req) | 938 | void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req) |
595 | { | 939 | { |
596 | struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; | 940 | struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; |
597 | 941 | ||
598 | _zfcp_san_dbf_event_common_els("rels", 2, fsf_req, els->d_id, | 942 | zfcp_san_dbf_event_els("rels", 2, fsf_req, els->d_id, |
599 | fc_host_port_id(els->adapter->scsi_host), | 943 | fc_host_port_id(els->adapter->scsi_host), |
600 | *(u8 *) zfcp_sg_to_address(els->req), | 944 | *(u8 *)zfcp_sg_to_address(els->req), |
601 | zfcp_sg_to_address(els->resp), | 945 | zfcp_sg_to_address(els->resp), |
602 | els->resp->length); | 946 | els->resp->length); |
603 | } | 947 | } |
604 | 948 | ||
949 | /** | ||
950 | * zfcp_san_dbf_event_incoming_els - trace event for incomig ELS | ||
951 | * @fsf_req: request containing unsolicited status buffer with incoming ELS | ||
952 | */ | ||
605 | void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req) | 953 | void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req) |
606 | { | 954 | { |
607 | struct zfcp_adapter *adapter = fsf_req->adapter; | 955 | struct zfcp_adapter *adapter = fsf_req->adapter; |
608 | struct fsf_status_read_buffer *status_buffer = | 956 | struct fsf_status_read_buffer *buf = |
609 | (struct fsf_status_read_buffer *)fsf_req->data; | 957 | (struct fsf_status_read_buffer *)fsf_req->data; |
610 | int length = (int)status_buffer->length - | 958 | int length = (int)buf->length - |
611 | (int)((void *)&status_buffer->payload - (void *)status_buffer); | 959 | (int)((void *)&buf->payload - (void *)buf); |
612 | 960 | ||
613 | _zfcp_san_dbf_event_common_els("iels", 1, fsf_req, status_buffer->d_id, | 961 | zfcp_san_dbf_event_els("iels", 1, fsf_req, buf->d_id, |
614 | fc_host_port_id(adapter->scsi_host), | 962 | fc_host_port_id(adapter->scsi_host), |
615 | *(u8 *) status_buffer->payload, | 963 | *(u8 *)buf->payload, (void *)buf->payload, |
616 | (void *)status_buffer->payload, length); | 964 | length); |
617 | } | 965 | } |
618 | 966 | ||
619 | static int | 967 | static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view, |
620 | zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view, | 968 | char *out_buf, const char *in_buf) |
621 | char *out_buf, const char *in_buf) | ||
622 | { | 969 | { |
623 | struct zfcp_san_dbf_record *rec = (struct zfcp_san_dbf_record *)in_buf; | 970 | struct zfcp_san_dbf_record *r = (struct zfcp_san_dbf_record *)in_buf; |
624 | char *buffer = NULL; | 971 | char *buffer = NULL; |
625 | int buflen = 0, total = 0; | 972 | int buflen = 0, total = 0; |
626 | int len = 0; | 973 | char *p = out_buf; |
627 | 974 | ||
628 | if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | 975 | if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) |
629 | return 0; | 976 | return 0; |
630 | 977 | ||
631 | len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); | 978 | zfcp_dbf_tag(&p, "tag", r->tag); |
632 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", | 979 | zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid); |
633 | rec->fsf_reqid); | 980 | zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno); |
634 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", | 981 | zfcp_dbf_out(&p, "s_id", "0x%06x", r->s_id); |
635 | rec->fsf_seqno); | 982 | zfcp_dbf_out(&p, "d_id", "0x%06x", r->d_id); |
636 | len += zfcp_dbf_view(out_buf + len, "s_id", "0x%06x", rec->s_id); | 983 | |
637 | len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", rec->d_id); | 984 | if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { |
638 | 985 | struct zfcp_san_dbf_record_ct_request *ct = &r->u.ct_req; | |
639 | if (strncmp(rec->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { | 986 | zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code); |
640 | len += zfcp_dbf_view(out_buf + len, "cmd_req_code", "0x%04x", | 987 | zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision); |
641 | rec->type.ct.type.request.cmd_req_code); | 988 | zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type); |
642 | len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x", | 989 | zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype); |
643 | rec->type.ct.type.request.revision); | 990 | zfcp_dbf_out(&p, "options", "0x%02x", ct->options); |
644 | len += zfcp_dbf_view(out_buf + len, "gs_type", "0x%02x", | 991 | zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size); |
645 | rec->type.ct.type.request.gs_type); | 992 | total = ct->len; |
646 | len += zfcp_dbf_view(out_buf + len, "gs_subtype", "0x%02x", | 993 | buffer = ct->payload; |
647 | rec->type.ct.type.request.gs_subtype); | ||
648 | len += zfcp_dbf_view(out_buf + len, "options", "0x%02x", | ||
649 | rec->type.ct.type.request.options); | ||
650 | len += zfcp_dbf_view(out_buf + len, "max_res_size", "0x%04x", | ||
651 | rec->type.ct.type.request.max_res_size); | ||
652 | total = rec->type.ct.payload_size; | ||
653 | buffer = rec->type.ct.payload; | ||
654 | buflen = min(total, ZFCP_DBF_CT_PAYLOAD); | 994 | buflen = min(total, ZFCP_DBF_CT_PAYLOAD); |
655 | } else if (strncmp(rec->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { | 995 | } else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { |
656 | len += zfcp_dbf_view(out_buf + len, "cmd_rsp_code", "0x%04x", | 996 | struct zfcp_san_dbf_record_ct_response *ct = &r->u.ct_resp; |
657 | rec->type.ct.type.response.cmd_rsp_code); | 997 | zfcp_dbf_out(&p, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code); |
658 | len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x", | 998 | zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision); |
659 | rec->type.ct.type.response.revision); | 999 | zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code); |
660 | len += zfcp_dbf_view(out_buf + len, "reason_code", "0x%02x", | 1000 | zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl); |
661 | rec->type.ct.type.response.reason_code); | 1001 | zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique); |
662 | len += | 1002 | total = ct->len; |
663 | zfcp_dbf_view(out_buf + len, "reason_code_expl", "0x%02x", | 1003 | buffer = ct->payload; |
664 | rec->type.ct.type.response.reason_code_expl); | ||
665 | len += | ||
666 | zfcp_dbf_view(out_buf + len, "vendor_unique", "0x%02x", | ||
667 | rec->type.ct.type.response.vendor_unique); | ||
668 | total = rec->type.ct.payload_size; | ||
669 | buffer = rec->type.ct.payload; | ||
670 | buflen = min(total, ZFCP_DBF_CT_PAYLOAD); | 1004 | buflen = min(total, ZFCP_DBF_CT_PAYLOAD); |
671 | } else if (strncmp(rec->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 || | 1005 | } else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 || |
672 | strncmp(rec->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || | 1006 | strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || |
673 | strncmp(rec->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { | 1007 | strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { |
674 | len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x", | 1008 | struct zfcp_san_dbf_record_els *els = &r->u.els; |
675 | rec->type.els.ls_code); | 1009 | zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code); |
676 | total = rec->type.els.payload_size; | 1010 | total = els->len; |
677 | buffer = rec->type.els.payload; | 1011 | buffer = els->payload; |
678 | buflen = min(total, ZFCP_DBF_ELS_PAYLOAD); | 1012 | buflen = min(total, ZFCP_DBF_ELS_PAYLOAD); |
679 | } | 1013 | } |
680 | 1014 | ||
681 | len += zfcp_dbf_view_dump(out_buf + len, "payload", | 1015 | zfcp_dbf_outd(&p, "payload", buffer, buflen, 0, total); |
682 | buffer, buflen, 0, total); | ||
683 | |||
684 | if (buflen == total) | 1016 | if (buflen == total) |
685 | len += sprintf(out_buf + len, "\n"); | 1017 | p += sprintf(p, "\n"); |
686 | 1018 | ||
687 | return len; | 1019 | return p - out_buf; |
688 | } | 1020 | } |
689 | 1021 | ||
690 | static struct debug_view zfcp_san_dbf_view = { | 1022 | static struct debug_view zfcp_san_dbf_view = { |
@@ -696,12 +1028,11 @@ static struct debug_view zfcp_san_dbf_view = { | |||
696 | NULL | 1028 | NULL |
697 | }; | 1029 | }; |
698 | 1030 | ||
699 | static void | 1031 | static void zfcp_scsi_dbf_event(const char *tag, const char *tag2, int level, |
700 | _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | 1032 | struct zfcp_adapter *adapter, |
701 | struct zfcp_adapter *adapter, | 1033 | struct scsi_cmnd *scsi_cmnd, |
702 | struct scsi_cmnd *scsi_cmnd, | 1034 | struct zfcp_fsf_req *fsf_req, |
703 | struct zfcp_fsf_req *fsf_req, | 1035 | unsigned long old_req_id) |
704 | unsigned long old_req_id) | ||
705 | { | 1036 | { |
706 | struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; | 1037 | struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; |
707 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; | 1038 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; |
@@ -712,7 +1043,7 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | |||
712 | 1043 | ||
713 | spin_lock_irqsave(&adapter->scsi_dbf_lock, flags); | 1044 | spin_lock_irqsave(&adapter->scsi_dbf_lock, flags); |
714 | do { | 1045 | do { |
715 | memset(rec, 0, sizeof(struct zfcp_scsi_dbf_record)); | 1046 | memset(rec, 0, sizeof(*rec)); |
716 | if (offset == 0) { | 1047 | if (offset == 0) { |
717 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); | 1048 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); |
718 | strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); | 1049 | strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); |
@@ -738,20 +1069,16 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | |||
738 | fcp_sns_info = | 1069 | fcp_sns_info = |
739 | zfcp_get_fcp_sns_info_ptr(fcp_rsp); | 1070 | zfcp_get_fcp_sns_info_ptr(fcp_rsp); |
740 | 1071 | ||
741 | rec->type.fcp.rsp_validity = | 1072 | rec->rsp_validity = fcp_rsp->validity.value; |
742 | fcp_rsp->validity.value; | 1073 | rec->rsp_scsi_status = fcp_rsp->scsi_status; |
743 | rec->type.fcp.rsp_scsi_status = | 1074 | rec->rsp_resid = fcp_rsp->fcp_resid; |
744 | fcp_rsp->scsi_status; | ||
745 | rec->type.fcp.rsp_resid = fcp_rsp->fcp_resid; | ||
746 | if (fcp_rsp->validity.bits.fcp_rsp_len_valid) | 1075 | if (fcp_rsp->validity.bits.fcp_rsp_len_valid) |
747 | rec->type.fcp.rsp_code = | 1076 | rec->rsp_code = *(fcp_rsp_info + 3); |
748 | *(fcp_rsp_info + 3); | ||
749 | if (fcp_rsp->validity.bits.fcp_sns_len_valid) { | 1077 | if (fcp_rsp->validity.bits.fcp_sns_len_valid) { |
750 | buflen = min((int)fcp_rsp->fcp_sns_len, | 1078 | buflen = min((int)fcp_rsp->fcp_sns_len, |
751 | ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO); | 1079 | ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO); |
752 | rec->type.fcp.sns_info_len = buflen; | 1080 | rec->sns_info_len = buflen; |
753 | memcpy(rec->type.fcp.sns_info, | 1081 | memcpy(rec->sns_info, fcp_sns_info, |
754 | fcp_sns_info, | ||
755 | min(buflen, | 1082 | min(buflen, |
756 | ZFCP_DBF_SCSI_FCP_SNS_INFO)); | 1083 | ZFCP_DBF_SCSI_FCP_SNS_INFO)); |
757 | offset += min(buflen, | 1084 | offset += min(buflen, |
@@ -762,7 +1089,7 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | |||
762 | rec->fsf_seqno = fsf_req->seq_no; | 1089 | rec->fsf_seqno = fsf_req->seq_no; |
763 | rec->fsf_issued = fsf_req->issued; | 1090 | rec->fsf_issued = fsf_req->issued; |
764 | } | 1091 | } |
765 | rec->type.old_fsf_reqid = old_req_id; | 1092 | rec->old_fsf_reqid = old_req_id; |
766 | } else { | 1093 | } else { |
767 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); | 1094 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); |
768 | dump->total_size = buflen; | 1095 | dump->total_size = buflen; |
@@ -774,108 +1101,101 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | |||
774 | memcpy(dump->data, fcp_sns_info + offset, dump->size); | 1101 | memcpy(dump->data, fcp_sns_info + offset, dump->size); |
775 | offset += dump->size; | 1102 | offset += dump->size; |
776 | } | 1103 | } |
777 | debug_event(adapter->scsi_dbf, level, | 1104 | debug_event(adapter->scsi_dbf, level, rec, sizeof(*rec)); |
778 | rec, sizeof(struct zfcp_scsi_dbf_record)); | ||
779 | } while (offset < buflen); | 1105 | } while (offset < buflen); |
780 | spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags); | 1106 | spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags); |
781 | } | 1107 | } |
782 | 1108 | ||
783 | void | 1109 | /** |
784 | zfcp_scsi_dbf_event_result(const char *tag, int level, | 1110 | * zfcp_scsi_dbf_event_result - trace event for SCSI command completion |
785 | struct zfcp_adapter *adapter, | 1111 | * @tag: tag indicating success or failure of SCSI command |
786 | struct scsi_cmnd *scsi_cmnd, | 1112 | * @level: trace level applicable for this event |
787 | struct zfcp_fsf_req *fsf_req) | 1113 | * @adapter: adapter that has been used to issue the SCSI command |
1114 | * @scsi_cmnd: SCSI command pointer | ||
1115 | * @fsf_req: request used to issue SCSI command (might be NULL) | ||
1116 | */ | ||
1117 | void zfcp_scsi_dbf_event_result(const char *tag, int level, | ||
1118 | struct zfcp_adapter *adapter, | ||
1119 | struct scsi_cmnd *scsi_cmnd, | ||
1120 | struct zfcp_fsf_req *fsf_req) | ||
788 | { | 1121 | { |
789 | _zfcp_scsi_dbf_event_common("rslt", tag, level, | 1122 | zfcp_scsi_dbf_event("rslt", tag, level, adapter, scsi_cmnd, fsf_req, 0); |
790 | adapter, scsi_cmnd, fsf_req, 0); | ||
791 | } | 1123 | } |
792 | 1124 | ||
793 | void | 1125 | /** |
794 | zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, | 1126 | * zfcp_scsi_dbf_event_abort - trace event for SCSI command abort |
795 | struct scsi_cmnd *scsi_cmnd, | 1127 | * @tag: tag indicating success or failure of abort operation |
796 | struct zfcp_fsf_req *new_fsf_req, | 1128 | * @adapter: adapter thas has been used to issue SCSI command to be aborted |
797 | unsigned long old_req_id) | 1129 | * @scsi_cmnd: SCSI command to be aborted |
1130 | * @new_fsf_req: request containing abort (might be NULL) | ||
1131 | * @old_req_id: identifier of request containg SCSI command to be aborted | ||
1132 | */ | ||
1133 | void zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, | ||
1134 | struct scsi_cmnd *scsi_cmnd, | ||
1135 | struct zfcp_fsf_req *new_fsf_req, | ||
1136 | unsigned long old_req_id) | ||
798 | { | 1137 | { |
799 | _zfcp_scsi_dbf_event_common("abrt", tag, 1, | 1138 | zfcp_scsi_dbf_event("abrt", tag, 1, adapter, scsi_cmnd, new_fsf_req, |
800 | adapter, scsi_cmnd, new_fsf_req, old_req_id); | 1139 | old_req_id); |
801 | } | 1140 | } |
802 | 1141 | ||
803 | void | 1142 | /** |
804 | zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, | 1143 | * zfcp_scsi_dbf_event_devreset - trace event for Logical Unit or Target Reset |
805 | struct scsi_cmnd *scsi_cmnd) | 1144 | * @tag: tag indicating success or failure of reset operation |
1145 | * @flag: indicates type of reset (Target Reset, Logical Unit Reset) | ||
1146 | * @unit: unit that needs reset | ||
1147 | * @scsi_cmnd: SCSI command which caused this error recovery | ||
1148 | */ | ||
1149 | void zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, | ||
1150 | struct zfcp_unit *unit, | ||
1151 | struct scsi_cmnd *scsi_cmnd) | ||
806 | { | 1152 | { |
807 | struct zfcp_adapter *adapter = unit->port->adapter; | 1153 | zfcp_scsi_dbf_event(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1, |
808 | 1154 | unit->port->adapter, scsi_cmnd, NULL, 0); | |
809 | _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst", | ||
810 | tag, 1, adapter, scsi_cmnd, NULL, 0); | ||
811 | } | 1155 | } |
812 | 1156 | ||
813 | static int | 1157 | static int zfcp_scsi_dbf_view_format(debug_info_t *id, struct debug_view *view, |
814 | zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, | 1158 | char *out_buf, const char *in_buf) |
815 | char *out_buf, const char *in_buf) | ||
816 | { | 1159 | { |
817 | struct zfcp_scsi_dbf_record *rec = | 1160 | struct zfcp_scsi_dbf_record *r = (struct zfcp_scsi_dbf_record *)in_buf; |
818 | (struct zfcp_scsi_dbf_record *)in_buf; | 1161 | struct timespec t; |
819 | int len = 0; | 1162 | char *p = out_buf; |
820 | 1163 | ||
821 | if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | 1164 | if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) |
822 | return 0; | 1165 | return 0; |
823 | 1166 | ||
824 | len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); | 1167 | zfcp_dbf_tag(&p, "tag", r->tag); |
825 | len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2); | 1168 | zfcp_dbf_tag(&p, "tag2", r->tag2); |
826 | len += zfcp_dbf_view(out_buf + len, "scsi_id", "0x%08x", rec->scsi_id); | 1169 | zfcp_dbf_out(&p, "scsi_id", "0x%08x", r->scsi_id); |
827 | len += zfcp_dbf_view(out_buf + len, "scsi_lun", "0x%08x", | 1170 | zfcp_dbf_out(&p, "scsi_lun", "0x%08x", r->scsi_lun); |
828 | rec->scsi_lun); | 1171 | zfcp_dbf_out(&p, "scsi_result", "0x%08x", r->scsi_result); |
829 | len += zfcp_dbf_view(out_buf + len, "scsi_result", "0x%08x", | 1172 | zfcp_dbf_out(&p, "scsi_cmnd", "0x%0Lx", r->scsi_cmnd); |
830 | rec->scsi_result); | 1173 | zfcp_dbf_out(&p, "scsi_serial", "0x%016Lx", r->scsi_serial); |
831 | len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx", | 1174 | zfcp_dbf_outd(&p, "scsi_opcode", r->scsi_opcode, ZFCP_DBF_SCSI_OPCODE, |
832 | rec->scsi_cmnd); | 1175 | 0, ZFCP_DBF_SCSI_OPCODE); |
833 | len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx", | 1176 | zfcp_dbf_out(&p, "scsi_retries", "0x%02x", r->scsi_retries); |
834 | rec->scsi_serial); | 1177 | zfcp_dbf_out(&p, "scsi_allowed", "0x%02x", r->scsi_allowed); |
835 | len += zfcp_dbf_view_dump(out_buf + len, "scsi_opcode", | 1178 | if (strncmp(r->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) |
836 | rec->scsi_opcode, | 1179 | zfcp_dbf_out(&p, "old_fsf_reqid", "0x%0Lx", r->old_fsf_reqid); |
837 | ZFCP_DBF_SCSI_OPCODE, | 1180 | zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid); |
838 | 0, ZFCP_DBF_SCSI_OPCODE); | 1181 | zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno); |
839 | len += zfcp_dbf_view(out_buf + len, "scsi_retries", "0x%02x", | 1182 | zfcp_dbf_timestamp(r->fsf_issued, &t); |
840 | rec->scsi_retries); | 1183 | zfcp_dbf_out(&p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec); |
841 | len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x", | 1184 | |
842 | rec->scsi_allowed); | 1185 | if (strncmp(r->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) { |
843 | if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) { | 1186 | zfcp_dbf_out(&p, "fcp_rsp_validity", "0x%02x", r->rsp_validity); |
844 | len += zfcp_dbf_view(out_buf + len, "old_fsf_reqid", "0x%0Lx", | 1187 | zfcp_dbf_out(&p, "fcp_rsp_scsi_status", "0x%02x", |
845 | rec->type.old_fsf_reqid); | 1188 | r->rsp_scsi_status); |
846 | } | 1189 | zfcp_dbf_out(&p, "fcp_rsp_resid", "0x%08x", r->rsp_resid); |
847 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", | 1190 | zfcp_dbf_out(&p, "fcp_rsp_code", "0x%08x", r->rsp_code); |
848 | rec->fsf_reqid); | 1191 | zfcp_dbf_out(&p, "fcp_sns_info_len", "0x%08x", r->sns_info_len); |
849 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", | 1192 | zfcp_dbf_outd(&p, "fcp_sns_info", r->sns_info, |
850 | rec->fsf_seqno); | 1193 | min((int)r->sns_info_len, |
851 | len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued); | 1194 | ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, |
852 | if (strncmp(rec->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) { | 1195 | r->sns_info_len); |
853 | len += | ||
854 | zfcp_dbf_view(out_buf + len, "fcp_rsp_validity", "0x%02x", | ||
855 | rec->type.fcp.rsp_validity); | ||
856 | len += | ||
857 | zfcp_dbf_view(out_buf + len, "fcp_rsp_scsi_status", | ||
858 | "0x%02x", rec->type.fcp.rsp_scsi_status); | ||
859 | len += | ||
860 | zfcp_dbf_view(out_buf + len, "fcp_rsp_resid", "0x%08x", | ||
861 | rec->type.fcp.rsp_resid); | ||
862 | len += | ||
863 | zfcp_dbf_view(out_buf + len, "fcp_rsp_code", "0x%08x", | ||
864 | rec->type.fcp.rsp_code); | ||
865 | len += | ||
866 | zfcp_dbf_view(out_buf + len, "fcp_sns_info_len", "0x%08x", | ||
867 | rec->type.fcp.sns_info_len); | ||
868 | len += | ||
869 | zfcp_dbf_view_dump(out_buf + len, "fcp_sns_info", | ||
870 | rec->type.fcp.sns_info, | ||
871 | min((int)rec->type.fcp.sns_info_len, | ||
872 | ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, | ||
873 | rec->type.fcp.sns_info_len); | ||
874 | } | 1196 | } |
875 | 1197 | p += sprintf(p, "\n"); | |
876 | len += sprintf(out_buf + len, "\n"); | 1198 | return p - out_buf; |
877 | |||
878 | return len; | ||
879 | } | 1199 | } |
880 | 1200 | ||
881 | static struct debug_view zfcp_scsi_dbf_view = { | 1201 | static struct debug_view zfcp_scsi_dbf_view = { |
@@ -897,13 +1217,14 @@ int zfcp_adapter_debug_register(struct zfcp_adapter *adapter) | |||
897 | char dbf_name[DEBUG_MAX_NAME_LEN]; | 1217 | char dbf_name[DEBUG_MAX_NAME_LEN]; |
898 | 1218 | ||
899 | /* debug feature area which records recovery activity */ | 1219 | /* debug feature area which records recovery activity */ |
900 | sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter)); | 1220 | sprintf(dbf_name, "zfcp_%s_rec", zfcp_get_busid_by_adapter(adapter)); |
901 | adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2, | 1221 | adapter->rec_dbf = debug_register(dbf_name, dbfsize, 1, |
902 | sizeof(struct zfcp_erp_dbf_record)); | 1222 | sizeof(struct zfcp_rec_dbf_record)); |
903 | if (!adapter->erp_dbf) | 1223 | if (!adapter->rec_dbf) |
904 | goto failed; | 1224 | goto failed; |
905 | debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view); | 1225 | debug_register_view(adapter->rec_dbf, &debug_hex_ascii_view); |
906 | debug_set_level(adapter->erp_dbf, 3); | 1226 | debug_register_view(adapter->rec_dbf, &zfcp_rec_dbf_view); |
1227 | debug_set_level(adapter->rec_dbf, 3); | ||
907 | 1228 | ||
908 | /* debug feature area which records HBA (FSF and QDIO) conditions */ | 1229 | /* debug feature area which records HBA (FSF and QDIO) conditions */ |
909 | sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter)); | 1230 | sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter)); |
@@ -952,11 +1273,11 @@ void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter) | |||
952 | debug_unregister(adapter->scsi_dbf); | 1273 | debug_unregister(adapter->scsi_dbf); |
953 | debug_unregister(adapter->san_dbf); | 1274 | debug_unregister(adapter->san_dbf); |
954 | debug_unregister(adapter->hba_dbf); | 1275 | debug_unregister(adapter->hba_dbf); |
955 | debug_unregister(adapter->erp_dbf); | 1276 | debug_unregister(adapter->rec_dbf); |
956 | adapter->scsi_dbf = NULL; | 1277 | adapter->scsi_dbf = NULL; |
957 | adapter->san_dbf = NULL; | 1278 | adapter->san_dbf = NULL; |
958 | adapter->hba_dbf = NULL; | 1279 | adapter->hba_dbf = NULL; |
959 | adapter->erp_dbf = NULL; | 1280 | adapter->rec_dbf = NULL; |
960 | } | 1281 | } |
961 | 1282 | ||
962 | #undef ZFCP_LOG_AREA | 1283 | #undef ZFCP_LOG_AREA |
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h new file mode 100644 index 000000000000..54c34e483457 --- /dev/null +++ b/drivers/s390/scsi/zfcp_dbf.h | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * This file is part of the zfcp device driver for | ||
3 | * FCP adapters for IBM System z9 and zSeries. | ||
4 | * | ||
5 | * Copyright IBM Corp. 2008, 2008 | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2, or (at your option) | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef ZFCP_DBF_H | ||
23 | #define ZFCP_DBF_H | ||
24 | |||
25 | #include "zfcp_fsf.h" | ||
26 | |||
27 | #define ZFCP_DBF_TAG_SIZE 4 | ||
28 | |||
29 | struct zfcp_dbf_dump { | ||
30 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
31 | u32 total_size; /* size of total dump data */ | ||
32 | u32 offset; /* how much data has being already dumped */ | ||
33 | u32 size; /* how much data comes with this record */ | ||
34 | u8 data[]; /* dump data */ | ||
35 | } __attribute__ ((packed)); | ||
36 | |||
37 | struct zfcp_rec_dbf_record_thread { | ||
38 | u32 total; | ||
39 | u32 ready; | ||
40 | u32 running; | ||
41 | } __attribute__ ((packed)); | ||
42 | |||
43 | struct zfcp_rec_dbf_record_target { | ||
44 | u64 ref; | ||
45 | u32 status; | ||
46 | u32 d_id; | ||
47 | u64 wwpn; | ||
48 | u64 fcp_lun; | ||
49 | u32 erp_count; | ||
50 | } __attribute__ ((packed)); | ||
51 | |||
52 | struct zfcp_rec_dbf_record_trigger { | ||
53 | u8 want; | ||
54 | u8 need; | ||
55 | u32 as; | ||
56 | u32 ps; | ||
57 | u32 us; | ||
58 | u64 ref; | ||
59 | u64 action; | ||
60 | u64 wwpn; | ||
61 | u64 fcp_lun; | ||
62 | } __attribute__ ((packed)); | ||
63 | |||
64 | struct zfcp_rec_dbf_record_action { | ||
65 | u32 status; | ||
66 | u32 step; | ||
67 | u64 action; | ||
68 | u64 fsf_req; | ||
69 | } __attribute__ ((packed)); | ||
70 | |||
71 | struct zfcp_rec_dbf_record { | ||
72 | u8 id; | ||
73 | u8 id2; | ||
74 | union { | ||
75 | struct zfcp_rec_dbf_record_action action; | ||
76 | struct zfcp_rec_dbf_record_thread thread; | ||
77 | struct zfcp_rec_dbf_record_target target; | ||
78 | struct zfcp_rec_dbf_record_trigger trigger; | ||
79 | } u; | ||
80 | } __attribute__ ((packed)); | ||
81 | |||
82 | enum { | ||
83 | ZFCP_REC_DBF_ID_ACTION, | ||
84 | ZFCP_REC_DBF_ID_THREAD, | ||
85 | ZFCP_REC_DBF_ID_TARGET, | ||
86 | ZFCP_REC_DBF_ID_TRIGGER, | ||
87 | }; | ||
88 | |||
89 | struct zfcp_hba_dbf_record_response { | ||
90 | u32 fsf_command; | ||
91 | u64 fsf_reqid; | ||
92 | u32 fsf_seqno; | ||
93 | u64 fsf_issued; | ||
94 | u32 fsf_prot_status; | ||
95 | u32 fsf_status; | ||
96 | u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE]; | ||
97 | u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; | ||
98 | u32 fsf_req_status; | ||
99 | u8 sbal_first; | ||
100 | u8 sbal_curr; | ||
101 | u8 sbal_last; | ||
102 | u8 pool; | ||
103 | u64 erp_action; | ||
104 | union { | ||
105 | struct { | ||
106 | u64 cmnd; | ||
107 | u64 serial; | ||
108 | } fcp; | ||
109 | struct { | ||
110 | u64 wwpn; | ||
111 | u32 d_id; | ||
112 | u32 port_handle; | ||
113 | } port; | ||
114 | struct { | ||
115 | u64 wwpn; | ||
116 | u64 fcp_lun; | ||
117 | u32 port_handle; | ||
118 | u32 lun_handle; | ||
119 | } unit; | ||
120 | struct { | ||
121 | u32 d_id; | ||
122 | u8 ls_code; | ||
123 | } els; | ||
124 | } u; | ||
125 | } __attribute__ ((packed)); | ||
126 | |||
127 | struct zfcp_hba_dbf_record_status { | ||
128 | u8 failed; | ||
129 | u32 status_type; | ||
130 | u32 status_subtype; | ||
131 | struct fsf_queue_designator | ||
132 | queue_designator; | ||
133 | u32 payload_size; | ||
134 | #define ZFCP_DBF_UNSOL_PAYLOAD 80 | ||
135 | #define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL 32 | ||
136 | #define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD 56 | ||
137 | #define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT 2 * sizeof(u32) | ||
138 | u8 payload[ZFCP_DBF_UNSOL_PAYLOAD]; | ||
139 | } __attribute__ ((packed)); | ||
140 | |||
141 | struct zfcp_hba_dbf_record_qdio { | ||
142 | u32 status; | ||
143 | u32 qdio_error; | ||
144 | u32 siga_error; | ||
145 | u8 sbal_index; | ||
146 | u8 sbal_count; | ||
147 | } __attribute__ ((packed)); | ||
148 | |||
149 | struct zfcp_hba_dbf_record { | ||
150 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
151 | u8 tag2[ZFCP_DBF_TAG_SIZE]; | ||
152 | union { | ||
153 | struct zfcp_hba_dbf_record_response response; | ||
154 | struct zfcp_hba_dbf_record_status status; | ||
155 | struct zfcp_hba_dbf_record_qdio qdio; | ||
156 | } u; | ||
157 | } __attribute__ ((packed)); | ||
158 | |||
159 | struct zfcp_san_dbf_record_ct_request { | ||
160 | u16 cmd_req_code; | ||
161 | u8 revision; | ||
162 | u8 gs_type; | ||
163 | u8 gs_subtype; | ||
164 | u8 options; | ||
165 | u16 max_res_size; | ||
166 | u32 len; | ||
167 | #define ZFCP_DBF_CT_PAYLOAD 24 | ||
168 | u8 payload[ZFCP_DBF_CT_PAYLOAD]; | ||
169 | } __attribute__ ((packed)); | ||
170 | |||
171 | struct zfcp_san_dbf_record_ct_response { | ||
172 | u16 cmd_rsp_code; | ||
173 | u8 revision; | ||
174 | u8 reason_code; | ||
175 | u8 expl; | ||
176 | u8 vendor_unique; | ||
177 | u32 len; | ||
178 | u8 payload[ZFCP_DBF_CT_PAYLOAD]; | ||
179 | } __attribute__ ((packed)); | ||
180 | |||
181 | struct zfcp_san_dbf_record_els { | ||
182 | u8 ls_code; | ||
183 | u32 len; | ||
184 | #define ZFCP_DBF_ELS_PAYLOAD 32 | ||
185 | #define ZFCP_DBF_ELS_MAX_PAYLOAD 1024 | ||
186 | u8 payload[ZFCP_DBF_ELS_PAYLOAD]; | ||
187 | } __attribute__ ((packed)); | ||
188 | |||
189 | struct zfcp_san_dbf_record { | ||
190 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
191 | u64 fsf_reqid; | ||
192 | u32 fsf_seqno; | ||
193 | u32 s_id; | ||
194 | u32 d_id; | ||
195 | union { | ||
196 | struct zfcp_san_dbf_record_ct_request ct_req; | ||
197 | struct zfcp_san_dbf_record_ct_response ct_resp; | ||
198 | struct zfcp_san_dbf_record_els els; | ||
199 | } u; | ||
200 | } __attribute__ ((packed)); | ||
201 | |||
202 | struct zfcp_scsi_dbf_record { | ||
203 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
204 | u8 tag2[ZFCP_DBF_TAG_SIZE]; | ||
205 | u32 scsi_id; | ||
206 | u32 scsi_lun; | ||
207 | u32 scsi_result; | ||
208 | u64 scsi_cmnd; | ||
209 | u64 scsi_serial; | ||
210 | #define ZFCP_DBF_SCSI_OPCODE 16 | ||
211 | u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE]; | ||
212 | u8 scsi_retries; | ||
213 | u8 scsi_allowed; | ||
214 | u64 fsf_reqid; | ||
215 | u32 fsf_seqno; | ||
216 | u64 fsf_issued; | ||
217 | u64 old_fsf_reqid; | ||
218 | u8 rsp_validity; | ||
219 | u8 rsp_scsi_status; | ||
220 | u32 rsp_resid; | ||
221 | u8 rsp_code; | ||
222 | #define ZFCP_DBF_SCSI_FCP_SNS_INFO 16 | ||
223 | #define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256 | ||
224 | u32 sns_info_len; | ||
225 | u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO]; | ||
226 | } __attribute__ ((packed)); | ||
227 | |||
228 | #endif /* ZFCP_DBF_H */ | ||
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 45a7cd98c140..bda8c77b22da 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <asm/qdio.h> | 47 | #include <asm/qdio.h> |
48 | #include <asm/debug.h> | 48 | #include <asm/debug.h> |
49 | #include <asm/ebcdic.h> | 49 | #include <asm/ebcdic.h> |
50 | #include "zfcp_dbf.h" | ||
50 | #include "zfcp_fsf.h" | 51 | #include "zfcp_fsf.h" |
51 | 52 | ||
52 | 53 | ||
@@ -262,167 +263,6 @@ struct fcp_logo { | |||
262 | } __attribute__((packed)); | 263 | } __attribute__((packed)); |
263 | 264 | ||
264 | /* | 265 | /* |
265 | * DBF stuff | ||
266 | */ | ||
267 | #define ZFCP_DBF_TAG_SIZE 4 | ||
268 | |||
269 | struct zfcp_dbf_dump { | ||
270 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
271 | u32 total_size; /* size of total dump data */ | ||
272 | u32 offset; /* how much data has being already dumped */ | ||
273 | u32 size; /* how much data comes with this record */ | ||
274 | u8 data[]; /* dump data */ | ||
275 | } __attribute__ ((packed)); | ||
276 | |||
277 | /* FIXME: to be inflated when reworking the erp dbf */ | ||
278 | struct zfcp_erp_dbf_record { | ||
279 | u8 dummy[16]; | ||
280 | } __attribute__ ((packed)); | ||
281 | |||
282 | struct zfcp_hba_dbf_record_response { | ||
283 | u32 fsf_command; | ||
284 | u64 fsf_reqid; | ||
285 | u32 fsf_seqno; | ||
286 | u64 fsf_issued; | ||
287 | u32 fsf_prot_status; | ||
288 | u32 fsf_status; | ||
289 | u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE]; | ||
290 | u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; | ||
291 | u32 fsf_req_status; | ||
292 | u8 sbal_first; | ||
293 | u8 sbal_curr; | ||
294 | u8 sbal_last; | ||
295 | u8 pool; | ||
296 | u64 erp_action; | ||
297 | union { | ||
298 | struct { | ||
299 | u64 scsi_cmnd; | ||
300 | u64 scsi_serial; | ||
301 | } send_fcp; | ||
302 | struct { | ||
303 | u64 wwpn; | ||
304 | u32 d_id; | ||
305 | u32 port_handle; | ||
306 | } port; | ||
307 | struct { | ||
308 | u64 wwpn; | ||
309 | u64 fcp_lun; | ||
310 | u32 port_handle; | ||
311 | u32 lun_handle; | ||
312 | } unit; | ||
313 | struct { | ||
314 | u32 d_id; | ||
315 | u8 ls_code; | ||
316 | } send_els; | ||
317 | } data; | ||
318 | } __attribute__ ((packed)); | ||
319 | |||
320 | struct zfcp_hba_dbf_record_status { | ||
321 | u8 failed; | ||
322 | u32 status_type; | ||
323 | u32 status_subtype; | ||
324 | struct fsf_queue_designator | ||
325 | queue_designator; | ||
326 | u32 payload_size; | ||
327 | #define ZFCP_DBF_UNSOL_PAYLOAD 80 | ||
328 | #define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL 32 | ||
329 | #define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD 56 | ||
330 | #define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT 2 * sizeof(u32) | ||
331 | u8 payload[ZFCP_DBF_UNSOL_PAYLOAD]; | ||
332 | } __attribute__ ((packed)); | ||
333 | |||
334 | struct zfcp_hba_dbf_record_qdio { | ||
335 | u32 status; | ||
336 | u32 qdio_error; | ||
337 | u32 siga_error; | ||
338 | u8 sbal_index; | ||
339 | u8 sbal_count; | ||
340 | } __attribute__ ((packed)); | ||
341 | |||
342 | struct zfcp_hba_dbf_record { | ||
343 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
344 | u8 tag2[ZFCP_DBF_TAG_SIZE]; | ||
345 | union { | ||
346 | struct zfcp_hba_dbf_record_response response; | ||
347 | struct zfcp_hba_dbf_record_status status; | ||
348 | struct zfcp_hba_dbf_record_qdio qdio; | ||
349 | } type; | ||
350 | } __attribute__ ((packed)); | ||
351 | |||
352 | struct zfcp_san_dbf_record_ct { | ||
353 | union { | ||
354 | struct { | ||
355 | u16 cmd_req_code; | ||
356 | u8 revision; | ||
357 | u8 gs_type; | ||
358 | u8 gs_subtype; | ||
359 | u8 options; | ||
360 | u16 max_res_size; | ||
361 | } request; | ||
362 | struct { | ||
363 | u16 cmd_rsp_code; | ||
364 | u8 revision; | ||
365 | u8 reason_code; | ||
366 | u8 reason_code_expl; | ||
367 | u8 vendor_unique; | ||
368 | } response; | ||
369 | } type; | ||
370 | u32 payload_size; | ||
371 | #define ZFCP_DBF_CT_PAYLOAD 24 | ||
372 | u8 payload[ZFCP_DBF_CT_PAYLOAD]; | ||
373 | } __attribute__ ((packed)); | ||
374 | |||
375 | struct zfcp_san_dbf_record_els { | ||
376 | u8 ls_code; | ||
377 | u32 payload_size; | ||
378 | #define ZFCP_DBF_ELS_PAYLOAD 32 | ||
379 | #define ZFCP_DBF_ELS_MAX_PAYLOAD 1024 | ||
380 | u8 payload[ZFCP_DBF_ELS_PAYLOAD]; | ||
381 | } __attribute__ ((packed)); | ||
382 | |||
383 | struct zfcp_san_dbf_record { | ||
384 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
385 | u64 fsf_reqid; | ||
386 | u32 fsf_seqno; | ||
387 | u32 s_id; | ||
388 | u32 d_id; | ||
389 | union { | ||
390 | struct zfcp_san_dbf_record_ct ct; | ||
391 | struct zfcp_san_dbf_record_els els; | ||
392 | } type; | ||
393 | } __attribute__ ((packed)); | ||
394 | |||
395 | struct zfcp_scsi_dbf_record { | ||
396 | u8 tag[ZFCP_DBF_TAG_SIZE]; | ||
397 | u8 tag2[ZFCP_DBF_TAG_SIZE]; | ||
398 | u32 scsi_id; | ||
399 | u32 scsi_lun; | ||
400 | u32 scsi_result; | ||
401 | u64 scsi_cmnd; | ||
402 | u64 scsi_serial; | ||
403 | #define ZFCP_DBF_SCSI_OPCODE 16 | ||
404 | u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE]; | ||
405 | u8 scsi_retries; | ||
406 | u8 scsi_allowed; | ||
407 | u64 fsf_reqid; | ||
408 | u32 fsf_seqno; | ||
409 | u64 fsf_issued; | ||
410 | union { | ||
411 | u64 old_fsf_reqid; | ||
412 | struct { | ||
413 | u8 rsp_validity; | ||
414 | u8 rsp_scsi_status; | ||
415 | u32 rsp_resid; | ||
416 | u8 rsp_code; | ||
417 | #define ZFCP_DBF_SCSI_FCP_SNS_INFO 16 | ||
418 | #define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256 | ||
419 | u32 sns_info_len; | ||
420 | u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO]; | ||
421 | } fcp; | ||
422 | } type; | ||
423 | } __attribute__ ((packed)); | ||
424 | |||
425 | /* | ||
426 | * FC-FS stuff | 266 | * FC-FS stuff |
427 | */ | 267 | */ |
428 | #define R_A_TOV 10 /* seconds */ | 268 | #define R_A_TOV 10 /* seconds */ |
@@ -634,7 +474,6 @@ do { \ | |||
634 | ZFCP_STATUS_PORT_NO_SCSI_ID) | 474 | ZFCP_STATUS_PORT_NO_SCSI_ID) |
635 | 475 | ||
636 | /* logical unit status */ | 476 | /* logical unit status */ |
637 | #define ZFCP_STATUS_UNIT_NOTSUPPUNITRESET 0x00000001 | ||
638 | #define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002 | 477 | #define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002 |
639 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 | 478 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 |
640 | #define ZFCP_STATUS_UNIT_READONLY 0x00000008 | 479 | #define ZFCP_STATUS_UNIT_READONLY 0x00000008 |
@@ -917,15 +756,15 @@ struct zfcp_adapter { | |||
917 | u32 erp_low_mem_count; /* nr of erp actions waiting | 756 | u32 erp_low_mem_count; /* nr of erp actions waiting |
918 | for memory */ | 757 | for memory */ |
919 | struct zfcp_port *nameserver_port; /* adapter's nameserver */ | 758 | struct zfcp_port *nameserver_port; /* adapter's nameserver */ |
920 | debug_info_t *erp_dbf; | 759 | debug_info_t *rec_dbf; |
921 | debug_info_t *hba_dbf; | 760 | debug_info_t *hba_dbf; |
922 | debug_info_t *san_dbf; /* debug feature areas */ | 761 | debug_info_t *san_dbf; /* debug feature areas */ |
923 | debug_info_t *scsi_dbf; | 762 | debug_info_t *scsi_dbf; |
924 | spinlock_t erp_dbf_lock; | 763 | spinlock_t rec_dbf_lock; |
925 | spinlock_t hba_dbf_lock; | 764 | spinlock_t hba_dbf_lock; |
926 | spinlock_t san_dbf_lock; | 765 | spinlock_t san_dbf_lock; |
927 | spinlock_t scsi_dbf_lock; | 766 | spinlock_t scsi_dbf_lock; |
928 | struct zfcp_erp_dbf_record erp_dbf_buf; | 767 | struct zfcp_rec_dbf_record rec_dbf_buf; |
929 | struct zfcp_hba_dbf_record hba_dbf_buf; | 768 | struct zfcp_hba_dbf_record hba_dbf_buf; |
930 | struct zfcp_san_dbf_record san_dbf_buf; | 769 | struct zfcp_san_dbf_record san_dbf_buf; |
931 | struct zfcp_scsi_dbf_record scsi_dbf_buf; | 770 | struct zfcp_scsi_dbf_record scsi_dbf_buf; |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 2dc8110ebf74..805484658dd9 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -26,13 +26,17 @@ | |||
26 | static int zfcp_erp_adisc(struct zfcp_port *); | 26 | static int zfcp_erp_adisc(struct zfcp_port *); |
27 | static void zfcp_erp_adisc_handler(unsigned long); | 27 | static void zfcp_erp_adisc_handler(unsigned long); |
28 | 28 | ||
29 | static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int); | 29 | static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int, u8, |
30 | static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *, int); | 30 | void *); |
31 | static int zfcp_erp_port_reopen_internal(struct zfcp_port *, int); | 31 | static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *, int, u8, |
32 | static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *, int); | 32 | void *); |
33 | 33 | static int zfcp_erp_port_reopen_internal(struct zfcp_port *, int, u8, void *); | |
34 | static int zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *, int); | 34 | static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *, int, u8, void *); |
35 | static int zfcp_erp_unit_reopen_all_internal(struct zfcp_port *, int); | 35 | |
36 | static int zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *, int, u8, | ||
37 | void *); | ||
38 | static int zfcp_erp_unit_reopen_all_internal(struct zfcp_port *, int, u8, | ||
39 | void *); | ||
36 | 40 | ||
37 | static void zfcp_erp_adapter_block(struct zfcp_adapter *, int); | 41 | static void zfcp_erp_adapter_block(struct zfcp_adapter *, int); |
38 | static void zfcp_erp_adapter_unblock(struct zfcp_adapter *); | 42 | static void zfcp_erp_adapter_unblock(struct zfcp_adapter *); |
@@ -97,7 +101,8 @@ static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *); | |||
97 | static void zfcp_erp_action_dismiss(struct zfcp_erp_action *); | 101 | static void zfcp_erp_action_dismiss(struct zfcp_erp_action *); |
98 | 102 | ||
99 | static int zfcp_erp_action_enqueue(int, struct zfcp_adapter *, | 103 | static int zfcp_erp_action_enqueue(int, struct zfcp_adapter *, |
100 | struct zfcp_port *, struct zfcp_unit *); | 104 | struct zfcp_port *, struct zfcp_unit *, |
105 | u8 id, void *ref); | ||
101 | static int zfcp_erp_action_dequeue(struct zfcp_erp_action *); | 106 | static int zfcp_erp_action_dequeue(struct zfcp_erp_action *); |
102 | static void zfcp_erp_action_cleanup(int, struct zfcp_adapter *, | 107 | static void zfcp_erp_action_cleanup(int, struct zfcp_adapter *, |
103 | struct zfcp_port *, struct zfcp_unit *, | 108 | struct zfcp_port *, struct zfcp_unit *, |
@@ -128,11 +133,9 @@ static void zfcp_close_qdio(struct zfcp_adapter *adapter) | |||
128 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); | 133 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); |
129 | write_unlock_irq(&req_queue->queue_lock); | 134 | write_unlock_irq(&req_queue->queue_lock); |
130 | 135 | ||
131 | debug_text_event(adapter->erp_dbf, 3, "qdio_down2a"); | ||
132 | while (qdio_shutdown(adapter->ccw_device, | 136 | while (qdio_shutdown(adapter->ccw_device, |
133 | QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS) | 137 | QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS) |
134 | ssleep(1); | 138 | ssleep(1); |
135 | debug_text_event(adapter->erp_dbf, 3, "qdio_down2b"); | ||
136 | 139 | ||
137 | /* cleanup used outbound sbals */ | 140 | /* cleanup used outbound sbals */ |
138 | count = atomic_read(&req_queue->free_count); | 141 | count = atomic_read(&req_queue->free_count); |
@@ -163,7 +166,7 @@ static void zfcp_close_fsf(struct zfcp_adapter *adapter) | |||
163 | /* reset FSF request sequence number */ | 166 | /* reset FSF request sequence number */ |
164 | adapter->fsf_req_seq_no = 0; | 167 | adapter->fsf_req_seq_no = 0; |
165 | /* all ports and units are closed */ | 168 | /* all ports and units are closed */ |
166 | zfcp_erp_modify_adapter_status(adapter, | 169 | zfcp_erp_modify_adapter_status(adapter, 24, NULL, |
167 | ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); | 170 | ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR); |
168 | } | 171 | } |
169 | 172 | ||
@@ -179,7 +182,8 @@ static void zfcp_close_fsf(struct zfcp_adapter *adapter) | |||
179 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | 182 | static void zfcp_fsf_request_timeout_handler(unsigned long data) |
180 | { | 183 | { |
181 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; | 184 | struct zfcp_adapter *adapter = (struct zfcp_adapter *) data; |
182 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED); | 185 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 62, |
186 | NULL); | ||
183 | } | 187 | } |
184 | 188 | ||
185 | void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout) | 189 | void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout) |
@@ -200,12 +204,11 @@ void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout) | |||
200 | * returns: 0 - initiated action successfully | 204 | * returns: 0 - initiated action successfully |
201 | * <0 - failed to initiate action | 205 | * <0 - failed to initiate action |
202 | */ | 206 | */ |
203 | static int | 207 | static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, |
204 | zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask) | 208 | int clear_mask, u8 id, void *ref) |
205 | { | 209 | { |
206 | int retval; | 210 | int retval; |
207 | 211 | ||
208 | debug_text_event(adapter->erp_dbf, 5, "a_ro"); | ||
209 | ZFCP_LOG_DEBUG("reopen adapter %s\n", | 212 | ZFCP_LOG_DEBUG("reopen adapter %s\n", |
210 | zfcp_get_busid_by_adapter(adapter)); | 213 | zfcp_get_busid_by_adapter(adapter)); |
211 | 214 | ||
@@ -214,14 +217,13 @@ zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask) | |||
214 | if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) { | 217 | if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) { |
215 | ZFCP_LOG_DEBUG("skipped reopen of failed adapter %s\n", | 218 | ZFCP_LOG_DEBUG("skipped reopen of failed adapter %s\n", |
216 | zfcp_get_busid_by_adapter(adapter)); | 219 | zfcp_get_busid_by_adapter(adapter)); |
217 | debug_text_event(adapter->erp_dbf, 5, "a_ro_f"); | ||
218 | /* ensure propagation of failed status to new devices */ | 220 | /* ensure propagation of failed status to new devices */ |
219 | zfcp_erp_adapter_failed(adapter); | 221 | zfcp_erp_adapter_failed(adapter, 13, NULL); |
220 | retval = -EIO; | 222 | retval = -EIO; |
221 | goto out; | 223 | goto out; |
222 | } | 224 | } |
223 | retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, | 225 | retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, |
224 | adapter, NULL, NULL); | 226 | adapter, NULL, NULL, id, ref); |
225 | 227 | ||
226 | out: | 228 | out: |
227 | return retval; | 229 | return retval; |
@@ -236,56 +238,56 @@ zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask) | |||
236 | * returns: 0 - initiated action successfully | 238 | * returns: 0 - initiated action successfully |
237 | * <0 - failed to initiate action | 239 | * <0 - failed to initiate action |
238 | */ | 240 | */ |
239 | int | 241 | int zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear_mask, |
240 | zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear_mask) | 242 | u8 id, void *ref) |
241 | { | 243 | { |
242 | int retval; | 244 | int retval; |
243 | unsigned long flags; | 245 | unsigned long flags; |
244 | 246 | ||
245 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 247 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
246 | write_lock(&adapter->erp_lock); | 248 | write_lock(&adapter->erp_lock); |
247 | retval = zfcp_erp_adapter_reopen_internal(adapter, clear_mask); | 249 | retval = zfcp_erp_adapter_reopen_internal(adapter, clear_mask, id, ref); |
248 | write_unlock(&adapter->erp_lock); | 250 | write_unlock(&adapter->erp_lock); |
249 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 251 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
250 | 252 | ||
251 | return retval; | 253 | return retval; |
252 | } | 254 | } |
253 | 255 | ||
254 | int | 256 | int zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear_mask, |
255 | zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear_mask) | 257 | u8 id, void *ref) |
256 | { | 258 | { |
257 | int retval; | 259 | int retval; |
258 | 260 | ||
259 | retval = zfcp_erp_adapter_reopen(adapter, | 261 | retval = zfcp_erp_adapter_reopen(adapter, |
260 | ZFCP_STATUS_COMMON_RUNNING | | 262 | ZFCP_STATUS_COMMON_RUNNING | |
261 | ZFCP_STATUS_COMMON_ERP_FAILED | | 263 | ZFCP_STATUS_COMMON_ERP_FAILED | |
262 | clear_mask); | 264 | clear_mask, id, ref); |
263 | 265 | ||
264 | return retval; | 266 | return retval; |
265 | } | 267 | } |
266 | 268 | ||
267 | int | 269 | int zfcp_erp_port_shutdown(struct zfcp_port *port, int clear_mask, u8 id, |
268 | zfcp_erp_port_shutdown(struct zfcp_port *port, int clear_mask) | 270 | void *ref) |
269 | { | 271 | { |
270 | int retval; | 272 | int retval; |
271 | 273 | ||
272 | retval = zfcp_erp_port_reopen(port, | 274 | retval = zfcp_erp_port_reopen(port, |
273 | ZFCP_STATUS_COMMON_RUNNING | | 275 | ZFCP_STATUS_COMMON_RUNNING | |
274 | ZFCP_STATUS_COMMON_ERP_FAILED | | 276 | ZFCP_STATUS_COMMON_ERP_FAILED | |
275 | clear_mask); | 277 | clear_mask, id, ref); |
276 | 278 | ||
277 | return retval; | 279 | return retval; |
278 | } | 280 | } |
279 | 281 | ||
280 | int | 282 | int zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask, u8 id, |
281 | zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask) | 283 | void *ref) |
282 | { | 284 | { |
283 | int retval; | 285 | int retval; |
284 | 286 | ||
285 | retval = zfcp_erp_unit_reopen(unit, | 287 | retval = zfcp_erp_unit_reopen(unit, |
286 | ZFCP_STATUS_COMMON_RUNNING | | 288 | ZFCP_STATUS_COMMON_RUNNING | |
287 | ZFCP_STATUS_COMMON_ERP_FAILED | | 289 | ZFCP_STATUS_COMMON_ERP_FAILED | |
288 | clear_mask); | 290 | clear_mask, id, ref); |
289 | 291 | ||
290 | return retval; | 292 | return retval; |
291 | } | 293 | } |
@@ -399,8 +401,7 @@ zfcp_erp_adisc_handler(unsigned long data) | |||
399 | "force physical port reopen " | 401 | "force physical port reopen " |
400 | "(adapter %s, port d_id=0x%06x)\n", | 402 | "(adapter %s, port d_id=0x%06x)\n", |
401 | zfcp_get_busid_by_adapter(adapter), d_id); | 403 | zfcp_get_busid_by_adapter(adapter), d_id); |
402 | debug_text_event(adapter->erp_dbf, 3, "forcreop"); | 404 | if (zfcp_erp_port_forced_reopen(port, 0, 63, NULL)) |
403 | if (zfcp_erp_port_forced_reopen(port, 0)) | ||
404 | ZFCP_LOG_NORMAL("failed reopen of port " | 405 | ZFCP_LOG_NORMAL("failed reopen of port " |
405 | "(adapter %s, wwpn=0x%016Lx)\n", | 406 | "(adapter %s, wwpn=0x%016Lx)\n", |
406 | zfcp_get_busid_by_port(port), | 407 | zfcp_get_busid_by_port(port), |
@@ -427,7 +428,7 @@ zfcp_erp_adisc_handler(unsigned long data) | |||
427 | "adisc_resp_wwpn=0x%016Lx)\n", | 428 | "adisc_resp_wwpn=0x%016Lx)\n", |
428 | zfcp_get_busid_by_port(port), | 429 | zfcp_get_busid_by_port(port), |
429 | port->wwpn, (wwn_t) adisc->wwpn); | 430 | port->wwpn, (wwn_t) adisc->wwpn); |
430 | if (zfcp_erp_port_reopen(port, 0)) | 431 | if (zfcp_erp_port_reopen(port, 0, 64, NULL)) |
431 | ZFCP_LOG_NORMAL("failed reopen of port " | 432 | ZFCP_LOG_NORMAL("failed reopen of port " |
432 | "(adapter %s, wwpn=0x%016Lx)\n", | 433 | "(adapter %s, wwpn=0x%016Lx)\n", |
433 | zfcp_get_busid_by_port(port), | 434 | zfcp_get_busid_by_port(port), |
@@ -461,7 +462,7 @@ zfcp_test_link(struct zfcp_port *port) | |||
461 | ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx " | 462 | ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx " |
462 | "on adapter %s\n ", port->wwpn, | 463 | "on adapter %s\n ", port->wwpn, |
463 | zfcp_get_busid_by_port(port)); | 464 | zfcp_get_busid_by_port(port)); |
464 | retval = zfcp_erp_port_forced_reopen(port, 0); | 465 | retval = zfcp_erp_port_forced_reopen(port, 0, 65, NULL); |
465 | if (retval != 0) { | 466 | if (retval != 0) { |
466 | ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx " | 467 | ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx " |
467 | "on adapter %s failed\n", port->wwpn, | 468 | "on adapter %s failed\n", port->wwpn, |
@@ -484,14 +485,11 @@ zfcp_test_link(struct zfcp_port *port) | |||
484 | * returns: 0 - initiated action successfully | 485 | * returns: 0 - initiated action successfully |
485 | * <0 - failed to initiate action | 486 | * <0 - failed to initiate action |
486 | */ | 487 | */ |
487 | static int | 488 | static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, |
488 | zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask) | 489 | int clear_mask, u8 id, |
490 | void *ref) | ||
489 | { | 491 | { |
490 | int retval; | 492 | int retval; |
491 | struct zfcp_adapter *adapter = port->adapter; | ||
492 | |||
493 | debug_text_event(adapter->erp_dbf, 5, "pf_ro"); | ||
494 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
495 | 493 | ||
496 | ZFCP_LOG_DEBUG("forced reopen of port 0x%016Lx on adapter %s\n", | 494 | ZFCP_LOG_DEBUG("forced reopen of port 0x%016Lx on adapter %s\n", |
497 | port->wwpn, zfcp_get_busid_by_port(port)); | 495 | port->wwpn, zfcp_get_busid_by_port(port)); |
@@ -502,14 +500,12 @@ zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask) | |||
502 | ZFCP_LOG_DEBUG("skipped forced reopen of failed port 0x%016Lx " | 500 | ZFCP_LOG_DEBUG("skipped forced reopen of failed port 0x%016Lx " |
503 | "on adapter %s\n", port->wwpn, | 501 | "on adapter %s\n", port->wwpn, |
504 | zfcp_get_busid_by_port(port)); | 502 | zfcp_get_busid_by_port(port)); |
505 | debug_text_event(adapter->erp_dbf, 5, "pf_ro_f"); | ||
506 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
507 | retval = -EIO; | 503 | retval = -EIO; |
508 | goto out; | 504 | goto out; |
509 | } | 505 | } |
510 | 506 | ||
511 | retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, | 507 | retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, |
512 | port->adapter, port, NULL); | 508 | port->adapter, port, NULL, id, ref); |
513 | 509 | ||
514 | out: | 510 | out: |
515 | return retval; | 511 | return retval; |
@@ -524,8 +520,8 @@ zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask) | |||
524 | * returns: 0 - initiated action successfully | 520 | * returns: 0 - initiated action successfully |
525 | * <0 - failed to initiate action | 521 | * <0 - failed to initiate action |
526 | */ | 522 | */ |
527 | int | 523 | int zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask, u8 id, |
528 | zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask) | 524 | void *ref) |
529 | { | 525 | { |
530 | int retval; | 526 | int retval; |
531 | unsigned long flags; | 527 | unsigned long flags; |
@@ -534,7 +530,8 @@ zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask) | |||
534 | adapter = port->adapter; | 530 | adapter = port->adapter; |
535 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 531 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
536 | write_lock(&adapter->erp_lock); | 532 | write_lock(&adapter->erp_lock); |
537 | retval = zfcp_erp_port_forced_reopen_internal(port, clear_mask); | 533 | retval = zfcp_erp_port_forced_reopen_internal(port, clear_mask, id, |
534 | ref); | ||
538 | write_unlock(&adapter->erp_lock); | 535 | write_unlock(&adapter->erp_lock); |
539 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 536 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
540 | 537 | ||
@@ -551,14 +548,10 @@ zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask) | |||
551 | * returns: 0 - initiated action successfully | 548 | * returns: 0 - initiated action successfully |
552 | * <0 - failed to initiate action | 549 | * <0 - failed to initiate action |
553 | */ | 550 | */ |
554 | static int | 551 | static int zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask, |
555 | zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask) | 552 | u8 id, void *ref) |
556 | { | 553 | { |
557 | int retval; | 554 | int retval; |
558 | struct zfcp_adapter *adapter = port->adapter; | ||
559 | |||
560 | debug_text_event(adapter->erp_dbf, 5, "p_ro"); | ||
561 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
562 | 555 | ||
563 | ZFCP_LOG_DEBUG("reopen of port 0x%016Lx on adapter %s\n", | 556 | ZFCP_LOG_DEBUG("reopen of port 0x%016Lx on adapter %s\n", |
564 | port->wwpn, zfcp_get_busid_by_port(port)); | 557 | port->wwpn, zfcp_get_busid_by_port(port)); |
@@ -569,16 +562,14 @@ zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask) | |||
569 | ZFCP_LOG_DEBUG("skipped reopen of failed port 0x%016Lx " | 562 | ZFCP_LOG_DEBUG("skipped reopen of failed port 0x%016Lx " |
570 | "on adapter %s\n", port->wwpn, | 563 | "on adapter %s\n", port->wwpn, |
571 | zfcp_get_busid_by_port(port)); | 564 | zfcp_get_busid_by_port(port)); |
572 | debug_text_event(adapter->erp_dbf, 5, "p_ro_f"); | ||
573 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
574 | /* ensure propagation of failed status to new devices */ | 565 | /* ensure propagation of failed status to new devices */ |
575 | zfcp_erp_port_failed(port); | 566 | zfcp_erp_port_failed(port, 14, NULL); |
576 | retval = -EIO; | 567 | retval = -EIO; |
577 | goto out; | 568 | goto out; |
578 | } | 569 | } |
579 | 570 | ||
580 | retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT, | 571 | retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT, |
581 | port->adapter, port, NULL); | 572 | port->adapter, port, NULL, id, ref); |
582 | 573 | ||
583 | out: | 574 | out: |
584 | return retval; | 575 | return retval; |
@@ -594,8 +585,8 @@ zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask) | |||
594 | * correct locking. An error recovery task is initiated to do the reopen. | 585 | * correct locking. An error recovery task is initiated to do the reopen. |
595 | * To wait for the completion of the reopen zfcp_erp_wait should be used. | 586 | * To wait for the completion of the reopen zfcp_erp_wait should be used. |
596 | */ | 587 | */ |
597 | int | 588 | int zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask, u8 id, |
598 | zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask) | 589 | void *ref) |
599 | { | 590 | { |
600 | int retval; | 591 | int retval; |
601 | unsigned long flags; | 592 | unsigned long flags; |
@@ -603,7 +594,7 @@ zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask) | |||
603 | 594 | ||
604 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 595 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
605 | write_lock(&adapter->erp_lock); | 596 | write_lock(&adapter->erp_lock); |
606 | retval = zfcp_erp_port_reopen_internal(port, clear_mask); | 597 | retval = zfcp_erp_port_reopen_internal(port, clear_mask, id, ref); |
607 | write_unlock(&adapter->erp_lock); | 598 | write_unlock(&adapter->erp_lock); |
608 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 599 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
609 | 600 | ||
@@ -620,14 +611,12 @@ zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask) | |||
620 | * returns: 0 - initiated action successfully | 611 | * returns: 0 - initiated action successfully |
621 | * <0 - failed to initiate action | 612 | * <0 - failed to initiate action |
622 | */ | 613 | */ |
623 | static int | 614 | static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask, |
624 | zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask) | 615 | u8 id, void *ref) |
625 | { | 616 | { |
626 | int retval; | 617 | int retval; |
627 | struct zfcp_adapter *adapter = unit->port->adapter; | 618 | struct zfcp_adapter *adapter = unit->port->adapter; |
628 | 619 | ||
629 | debug_text_event(adapter->erp_dbf, 5, "u_ro"); | ||
630 | debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t)); | ||
631 | ZFCP_LOG_DEBUG("reopen of unit 0x%016Lx on port 0x%016Lx " | 620 | ZFCP_LOG_DEBUG("reopen of unit 0x%016Lx on port 0x%016Lx " |
632 | "on adapter %s\n", unit->fcp_lun, | 621 | "on adapter %s\n", unit->fcp_lun, |
633 | unit->port->wwpn, zfcp_get_busid_by_unit(unit)); | 622 | unit->port->wwpn, zfcp_get_busid_by_unit(unit)); |
@@ -639,15 +628,12 @@ zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask) | |||
639 | "on port 0x%016Lx on adapter %s\n", | 628 | "on port 0x%016Lx on adapter %s\n", |
640 | unit->fcp_lun, unit->port->wwpn, | 629 | unit->fcp_lun, unit->port->wwpn, |
641 | zfcp_get_busid_by_unit(unit)); | 630 | zfcp_get_busid_by_unit(unit)); |
642 | debug_text_event(adapter->erp_dbf, 5, "u_ro_f"); | ||
643 | debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, | ||
644 | sizeof (fcp_lun_t)); | ||
645 | retval = -EIO; | 631 | retval = -EIO; |
646 | goto out; | 632 | goto out; |
647 | } | 633 | } |
648 | 634 | ||
649 | retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT, | 635 | retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT, |
650 | unit->port->adapter, unit->port, unit); | 636 | adapter, unit->port, unit, id, ref); |
651 | out: | 637 | out: |
652 | return retval; | 638 | return retval; |
653 | } | 639 | } |
@@ -662,8 +648,8 @@ zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask) | |||
662 | * locking. An error recovery task is initiated to do the reopen. | 648 | * locking. An error recovery task is initiated to do the reopen. |
663 | * To wait for the completion of the reopen zfcp_erp_wait should be used. | 649 | * To wait for the completion of the reopen zfcp_erp_wait should be used. |
664 | */ | 650 | */ |
665 | int | 651 | int zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask, u8 id, |
666 | zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask) | 652 | void *ref) |
667 | { | 653 | { |
668 | int retval; | 654 | int retval; |
669 | unsigned long flags; | 655 | unsigned long flags; |
@@ -675,7 +661,7 @@ zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask) | |||
675 | 661 | ||
676 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 662 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
677 | write_lock(&adapter->erp_lock); | 663 | write_lock(&adapter->erp_lock); |
678 | retval = zfcp_erp_unit_reopen_internal(unit, clear_mask); | 664 | retval = zfcp_erp_unit_reopen_internal(unit, clear_mask, id, ref); |
679 | write_unlock(&adapter->erp_lock); | 665 | write_unlock(&adapter->erp_lock); |
680 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 666 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
681 | 667 | ||
@@ -687,19 +673,43 @@ zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask) | |||
687 | */ | 673 | */ |
688 | static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask) | 674 | static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask) |
689 | { | 675 | { |
690 | debug_text_event(adapter->erp_dbf, 6, "a_bl"); | 676 | zfcp_erp_modify_adapter_status(adapter, 15, NULL, |
691 | zfcp_erp_modify_adapter_status(adapter, | ||
692 | ZFCP_STATUS_COMMON_UNBLOCKED | | 677 | ZFCP_STATUS_COMMON_UNBLOCKED | |
693 | clear_mask, ZFCP_CLEAR); | 678 | clear_mask, ZFCP_CLEAR); |
694 | } | 679 | } |
695 | 680 | ||
681 | /* FIXME: isn't really atomic */ | ||
682 | /* | ||
683 | * returns the mask which has not been set so far, i.e. | ||
684 | * 0 if no bit has been changed, !0 if some bit has been changed | ||
685 | */ | ||
686 | static int atomic_test_and_set_mask(unsigned long mask, atomic_t *v) | ||
687 | { | ||
688 | int changed_bits = (atomic_read(v) /*XOR*/^ mask) & mask; | ||
689 | atomic_set_mask(mask, v); | ||
690 | return changed_bits; | ||
691 | } | ||
692 | |||
693 | /* FIXME: isn't really atomic */ | ||
694 | /* | ||
695 | * returns the mask which has not been cleared so far, i.e. | ||
696 | * 0 if no bit has been changed, !0 if some bit has been changed | ||
697 | */ | ||
698 | static int atomic_test_and_clear_mask(unsigned long mask, atomic_t *v) | ||
699 | { | ||
700 | int changed_bits = atomic_read(v) & mask; | ||
701 | atomic_clear_mask(mask, v); | ||
702 | return changed_bits; | ||
703 | } | ||
704 | |||
696 | /** | 705 | /** |
697 | * zfcp_erp_adapter_unblock - mark adapter as unblocked, allow scsi requests | 706 | * zfcp_erp_adapter_unblock - mark adapter as unblocked, allow scsi requests |
698 | */ | 707 | */ |
699 | static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter) | 708 | static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter) |
700 | { | 709 | { |
701 | debug_text_event(adapter->erp_dbf, 6, "a_ubl"); | 710 | if (atomic_test_and_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, |
702 | atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status); | 711 | &adapter->status)) |
712 | zfcp_rec_dbf_event_adapter(16, NULL, adapter); | ||
703 | } | 713 | } |
704 | 714 | ||
705 | /* | 715 | /* |
@@ -714,11 +724,7 @@ static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter) | |||
714 | static void | 724 | static void |
715 | zfcp_erp_port_block(struct zfcp_port *port, int clear_mask) | 725 | zfcp_erp_port_block(struct zfcp_port *port, int clear_mask) |
716 | { | 726 | { |
717 | struct zfcp_adapter *adapter = port->adapter; | 727 | zfcp_erp_modify_port_status(port, 17, NULL, |
718 | |||
719 | debug_text_event(adapter->erp_dbf, 6, "p_bl"); | ||
720 | debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t)); | ||
721 | zfcp_erp_modify_port_status(port, | ||
722 | ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask, | 728 | ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask, |
723 | ZFCP_CLEAR); | 729 | ZFCP_CLEAR); |
724 | } | 730 | } |
@@ -733,11 +739,9 @@ zfcp_erp_port_block(struct zfcp_port *port, int clear_mask) | |||
733 | static void | 739 | static void |
734 | zfcp_erp_port_unblock(struct zfcp_port *port) | 740 | zfcp_erp_port_unblock(struct zfcp_port *port) |
735 | { | 741 | { |
736 | struct zfcp_adapter *adapter = port->adapter; | 742 | if (atomic_test_and_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, |
737 | 743 | &port->status)) | |
738 | debug_text_event(adapter->erp_dbf, 6, "p_ubl"); | 744 | zfcp_rec_dbf_event_port(18, NULL, port); |
739 | debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t)); | ||
740 | atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status); | ||
741 | } | 745 | } |
742 | 746 | ||
743 | /* | 747 | /* |
@@ -752,11 +756,7 @@ zfcp_erp_port_unblock(struct zfcp_port *port) | |||
752 | static void | 756 | static void |
753 | zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask) | 757 | zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask) |
754 | { | 758 | { |
755 | struct zfcp_adapter *adapter = unit->port->adapter; | 759 | zfcp_erp_modify_unit_status(unit, 19, NULL, |
756 | |||
757 | debug_text_event(adapter->erp_dbf, 6, "u_bl"); | ||
758 | debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t)); | ||
759 | zfcp_erp_modify_unit_status(unit, | ||
760 | ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask, | 760 | ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask, |
761 | ZFCP_CLEAR); | 761 | ZFCP_CLEAR); |
762 | } | 762 | } |
@@ -771,11 +771,9 @@ zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask) | |||
771 | static void | 771 | static void |
772 | zfcp_erp_unit_unblock(struct zfcp_unit *unit) | 772 | zfcp_erp_unit_unblock(struct zfcp_unit *unit) |
773 | { | 773 | { |
774 | struct zfcp_adapter *adapter = unit->port->adapter; | 774 | if (atomic_test_and_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, |
775 | 775 | &unit->status)) | |
776 | debug_text_event(adapter->erp_dbf, 6, "u_ubl"); | 776 | zfcp_rec_dbf_event_unit(20, NULL, unit); |
777 | debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t)); | ||
778 | atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status); | ||
779 | } | 777 | } |
780 | 778 | ||
781 | static void | 779 | static void |
@@ -783,11 +781,9 @@ zfcp_erp_action_ready(struct zfcp_erp_action *erp_action) | |||
783 | { | 781 | { |
784 | struct zfcp_adapter *adapter = erp_action->adapter; | 782 | struct zfcp_adapter *adapter = erp_action->adapter; |
785 | 783 | ||
786 | debug_text_event(adapter->erp_dbf, 4, "a_ar"); | ||
787 | debug_event(adapter->erp_dbf, 4, &erp_action->action, sizeof (int)); | ||
788 | |||
789 | zfcp_erp_action_to_ready(erp_action); | 784 | zfcp_erp_action_to_ready(erp_action); |
790 | up(&adapter->erp_ready_sem); | 785 | up(&adapter->erp_ready_sem); |
786 | zfcp_rec_dbf_event_thread(2, adapter, 0); | ||
791 | } | 787 | } |
792 | 788 | ||
793 | /* | 789 | /* |
@@ -849,18 +845,15 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | |||
849 | if (zfcp_reqlist_find_safe(adapter, erp_action->fsf_req) && | 845 | if (zfcp_reqlist_find_safe(adapter, erp_action->fsf_req) && |
850 | erp_action->fsf_req->erp_action == erp_action) { | 846 | erp_action->fsf_req->erp_action == erp_action) { |
851 | /* fsf_req still exists */ | 847 | /* fsf_req still exists */ |
852 | debug_text_event(adapter->erp_dbf, 3, "a_ca_req"); | ||
853 | debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req, | ||
854 | sizeof (unsigned long)); | ||
855 | /* dismiss fsf_req of timed out/dismissed erp_action */ | 848 | /* dismiss fsf_req of timed out/dismissed erp_action */ |
856 | if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED | | 849 | if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED | |
857 | ZFCP_STATUS_ERP_TIMEDOUT)) { | 850 | ZFCP_STATUS_ERP_TIMEDOUT)) { |
858 | debug_text_event(adapter->erp_dbf, 3, | ||
859 | "a_ca_disreq"); | ||
860 | erp_action->fsf_req->status |= | 851 | erp_action->fsf_req->status |= |
861 | ZFCP_STATUS_FSFREQ_DISMISSED; | 852 | ZFCP_STATUS_FSFREQ_DISMISSED; |
853 | zfcp_rec_dbf_event_action(142, erp_action); | ||
862 | } | 854 | } |
863 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { | 855 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { |
856 | zfcp_rec_dbf_event_action(143, erp_action); | ||
864 | ZFCP_LOG_NORMAL("error: erp step timed out " | 857 | ZFCP_LOG_NORMAL("error: erp step timed out " |
865 | "(action=%d, fsf_req=%p)\n ", | 858 | "(action=%d, fsf_req=%p)\n ", |
866 | erp_action->action, | 859 | erp_action->action, |
@@ -879,7 +872,6 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | |||
879 | erp_action->fsf_req = NULL; | 872 | erp_action->fsf_req = NULL; |
880 | } | 873 | } |
881 | } else { | 874 | } else { |
882 | debug_text_event(adapter->erp_dbf, 3, "a_ca_gonereq"); | ||
883 | /* | 875 | /* |
884 | * even if this fsf_req has gone, forget about | 876 | * even if this fsf_req has gone, forget about |
885 | * association between erp_action and fsf_req | 877 | * association between erp_action and fsf_req |
@@ -887,8 +879,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | |||
887 | erp_action->fsf_req = NULL; | 879 | erp_action->fsf_req = NULL; |
888 | } | 880 | } |
889 | spin_unlock(&adapter->req_list_lock); | 881 | spin_unlock(&adapter->req_list_lock); |
890 | } else | 882 | } |
891 | debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq"); | ||
892 | } | 883 | } |
893 | 884 | ||
894 | /** | 885 | /** |
@@ -900,19 +891,11 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action) | |||
900 | static void zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action, | 891 | static void zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action, |
901 | unsigned long set_mask) | 892 | unsigned long set_mask) |
902 | { | 893 | { |
903 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
904 | |||
905 | if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) { | 894 | if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) { |
906 | debug_text_event(adapter->erp_dbf, 2, "a_asyh_ex"); | ||
907 | debug_event(adapter->erp_dbf, 2, &erp_action->action, | ||
908 | sizeof (int)); | ||
909 | erp_action->status |= set_mask; | 895 | erp_action->status |= set_mask; |
910 | zfcp_erp_action_ready(erp_action); | 896 | zfcp_erp_action_ready(erp_action); |
911 | } else { | 897 | } else { |
912 | /* action is ready or gone - nothing to do */ | 898 | /* action is ready or gone - nothing to do */ |
913 | debug_text_event(adapter->erp_dbf, 3, "a_asyh_gone"); | ||
914 | debug_event(adapter->erp_dbf, 3, &erp_action->action, | ||
915 | sizeof (int)); | ||
916 | } | 899 | } |
917 | } | 900 | } |
918 | 901 | ||
@@ -939,10 +922,6 @@ static void | |||
939 | zfcp_erp_memwait_handler(unsigned long data) | 922 | zfcp_erp_memwait_handler(unsigned long data) |
940 | { | 923 | { |
941 | struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data; | 924 | struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data; |
942 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
943 | |||
944 | debug_text_event(adapter->erp_dbf, 2, "a_mwh"); | ||
945 | debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int)); | ||
946 | 925 | ||
947 | zfcp_erp_async_handler(erp_action, 0); | 926 | zfcp_erp_async_handler(erp_action, 0); |
948 | } | 927 | } |
@@ -955,10 +934,6 @@ zfcp_erp_memwait_handler(unsigned long data) | |||
955 | static void zfcp_erp_timeout_handler(unsigned long data) | 934 | static void zfcp_erp_timeout_handler(unsigned long data) |
956 | { | 935 | { |
957 | struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data; | 936 | struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data; |
958 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
959 | |||
960 | debug_text_event(adapter->erp_dbf, 2, "a_th"); | ||
961 | debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int)); | ||
962 | 937 | ||
963 | zfcp_erp_async_handler(erp_action, ZFCP_STATUS_ERP_TIMEDOUT); | 938 | zfcp_erp_async_handler(erp_action, ZFCP_STATUS_ERP_TIMEDOUT); |
964 | } | 939 | } |
@@ -973,11 +948,6 @@ static void zfcp_erp_timeout_handler(unsigned long data) | |||
973 | */ | 948 | */ |
974 | static void zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action) | 949 | static void zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action) |
975 | { | 950 | { |
976 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
977 | |||
978 | debug_text_event(adapter->erp_dbf, 2, "a_adis"); | ||
979 | debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int)); | ||
980 | |||
981 | erp_action->status |= ZFCP_STATUS_ERP_DISMISSED; | 951 | erp_action->status |= ZFCP_STATUS_ERP_DISMISSED; |
982 | if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) | 952 | if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) |
983 | zfcp_erp_action_ready(erp_action); | 953 | zfcp_erp_action_ready(erp_action); |
@@ -995,12 +965,10 @@ zfcp_erp_thread_setup(struct zfcp_adapter *adapter) | |||
995 | ZFCP_LOG_NORMAL("error: creation of erp thread failed for " | 965 | ZFCP_LOG_NORMAL("error: creation of erp thread failed for " |
996 | "adapter %s\n", | 966 | "adapter %s\n", |
997 | zfcp_get_busid_by_adapter(adapter)); | 967 | zfcp_get_busid_by_adapter(adapter)); |
998 | debug_text_event(adapter->erp_dbf, 5, "a_thset_fail"); | ||
999 | } else { | 968 | } else { |
1000 | wait_event(adapter->erp_thread_wqh, | 969 | wait_event(adapter->erp_thread_wqh, |
1001 | atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, | 970 | atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, |
1002 | &adapter->status)); | 971 | &adapter->status)); |
1003 | debug_text_event(adapter->erp_dbf, 5, "a_thset_ok"); | ||
1004 | } | 972 | } |
1005 | 973 | ||
1006 | return (retval < 0); | 974 | return (retval < 0); |
@@ -1027,6 +995,7 @@ zfcp_erp_thread_kill(struct zfcp_adapter *adapter) | |||
1027 | 995 | ||
1028 | atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status); | 996 | atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status); |
1029 | up(&adapter->erp_ready_sem); | 997 | up(&adapter->erp_ready_sem); |
998 | zfcp_rec_dbf_event_thread(2, adapter, 1); | ||
1030 | 999 | ||
1031 | wait_event(adapter->erp_thread_wqh, | 1000 | wait_event(adapter->erp_thread_wqh, |
1032 | !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, | 1001 | !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, |
@@ -1035,8 +1004,6 @@ zfcp_erp_thread_kill(struct zfcp_adapter *adapter) | |||
1035 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, | 1004 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, |
1036 | &adapter->status); | 1005 | &adapter->status); |
1037 | 1006 | ||
1038 | debug_text_event(adapter->erp_dbf, 5, "a_thki_ok"); | ||
1039 | |||
1040 | return retval; | 1007 | return retval; |
1041 | } | 1008 | } |
1042 | 1009 | ||
@@ -1059,7 +1026,6 @@ zfcp_erp_thread(void *data) | |||
1059 | /* Block all signals */ | 1026 | /* Block all signals */ |
1060 | siginitsetinv(¤t->blocked, 0); | 1027 | siginitsetinv(¤t->blocked, 0); |
1061 | atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); | 1028 | atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); |
1062 | debug_text_event(adapter->erp_dbf, 5, "a_th_run"); | ||
1063 | wake_up(&adapter->erp_thread_wqh); | 1029 | wake_up(&adapter->erp_thread_wqh); |
1064 | 1030 | ||
1065 | while (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, | 1031 | while (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, |
@@ -1084,12 +1050,12 @@ zfcp_erp_thread(void *data) | |||
1084 | * no action in 'ready' queue to be processed and | 1050 | * no action in 'ready' queue to be processed and |
1085 | * thread is not to be killed | 1051 | * thread is not to be killed |
1086 | */ | 1052 | */ |
1053 | zfcp_rec_dbf_event_thread(4, adapter, 1); | ||
1087 | down_interruptible(&adapter->erp_ready_sem); | 1054 | down_interruptible(&adapter->erp_ready_sem); |
1088 | debug_text_event(adapter->erp_dbf, 5, "a_th_woken"); | 1055 | zfcp_rec_dbf_event_thread(5, adapter, 1); |
1089 | } | 1056 | } |
1090 | 1057 | ||
1091 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); | 1058 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status); |
1092 | debug_text_event(adapter->erp_dbf, 5, "a_th_stop"); | ||
1093 | wake_up(&adapter->erp_thread_wqh); | 1059 | wake_up(&adapter->erp_thread_wqh); |
1094 | 1060 | ||
1095 | return 0; | 1061 | return 0; |
@@ -1125,7 +1091,6 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action) | |||
1125 | /* dequeue dismissed action and leave, if required */ | 1091 | /* dequeue dismissed action and leave, if required */ |
1126 | retval = zfcp_erp_strategy_check_action(erp_action, retval); | 1092 | retval = zfcp_erp_strategy_check_action(erp_action, retval); |
1127 | if (retval == ZFCP_ERP_DISMISSED) { | 1093 | if (retval == ZFCP_ERP_DISMISSED) { |
1128 | debug_text_event(adapter->erp_dbf, 4, "a_st_dis1"); | ||
1129 | goto unlock; | 1094 | goto unlock; |
1130 | } | 1095 | } |
1131 | 1096 | ||
@@ -1176,20 +1141,17 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action) | |||
1176 | element was timed out. | 1141 | element was timed out. |
1177 | */ | 1142 | */ |
1178 | if (adapter->erp_total_count == adapter->erp_low_mem_count) { | 1143 | if (adapter->erp_total_count == adapter->erp_low_mem_count) { |
1179 | debug_text_event(adapter->erp_dbf, 3, "a_st_lowmem"); | ||
1180 | ZFCP_LOG_NORMAL("error: no mempool elements available, " | 1144 | ZFCP_LOG_NORMAL("error: no mempool elements available, " |
1181 | "restarting I/O on adapter %s " | 1145 | "restarting I/O on adapter %s " |
1182 | "to free mempool\n", | 1146 | "to free mempool\n", |
1183 | zfcp_get_busid_by_adapter(adapter)); | 1147 | zfcp_get_busid_by_adapter(adapter)); |
1184 | zfcp_erp_adapter_reopen_internal(adapter, 0); | 1148 | zfcp_erp_adapter_reopen_internal(adapter, 0, 66, NULL); |
1185 | } else { | 1149 | } else { |
1186 | debug_text_event(adapter->erp_dbf, 2, "a_st_memw"); | ||
1187 | retval = zfcp_erp_strategy_memwait(erp_action); | 1150 | retval = zfcp_erp_strategy_memwait(erp_action); |
1188 | } | 1151 | } |
1189 | goto unlock; | 1152 | goto unlock; |
1190 | case ZFCP_ERP_CONTINUES: | 1153 | case ZFCP_ERP_CONTINUES: |
1191 | /* leave since this action runs asynchronously */ | 1154 | /* leave since this action runs asynchronously */ |
1192 | debug_text_event(adapter->erp_dbf, 6, "a_st_cont"); | ||
1193 | if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) { | 1155 | if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) { |
1194 | --adapter->erp_low_mem_count; | 1156 | --adapter->erp_low_mem_count; |
1195 | erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; | 1157 | erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; |
@@ -1218,7 +1180,6 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action) | |||
1218 | * action is repeated in order to process state change | 1180 | * action is repeated in order to process state change |
1219 | */ | 1181 | */ |
1220 | if (retval == ZFCP_ERP_EXIT) { | 1182 | if (retval == ZFCP_ERP_EXIT) { |
1221 | debug_text_event(adapter->erp_dbf, 2, "a_st_exit"); | ||
1222 | goto unlock; | 1183 | goto unlock; |
1223 | } | 1184 | } |
1224 | 1185 | ||
@@ -1244,8 +1205,6 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action) | |||
1244 | if (retval != ZFCP_ERP_DISMISSED) | 1205 | if (retval != ZFCP_ERP_DISMISSED) |
1245 | zfcp_erp_strategy_check_queues(adapter); | 1206 | zfcp_erp_strategy_check_queues(adapter); |
1246 | 1207 | ||
1247 | debug_text_event(adapter->erp_dbf, 6, "a_st_done"); | ||
1248 | |||
1249 | return retval; | 1208 | return retval; |
1250 | } | 1209 | } |
1251 | 1210 | ||
@@ -1260,17 +1219,12 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action) | |||
1260 | static int | 1219 | static int |
1261 | zfcp_erp_strategy_check_action(struct zfcp_erp_action *erp_action, int retval) | 1220 | zfcp_erp_strategy_check_action(struct zfcp_erp_action *erp_action, int retval) |
1262 | { | 1221 | { |
1263 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
1264 | |||
1265 | zfcp_erp_strategy_check_fsfreq(erp_action); | 1222 | zfcp_erp_strategy_check_fsfreq(erp_action); |
1266 | 1223 | ||
1267 | debug_event(adapter->erp_dbf, 5, &erp_action->action, sizeof (int)); | ||
1268 | if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { | 1224 | if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { |
1269 | debug_text_event(adapter->erp_dbf, 3, "a_stcd_dis"); | ||
1270 | zfcp_erp_action_dequeue(erp_action); | 1225 | zfcp_erp_action_dequeue(erp_action); |
1271 | retval = ZFCP_ERP_DISMISSED; | 1226 | retval = ZFCP_ERP_DISMISSED; |
1272 | } else | 1227 | } |
1273 | debug_text_event(adapter->erp_dbf, 5, "a_stcd_nodis"); | ||
1274 | 1228 | ||
1275 | return retval; | 1229 | return retval; |
1276 | } | 1230 | } |
@@ -1279,7 +1233,6 @@ static int | |||
1279 | zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) | 1233 | zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) |
1280 | { | 1234 | { |
1281 | int retval = ZFCP_ERP_FAILED; | 1235 | int retval = ZFCP_ERP_FAILED; |
1282 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
1283 | 1236 | ||
1284 | /* | 1237 | /* |
1285 | * try to execute/continue action as far as possible, | 1238 | * try to execute/continue action as far as possible, |
@@ -1309,9 +1262,6 @@ zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) | |||
1309 | break; | 1262 | break; |
1310 | 1263 | ||
1311 | default: | 1264 | default: |
1312 | debug_text_exception(adapter->erp_dbf, 1, "a_stda_bug"); | ||
1313 | debug_event(adapter->erp_dbf, 1, &erp_action->action, | ||
1314 | sizeof (int)); | ||
1315 | ZFCP_LOG_NORMAL("bug: unknown erp action requested on " | 1265 | ZFCP_LOG_NORMAL("bug: unknown erp action requested on " |
1316 | "adapter %s (action=%d)\n", | 1266 | "adapter %s (action=%d)\n", |
1317 | zfcp_get_busid_by_adapter(erp_action->adapter), | 1267 | zfcp_get_busid_by_adapter(erp_action->adapter), |
@@ -1333,10 +1283,7 @@ static int | |||
1333 | zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action) | 1283 | zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action) |
1334 | { | 1284 | { |
1335 | int retval = ZFCP_ERP_CONTINUES; | 1285 | int retval = ZFCP_ERP_CONTINUES; |
1336 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
1337 | 1286 | ||
1338 | debug_text_event(adapter->erp_dbf, 6, "a_mwinit"); | ||
1339 | debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int)); | ||
1340 | init_timer(&erp_action->timer); | 1287 | init_timer(&erp_action->timer); |
1341 | erp_action->timer.function = zfcp_erp_memwait_handler; | 1288 | erp_action->timer.function = zfcp_erp_memwait_handler; |
1342 | erp_action->timer.data = (unsigned long) erp_action; | 1289 | erp_action->timer.data = (unsigned long) erp_action; |
@@ -1353,13 +1300,12 @@ zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action) | |||
1353 | * | 1300 | * |
1354 | */ | 1301 | */ |
1355 | void | 1302 | void |
1356 | zfcp_erp_adapter_failed(struct zfcp_adapter *adapter) | 1303 | zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref) |
1357 | { | 1304 | { |
1358 | zfcp_erp_modify_adapter_status(adapter, | 1305 | zfcp_erp_modify_adapter_status(adapter, id, ref, |
1359 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); | 1306 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); |
1360 | ZFCP_LOG_NORMAL("adapter erp failed on adapter %s\n", | 1307 | ZFCP_LOG_NORMAL("adapter erp failed on adapter %s\n", |
1361 | zfcp_get_busid_by_adapter(adapter)); | 1308 | zfcp_get_busid_by_adapter(adapter)); |
1362 | debug_text_event(adapter->erp_dbf, 2, "a_afail"); | ||
1363 | } | 1309 | } |
1364 | 1310 | ||
1365 | /* | 1311 | /* |
@@ -1369,9 +1315,9 @@ zfcp_erp_adapter_failed(struct zfcp_adapter *adapter) | |||
1369 | * | 1315 | * |
1370 | */ | 1316 | */ |
1371 | void | 1317 | void |
1372 | zfcp_erp_port_failed(struct zfcp_port *port) | 1318 | zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref) |
1373 | { | 1319 | { |
1374 | zfcp_erp_modify_port_status(port, | 1320 | zfcp_erp_modify_port_status(port, id, ref, |
1375 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); | 1321 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); |
1376 | 1322 | ||
1377 | if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) | 1323 | if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) |
@@ -1381,9 +1327,6 @@ zfcp_erp_port_failed(struct zfcp_port *port) | |||
1381 | else | 1327 | else |
1382 | ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n", | 1328 | ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n", |
1383 | zfcp_get_busid_by_port(port), port->wwpn); | 1329 | zfcp_get_busid_by_port(port), port->wwpn); |
1384 | |||
1385 | debug_text_event(port->adapter->erp_dbf, 2, "p_pfail"); | ||
1386 | debug_event(port->adapter->erp_dbf, 2, &port->wwpn, sizeof (wwn_t)); | ||
1387 | } | 1330 | } |
1388 | 1331 | ||
1389 | /* | 1332 | /* |
@@ -1393,17 +1336,14 @@ zfcp_erp_port_failed(struct zfcp_port *port) | |||
1393 | * | 1336 | * |
1394 | */ | 1337 | */ |
1395 | void | 1338 | void |
1396 | zfcp_erp_unit_failed(struct zfcp_unit *unit) | 1339 | zfcp_erp_unit_failed(struct zfcp_unit *unit, u8 id, void *ref) |
1397 | { | 1340 | { |
1398 | zfcp_erp_modify_unit_status(unit, | 1341 | zfcp_erp_modify_unit_status(unit, id, ref, |
1399 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); | 1342 | ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET); |
1400 | 1343 | ||
1401 | ZFCP_LOG_NORMAL("unit erp failed on unit 0x%016Lx on port 0x%016Lx " | 1344 | ZFCP_LOG_NORMAL("unit erp failed on unit 0x%016Lx on port 0x%016Lx " |
1402 | " on adapter %s\n", unit->fcp_lun, | 1345 | " on adapter %s\n", unit->fcp_lun, |
1403 | unit->port->wwpn, zfcp_get_busid_by_unit(unit)); | 1346 | unit->port->wwpn, zfcp_get_busid_by_unit(unit)); |
1404 | debug_text_event(unit->port->adapter->erp_dbf, 2, "u_ufail"); | ||
1405 | debug_event(unit->port->adapter->erp_dbf, 2, | ||
1406 | &unit->fcp_lun, sizeof (fcp_lun_t)); | ||
1407 | } | 1347 | } |
1408 | 1348 | ||
1409 | /* | 1349 | /* |
@@ -1427,10 +1367,6 @@ zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, int result) | |||
1427 | struct zfcp_port *port = erp_action->port; | 1367 | struct zfcp_port *port = erp_action->port; |
1428 | struct zfcp_unit *unit = erp_action->unit; | 1368 | struct zfcp_unit *unit = erp_action->unit; |
1429 | 1369 | ||
1430 | debug_text_event(adapter->erp_dbf, 5, "a_stct_norm"); | ||
1431 | debug_event(adapter->erp_dbf, 5, &erp_action->action, sizeof (int)); | ||
1432 | debug_event(adapter->erp_dbf, 5, &result, sizeof (int)); | ||
1433 | |||
1434 | switch (erp_action->action) { | 1370 | switch (erp_action->action) { |
1435 | 1371 | ||
1436 | case ZFCP_ERP_ACTION_REOPEN_UNIT: | 1372 | case ZFCP_ERP_ACTION_REOPEN_UNIT: |
@@ -1457,15 +1393,14 @@ zfcp_erp_strategy_statechange(int action, | |||
1457 | struct zfcp_port *port, | 1393 | struct zfcp_port *port, |
1458 | struct zfcp_unit *unit, int retval) | 1394 | struct zfcp_unit *unit, int retval) |
1459 | { | 1395 | { |
1460 | debug_text_event(adapter->erp_dbf, 3, "a_stsc"); | ||
1461 | debug_event(adapter->erp_dbf, 3, &action, sizeof (int)); | ||
1462 | |||
1463 | switch (action) { | 1396 | switch (action) { |
1464 | 1397 | ||
1465 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: | 1398 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
1466 | if (zfcp_erp_strategy_statechange_detected(&adapter->status, | 1399 | if (zfcp_erp_strategy_statechange_detected(&adapter->status, |
1467 | status)) { | 1400 | status)) { |
1468 | zfcp_erp_adapter_reopen_internal(adapter, ZFCP_STATUS_COMMON_ERP_FAILED); | 1401 | zfcp_erp_adapter_reopen_internal(adapter, |
1402 | ZFCP_STATUS_COMMON_ERP_FAILED, | ||
1403 | 67, NULL); | ||
1469 | retval = ZFCP_ERP_EXIT; | 1404 | retval = ZFCP_ERP_EXIT; |
1470 | } | 1405 | } |
1471 | break; | 1406 | break; |
@@ -1474,7 +1409,9 @@ zfcp_erp_strategy_statechange(int action, | |||
1474 | case ZFCP_ERP_ACTION_REOPEN_PORT: | 1409 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
1475 | if (zfcp_erp_strategy_statechange_detected(&port->status, | 1410 | if (zfcp_erp_strategy_statechange_detected(&port->status, |
1476 | status)) { | 1411 | status)) { |
1477 | zfcp_erp_port_reopen_internal(port, ZFCP_STATUS_COMMON_ERP_FAILED); | 1412 | zfcp_erp_port_reopen_internal(port, |
1413 | ZFCP_STATUS_COMMON_ERP_FAILED, | ||
1414 | 68, NULL); | ||
1478 | retval = ZFCP_ERP_EXIT; | 1415 | retval = ZFCP_ERP_EXIT; |
1479 | } | 1416 | } |
1480 | break; | 1417 | break; |
@@ -1482,7 +1419,9 @@ zfcp_erp_strategy_statechange(int action, | |||
1482 | case ZFCP_ERP_ACTION_REOPEN_UNIT: | 1419 | case ZFCP_ERP_ACTION_REOPEN_UNIT: |
1483 | if (zfcp_erp_strategy_statechange_detected(&unit->status, | 1420 | if (zfcp_erp_strategy_statechange_detected(&unit->status, |
1484 | status)) { | 1421 | status)) { |
1485 | zfcp_erp_unit_reopen_internal(unit, ZFCP_STATUS_COMMON_ERP_FAILED); | 1422 | zfcp_erp_unit_reopen_internal(unit, |
1423 | ZFCP_STATUS_COMMON_ERP_FAILED, | ||
1424 | 69, NULL); | ||
1486 | retval = ZFCP_ERP_EXIT; | 1425 | retval = ZFCP_ERP_EXIT; |
1487 | } | 1426 | } |
1488 | break; | 1427 | break; |
@@ -1506,10 +1445,6 @@ zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status) | |||
1506 | static int | 1445 | static int |
1507 | zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) | 1446 | zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) |
1508 | { | 1447 | { |
1509 | debug_text_event(unit->port->adapter->erp_dbf, 5, "u_stct"); | ||
1510 | debug_event(unit->port->adapter->erp_dbf, 5, &unit->fcp_lun, | ||
1511 | sizeof (fcp_lun_t)); | ||
1512 | |||
1513 | switch (result) { | 1448 | switch (result) { |
1514 | case ZFCP_ERP_SUCCEEDED : | 1449 | case ZFCP_ERP_SUCCEEDED : |
1515 | atomic_set(&unit->erp_counter, 0); | 1450 | atomic_set(&unit->erp_counter, 0); |
@@ -1518,7 +1453,7 @@ zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) | |||
1518 | case ZFCP_ERP_FAILED : | 1453 | case ZFCP_ERP_FAILED : |
1519 | atomic_inc(&unit->erp_counter); | 1454 | atomic_inc(&unit->erp_counter); |
1520 | if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS) | 1455 | if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS) |
1521 | zfcp_erp_unit_failed(unit); | 1456 | zfcp_erp_unit_failed(unit, 21, NULL); |
1522 | break; | 1457 | break; |
1523 | case ZFCP_ERP_EXIT : | 1458 | case ZFCP_ERP_EXIT : |
1524 | /* nothing */ | 1459 | /* nothing */ |
@@ -1536,9 +1471,6 @@ zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result) | |||
1536 | static int | 1471 | static int |
1537 | zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) | 1472 | zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) |
1538 | { | 1473 | { |
1539 | debug_text_event(port->adapter->erp_dbf, 5, "p_stct"); | ||
1540 | debug_event(port->adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
1541 | |||
1542 | switch (result) { | 1474 | switch (result) { |
1543 | case ZFCP_ERP_SUCCEEDED : | 1475 | case ZFCP_ERP_SUCCEEDED : |
1544 | atomic_set(&port->erp_counter, 0); | 1476 | atomic_set(&port->erp_counter, 0); |
@@ -1547,7 +1479,7 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) | |||
1547 | case ZFCP_ERP_FAILED : | 1479 | case ZFCP_ERP_FAILED : |
1548 | atomic_inc(&port->erp_counter); | 1480 | atomic_inc(&port->erp_counter); |
1549 | if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS) | 1481 | if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS) |
1550 | zfcp_erp_port_failed(port); | 1482 | zfcp_erp_port_failed(port, 22, NULL); |
1551 | break; | 1483 | break; |
1552 | case ZFCP_ERP_EXIT : | 1484 | case ZFCP_ERP_EXIT : |
1553 | /* nothing */ | 1485 | /* nothing */ |
@@ -1565,8 +1497,6 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) | |||
1565 | static int | 1497 | static int |
1566 | zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result) | 1498 | zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result) |
1567 | { | 1499 | { |
1568 | debug_text_event(adapter->erp_dbf, 5, "a_stct"); | ||
1569 | |||
1570 | switch (result) { | 1500 | switch (result) { |
1571 | case ZFCP_ERP_SUCCEEDED : | 1501 | case ZFCP_ERP_SUCCEEDED : |
1572 | atomic_set(&adapter->erp_counter, 0); | 1502 | atomic_set(&adapter->erp_counter, 0); |
@@ -1575,7 +1505,7 @@ zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result) | |||
1575 | case ZFCP_ERP_FAILED : | 1505 | case ZFCP_ERP_FAILED : |
1576 | atomic_inc(&adapter->erp_counter); | 1506 | atomic_inc(&adapter->erp_counter); |
1577 | if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS) | 1507 | if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS) |
1578 | zfcp_erp_adapter_failed(adapter); | 1508 | zfcp_erp_adapter_failed(adapter, 23, NULL); |
1579 | break; | 1509 | break; |
1580 | case ZFCP_ERP_EXIT : | 1510 | case ZFCP_ERP_EXIT : |
1581 | /* nothing */ | 1511 | /* nothing */ |
@@ -1658,37 +1588,34 @@ zfcp_erp_strategy_followup_actions(int action, | |||
1658 | struct zfcp_port *port, | 1588 | struct zfcp_port *port, |
1659 | struct zfcp_unit *unit, int status) | 1589 | struct zfcp_unit *unit, int status) |
1660 | { | 1590 | { |
1661 | debug_text_event(adapter->erp_dbf, 5, "a_stfol"); | ||
1662 | debug_event(adapter->erp_dbf, 5, &action, sizeof (int)); | ||
1663 | |||
1664 | /* initiate follow-up actions depending on success of finished action */ | 1591 | /* initiate follow-up actions depending on success of finished action */ |
1665 | switch (action) { | 1592 | switch (action) { |
1666 | 1593 | ||
1667 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: | 1594 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
1668 | if (status == ZFCP_ERP_SUCCEEDED) | 1595 | if (status == ZFCP_ERP_SUCCEEDED) |
1669 | zfcp_erp_port_reopen_all_internal(adapter, 0); | 1596 | zfcp_erp_port_reopen_all_internal(adapter, 0, 70, NULL); |
1670 | else | 1597 | else |
1671 | zfcp_erp_adapter_reopen_internal(adapter, 0); | 1598 | zfcp_erp_adapter_reopen_internal(adapter, 0, 71, NULL); |
1672 | break; | 1599 | break; |
1673 | 1600 | ||
1674 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: | 1601 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
1675 | if (status == ZFCP_ERP_SUCCEEDED) | 1602 | if (status == ZFCP_ERP_SUCCEEDED) |
1676 | zfcp_erp_port_reopen_internal(port, 0); | 1603 | zfcp_erp_port_reopen_internal(port, 0, 72, NULL); |
1677 | else | 1604 | else |
1678 | zfcp_erp_adapter_reopen_internal(adapter, 0); | 1605 | zfcp_erp_adapter_reopen_internal(adapter, 0, 73, NULL); |
1679 | break; | 1606 | break; |
1680 | 1607 | ||
1681 | case ZFCP_ERP_ACTION_REOPEN_PORT: | 1608 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
1682 | if (status == ZFCP_ERP_SUCCEEDED) | 1609 | if (status == ZFCP_ERP_SUCCEEDED) |
1683 | zfcp_erp_unit_reopen_all_internal(port, 0); | 1610 | zfcp_erp_unit_reopen_all_internal(port, 0, 74, NULL); |
1684 | else | 1611 | else |
1685 | zfcp_erp_port_forced_reopen_internal(port, 0); | 1612 | zfcp_erp_port_forced_reopen_internal(port, 0, 75, NULL); |
1686 | break; | 1613 | break; |
1687 | 1614 | ||
1688 | case ZFCP_ERP_ACTION_REOPEN_UNIT: | 1615 | case ZFCP_ERP_ACTION_REOPEN_UNIT: |
1689 | /* Nothing to do if status == ZFCP_ERP_SUCCEEDED */ | 1616 | /* Nothing to do if status == ZFCP_ERP_SUCCEEDED */ |
1690 | if (status != ZFCP_ERP_SUCCEEDED) | 1617 | if (status != ZFCP_ERP_SUCCEEDED) |
1691 | zfcp_erp_port_reopen_internal(unit->port, 0); | 1618 | zfcp_erp_port_reopen_internal(unit->port, 0, 76, NULL); |
1692 | break; | 1619 | break; |
1693 | } | 1620 | } |
1694 | 1621 | ||
@@ -1704,12 +1631,10 @@ zfcp_erp_strategy_check_queues(struct zfcp_adapter *adapter) | |||
1704 | read_lock(&adapter->erp_lock); | 1631 | read_lock(&adapter->erp_lock); |
1705 | if (list_empty(&adapter->erp_ready_head) && | 1632 | if (list_empty(&adapter->erp_ready_head) && |
1706 | list_empty(&adapter->erp_running_head)) { | 1633 | list_empty(&adapter->erp_running_head)) { |
1707 | debug_text_event(adapter->erp_dbf, 4, "a_cq_wake"); | ||
1708 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, | 1634 | atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, |
1709 | &adapter->status); | 1635 | &adapter->status); |
1710 | wake_up(&adapter->erp_done_wqh); | 1636 | wake_up(&adapter->erp_done_wqh); |
1711 | } else | 1637 | } |
1712 | debug_text_event(adapter->erp_dbf, 5, "a_cq_notempty"); | ||
1713 | read_unlock(&adapter->erp_lock); | 1638 | read_unlock(&adapter->erp_lock); |
1714 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 1639 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
1715 | 1640 | ||
@@ -1733,29 +1658,27 @@ zfcp_erp_wait(struct zfcp_adapter *adapter) | |||
1733 | return retval; | 1658 | return retval; |
1734 | } | 1659 | } |
1735 | 1660 | ||
1736 | void | 1661 | void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, u8 id, |
1737 | zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, | 1662 | void *ref, u32 mask, int set_or_clear) |
1738 | u32 mask, int set_or_clear) | ||
1739 | { | 1663 | { |
1740 | struct zfcp_port *port; | 1664 | struct zfcp_port *port; |
1741 | u32 common_mask = mask & ZFCP_COMMON_FLAGS; | 1665 | u32 changed, common_mask = mask & ZFCP_COMMON_FLAGS; |
1742 | 1666 | ||
1743 | if (set_or_clear == ZFCP_SET) { | 1667 | if (set_or_clear == ZFCP_SET) { |
1744 | atomic_set_mask(mask, &adapter->status); | 1668 | changed = atomic_test_and_set_mask(mask, &adapter->status); |
1745 | debug_text_event(adapter->erp_dbf, 3, "a_mod_as_s"); | ||
1746 | } else { | 1669 | } else { |
1747 | atomic_clear_mask(mask, &adapter->status); | 1670 | changed = atomic_test_and_clear_mask(mask, &adapter->status); |
1748 | if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) | 1671 | if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) |
1749 | atomic_set(&adapter->erp_counter, 0); | 1672 | atomic_set(&adapter->erp_counter, 0); |
1750 | debug_text_event(adapter->erp_dbf, 3, "a_mod_as_c"); | ||
1751 | } | 1673 | } |
1752 | debug_event(adapter->erp_dbf, 3, &mask, sizeof (u32)); | 1674 | if (changed) |
1675 | zfcp_rec_dbf_event_adapter(id, ref, adapter); | ||
1753 | 1676 | ||
1754 | /* Deal with all underlying devices, only pass common_mask */ | 1677 | /* Deal with all underlying devices, only pass common_mask */ |
1755 | if (common_mask) | 1678 | if (common_mask) |
1756 | list_for_each_entry(port, &adapter->port_list_head, list) | 1679 | list_for_each_entry(port, &adapter->port_list_head, list) |
1757 | zfcp_erp_modify_port_status(port, common_mask, | 1680 | zfcp_erp_modify_port_status(port, id, ref, common_mask, |
1758 | set_or_clear); | 1681 | set_or_clear); |
1759 | } | 1682 | } |
1760 | 1683 | ||
1761 | /* | 1684 | /* |
@@ -1764,29 +1687,27 @@ zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, | |||
1764 | * purpose: sets the port and all underlying devices to ERP_FAILED | 1687 | * purpose: sets the port and all underlying devices to ERP_FAILED |
1765 | * | 1688 | * |
1766 | */ | 1689 | */ |
1767 | void | 1690 | void zfcp_erp_modify_port_status(struct zfcp_port *port, u8 id, void *ref, |
1768 | zfcp_erp_modify_port_status(struct zfcp_port *port, u32 mask, int set_or_clear) | 1691 | u32 mask, int set_or_clear) |
1769 | { | 1692 | { |
1770 | struct zfcp_unit *unit; | 1693 | struct zfcp_unit *unit; |
1771 | u32 common_mask = mask & ZFCP_COMMON_FLAGS; | 1694 | u32 changed, common_mask = mask & ZFCP_COMMON_FLAGS; |
1772 | 1695 | ||
1773 | if (set_or_clear == ZFCP_SET) { | 1696 | if (set_or_clear == ZFCP_SET) { |
1774 | atomic_set_mask(mask, &port->status); | 1697 | changed = atomic_test_and_set_mask(mask, &port->status); |
1775 | debug_text_event(port->adapter->erp_dbf, 3, "p_mod_ps_s"); | ||
1776 | } else { | 1698 | } else { |
1777 | atomic_clear_mask(mask, &port->status); | 1699 | changed = atomic_test_and_clear_mask(mask, &port->status); |
1778 | if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) | 1700 | if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) |
1779 | atomic_set(&port->erp_counter, 0); | 1701 | atomic_set(&port->erp_counter, 0); |
1780 | debug_text_event(port->adapter->erp_dbf, 3, "p_mod_ps_c"); | ||
1781 | } | 1702 | } |
1782 | debug_event(port->adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t)); | 1703 | if (changed) |
1783 | debug_event(port->adapter->erp_dbf, 3, &mask, sizeof (u32)); | 1704 | zfcp_rec_dbf_event_port(id, ref, port); |
1784 | 1705 | ||
1785 | /* Modify status of all underlying devices, only pass common mask */ | 1706 | /* Modify status of all underlying devices, only pass common mask */ |
1786 | if (common_mask) | 1707 | if (common_mask) |
1787 | list_for_each_entry(unit, &port->unit_list_head, list) | 1708 | list_for_each_entry(unit, &port->unit_list_head, list) |
1788 | zfcp_erp_modify_unit_status(unit, common_mask, | 1709 | zfcp_erp_modify_unit_status(unit, id, ref, common_mask, |
1789 | set_or_clear); | 1710 | set_or_clear); |
1790 | } | 1711 | } |
1791 | 1712 | ||
1792 | /* | 1713 | /* |
@@ -1795,22 +1716,21 @@ zfcp_erp_modify_port_status(struct zfcp_port *port, u32 mask, int set_or_clear) | |||
1795 | * purpose: sets the unit to ERP_FAILED | 1716 | * purpose: sets the unit to ERP_FAILED |
1796 | * | 1717 | * |
1797 | */ | 1718 | */ |
1798 | void | 1719 | void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u8 id, void *ref, |
1799 | zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear) | 1720 | u32 mask, int set_or_clear) |
1800 | { | 1721 | { |
1722 | u32 changed; | ||
1723 | |||
1801 | if (set_or_clear == ZFCP_SET) { | 1724 | if (set_or_clear == ZFCP_SET) { |
1802 | atomic_set_mask(mask, &unit->status); | 1725 | changed = atomic_test_and_set_mask(mask, &unit->status); |
1803 | debug_text_event(unit->port->adapter->erp_dbf, 3, "u_mod_us_s"); | ||
1804 | } else { | 1726 | } else { |
1805 | atomic_clear_mask(mask, &unit->status); | 1727 | changed = atomic_test_and_clear_mask(mask, &unit->status); |
1806 | if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) { | 1728 | if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) { |
1807 | atomic_set(&unit->erp_counter, 0); | 1729 | atomic_set(&unit->erp_counter, 0); |
1808 | } | 1730 | } |
1809 | debug_text_event(unit->port->adapter->erp_dbf, 3, "u_mod_us_c"); | ||
1810 | } | 1731 | } |
1811 | debug_event(unit->port->adapter->erp_dbf, 3, &unit->fcp_lun, | 1732 | if (changed) |
1812 | sizeof (fcp_lun_t)); | 1733 | zfcp_rec_dbf_event_unit(id, ref, unit); |
1813 | debug_event(unit->port->adapter->erp_dbf, 3, &mask, sizeof (u32)); | ||
1814 | } | 1734 | } |
1815 | 1735 | ||
1816 | /* | 1736 | /* |
@@ -1822,30 +1742,32 @@ zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear) | |||
1822 | * returns: 0 - initiated action successfully | 1742 | * returns: 0 - initiated action successfully |
1823 | * <0 - failed to initiate action | 1743 | * <0 - failed to initiate action |
1824 | */ | 1744 | */ |
1825 | int | 1745 | int zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, int clear_mask, |
1826 | zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, int clear_mask) | 1746 | u8 id, void *ref) |
1827 | { | 1747 | { |
1828 | int retval; | 1748 | int retval; |
1829 | unsigned long flags; | 1749 | unsigned long flags; |
1830 | 1750 | ||
1831 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 1751 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
1832 | write_lock(&adapter->erp_lock); | 1752 | write_lock(&adapter->erp_lock); |
1833 | retval = zfcp_erp_port_reopen_all_internal(adapter, clear_mask); | 1753 | retval = zfcp_erp_port_reopen_all_internal(adapter, clear_mask, id, |
1754 | ref); | ||
1834 | write_unlock(&adapter->erp_lock); | 1755 | write_unlock(&adapter->erp_lock); |
1835 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 1756 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
1836 | 1757 | ||
1837 | return retval; | 1758 | return retval; |
1838 | } | 1759 | } |
1839 | 1760 | ||
1840 | static int | 1761 | static int zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, |
1841 | zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask) | 1762 | int clear_mask, u8 id, void *ref) |
1842 | { | 1763 | { |
1843 | int retval = 0; | 1764 | int retval = 0; |
1844 | struct zfcp_port *port; | 1765 | struct zfcp_port *port; |
1845 | 1766 | ||
1846 | list_for_each_entry(port, &adapter->port_list_head, list) | 1767 | list_for_each_entry(port, &adapter->port_list_head, list) |
1847 | if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) | 1768 | if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) |
1848 | zfcp_erp_port_reopen_internal(port, clear_mask); | 1769 | zfcp_erp_port_reopen_internal(port, clear_mask, id, |
1770 | ref); | ||
1849 | 1771 | ||
1850 | return retval; | 1772 | return retval; |
1851 | } | 1773 | } |
@@ -1857,14 +1779,14 @@ zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask) | |||
1857 | * | 1779 | * |
1858 | * returns: FIXME | 1780 | * returns: FIXME |
1859 | */ | 1781 | */ |
1860 | static int | 1782 | static int zfcp_erp_unit_reopen_all_internal(struct zfcp_port *port, |
1861 | zfcp_erp_unit_reopen_all_internal(struct zfcp_port *port, int clear_mask) | 1783 | int clear_mask, u8 id, void *ref) |
1862 | { | 1784 | { |
1863 | int retval = 0; | 1785 | int retval = 0; |
1864 | struct zfcp_unit *unit; | 1786 | struct zfcp_unit *unit; |
1865 | 1787 | ||
1866 | list_for_each_entry(unit, &port->unit_list_head, list) | 1788 | list_for_each_entry(unit, &port->unit_list_head, list) |
1867 | zfcp_erp_unit_reopen_internal(unit, clear_mask); | 1789 | zfcp_erp_unit_reopen_internal(unit, clear_mask, id, ref); |
1868 | 1790 | ||
1869 | return retval; | 1791 | return retval; |
1870 | } | 1792 | } |
@@ -1892,10 +1814,6 @@ zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action) | |||
1892 | else | 1814 | else |
1893 | retval = zfcp_erp_adapter_strategy_open(erp_action); | 1815 | retval = zfcp_erp_adapter_strategy_open(erp_action); |
1894 | 1816 | ||
1895 | debug_text_event(adapter->erp_dbf, 3, "a_ast/ret"); | ||
1896 | debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int)); | ||
1897 | debug_event(adapter->erp_dbf, 3, &retval, sizeof (int)); | ||
1898 | |||
1899 | if (retval == ZFCP_ERP_FAILED) { | 1817 | if (retval == ZFCP_ERP_FAILED) { |
1900 | ZFCP_LOG_INFO("Waiting to allow the adapter %s " | 1818 | ZFCP_LOG_INFO("Waiting to allow the adapter %s " |
1901 | "to recover itself\n", | 1819 | "to recover itself\n", |
@@ -2021,7 +1939,6 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) | |||
2021 | zfcp_get_busid_by_adapter(adapter)); | 1939 | zfcp_get_busid_by_adapter(adapter)); |
2022 | goto failed_qdio_establish; | 1940 | goto failed_qdio_establish; |
2023 | } | 1941 | } |
2024 | debug_text_event(adapter->erp_dbf, 3, "qdio_est"); | ||
2025 | 1942 | ||
2026 | if (qdio_activate(adapter->ccw_device, 0) != 0) { | 1943 | if (qdio_activate(adapter->ccw_device, 0) != 0) { |
2027 | ZFCP_LOG_INFO("error: activation of QDIO queues failed " | 1944 | ZFCP_LOG_INFO("error: activation of QDIO queues failed " |
@@ -2029,7 +1946,6 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) | |||
2029 | zfcp_get_busid_by_adapter(adapter)); | 1946 | zfcp_get_busid_by_adapter(adapter)); |
2030 | goto failed_qdio_activate; | 1947 | goto failed_qdio_activate; |
2031 | } | 1948 | } |
2032 | debug_text_event(adapter->erp_dbf, 3, "qdio_act"); | ||
2033 | 1949 | ||
2034 | /* | 1950 | /* |
2035 | * put buffers into response queue, | 1951 | * put buffers into response queue, |
@@ -2077,11 +1993,9 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action) | |||
2077 | /* NOP */ | 1993 | /* NOP */ |
2078 | 1994 | ||
2079 | failed_qdio_activate: | 1995 | failed_qdio_activate: |
2080 | debug_text_event(adapter->erp_dbf, 3, "qdio_down1a"); | ||
2081 | while (qdio_shutdown(adapter->ccw_device, | 1996 | while (qdio_shutdown(adapter->ccw_device, |
2082 | QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS) | 1997 | QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS) |
2083 | ssleep(1); | 1998 | ssleep(1); |
2084 | debug_text_event(adapter->erp_dbf, 3, "qdio_down1b"); | ||
2085 | 1999 | ||
2086 | failed_qdio_establish: | 2000 | failed_qdio_establish: |
2087 | failed_sanity: | 2001 | failed_sanity: |
@@ -2127,14 +2041,12 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) | |||
2127 | write_unlock_irq(&adapter->erp_lock); | 2041 | write_unlock_irq(&adapter->erp_lock); |
2128 | if (zfcp_fsf_exchange_config_data(erp_action)) { | 2042 | if (zfcp_fsf_exchange_config_data(erp_action)) { |
2129 | retval = ZFCP_ERP_FAILED; | 2043 | retval = ZFCP_ERP_FAILED; |
2130 | debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf"); | ||
2131 | ZFCP_LOG_INFO("error: initiation of exchange of " | 2044 | ZFCP_LOG_INFO("error: initiation of exchange of " |
2132 | "configuration data failed for " | 2045 | "configuration data failed for " |
2133 | "adapter %s\n", | 2046 | "adapter %s\n", |
2134 | zfcp_get_busid_by_adapter(adapter)); | 2047 | zfcp_get_busid_by_adapter(adapter)); |
2135 | break; | 2048 | break; |
2136 | } | 2049 | } |
2137 | debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok"); | ||
2138 | ZFCP_LOG_DEBUG("Xchange underway\n"); | 2050 | ZFCP_LOG_DEBUG("Xchange underway\n"); |
2139 | 2051 | ||
2140 | /* | 2052 | /* |
@@ -2150,7 +2062,9 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action) | |||
2150 | * _must_ be the one belonging to the 'exchange config | 2062 | * _must_ be the one belonging to the 'exchange config |
2151 | * data' request. | 2063 | * data' request. |
2152 | */ | 2064 | */ |
2065 | zfcp_rec_dbf_event_thread(6, adapter, 1); | ||
2153 | down(&adapter->erp_ready_sem); | 2066 | down(&adapter->erp_ready_sem); |
2067 | zfcp_rec_dbf_event_thread(7, adapter, 1); | ||
2154 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { | 2068 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { |
2155 | ZFCP_LOG_INFO("error: exchange of configuration data " | 2069 | ZFCP_LOG_INFO("error: exchange of configuration data " |
2156 | "for adapter %s timed out\n", | 2070 | "for adapter %s timed out\n", |
@@ -2198,16 +2112,15 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action) | |||
2198 | 2112 | ||
2199 | ret = zfcp_fsf_exchange_port_data(erp_action); | 2113 | ret = zfcp_fsf_exchange_port_data(erp_action); |
2200 | if (ret == -EOPNOTSUPP) { | 2114 | if (ret == -EOPNOTSUPP) { |
2201 | debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp"); | ||
2202 | return ZFCP_ERP_SUCCEEDED; | 2115 | return ZFCP_ERP_SUCCEEDED; |
2203 | } else if (ret) { | 2116 | } else if (ret) { |
2204 | debug_text_event(adapter->erp_dbf, 3, "a_xport_failed"); | ||
2205 | return ZFCP_ERP_FAILED; | 2117 | return ZFCP_ERP_FAILED; |
2206 | } | 2118 | } |
2207 | debug_text_event(adapter->erp_dbf, 6, "a_xport_ok"); | ||
2208 | 2119 | ||
2209 | ret = ZFCP_ERP_SUCCEEDED; | 2120 | ret = ZFCP_ERP_SUCCEEDED; |
2121 | zfcp_rec_dbf_event_thread(8, adapter, 1); | ||
2210 | down(&adapter->erp_ready_sem); | 2122 | down(&adapter->erp_ready_sem); |
2123 | zfcp_rec_dbf_event_thread(9, adapter, 1); | ||
2211 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { | 2124 | if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { |
2212 | ZFCP_LOG_INFO("error: exchange port data timed out (adapter " | 2125 | ZFCP_LOG_INFO("error: exchange port data timed out (adapter " |
2213 | "%s)\n", zfcp_get_busid_by_adapter(adapter)); | 2126 | "%s)\n", zfcp_get_busid_by_adapter(adapter)); |
@@ -2261,7 +2174,6 @@ zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action) | |||
2261 | { | 2174 | { |
2262 | int retval = ZFCP_ERP_FAILED; | 2175 | int retval = ZFCP_ERP_FAILED; |
2263 | struct zfcp_port *port = erp_action->port; | 2176 | struct zfcp_port *port = erp_action->port; |
2264 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2265 | 2177 | ||
2266 | switch (erp_action->step) { | 2178 | switch (erp_action->step) { |
2267 | 2179 | ||
@@ -2298,11 +2210,6 @@ zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action) | |||
2298 | break; | 2210 | break; |
2299 | } | 2211 | } |
2300 | 2212 | ||
2301 | debug_text_event(adapter->erp_dbf, 3, "p_pfst/ret"); | ||
2302 | debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t)); | ||
2303 | debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int)); | ||
2304 | debug_event(adapter->erp_dbf, 3, &retval, sizeof (int)); | ||
2305 | |||
2306 | return retval; | 2213 | return retval; |
2307 | } | 2214 | } |
2308 | 2215 | ||
@@ -2320,7 +2227,6 @@ zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) | |||
2320 | { | 2227 | { |
2321 | int retval = ZFCP_ERP_FAILED; | 2228 | int retval = ZFCP_ERP_FAILED; |
2322 | struct zfcp_port *port = erp_action->port; | 2229 | struct zfcp_port *port = erp_action->port; |
2323 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2324 | 2230 | ||
2325 | switch (erp_action->step) { | 2231 | switch (erp_action->step) { |
2326 | 2232 | ||
@@ -2353,11 +2259,6 @@ zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) | |||
2353 | retval = zfcp_erp_port_strategy_open(erp_action); | 2259 | retval = zfcp_erp_port_strategy_open(erp_action); |
2354 | 2260 | ||
2355 | out: | 2261 | out: |
2356 | debug_text_event(adapter->erp_dbf, 3, "p_pst/ret"); | ||
2357 | debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t)); | ||
2358 | debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int)); | ||
2359 | debug_event(adapter->erp_dbf, 3, &retval, sizeof (int)); | ||
2360 | |||
2361 | return retval; | 2262 | return retval; |
2362 | } | 2263 | } |
2363 | 2264 | ||
@@ -2395,7 +2296,7 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) | |||
2395 | port->wwpn, | 2296 | port->wwpn, |
2396 | zfcp_get_busid_by_adapter(adapter), | 2297 | zfcp_get_busid_by_adapter(adapter), |
2397 | adapter->peer_wwpn); | 2298 | adapter->peer_wwpn); |
2398 | zfcp_erp_port_failed(port); | 2299 | zfcp_erp_port_failed(port, 25, NULL); |
2399 | retval = ZFCP_ERP_FAILED; | 2300 | retval = ZFCP_ERP_FAILED; |
2400 | break; | 2301 | break; |
2401 | } | 2302 | } |
@@ -2421,8 +2322,8 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) | |||
2421 | /* nameserver port may live again */ | 2322 | /* nameserver port may live again */ |
2422 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, | 2323 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, |
2423 | &adapter->nameserver_port->status); | 2324 | &adapter->nameserver_port->status); |
2424 | if (zfcp_erp_port_reopen(adapter->nameserver_port, 0) | 2325 | if (zfcp_erp_port_reopen(adapter->nameserver_port, 0, |
2425 | >= 0) { | 2326 | 77, erp_action) >= 0) { |
2426 | erp_action->step = | 2327 | erp_action->step = |
2427 | ZFCP_ERP_STEP_NAMESERVER_OPEN; | 2328 | ZFCP_ERP_STEP_NAMESERVER_OPEN; |
2428 | retval = ZFCP_ERP_CONTINUES; | 2329 | retval = ZFCP_ERP_CONTINUES; |
@@ -2453,7 +2354,7 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action) | |||
2453 | "for port 0x%016Lx " | 2354 | "for port 0x%016Lx " |
2454 | "(misconfigured WWPN?)\n", | 2355 | "(misconfigured WWPN?)\n", |
2455 | port->wwpn); | 2356 | port->wwpn); |
2456 | zfcp_erp_port_failed(port); | 2357 | zfcp_erp_port_failed(port, 26, NULL); |
2457 | retval = ZFCP_ERP_EXIT; | 2358 | retval = ZFCP_ERP_EXIT; |
2458 | } else { | 2359 | } else { |
2459 | ZFCP_LOG_DEBUG("nameserver look-up failed for " | 2360 | ZFCP_LOG_DEBUG("nameserver look-up failed for " |
@@ -2549,17 +2450,12 @@ zfcp_erp_port_strategy_open_nameserver_wakeup(struct zfcp_erp_action | |||
2549 | read_lock_irqsave(&adapter->erp_lock, flags); | 2450 | read_lock_irqsave(&adapter->erp_lock, flags); |
2550 | list_for_each_entry_safe(erp_action, tmp, &adapter->erp_running_head, | 2451 | list_for_each_entry_safe(erp_action, tmp, &adapter->erp_running_head, |
2551 | list) { | 2452 | list) { |
2552 | debug_text_event(adapter->erp_dbf, 4, "p_pstnsw_n"); | ||
2553 | debug_event(adapter->erp_dbf, 4, &erp_action->port->wwpn, | ||
2554 | sizeof (wwn_t)); | ||
2555 | if (erp_action->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) { | 2453 | if (erp_action->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) { |
2556 | debug_text_event(adapter->erp_dbf, 3, "p_pstnsw_w"); | ||
2557 | debug_event(adapter->erp_dbf, 3, | ||
2558 | &erp_action->port->wwpn, sizeof (wwn_t)); | ||
2559 | if (atomic_test_mask( | 2454 | if (atomic_test_mask( |
2560 | ZFCP_STATUS_COMMON_ERP_FAILED, | 2455 | ZFCP_STATUS_COMMON_ERP_FAILED, |
2561 | &adapter->nameserver_port->status)) | 2456 | &adapter->nameserver_port->status)) |
2562 | zfcp_erp_port_failed(erp_action->port); | 2457 | zfcp_erp_port_failed(erp_action->port, 27, |
2458 | NULL); | ||
2563 | zfcp_erp_action_ready(erp_action); | 2459 | zfcp_erp_action_ready(erp_action); |
2564 | } | 2460 | } |
2565 | } | 2461 | } |
@@ -2580,26 +2476,18 @@ static int | |||
2580 | zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *erp_action) | 2476 | zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *erp_action) |
2581 | { | 2477 | { |
2582 | int retval; | 2478 | int retval; |
2583 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2584 | struct zfcp_port *port = erp_action->port; | ||
2585 | 2479 | ||
2586 | retval = zfcp_fsf_close_physical_port(erp_action); | 2480 | retval = zfcp_fsf_close_physical_port(erp_action); |
2587 | if (retval == -ENOMEM) { | 2481 | if (retval == -ENOMEM) { |
2588 | debug_text_event(adapter->erp_dbf, 5, "o_pfstc_nomem"); | ||
2589 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
2590 | retval = ZFCP_ERP_NOMEM; | 2482 | retval = ZFCP_ERP_NOMEM; |
2591 | goto out; | 2483 | goto out; |
2592 | } | 2484 | } |
2593 | erp_action->step = ZFCP_ERP_STEP_PHYS_PORT_CLOSING; | 2485 | erp_action->step = ZFCP_ERP_STEP_PHYS_PORT_CLOSING; |
2594 | if (retval != 0) { | 2486 | if (retval != 0) { |
2595 | debug_text_event(adapter->erp_dbf, 5, "o_pfstc_cpf"); | ||
2596 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
2597 | /* could not send 'open', fail */ | 2487 | /* could not send 'open', fail */ |
2598 | retval = ZFCP_ERP_FAILED; | 2488 | retval = ZFCP_ERP_FAILED; |
2599 | goto out; | 2489 | goto out; |
2600 | } | 2490 | } |
2601 | debug_text_event(adapter->erp_dbf, 6, "o_pfstc_cpok"); | ||
2602 | debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t)); | ||
2603 | retval = ZFCP_ERP_CONTINUES; | 2491 | retval = ZFCP_ERP_CONTINUES; |
2604 | out: | 2492 | out: |
2605 | return retval; | 2493 | return retval; |
@@ -2609,10 +2497,6 @@ static int | |||
2609 | zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) | 2497 | zfcp_erp_port_strategy_clearstati(struct zfcp_port *port) |
2610 | { | 2498 | { |
2611 | int retval = 0; | 2499 | int retval = 0; |
2612 | struct zfcp_adapter *adapter = port->adapter; | ||
2613 | |||
2614 | debug_text_event(adapter->erp_dbf, 5, "p_pstclst"); | ||
2615 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
2616 | 2500 | ||
2617 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING | | 2501 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING | |
2618 | ZFCP_STATUS_COMMON_CLOSING | | 2502 | ZFCP_STATUS_COMMON_CLOSING | |
@@ -2636,26 +2520,18 @@ static int | |||
2636 | zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action) | 2520 | zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action) |
2637 | { | 2521 | { |
2638 | int retval; | 2522 | int retval; |
2639 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2640 | struct zfcp_port *port = erp_action->port; | ||
2641 | 2523 | ||
2642 | retval = zfcp_fsf_close_port(erp_action); | 2524 | retval = zfcp_fsf_close_port(erp_action); |
2643 | if (retval == -ENOMEM) { | 2525 | if (retval == -ENOMEM) { |
2644 | debug_text_event(adapter->erp_dbf, 5, "p_pstc_nomem"); | ||
2645 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
2646 | retval = ZFCP_ERP_NOMEM; | 2526 | retval = ZFCP_ERP_NOMEM; |
2647 | goto out; | 2527 | goto out; |
2648 | } | 2528 | } |
2649 | erp_action->step = ZFCP_ERP_STEP_PORT_CLOSING; | 2529 | erp_action->step = ZFCP_ERP_STEP_PORT_CLOSING; |
2650 | if (retval != 0) { | 2530 | if (retval != 0) { |
2651 | debug_text_event(adapter->erp_dbf, 5, "p_pstc_cpf"); | ||
2652 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
2653 | /* could not send 'close', fail */ | 2531 | /* could not send 'close', fail */ |
2654 | retval = ZFCP_ERP_FAILED; | 2532 | retval = ZFCP_ERP_FAILED; |
2655 | goto out; | 2533 | goto out; |
2656 | } | 2534 | } |
2657 | debug_text_event(adapter->erp_dbf, 6, "p_pstc_cpok"); | ||
2658 | debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t)); | ||
2659 | retval = ZFCP_ERP_CONTINUES; | 2535 | retval = ZFCP_ERP_CONTINUES; |
2660 | out: | 2536 | out: |
2661 | return retval; | 2537 | return retval; |
@@ -2673,26 +2549,18 @@ static int | |||
2673 | zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action) | 2549 | zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action) |
2674 | { | 2550 | { |
2675 | int retval; | 2551 | int retval; |
2676 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2677 | struct zfcp_port *port = erp_action->port; | ||
2678 | 2552 | ||
2679 | retval = zfcp_fsf_open_port(erp_action); | 2553 | retval = zfcp_fsf_open_port(erp_action); |
2680 | if (retval == -ENOMEM) { | 2554 | if (retval == -ENOMEM) { |
2681 | debug_text_event(adapter->erp_dbf, 5, "p_psto_nomem"); | ||
2682 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
2683 | retval = ZFCP_ERP_NOMEM; | 2555 | retval = ZFCP_ERP_NOMEM; |
2684 | goto out; | 2556 | goto out; |
2685 | } | 2557 | } |
2686 | erp_action->step = ZFCP_ERP_STEP_PORT_OPENING; | 2558 | erp_action->step = ZFCP_ERP_STEP_PORT_OPENING; |
2687 | if (retval != 0) { | 2559 | if (retval != 0) { |
2688 | debug_text_event(adapter->erp_dbf, 5, "p_psto_opf"); | ||
2689 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
2690 | /* could not send 'open', fail */ | 2560 | /* could not send 'open', fail */ |
2691 | retval = ZFCP_ERP_FAILED; | 2561 | retval = ZFCP_ERP_FAILED; |
2692 | goto out; | 2562 | goto out; |
2693 | } | 2563 | } |
2694 | debug_text_event(adapter->erp_dbf, 6, "p_psto_opok"); | ||
2695 | debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t)); | ||
2696 | retval = ZFCP_ERP_CONTINUES; | 2564 | retval = ZFCP_ERP_CONTINUES; |
2697 | out: | 2565 | out: |
2698 | return retval; | 2566 | return retval; |
@@ -2710,26 +2578,18 @@ static int | |||
2710 | zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action) | 2578 | zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action) |
2711 | { | 2579 | { |
2712 | int retval; | 2580 | int retval; |
2713 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2714 | struct zfcp_port *port = erp_action->port; | ||
2715 | 2581 | ||
2716 | retval = zfcp_ns_gid_pn_request(erp_action); | 2582 | retval = zfcp_ns_gid_pn_request(erp_action); |
2717 | if (retval == -ENOMEM) { | 2583 | if (retval == -ENOMEM) { |
2718 | debug_text_event(adapter->erp_dbf, 5, "p_pstn_nomem"); | ||
2719 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
2720 | retval = ZFCP_ERP_NOMEM; | 2584 | retval = ZFCP_ERP_NOMEM; |
2721 | goto out; | 2585 | goto out; |
2722 | } | 2586 | } |
2723 | erp_action->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; | 2587 | erp_action->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP; |
2724 | if (retval != 0) { | 2588 | if (retval != 0) { |
2725 | debug_text_event(adapter->erp_dbf, 5, "p_pstn_ref"); | ||
2726 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
2727 | /* could not send nameserver request, fail */ | 2589 | /* could not send nameserver request, fail */ |
2728 | retval = ZFCP_ERP_FAILED; | 2590 | retval = ZFCP_ERP_FAILED; |
2729 | goto out; | 2591 | goto out; |
2730 | } | 2592 | } |
2731 | debug_text_event(adapter->erp_dbf, 6, "p_pstn_reok"); | ||
2732 | debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t)); | ||
2733 | retval = ZFCP_ERP_CONTINUES; | 2593 | retval = ZFCP_ERP_CONTINUES; |
2734 | out: | 2594 | out: |
2735 | return retval; | 2595 | return retval; |
@@ -2750,7 +2610,6 @@ zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action) | |||
2750 | { | 2610 | { |
2751 | int retval = ZFCP_ERP_FAILED; | 2611 | int retval = ZFCP_ERP_FAILED; |
2752 | struct zfcp_unit *unit = erp_action->unit; | 2612 | struct zfcp_unit *unit = erp_action->unit; |
2753 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2754 | 2613 | ||
2755 | switch (erp_action->step) { | 2614 | switch (erp_action->step) { |
2756 | 2615 | ||
@@ -2797,10 +2656,6 @@ zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action) | |||
2797 | break; | 2656 | break; |
2798 | } | 2657 | } |
2799 | 2658 | ||
2800 | debug_text_event(adapter->erp_dbf, 3, "u_ust/ret"); | ||
2801 | debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof (fcp_lun_t)); | ||
2802 | debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int)); | ||
2803 | debug_event(adapter->erp_dbf, 3, &retval, sizeof (int)); | ||
2804 | return retval; | 2659 | return retval; |
2805 | } | 2660 | } |
2806 | 2661 | ||
@@ -2808,10 +2663,6 @@ static int | |||
2808 | zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) | 2663 | zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit) |
2809 | { | 2664 | { |
2810 | int retval = 0; | 2665 | int retval = 0; |
2811 | struct zfcp_adapter *adapter = unit->port->adapter; | ||
2812 | |||
2813 | debug_text_event(adapter->erp_dbf, 5, "u_ustclst"); | ||
2814 | debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t)); | ||
2815 | 2666 | ||
2816 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING | | 2667 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING | |
2817 | ZFCP_STATUS_COMMON_CLOSING | | 2668 | ZFCP_STATUS_COMMON_CLOSING | |
@@ -2835,28 +2686,18 @@ static int | |||
2835 | zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action) | 2686 | zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action) |
2836 | { | 2687 | { |
2837 | int retval; | 2688 | int retval; |
2838 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2839 | struct zfcp_unit *unit = erp_action->unit; | ||
2840 | 2689 | ||
2841 | retval = zfcp_fsf_close_unit(erp_action); | 2690 | retval = zfcp_fsf_close_unit(erp_action); |
2842 | if (retval == -ENOMEM) { | 2691 | if (retval == -ENOMEM) { |
2843 | debug_text_event(adapter->erp_dbf, 5, "u_ustc_nomem"); | ||
2844 | debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, | ||
2845 | sizeof (fcp_lun_t)); | ||
2846 | retval = ZFCP_ERP_NOMEM; | 2692 | retval = ZFCP_ERP_NOMEM; |
2847 | goto out; | 2693 | goto out; |
2848 | } | 2694 | } |
2849 | erp_action->step = ZFCP_ERP_STEP_UNIT_CLOSING; | 2695 | erp_action->step = ZFCP_ERP_STEP_UNIT_CLOSING; |
2850 | if (retval != 0) { | 2696 | if (retval != 0) { |
2851 | debug_text_event(adapter->erp_dbf, 5, "u_ustc_cuf"); | ||
2852 | debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, | ||
2853 | sizeof (fcp_lun_t)); | ||
2854 | /* could not send 'close', fail */ | 2697 | /* could not send 'close', fail */ |
2855 | retval = ZFCP_ERP_FAILED; | 2698 | retval = ZFCP_ERP_FAILED; |
2856 | goto out; | 2699 | goto out; |
2857 | } | 2700 | } |
2858 | debug_text_event(adapter->erp_dbf, 6, "u_ustc_cuok"); | ||
2859 | debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t)); | ||
2860 | retval = ZFCP_ERP_CONTINUES; | 2701 | retval = ZFCP_ERP_CONTINUES; |
2861 | 2702 | ||
2862 | out: | 2703 | out: |
@@ -2875,28 +2716,18 @@ static int | |||
2875 | zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action) | 2716 | zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action) |
2876 | { | 2717 | { |
2877 | int retval; | 2718 | int retval; |
2878 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
2879 | struct zfcp_unit *unit = erp_action->unit; | ||
2880 | 2719 | ||
2881 | retval = zfcp_fsf_open_unit(erp_action); | 2720 | retval = zfcp_fsf_open_unit(erp_action); |
2882 | if (retval == -ENOMEM) { | 2721 | if (retval == -ENOMEM) { |
2883 | debug_text_event(adapter->erp_dbf, 5, "u_usto_nomem"); | ||
2884 | debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, | ||
2885 | sizeof (fcp_lun_t)); | ||
2886 | retval = ZFCP_ERP_NOMEM; | 2722 | retval = ZFCP_ERP_NOMEM; |
2887 | goto out; | 2723 | goto out; |
2888 | } | 2724 | } |
2889 | erp_action->step = ZFCP_ERP_STEP_UNIT_OPENING; | 2725 | erp_action->step = ZFCP_ERP_STEP_UNIT_OPENING; |
2890 | if (retval != 0) { | 2726 | if (retval != 0) { |
2891 | debug_text_event(adapter->erp_dbf, 5, "u_usto_ouf"); | ||
2892 | debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, | ||
2893 | sizeof (fcp_lun_t)); | ||
2894 | /* could not send 'open', fail */ | 2727 | /* could not send 'open', fail */ |
2895 | retval = ZFCP_ERP_FAILED; | 2728 | retval = ZFCP_ERP_FAILED; |
2896 | goto out; | 2729 | goto out; |
2897 | } | 2730 | } |
2898 | debug_text_event(adapter->erp_dbf, 6, "u_usto_ouok"); | ||
2899 | debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t)); | ||
2900 | retval = ZFCP_ERP_CONTINUES; | 2731 | retval = ZFCP_ERP_CONTINUES; |
2901 | out: | 2732 | out: |
2902 | return retval; | 2733 | return retval; |
@@ -2918,14 +2749,12 @@ void zfcp_erp_start_timer(struct zfcp_fsf_req *fsf_req) | |||
2918 | * | 2749 | * |
2919 | * returns: | 2750 | * returns: |
2920 | */ | 2751 | */ |
2921 | static int | 2752 | static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, |
2922 | zfcp_erp_action_enqueue(int action, | 2753 | struct zfcp_port *port, |
2923 | struct zfcp_adapter *adapter, | 2754 | struct zfcp_unit *unit, u8 id, void *ref) |
2924 | struct zfcp_port *port, struct zfcp_unit *unit) | ||
2925 | { | 2755 | { |
2926 | int retval = 1; | 2756 | int retval = 1, need = want; |
2927 | struct zfcp_erp_action *erp_action = NULL; | 2757 | struct zfcp_erp_action *erp_action = NULL; |
2928 | int stronger_action = 0; | ||
2929 | u32 status = 0; | 2758 | u32 status = 0; |
2930 | 2759 | ||
2931 | /* | 2760 | /* |
@@ -2944,17 +2773,11 @@ zfcp_erp_action_enqueue(int action, | |||
2944 | &adapter->status)) | 2773 | &adapter->status)) |
2945 | return -EIO; | 2774 | return -EIO; |
2946 | 2775 | ||
2947 | debug_event(adapter->erp_dbf, 4, &action, sizeof (int)); | ||
2948 | /* check whether we really need this */ | 2776 | /* check whether we really need this */ |
2949 | switch (action) { | 2777 | switch (want) { |
2950 | case ZFCP_ERP_ACTION_REOPEN_UNIT: | 2778 | case ZFCP_ERP_ACTION_REOPEN_UNIT: |
2951 | if (atomic_test_mask | 2779 | if (atomic_test_mask |
2952 | (ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) { | 2780 | (ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) { |
2953 | debug_text_event(adapter->erp_dbf, 4, "u_actenq_drp"); | ||
2954 | debug_event(adapter->erp_dbf, 4, &port->wwpn, | ||
2955 | sizeof (wwn_t)); | ||
2956 | debug_event(adapter->erp_dbf, 4, &unit->fcp_lun, | ||
2957 | sizeof (fcp_lun_t)); | ||
2958 | goto out; | 2781 | goto out; |
2959 | } | 2782 | } |
2960 | if (!atomic_test_mask | 2783 | if (!atomic_test_mask |
@@ -2964,18 +2787,13 @@ zfcp_erp_action_enqueue(int action, | |||
2964 | goto out; | 2787 | goto out; |
2965 | } | 2788 | } |
2966 | if (!atomic_test_mask | 2789 | if (!atomic_test_mask |
2967 | (ZFCP_STATUS_COMMON_UNBLOCKED, &port->status)) { | 2790 | (ZFCP_STATUS_COMMON_UNBLOCKED, &port->status)) |
2968 | stronger_action = ZFCP_ERP_ACTION_REOPEN_PORT; | 2791 | need = ZFCP_ERP_ACTION_REOPEN_PORT; |
2969 | unit = NULL; | ||
2970 | } | ||
2971 | /* fall through !!! */ | 2792 | /* fall through !!! */ |
2972 | 2793 | ||
2973 | case ZFCP_ERP_ACTION_REOPEN_PORT: | 2794 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
2974 | if (atomic_test_mask | 2795 | if (atomic_test_mask |
2975 | (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)) { | 2796 | (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)) { |
2976 | debug_text_event(adapter->erp_dbf, 4, "p_actenq_drp"); | ||
2977 | debug_event(adapter->erp_dbf, 4, &port->wwpn, | ||
2978 | sizeof (wwn_t)); | ||
2979 | goto out; | 2797 | goto out; |
2980 | } | 2798 | } |
2981 | /* fall through !!! */ | 2799 | /* fall through !!! */ |
@@ -2987,15 +2805,9 @@ zfcp_erp_action_enqueue(int action, | |||
2987 | ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) { | 2805 | ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) { |
2988 | ZFCP_LOG_INFO("dropped erp action %i (port " | 2806 | ZFCP_LOG_INFO("dropped erp action %i (port " |
2989 | "0x%016Lx, action in use: %i)\n", | 2807 | "0x%016Lx, action in use: %i)\n", |
2990 | action, port->wwpn, | 2808 | want, port->wwpn, |
2991 | port->erp_action.action); | 2809 | port->erp_action.action); |
2992 | debug_text_event(adapter->erp_dbf, 4, | 2810 | } |
2993 | "pf_actenq_drp"); | ||
2994 | } else | ||
2995 | debug_text_event(adapter->erp_dbf, 4, | ||
2996 | "pf_actenq_drpcp"); | ||
2997 | debug_event(adapter->erp_dbf, 4, &port->wwpn, | ||
2998 | sizeof (wwn_t)); | ||
2999 | goto out; | 2811 | goto out; |
3000 | } | 2812 | } |
3001 | if (!atomic_test_mask | 2813 | if (!atomic_test_mask |
@@ -3005,46 +2817,36 @@ zfcp_erp_action_enqueue(int action, | |||
3005 | goto out; | 2817 | goto out; |
3006 | } | 2818 | } |
3007 | if (!atomic_test_mask | 2819 | if (!atomic_test_mask |
3008 | (ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status)) { | 2820 | (ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status)) |
3009 | stronger_action = ZFCP_ERP_ACTION_REOPEN_ADAPTER; | 2821 | need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; |
3010 | port = NULL; | ||
3011 | } | ||
3012 | /* fall through !!! */ | 2822 | /* fall through !!! */ |
3013 | 2823 | ||
3014 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: | 2824 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
3015 | if (atomic_test_mask | 2825 | if (atomic_test_mask |
3016 | (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)) { | 2826 | (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)) { |
3017 | debug_text_event(adapter->erp_dbf, 4, "a_actenq_drp"); | ||
3018 | goto out; | 2827 | goto out; |
3019 | } | 2828 | } |
3020 | break; | 2829 | break; |
3021 | 2830 | ||
3022 | default: | 2831 | default: |
3023 | debug_text_exception(adapter->erp_dbf, 1, "a_actenq_bug"); | ||
3024 | debug_event(adapter->erp_dbf, 1, &action, sizeof (int)); | ||
3025 | ZFCP_LOG_NORMAL("bug: unknown erp action requested " | 2832 | ZFCP_LOG_NORMAL("bug: unknown erp action requested " |
3026 | "on adapter %s (action=%d)\n", | 2833 | "on adapter %s (action=%d)\n", |
3027 | zfcp_get_busid_by_adapter(adapter), action); | 2834 | zfcp_get_busid_by_adapter(adapter), want); |
3028 | goto out; | 2835 | goto out; |
3029 | } | 2836 | } |
3030 | 2837 | ||
3031 | /* check whether we need something stronger first */ | 2838 | /* check whether we need something stronger first */ |
3032 | if (stronger_action) { | 2839 | if (need) { |
3033 | debug_text_event(adapter->erp_dbf, 4, "a_actenq_str"); | ||
3034 | debug_event(adapter->erp_dbf, 4, &stronger_action, | ||
3035 | sizeof (int)); | ||
3036 | ZFCP_LOG_DEBUG("stronger erp action %d needed before " | 2840 | ZFCP_LOG_DEBUG("stronger erp action %d needed before " |
3037 | "erp action %d on adapter %s\n", | 2841 | "erp action %d on adapter %s\n", |
3038 | stronger_action, action, | 2842 | need, want, zfcp_get_busid_by_adapter(adapter)); |
3039 | zfcp_get_busid_by_adapter(adapter)); | ||
3040 | action = stronger_action; | ||
3041 | } | 2843 | } |
3042 | 2844 | ||
3043 | /* mark adapter to have some error recovery pending */ | 2845 | /* mark adapter to have some error recovery pending */ |
3044 | atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status); | 2846 | atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status); |
3045 | 2847 | ||
3046 | /* setup error recovery action */ | 2848 | /* setup error recovery action */ |
3047 | switch (action) { | 2849 | switch (need) { |
3048 | 2850 | ||
3049 | case ZFCP_ERP_ACTION_REOPEN_UNIT: | 2851 | case ZFCP_ERP_ACTION_REOPEN_UNIT: |
3050 | zfcp_unit_get(unit); | 2852 | zfcp_unit_get(unit); |
@@ -3077,13 +2879,11 @@ zfcp_erp_action_enqueue(int action, | |||
3077 | break; | 2879 | break; |
3078 | } | 2880 | } |
3079 | 2881 | ||
3080 | debug_text_event(adapter->erp_dbf, 4, "a_actenq"); | ||
3081 | |||
3082 | memset(erp_action, 0, sizeof (struct zfcp_erp_action)); | 2882 | memset(erp_action, 0, sizeof (struct zfcp_erp_action)); |
3083 | erp_action->adapter = adapter; | 2883 | erp_action->adapter = adapter; |
3084 | erp_action->port = port; | 2884 | erp_action->port = port; |
3085 | erp_action->unit = unit; | 2885 | erp_action->unit = unit; |
3086 | erp_action->action = action; | 2886 | erp_action->action = need; |
3087 | erp_action->status = status; | 2887 | erp_action->status = status; |
3088 | 2888 | ||
3089 | ++adapter->erp_total_count; | 2889 | ++adapter->erp_total_count; |
@@ -3091,8 +2891,11 @@ zfcp_erp_action_enqueue(int action, | |||
3091 | /* finally put it into 'ready' queue and kick erp thread */ | 2891 | /* finally put it into 'ready' queue and kick erp thread */ |
3092 | list_add_tail(&erp_action->list, &adapter->erp_ready_head); | 2892 | list_add_tail(&erp_action->list, &adapter->erp_ready_head); |
3093 | up(&adapter->erp_ready_sem); | 2893 | up(&adapter->erp_ready_sem); |
2894 | zfcp_rec_dbf_event_thread(1, adapter, 0); | ||
3094 | retval = 0; | 2895 | retval = 0; |
3095 | out: | 2896 | out: |
2897 | zfcp_rec_dbf_event_trigger(id, ref, want, need, erp_action, | ||
2898 | adapter, port, unit); | ||
3096 | return retval; | 2899 | return retval; |
3097 | } | 2900 | } |
3098 | 2901 | ||
@@ -3108,9 +2911,9 @@ zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action) | |||
3108 | erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; | 2911 | erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; |
3109 | } | 2912 | } |
3110 | 2913 | ||
3111 | debug_text_event(adapter->erp_dbf, 4, "a_actdeq"); | ||
3112 | debug_event(adapter->erp_dbf, 4, &erp_action->action, sizeof (int)); | ||
3113 | list_del(&erp_action->list); | 2914 | list_del(&erp_action->list); |
2915 | zfcp_rec_dbf_event_action(144, erp_action); | ||
2916 | |||
3114 | switch (erp_action->action) { | 2917 | switch (erp_action->action) { |
3115 | case ZFCP_ERP_ACTION_REOPEN_UNIT: | 2918 | case ZFCP_ERP_ACTION_REOPEN_UNIT: |
3116 | atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE, | 2919 | atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE, |
@@ -3215,7 +3018,6 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) | |||
3215 | { | 3018 | { |
3216 | struct zfcp_port *port; | 3019 | struct zfcp_port *port; |
3217 | 3020 | ||
3218 | debug_text_event(adapter->erp_dbf, 5, "a_actab"); | ||
3219 | if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)) | 3021 | if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)) |
3220 | zfcp_erp_action_dismiss(&adapter->erp_action); | 3022 | zfcp_erp_action_dismiss(&adapter->erp_action); |
3221 | else | 3023 | else |
@@ -3226,10 +3028,7 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter) | |||
3226 | static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) | 3028 | static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) |
3227 | { | 3029 | { |
3228 | struct zfcp_unit *unit; | 3030 | struct zfcp_unit *unit; |
3229 | struct zfcp_adapter *adapter = port->adapter; | ||
3230 | 3031 | ||
3231 | debug_text_event(adapter->erp_dbf, 5, "p_actab"); | ||
3232 | debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t)); | ||
3233 | if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)) | 3032 | if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)) |
3234 | zfcp_erp_action_dismiss(&port->erp_action); | 3033 | zfcp_erp_action_dismiss(&port->erp_action); |
3235 | else | 3034 | else |
@@ -3239,92 +3038,60 @@ static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) | |||
3239 | 3038 | ||
3240 | static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit) | 3039 | static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit) |
3241 | { | 3040 | { |
3242 | struct zfcp_adapter *adapter = unit->port->adapter; | ||
3243 | |||
3244 | debug_text_event(adapter->erp_dbf, 5, "u_actab"); | ||
3245 | debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t)); | ||
3246 | if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) | 3041 | if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) |
3247 | zfcp_erp_action_dismiss(&unit->erp_action); | 3042 | zfcp_erp_action_dismiss(&unit->erp_action); |
3248 | } | 3043 | } |
3249 | 3044 | ||
3250 | static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) | 3045 | static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action) |
3251 | { | 3046 | { |
3252 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
3253 | |||
3254 | debug_text_event(adapter->erp_dbf, 6, "a_toru"); | ||
3255 | debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int)); | ||
3256 | list_move(&erp_action->list, &erp_action->adapter->erp_running_head); | 3047 | list_move(&erp_action->list, &erp_action->adapter->erp_running_head); |
3048 | zfcp_rec_dbf_event_action(145, erp_action); | ||
3257 | } | 3049 | } |
3258 | 3050 | ||
3259 | static void zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action) | 3051 | static void zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action) |
3260 | { | 3052 | { |
3261 | struct zfcp_adapter *adapter = erp_action->adapter; | ||
3262 | |||
3263 | debug_text_event(adapter->erp_dbf, 6, "a_tore"); | ||
3264 | debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int)); | ||
3265 | list_move(&erp_action->list, &erp_action->adapter->erp_ready_head); | 3053 | list_move(&erp_action->list, &erp_action->adapter->erp_ready_head); |
3054 | zfcp_rec_dbf_event_action(146, erp_action); | ||
3266 | } | 3055 | } |
3267 | 3056 | ||
3268 | void | 3057 | void zfcp_erp_port_boxed(struct zfcp_port *port, u8 id, void *ref) |
3269 | zfcp_erp_port_boxed(struct zfcp_port *port) | ||
3270 | { | 3058 | { |
3271 | struct zfcp_adapter *adapter = port->adapter; | ||
3272 | unsigned long flags; | 3059 | unsigned long flags; |
3273 | 3060 | ||
3274 | debug_text_event(adapter->erp_dbf, 3, "p_access_boxed"); | ||
3275 | debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t)); | ||
3276 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 3061 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
3277 | zfcp_erp_modify_port_status(port, | 3062 | zfcp_erp_modify_port_status(port, id, ref, |
3278 | ZFCP_STATUS_COMMON_ACCESS_BOXED, | 3063 | ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); |
3279 | ZFCP_SET); | ||
3280 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 3064 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
3281 | zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED); | 3065 | zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); |
3282 | } | 3066 | } |
3283 | 3067 | ||
3284 | void | 3068 | void zfcp_erp_unit_boxed(struct zfcp_unit *unit, u8 id, void *ref) |
3285 | zfcp_erp_unit_boxed(struct zfcp_unit *unit) | ||
3286 | { | 3069 | { |
3287 | struct zfcp_adapter *adapter = unit->port->adapter; | 3070 | zfcp_erp_modify_unit_status(unit, id, ref, |
3288 | 3071 | ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET); | |
3289 | debug_text_event(adapter->erp_dbf, 3, "u_access_boxed"); | 3072 | zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref); |
3290 | debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t)); | ||
3291 | zfcp_erp_modify_unit_status(unit, | ||
3292 | ZFCP_STATUS_COMMON_ACCESS_BOXED, | ||
3293 | ZFCP_SET); | ||
3294 | zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED); | ||
3295 | } | 3073 | } |
3296 | 3074 | ||
3297 | void | 3075 | void zfcp_erp_port_access_denied(struct zfcp_port *port, u8 id, void *ref) |
3298 | zfcp_erp_port_access_denied(struct zfcp_port *port) | ||
3299 | { | 3076 | { |
3300 | struct zfcp_adapter *adapter = port->adapter; | ||
3301 | unsigned long flags; | 3077 | unsigned long flags; |
3302 | 3078 | ||
3303 | debug_text_event(adapter->erp_dbf, 3, "p_access_denied"); | ||
3304 | debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t)); | ||
3305 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 3079 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
3306 | zfcp_erp_modify_port_status(port, | 3080 | zfcp_erp_modify_port_status(port, id, ref, |
3307 | ZFCP_STATUS_COMMON_ERP_FAILED | | 3081 | ZFCP_STATUS_COMMON_ERP_FAILED | |
3308 | ZFCP_STATUS_COMMON_ACCESS_DENIED, | 3082 | ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); |
3309 | ZFCP_SET); | ||
3310 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 3083 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
3311 | } | 3084 | } |
3312 | 3085 | ||
3313 | void | 3086 | void zfcp_erp_unit_access_denied(struct zfcp_unit *unit, u8 id, void *ref) |
3314 | zfcp_erp_unit_access_denied(struct zfcp_unit *unit) | ||
3315 | { | 3087 | { |
3316 | struct zfcp_adapter *adapter = unit->port->adapter; | 3088 | zfcp_erp_modify_unit_status(unit, id, ref, |
3317 | 3089 | ZFCP_STATUS_COMMON_ERP_FAILED | | |
3318 | debug_text_event(adapter->erp_dbf, 3, "u_access_denied"); | 3090 | ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET); |
3319 | debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t)); | ||
3320 | zfcp_erp_modify_unit_status(unit, | ||
3321 | ZFCP_STATUS_COMMON_ERP_FAILED | | ||
3322 | ZFCP_STATUS_COMMON_ACCESS_DENIED, | ||
3323 | ZFCP_SET); | ||
3324 | } | 3091 | } |
3325 | 3092 | ||
3326 | void | 3093 | void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id, |
3327 | zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter) | 3094 | void *ref) |
3328 | { | 3095 | { |
3329 | struct zfcp_port *port; | 3096 | struct zfcp_port *port; |
3330 | unsigned long flags; | 3097 | unsigned long flags; |
@@ -3332,54 +3099,43 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter) | |||
3332 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) | 3099 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) |
3333 | return; | 3100 | return; |
3334 | 3101 | ||
3335 | debug_text_event(adapter->erp_dbf, 3, "a_access_recover"); | ||
3336 | debug_event(adapter->erp_dbf, 3, zfcp_get_busid_by_adapter(adapter), 8); | ||
3337 | |||
3338 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 3102 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
3339 | if (adapter->nameserver_port) | 3103 | if (adapter->nameserver_port) |
3340 | zfcp_erp_port_access_changed(adapter->nameserver_port); | 3104 | zfcp_erp_port_access_changed(adapter->nameserver_port, id, ref); |
3341 | list_for_each_entry(port, &adapter->port_list_head, list) | 3105 | list_for_each_entry(port, &adapter->port_list_head, list) |
3342 | if (port != adapter->nameserver_port) | 3106 | if (port != adapter->nameserver_port) |
3343 | zfcp_erp_port_access_changed(port); | 3107 | zfcp_erp_port_access_changed(port, id, ref); |
3344 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 3108 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
3345 | } | 3109 | } |
3346 | 3110 | ||
3347 | void | 3111 | void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id, void *ref) |
3348 | zfcp_erp_port_access_changed(struct zfcp_port *port) | ||
3349 | { | 3112 | { |
3350 | struct zfcp_adapter *adapter = port->adapter; | 3113 | struct zfcp_adapter *adapter = port->adapter; |
3351 | struct zfcp_unit *unit; | 3114 | struct zfcp_unit *unit; |
3352 | 3115 | ||
3353 | debug_text_event(adapter->erp_dbf, 3, "p_access_recover"); | ||
3354 | debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t)); | ||
3355 | |||
3356 | if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, | 3116 | if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, |
3357 | &port->status) && | 3117 | &port->status) && |
3358 | !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED, | 3118 | !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED, |
3359 | &port->status)) { | 3119 | &port->status)) { |
3360 | if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) | 3120 | if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status)) |
3361 | list_for_each_entry(unit, &port->unit_list_head, list) | 3121 | list_for_each_entry(unit, &port->unit_list_head, list) |
3362 | zfcp_erp_unit_access_changed(unit); | 3122 | zfcp_erp_unit_access_changed(unit, id, ref); |
3363 | return; | 3123 | return; |
3364 | } | 3124 | } |
3365 | 3125 | ||
3366 | ZFCP_LOG_NORMAL("reopen of port 0x%016Lx on adapter %s " | 3126 | ZFCP_LOG_NORMAL("reopen of port 0x%016Lx on adapter %s " |
3367 | "(due to ACT update)\n", | 3127 | "(due to ACT update)\n", |
3368 | port->wwpn, zfcp_get_busid_by_adapter(adapter)); | 3128 | port->wwpn, zfcp_get_busid_by_adapter(adapter)); |
3369 | if (zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED) != 0) | 3129 | if (zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref)) |
3370 | ZFCP_LOG_NORMAL("failed reopen of port" | 3130 | ZFCP_LOG_NORMAL("failed reopen of port" |
3371 | "(adapter %s, wwpn=0x%016Lx)\n", | 3131 | "(adapter %s, wwpn=0x%016Lx)\n", |
3372 | zfcp_get_busid_by_adapter(adapter), port->wwpn); | 3132 | zfcp_get_busid_by_adapter(adapter), port->wwpn); |
3373 | } | 3133 | } |
3374 | 3134 | ||
3375 | void | 3135 | void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, u8 id, void *ref) |
3376 | zfcp_erp_unit_access_changed(struct zfcp_unit *unit) | ||
3377 | { | 3136 | { |
3378 | struct zfcp_adapter *adapter = unit->port->adapter; | 3137 | struct zfcp_adapter *adapter = unit->port->adapter; |
3379 | 3138 | ||
3380 | debug_text_event(adapter->erp_dbf, 3, "u_access_recover"); | ||
3381 | debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t)); | ||
3382 | |||
3383 | if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, | 3139 | if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, |
3384 | &unit->status) && | 3140 | &unit->status) && |
3385 | !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED, | 3141 | !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED, |
@@ -3390,7 +3146,7 @@ zfcp_erp_unit_access_changed(struct zfcp_unit *unit) | |||
3390 | " on adapter %s (due to ACT update)\n", | 3146 | " on adapter %s (due to ACT update)\n", |
3391 | unit->fcp_lun, unit->port->wwpn, | 3147 | unit->fcp_lun, unit->port->wwpn, |
3392 | zfcp_get_busid_by_adapter(adapter)); | 3148 | zfcp_get_busid_by_adapter(adapter)); |
3393 | if (zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED) != 0) | 3149 | if (zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref)) |
3394 | ZFCP_LOG_NORMAL("failed reopen of unit (adapter %s, " | 3150 | ZFCP_LOG_NORMAL("failed reopen of unit (adapter %s, " |
3395 | "wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n", | 3151 | "wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n", |
3396 | zfcp_get_busid_by_adapter(adapter), | 3152 | zfcp_get_busid_by_adapter(adapter), |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 06b1079b7f3d..6abf178fda5d 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -131,22 +131,25 @@ extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, int); | |||
131 | extern struct fc_function_template zfcp_transport_functions; | 131 | extern struct fc_function_template zfcp_transport_functions; |
132 | 132 | ||
133 | /******************************** ERP ****************************************/ | 133 | /******************************** ERP ****************************************/ |
134 | extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u32, int); | 134 | extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u8, void *, |
135 | extern int zfcp_erp_adapter_reopen(struct zfcp_adapter *, int); | 135 | u32, int); |
136 | extern int zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int); | 136 | extern int zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, u8, void *); |
137 | extern void zfcp_erp_adapter_failed(struct zfcp_adapter *); | 137 | extern int zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, u8, void *); |
138 | 138 | extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, u8, void *); | |
139 | extern void zfcp_erp_modify_port_status(struct zfcp_port *, u32, int); | 139 | |
140 | extern int zfcp_erp_port_reopen(struct zfcp_port *, int); | 140 | extern void zfcp_erp_modify_port_status(struct zfcp_port *, u8, void *, u32, |
141 | extern int zfcp_erp_port_shutdown(struct zfcp_port *, int); | 141 | int); |
142 | extern int zfcp_erp_port_forced_reopen(struct zfcp_port *, int); | 142 | extern int zfcp_erp_port_reopen(struct zfcp_port *, int, u8, void *); |
143 | extern void zfcp_erp_port_failed(struct zfcp_port *); | 143 | extern int zfcp_erp_port_shutdown(struct zfcp_port *, int, u8, void *); |
144 | extern int zfcp_erp_port_reopen_all(struct zfcp_adapter *, int); | 144 | extern int zfcp_erp_port_forced_reopen(struct zfcp_port *, int, u8, void *); |
145 | 145 | extern void zfcp_erp_port_failed(struct zfcp_port *, u8, void *); | |
146 | extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, u32, int); | 146 | extern int zfcp_erp_port_reopen_all(struct zfcp_adapter *, int, u8, void *); |
147 | extern int zfcp_erp_unit_reopen(struct zfcp_unit *, int); | 147 | |
148 | extern int zfcp_erp_unit_shutdown(struct zfcp_unit *, int); | 148 | extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, u8, void *, u32, |
149 | extern void zfcp_erp_unit_failed(struct zfcp_unit *); | 149 | int); |
150 | extern int zfcp_erp_unit_reopen(struct zfcp_unit *, int, u8, void *); | ||
151 | extern int zfcp_erp_unit_shutdown(struct zfcp_unit *, int, u8, void *); | ||
152 | extern void zfcp_erp_unit_failed(struct zfcp_unit *, u8, void *); | ||
150 | 153 | ||
151 | extern int zfcp_erp_thread_setup(struct zfcp_adapter *); | 154 | extern int zfcp_erp_thread_setup(struct zfcp_adapter *); |
152 | extern int zfcp_erp_thread_kill(struct zfcp_adapter *); | 155 | extern int zfcp_erp_thread_kill(struct zfcp_adapter *); |
@@ -155,15 +158,25 @@ extern void zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long); | |||
155 | 158 | ||
156 | extern int zfcp_test_link(struct zfcp_port *); | 159 | extern int zfcp_test_link(struct zfcp_port *); |
157 | 160 | ||
158 | extern void zfcp_erp_port_boxed(struct zfcp_port *); | 161 | extern void zfcp_erp_port_boxed(struct zfcp_port *, u8 id, void *ref); |
159 | extern void zfcp_erp_unit_boxed(struct zfcp_unit *); | 162 | extern void zfcp_erp_unit_boxed(struct zfcp_unit *, u8 id, void *ref); |
160 | extern void zfcp_erp_port_access_denied(struct zfcp_port *); | 163 | extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8 id, void *ref); |
161 | extern void zfcp_erp_unit_access_denied(struct zfcp_unit *); | 164 | extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8 id, void *ref); |
162 | extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *); | 165 | extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *); |
163 | extern void zfcp_erp_port_access_changed(struct zfcp_port *); | 166 | extern void zfcp_erp_port_access_changed(struct zfcp_port *, u8, void *); |
164 | extern void zfcp_erp_unit_access_changed(struct zfcp_unit *); | 167 | extern void zfcp_erp_unit_access_changed(struct zfcp_unit *, u8, void *); |
165 | 168 | ||
166 | /******************************** AUX ****************************************/ | 169 | /******************************** AUX ****************************************/ |
170 | extern void zfcp_rec_dbf_event_thread(u8 id, struct zfcp_adapter *adapter, | ||
171 | int lock); | ||
172 | extern void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *); | ||
173 | extern void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port); | ||
174 | extern void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit); | ||
175 | extern void zfcp_rec_dbf_event_trigger(u8 id, void *ref, u8 want, u8 need, | ||
176 | void *action, struct zfcp_adapter *, | ||
177 | struct zfcp_port *, struct zfcp_unit *); | ||
178 | extern void zfcp_rec_dbf_event_action(u8 id, struct zfcp_erp_action *); | ||
179 | |||
167 | extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *); | 180 | extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *); |
168 | extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *, | 181 | extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *, |
169 | struct fsf_status_read_buffer *); | 182 | struct fsf_status_read_buffer *); |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 0dff05840ee2..7c3f02816e95 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -46,7 +46,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *); | |||
46 | static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *); | 46 | static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *); |
47 | static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *); | 47 | static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *); |
48 | static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *); | 48 | static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *); |
49 | static void zfcp_fsf_link_down_info_eval(struct zfcp_adapter *, | 49 | static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *, u8, |
50 | struct fsf_link_down_info *); | 50 | struct fsf_link_down_info *); |
51 | static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *); | 51 | static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *); |
52 | 52 | ||
@@ -284,37 +284,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
284 | goto skip_protstatus; | 284 | goto skip_protstatus; |
285 | } | 285 | } |
286 | 286 | ||
287 | /* log additional information provided by FSF (if any) */ | ||
288 | if (likely(qtcb->header.log_length)) { | ||
289 | /* do not trust them ;-) */ | ||
290 | if (unlikely(qtcb->header.log_start > | ||
291 | sizeof(struct fsf_qtcb))) { | ||
292 | ZFCP_LOG_NORMAL | ||
293 | ("bug: ULP (FSF logging) log data starts " | ||
294 | "beyond end of packet header. Ignored. " | ||
295 | "(start=%i, size=%li)\n", | ||
296 | qtcb->header.log_start, | ||
297 | sizeof(struct fsf_qtcb)); | ||
298 | goto forget_log; | ||
299 | } | ||
300 | if (unlikely((size_t) (qtcb->header.log_start + | ||
301 | qtcb->header.log_length) > | ||
302 | sizeof(struct fsf_qtcb))) { | ||
303 | ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends " | ||
304 | "beyond end of packet header. Ignored. " | ||
305 | "(start=%i, length=%i, size=%li)\n", | ||
306 | qtcb->header.log_start, | ||
307 | qtcb->header.log_length, | ||
308 | sizeof(struct fsf_qtcb)); | ||
309 | goto forget_log; | ||
310 | } | ||
311 | ZFCP_LOG_TRACE("ULP log data: \n"); | ||
312 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, | ||
313 | (char *) qtcb + qtcb->header.log_start, | ||
314 | qtcb->header.log_length); | ||
315 | } | ||
316 | forget_log: | ||
317 | |||
318 | /* evaluate FSF Protocol Status */ | 287 | /* evaluate FSF Protocol Status */ |
319 | switch (qtcb->prefix.prot_status) { | 288 | switch (qtcb->prefix.prot_status) { |
320 | 289 | ||
@@ -329,7 +298,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
329 | zfcp_get_busid_by_adapter(adapter), | 298 | zfcp_get_busid_by_adapter(adapter), |
330 | prot_status_qual->version_error.fsf_version, | 299 | prot_status_qual->version_error.fsf_version, |
331 | ZFCP_QTCB_VERSION); | 300 | ZFCP_QTCB_VERSION); |
332 | zfcp_erp_adapter_shutdown(adapter, 0); | 301 | zfcp_erp_adapter_shutdown(adapter, 0, 117, fsf_req); |
333 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 302 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
334 | break; | 303 | break; |
335 | 304 | ||
@@ -340,7 +309,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
340 | qtcb->prefix.req_seq_no, | 309 | qtcb->prefix.req_seq_no, |
341 | zfcp_get_busid_by_adapter(adapter), | 310 | zfcp_get_busid_by_adapter(adapter), |
342 | prot_status_qual->sequence_error.exp_req_seq_no); | 311 | prot_status_qual->sequence_error.exp_req_seq_no); |
343 | zfcp_erp_adapter_reopen(adapter, 0); | 312 | zfcp_erp_adapter_reopen(adapter, 0, 98, fsf_req); |
344 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; | 313 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; |
345 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 314 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
346 | break; | 315 | break; |
@@ -351,7 +320,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
351 | "that used on adapter %s. " | 320 | "that used on adapter %s. " |
352 | "Stopping all operations on this adapter.\n", | 321 | "Stopping all operations on this adapter.\n", |
353 | zfcp_get_busid_by_adapter(adapter)); | 322 | zfcp_get_busid_by_adapter(adapter)); |
354 | zfcp_erp_adapter_shutdown(adapter, 0); | 323 | zfcp_erp_adapter_shutdown(adapter, 0, 118, fsf_req); |
355 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 324 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
356 | break; | 325 | break; |
357 | 326 | ||
@@ -368,14 +337,15 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
368 | *(unsigned long long*) | 337 | *(unsigned long long*) |
369 | (&qtcb->bottom.support.req_handle), | 338 | (&qtcb->bottom.support.req_handle), |
370 | zfcp_get_busid_by_adapter(adapter)); | 339 | zfcp_get_busid_by_adapter(adapter)); |
371 | zfcp_erp_adapter_shutdown(adapter, 0); | 340 | zfcp_erp_adapter_shutdown(adapter, 0, 78, fsf_req); |
372 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 341 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
373 | break; | 342 | break; |
374 | 343 | ||
375 | case FSF_PROT_LINK_DOWN: | 344 | case FSF_PROT_LINK_DOWN: |
376 | zfcp_fsf_link_down_info_eval(adapter, | 345 | zfcp_fsf_link_down_info_eval(fsf_req, 37, |
377 | &prot_status_qual->link_down_info); | 346 | &prot_status_qual->link_down_info); |
378 | zfcp_erp_adapter_reopen(adapter, 0); | 347 | /* FIXME: reopening adapter now? better wait for link up */ |
348 | zfcp_erp_adapter_reopen(adapter, 0, 79, fsf_req); | ||
379 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 349 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
380 | break; | 350 | break; |
381 | 351 | ||
@@ -385,12 +355,13 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
385 | "Re-starting operations on this adapter.\n", | 355 | "Re-starting operations on this adapter.\n", |
386 | zfcp_get_busid_by_adapter(adapter)); | 356 | zfcp_get_busid_by_adapter(adapter)); |
387 | /* All ports should be marked as ready to run again */ | 357 | /* All ports should be marked as ready to run again */ |
388 | zfcp_erp_modify_adapter_status(adapter, | 358 | zfcp_erp_modify_adapter_status(adapter, 28, NULL, |
389 | ZFCP_STATUS_COMMON_RUNNING, | 359 | ZFCP_STATUS_COMMON_RUNNING, |
390 | ZFCP_SET); | 360 | ZFCP_SET); |
391 | zfcp_erp_adapter_reopen(adapter, | 361 | zfcp_erp_adapter_reopen(adapter, |
392 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | 362 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
393 | | ZFCP_STATUS_COMMON_ERP_FAILED); | 363 | | ZFCP_STATUS_COMMON_ERP_FAILED, |
364 | 99, fsf_req); | ||
394 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 365 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
395 | break; | 366 | break; |
396 | 367 | ||
@@ -400,7 +371,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
400 | "Restarting all operations on this " | 371 | "Restarting all operations on this " |
401 | "adapter.\n", | 372 | "adapter.\n", |
402 | zfcp_get_busid_by_adapter(adapter)); | 373 | zfcp_get_busid_by_adapter(adapter)); |
403 | zfcp_erp_adapter_reopen(adapter, 0); | 374 | zfcp_erp_adapter_reopen(adapter, 0, 100, fsf_req); |
404 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; | 375 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; |
405 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 376 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
406 | break; | 377 | break; |
@@ -413,7 +384,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
413 | "(debug info 0x%x).\n", | 384 | "(debug info 0x%x).\n", |
414 | zfcp_get_busid_by_adapter(adapter), | 385 | zfcp_get_busid_by_adapter(adapter), |
415 | qtcb->prefix.prot_status); | 386 | qtcb->prefix.prot_status); |
416 | zfcp_erp_adapter_shutdown(adapter, 0); | 387 | zfcp_erp_adapter_shutdown(adapter, 0, 119, fsf_req); |
417 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 388 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
418 | } | 389 | } |
419 | 390 | ||
@@ -452,7 +423,7 @@ zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
452 | "(debug info 0x%x).\n", | 423 | "(debug info 0x%x).\n", |
453 | zfcp_get_busid_by_adapter(fsf_req->adapter), | 424 | zfcp_get_busid_by_adapter(fsf_req->adapter), |
454 | fsf_req->qtcb->header.fsf_command); | 425 | fsf_req->qtcb->header.fsf_command); |
455 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); | 426 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0, 120, fsf_req); |
456 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 427 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
457 | break; | 428 | break; |
458 | 429 | ||
@@ -506,7 +477,7 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) | |||
506 | "problem on the adapter %s " | 477 | "problem on the adapter %s " |
507 | "Stopping all operations on this adapter. ", | 478 | "Stopping all operations on this adapter. ", |
508 | zfcp_get_busid_by_adapter(fsf_req->adapter)); | 479 | zfcp_get_busid_by_adapter(fsf_req->adapter)); |
509 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); | 480 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0, 121, fsf_req); |
510 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 481 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
511 | break; | 482 | break; |
512 | case FSF_SQ_ULP_PROGRAMMING_ERROR: | 483 | case FSF_SQ_ULP_PROGRAMMING_ERROR: |
@@ -537,9 +508,11 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) | |||
537 | * zfcp_fsf_link_down_info_eval - evaluate link down information block | 508 | * zfcp_fsf_link_down_info_eval - evaluate link down information block |
538 | */ | 509 | */ |
539 | static void | 510 | static void |
540 | zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, | 511 | zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *fsf_req, u8 id, |
541 | struct fsf_link_down_info *link_down) | 512 | struct fsf_link_down_info *link_down) |
542 | { | 513 | { |
514 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
515 | |||
543 | if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | 516 | if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, |
544 | &adapter->status)) | 517 | &adapter->status)) |
545 | return; | 518 | return; |
@@ -630,7 +603,7 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, | |||
630 | link_down->vendor_specific_code); | 603 | link_down->vendor_specific_code); |
631 | 604 | ||
632 | out: | 605 | out: |
633 | zfcp_erp_adapter_failed(adapter); | 606 | zfcp_erp_adapter_failed(adapter, id, fsf_req); |
634 | } | 607 | } |
635 | 608 | ||
636 | /* | 609 | /* |
@@ -824,19 +797,14 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) | |||
824 | switch (status_buffer->status_subtype) { | 797 | switch (status_buffer->status_subtype) { |
825 | 798 | ||
826 | case FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT: | 799 | case FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT: |
827 | debug_text_event(adapter->erp_dbf, 3, "unsol_pc_phys:"); | 800 | zfcp_erp_port_reopen(port, 0, 101, fsf_req); |
828 | zfcp_erp_port_reopen(port, 0); | ||
829 | break; | 801 | break; |
830 | 802 | ||
831 | case FSF_STATUS_READ_SUB_ERROR_PORT: | 803 | case FSF_STATUS_READ_SUB_ERROR_PORT: |
832 | debug_text_event(adapter->erp_dbf, 1, "unsol_pc_err:"); | 804 | zfcp_erp_port_shutdown(port, 0, 122, fsf_req); |
833 | zfcp_erp_port_shutdown(port, 0); | ||
834 | break; | 805 | break; |
835 | 806 | ||
836 | default: | 807 | default: |
837 | debug_text_event(adapter->erp_dbf, 0, "unsol_unk_sub:"); | ||
838 | debug_exception(adapter->erp_dbf, 0, | ||
839 | &status_buffer->status_subtype, sizeof (u32)); | ||
840 | ZFCP_LOG_NORMAL("bug: Undefined status subtype received " | 808 | ZFCP_LOG_NORMAL("bug: Undefined status subtype received " |
841 | "for a reopen indication on port with " | 809 | "for a reopen indication on port with " |
842 | "d_id 0x%06x on the adapter %s. " | 810 | "d_id 0x%06x on the adapter %s. " |
@@ -928,7 +896,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
928 | case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: | 896 | case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: |
929 | ZFCP_LOG_INFO("Physical link to adapter %s is down\n", | 897 | ZFCP_LOG_INFO("Physical link to adapter %s is down\n", |
930 | zfcp_get_busid_by_adapter(adapter)); | 898 | zfcp_get_busid_by_adapter(adapter)); |
931 | zfcp_fsf_link_down_info_eval(adapter, | 899 | zfcp_fsf_link_down_info_eval(fsf_req, 38, |
932 | (struct fsf_link_down_info *) | 900 | (struct fsf_link_down_info *) |
933 | &status_buffer->payload); | 901 | &status_buffer->payload); |
934 | break; | 902 | break; |
@@ -936,7 +904,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
936 | ZFCP_LOG_INFO("Local link to adapter %s is down " | 904 | ZFCP_LOG_INFO("Local link to adapter %s is down " |
937 | "due to failed FDISC login\n", | 905 | "due to failed FDISC login\n", |
938 | zfcp_get_busid_by_adapter(adapter)); | 906 | zfcp_get_busid_by_adapter(adapter)); |
939 | zfcp_fsf_link_down_info_eval(adapter, | 907 | zfcp_fsf_link_down_info_eval(fsf_req, 39, |
940 | (struct fsf_link_down_info *) | 908 | (struct fsf_link_down_info *) |
941 | &status_buffer->payload); | 909 | &status_buffer->payload); |
942 | break; | 910 | break; |
@@ -944,13 +912,13 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
944 | ZFCP_LOG_INFO("Local link to adapter %s is down " | 912 | ZFCP_LOG_INFO("Local link to adapter %s is down " |
945 | "due to firmware update on adapter\n", | 913 | "due to firmware update on adapter\n", |
946 | zfcp_get_busid_by_adapter(adapter)); | 914 | zfcp_get_busid_by_adapter(adapter)); |
947 | zfcp_fsf_link_down_info_eval(adapter, NULL); | 915 | zfcp_fsf_link_down_info_eval(fsf_req, 40, NULL); |
948 | break; | 916 | break; |
949 | default: | 917 | default: |
950 | ZFCP_LOG_INFO("Local link to adapter %s is down " | 918 | ZFCP_LOG_INFO("Local link to adapter %s is down " |
951 | "due to unknown reason\n", | 919 | "due to unknown reason\n", |
952 | zfcp_get_busid_by_adapter(adapter)); | 920 | zfcp_get_busid_by_adapter(adapter)); |
953 | zfcp_fsf_link_down_info_eval(adapter, NULL); | 921 | zfcp_fsf_link_down_info_eval(fsf_req, 41, NULL); |
954 | }; | 922 | }; |
955 | break; | 923 | break; |
956 | 924 | ||
@@ -959,12 +927,13 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
959 | "Restarting operations on this adapter\n", | 927 | "Restarting operations on this adapter\n", |
960 | zfcp_get_busid_by_adapter(adapter)); | 928 | zfcp_get_busid_by_adapter(adapter)); |
961 | /* All ports should be marked as ready to run again */ | 929 | /* All ports should be marked as ready to run again */ |
962 | zfcp_erp_modify_adapter_status(adapter, | 930 | zfcp_erp_modify_adapter_status(adapter, 30, NULL, |
963 | ZFCP_STATUS_COMMON_RUNNING, | 931 | ZFCP_STATUS_COMMON_RUNNING, |
964 | ZFCP_SET); | 932 | ZFCP_SET); |
965 | zfcp_erp_adapter_reopen(adapter, | 933 | zfcp_erp_adapter_reopen(adapter, |
966 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | 934 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
967 | | ZFCP_STATUS_COMMON_ERP_FAILED); | 935 | | ZFCP_STATUS_COMMON_ERP_FAILED, |
936 | 102, fsf_req); | ||
968 | break; | 937 | break; |
969 | 938 | ||
970 | case FSF_STATUS_READ_NOTIFICATION_LOST: | 939 | case FSF_STATUS_READ_NOTIFICATION_LOST: |
@@ -998,13 +967,13 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
998 | 967 | ||
999 | if (status_buffer->status_subtype & | 968 | if (status_buffer->status_subtype & |
1000 | FSF_STATUS_READ_SUB_ACT_UPDATED) | 969 | FSF_STATUS_READ_SUB_ACT_UPDATED) |
1001 | zfcp_erp_adapter_access_changed(adapter); | 970 | zfcp_erp_adapter_access_changed(adapter, 135, fsf_req); |
1002 | break; | 971 | break; |
1003 | 972 | ||
1004 | case FSF_STATUS_READ_CFDC_UPDATED: | 973 | case FSF_STATUS_READ_CFDC_UPDATED: |
1005 | ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n", | 974 | ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n", |
1006 | zfcp_get_busid_by_adapter(adapter)); | 975 | zfcp_get_busid_by_adapter(adapter)); |
1007 | zfcp_erp_adapter_access_changed(adapter); | 976 | zfcp_erp_adapter_access_changed(adapter, 136, fsf_req); |
1008 | break; | 977 | break; |
1009 | 978 | ||
1010 | case FSF_STATUS_READ_CFDC_HARDENED: | 979 | case FSF_STATUS_READ_CFDC_HARDENED: |
@@ -1025,7 +994,6 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
1025 | break; | 994 | break; |
1026 | 995 | ||
1027 | case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: | 996 | case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: |
1028 | debug_text_event(adapter->erp_dbf, 2, "unsol_features:"); | ||
1029 | ZFCP_LOG_INFO("List of supported features on adapter %s has " | 997 | ZFCP_LOG_INFO("List of supported features on adapter %s has " |
1030 | "been changed from 0x%08X to 0x%08X\n", | 998 | "been changed from 0x%08X to 0x%08X\n", |
1031 | zfcp_get_busid_by_adapter(adapter), | 999 | zfcp_get_busid_by_adapter(adapter), |
@@ -1073,7 +1041,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
1073 | ZFCP_LOG_INFO("restart adapter %s due to status read " | 1041 | ZFCP_LOG_INFO("restart adapter %s due to status read " |
1074 | "buffer shortage\n", | 1042 | "buffer shortage\n", |
1075 | zfcp_get_busid_by_adapter(adapter)); | 1043 | zfcp_get_busid_by_adapter(adapter)); |
1076 | zfcp_erp_adapter_reopen(adapter, 0); | 1044 | zfcp_erp_adapter_reopen(adapter, 0, 103, fsf_req); |
1077 | } | 1045 | } |
1078 | } | 1046 | } |
1079 | out: | 1047 | out: |
@@ -1174,8 +1142,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) | |||
1174 | 1142 | ||
1175 | case FSF_PORT_HANDLE_NOT_VALID: | 1143 | case FSF_PORT_HANDLE_NOT_VALID: |
1176 | if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) { | 1144 | if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) { |
1177 | debug_text_event(new_fsf_req->adapter->erp_dbf, 3, | ||
1178 | "fsf_s_phand_nv0"); | ||
1179 | /* | 1145 | /* |
1180 | * In this case a command that was sent prior to a port | 1146 | * In this case a command that was sent prior to a port |
1181 | * reopen was aborted (handles are different). This is | 1147 | * reopen was aborted (handles are different). This is |
@@ -1194,17 +1160,14 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) | |||
1194 | fsf_status_qual, | 1160 | fsf_status_qual, |
1195 | sizeof (union fsf_status_qual)); | 1161 | sizeof (union fsf_status_qual)); |
1196 | /* Let's hope this sorts out the mess */ | 1162 | /* Let's hope this sorts out the mess */ |
1197 | debug_text_event(new_fsf_req->adapter->erp_dbf, 1, | 1163 | zfcp_erp_adapter_reopen(unit->port->adapter, 0, 104, |
1198 | "fsf_s_phand_nv1"); | 1164 | new_fsf_req); |
1199 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); | ||
1200 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1165 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1201 | } | 1166 | } |
1202 | break; | 1167 | break; |
1203 | 1168 | ||
1204 | case FSF_LUN_HANDLE_NOT_VALID: | 1169 | case FSF_LUN_HANDLE_NOT_VALID: |
1205 | if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) { | 1170 | if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) { |
1206 | debug_text_event(new_fsf_req->adapter->erp_dbf, 3, | ||
1207 | "fsf_s_lhand_nv0"); | ||
1208 | /* | 1171 | /* |
1209 | * In this case a command that was sent prior to a unit | 1172 | * In this case a command that was sent prior to a unit |
1210 | * reopen was aborted (handles are different). | 1173 | * reopen was aborted (handles are different). |
@@ -1226,17 +1189,13 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) | |||
1226 | fsf_status_qual, | 1189 | fsf_status_qual, |
1227 | sizeof (union fsf_status_qual)); | 1190 | sizeof (union fsf_status_qual)); |
1228 | /* Let's hope this sorts out the mess */ | 1191 | /* Let's hope this sorts out the mess */ |
1229 | debug_text_event(new_fsf_req->adapter->erp_dbf, 1, | 1192 | zfcp_erp_port_reopen(unit->port, 0, 105, new_fsf_req); |
1230 | "fsf_s_lhand_nv1"); | ||
1231 | zfcp_erp_port_reopen(unit->port, 0); | ||
1232 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1193 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1233 | } | 1194 | } |
1234 | break; | 1195 | break; |
1235 | 1196 | ||
1236 | case FSF_FCP_COMMAND_DOES_NOT_EXIST: | 1197 | case FSF_FCP_COMMAND_DOES_NOT_EXIST: |
1237 | retval = 0; | 1198 | retval = 0; |
1238 | debug_text_event(new_fsf_req->adapter->erp_dbf, 3, | ||
1239 | "fsf_s_no_exist"); | ||
1240 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED; | 1199 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED; |
1241 | break; | 1200 | break; |
1242 | 1201 | ||
@@ -1244,9 +1203,7 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) | |||
1244 | ZFCP_LOG_INFO("Remote port 0x%016Lx on adapter %s needs to " | 1203 | ZFCP_LOG_INFO("Remote port 0x%016Lx on adapter %s needs to " |
1245 | "be reopened\n", unit->port->wwpn, | 1204 | "be reopened\n", unit->port->wwpn, |
1246 | zfcp_get_busid_by_unit(unit)); | 1205 | zfcp_get_busid_by_unit(unit)); |
1247 | debug_text_event(new_fsf_req->adapter->erp_dbf, 2, | 1206 | zfcp_erp_port_boxed(unit->port, 47, new_fsf_req); |
1248 | "fsf_s_pboxed"); | ||
1249 | zfcp_erp_port_boxed(unit->port); | ||
1250 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | 1207 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
1251 | | ZFCP_STATUS_FSFREQ_RETRY; | 1208 | | ZFCP_STATUS_FSFREQ_RETRY; |
1252 | break; | 1209 | break; |
@@ -1257,8 +1214,7 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) | |||
1257 | "to be reopened\n", | 1214 | "to be reopened\n", |
1258 | unit->fcp_lun, unit->port->wwpn, | 1215 | unit->fcp_lun, unit->port->wwpn, |
1259 | zfcp_get_busid_by_unit(unit)); | 1216 | zfcp_get_busid_by_unit(unit)); |
1260 | debug_text_event(new_fsf_req->adapter->erp_dbf, 1, "fsf_s_lboxed"); | 1217 | zfcp_erp_unit_boxed(unit, 48, new_fsf_req); |
1261 | zfcp_erp_unit_boxed(unit); | ||
1262 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | 1218 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
1263 | | ZFCP_STATUS_FSFREQ_RETRY; | 1219 | | ZFCP_STATUS_FSFREQ_RETRY; |
1264 | break; | 1220 | break; |
@@ -1266,26 +1222,17 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) | |||
1266 | case FSF_ADAPTER_STATUS_AVAILABLE: | 1222 | case FSF_ADAPTER_STATUS_AVAILABLE: |
1267 | switch (new_fsf_req->qtcb->header.fsf_status_qual.word[0]) { | 1223 | switch (new_fsf_req->qtcb->header.fsf_status_qual.word[0]) { |
1268 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 1224 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
1269 | debug_text_event(new_fsf_req->adapter->erp_dbf, 1, | ||
1270 | "fsf_sq_ltest"); | ||
1271 | zfcp_test_link(unit->port); | 1225 | zfcp_test_link(unit->port); |
1272 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1226 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1273 | break; | 1227 | break; |
1274 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 1228 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
1275 | /* SCSI stack will escalate */ | 1229 | /* SCSI stack will escalate */ |
1276 | debug_text_event(new_fsf_req->adapter->erp_dbf, 1, | ||
1277 | "fsf_sq_ulp"); | ||
1278 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1230 | new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1279 | break; | 1231 | break; |
1280 | default: | 1232 | default: |
1281 | ZFCP_LOG_NORMAL | 1233 | ZFCP_LOG_NORMAL |
1282 | ("bug: Wrong status qualifier 0x%x arrived.\n", | 1234 | ("bug: Wrong status qualifier 0x%x arrived.\n", |
1283 | new_fsf_req->qtcb->header.fsf_status_qual.word[0]); | 1235 | new_fsf_req->qtcb->header.fsf_status_qual.word[0]); |
1284 | debug_text_event(new_fsf_req->adapter->erp_dbf, 0, | ||
1285 | "fsf_sq_inval:"); | ||
1286 | debug_exception(new_fsf_req->adapter->erp_dbf, 0, | ||
1287 | &new_fsf_req->qtcb->header. | ||
1288 | fsf_status_qual.word[0], sizeof (u32)); | ||
1289 | break; | 1236 | break; |
1290 | } | 1237 | } |
1291 | break; | 1238 | break; |
@@ -1299,11 +1246,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) | |||
1299 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " | 1246 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " |
1300 | "(debug info 0x%x)\n", | 1247 | "(debug info 0x%x)\n", |
1301 | new_fsf_req->qtcb->header.fsf_status); | 1248 | new_fsf_req->qtcb->header.fsf_status); |
1302 | debug_text_event(new_fsf_req->adapter->erp_dbf, 0, | ||
1303 | "fsf_s_inval:"); | ||
1304 | debug_exception(new_fsf_req->adapter->erp_dbf, 0, | ||
1305 | &new_fsf_req->qtcb->header.fsf_status, | ||
1306 | sizeof (u32)); | ||
1307 | break; | 1249 | break; |
1308 | } | 1250 | } |
1309 | skip_fsfstatus: | 1251 | skip_fsfstatus: |
@@ -1506,8 +1448,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1506 | zfcp_get_busid_by_port(port), | 1448 | zfcp_get_busid_by_port(port), |
1507 | ZFCP_FC_SERVICE_CLASS_DEFAULT); | 1449 | ZFCP_FC_SERVICE_CLASS_DEFAULT); |
1508 | /* stop operation for this adapter */ | 1450 | /* stop operation for this adapter */ |
1509 | debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup"); | 1451 | zfcp_erp_adapter_shutdown(adapter, 0, 123, fsf_req); |
1510 | zfcp_erp_adapter_shutdown(adapter, 0); | ||
1511 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1452 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1512 | break; | 1453 | break; |
1513 | 1454 | ||
@@ -1515,13 +1456,11 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1515 | switch (header->fsf_status_qual.word[0]){ | 1456 | switch (header->fsf_status_qual.word[0]){ |
1516 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 1457 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
1517 | /* reopening link to port */ | 1458 | /* reopening link to port */ |
1518 | debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ltest"); | ||
1519 | zfcp_test_link(port); | 1459 | zfcp_test_link(port); |
1520 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1460 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1521 | break; | 1461 | break; |
1522 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 1462 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
1523 | /* ERP strategy will escalate */ | 1463 | /* ERP strategy will escalate */ |
1524 | debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ulp"); | ||
1525 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1464 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1526 | break; | 1465 | break; |
1527 | default: | 1466 | default: |
@@ -1549,8 +1488,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1549 | break; | 1488 | break; |
1550 | } | 1489 | } |
1551 | } | 1490 | } |
1552 | debug_text_event(adapter->erp_dbf, 1, "fsf_s_access"); | 1491 | zfcp_erp_port_access_denied(port, 55, fsf_req); |
1553 | zfcp_erp_port_access_denied(port); | ||
1554 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1492 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1555 | break; | 1493 | break; |
1556 | 1494 | ||
@@ -1562,7 +1500,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1562 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, | 1500 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, |
1563 | (char *) &header->fsf_status_qual, | 1501 | (char *) &header->fsf_status_qual, |
1564 | sizeof (union fsf_status_qual)); | 1502 | sizeof (union fsf_status_qual)); |
1565 | debug_text_event(adapter->erp_dbf, 1, "fsf_s_gcom_rej"); | ||
1566 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1503 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1567 | break; | 1504 | break; |
1568 | 1505 | ||
@@ -1575,8 +1512,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1575 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, | 1512 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO, |
1576 | (char *) &header->fsf_status_qual, | 1513 | (char *) &header->fsf_status_qual, |
1577 | sizeof (union fsf_status_qual)); | 1514 | sizeof (union fsf_status_qual)); |
1578 | debug_text_event(adapter->erp_dbf, 1, "fsf_s_phandle_nv"); | 1515 | zfcp_erp_adapter_reopen(adapter, 0, 106, fsf_req); |
1579 | zfcp_erp_adapter_reopen(adapter, 0); | ||
1580 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1516 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1581 | break; | 1517 | break; |
1582 | 1518 | ||
@@ -1584,8 +1520,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1584 | ZFCP_LOG_INFO("port needs to be reopened " | 1520 | ZFCP_LOG_INFO("port needs to be reopened " |
1585 | "(adapter %s, port d_id=0x%06x)\n", | 1521 | "(adapter %s, port d_id=0x%06x)\n", |
1586 | zfcp_get_busid_by_port(port), port->d_id); | 1522 | zfcp_get_busid_by_port(port), port->d_id); |
1587 | debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed"); | 1523 | zfcp_erp_port_boxed(port, 49, fsf_req); |
1588 | zfcp_erp_port_boxed(port); | ||
1589 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | 1524 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
1590 | | ZFCP_STATUS_FSFREQ_RETRY; | 1525 | | ZFCP_STATUS_FSFREQ_RETRY; |
1591 | break; | 1526 | break; |
@@ -1624,9 +1559,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1624 | default: | 1559 | default: |
1625 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " | 1560 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " |
1626 | "(debug info 0x%x)\n", header->fsf_status); | 1561 | "(debug info 0x%x)\n", header->fsf_status); |
1627 | debug_text_event(adapter->erp_dbf, 0, "fsf_sq_inval:"); | ||
1628 | debug_exception(adapter->erp_dbf, 0, | ||
1629 | &header->fsf_status_qual.word[0], sizeof (u32)); | ||
1630 | break; | 1562 | break; |
1631 | } | 1563 | } |
1632 | 1564 | ||
@@ -1810,21 +1742,18 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) | |||
1810 | zfcp_get_busid_by_adapter(adapter), | 1742 | zfcp_get_busid_by_adapter(adapter), |
1811 | ZFCP_FC_SERVICE_CLASS_DEFAULT); | 1743 | ZFCP_FC_SERVICE_CLASS_DEFAULT); |
1812 | /* stop operation for this adapter */ | 1744 | /* stop operation for this adapter */ |
1813 | debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup"); | 1745 | zfcp_erp_adapter_shutdown(adapter, 0, 124, fsf_req); |
1814 | zfcp_erp_adapter_shutdown(adapter, 0); | ||
1815 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1746 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1816 | break; | 1747 | break; |
1817 | 1748 | ||
1818 | case FSF_ADAPTER_STATUS_AVAILABLE: | 1749 | case FSF_ADAPTER_STATUS_AVAILABLE: |
1819 | switch (header->fsf_status_qual.word[0]){ | 1750 | switch (header->fsf_status_qual.word[0]){ |
1820 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 1751 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
1821 | debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ltest"); | ||
1822 | if (port && (send_els->ls_code != ZFCP_LS_ADISC)) | 1752 | if (port && (send_els->ls_code != ZFCP_LS_ADISC)) |
1823 | zfcp_test_link(port); | 1753 | zfcp_test_link(port); |
1824 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1754 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1825 | break; | 1755 | break; |
1826 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 1756 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
1827 | debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ulp"); | ||
1828 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1757 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1829 | retval = | 1758 | retval = |
1830 | zfcp_handle_els_rjt(header->fsf_status_qual.word[1], | 1759 | zfcp_handle_els_rjt(header->fsf_status_qual.word[1], |
@@ -1832,7 +1761,6 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) | |||
1832 | &header->fsf_status_qual.word[2]); | 1761 | &header->fsf_status_qual.word[2]); |
1833 | break; | 1762 | break; |
1834 | case FSF_SQ_RETRY_IF_POSSIBLE: | 1763 | case FSF_SQ_RETRY_IF_POSSIBLE: |
1835 | debug_text_event(adapter->erp_dbf, 1, "fsf_sq_retry"); | ||
1836 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1764 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1837 | break; | 1765 | break; |
1838 | default: | 1766 | default: |
@@ -1909,9 +1837,8 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) | |||
1909 | break; | 1837 | break; |
1910 | } | 1838 | } |
1911 | } | 1839 | } |
1912 | debug_text_event(adapter->erp_dbf, 1, "fsf_s_access"); | ||
1913 | if (port != NULL) | 1840 | if (port != NULL) |
1914 | zfcp_erp_port_access_denied(port); | 1841 | zfcp_erp_port_access_denied(port, 56, fsf_req); |
1915 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1842 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1916 | break; | 1843 | break; |
1917 | 1844 | ||
@@ -1921,9 +1848,6 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) | |||
1921 | "(adapter: %s, fsf_status=0x%08x)\n", | 1848 | "(adapter: %s, fsf_status=0x%08x)\n", |
1922 | zfcp_get_busid_by_adapter(adapter), | 1849 | zfcp_get_busid_by_adapter(adapter), |
1923 | header->fsf_status); | 1850 | header->fsf_status); |
1924 | debug_text_event(adapter->erp_dbf, 0, "fsf_sq_inval"); | ||
1925 | debug_exception(adapter->erp_dbf, 0, | ||
1926 | &header->fsf_status_qual.word[0], sizeof(u32)); | ||
1927 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 1851 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
1928 | break; | 1852 | break; |
1929 | } | 1853 | } |
@@ -2132,8 +2056,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
2132 | "versions in comparison to this device " | 2056 | "versions in comparison to this device " |
2133 | "driver (try updated device driver)\n", | 2057 | "driver (try updated device driver)\n", |
2134 | zfcp_get_busid_by_adapter(adapter)); | 2058 | zfcp_get_busid_by_adapter(adapter)); |
2135 | debug_text_event(adapter->erp_dbf, 0, "low_qtcb_ver"); | 2059 | zfcp_erp_adapter_shutdown(adapter, 0, 125, fsf_req); |
2136 | zfcp_erp_adapter_shutdown(adapter, 0); | ||
2137 | return -EIO; | 2060 | return -EIO; |
2138 | } | 2061 | } |
2139 | if (ZFCP_QTCB_VERSION > bottom->high_qtcb_version) { | 2062 | if (ZFCP_QTCB_VERSION > bottom->high_qtcb_version) { |
@@ -2142,8 +2065,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
2142 | "versions than this device driver uses" | 2065 | "versions than this device driver uses" |
2143 | "(consider a microcode upgrade)\n", | 2066 | "(consider a microcode upgrade)\n", |
2144 | zfcp_get_busid_by_adapter(adapter)); | 2067 | zfcp_get_busid_by_adapter(adapter)); |
2145 | debug_text_event(adapter->erp_dbf, 0, "high_qtcb_ver"); | 2068 | zfcp_erp_adapter_shutdown(adapter, 0, 126, fsf_req); |
2146 | zfcp_erp_adapter_shutdown(adapter, 0); | ||
2147 | return -EIO; | 2069 | return -EIO; |
2148 | } | 2070 | } |
2149 | return 0; | 2071 | return 0; |
@@ -2183,17 +2105,13 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2183 | adapter->peer_wwnn, | 2105 | adapter->peer_wwnn, |
2184 | adapter->peer_wwpn, | 2106 | adapter->peer_wwpn, |
2185 | adapter->peer_d_id); | 2107 | adapter->peer_d_id); |
2186 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | ||
2187 | "top-p-to-p"); | ||
2188 | break; | 2108 | break; |
2189 | case FC_PORTTYPE_NLPORT: | 2109 | case FC_PORTTYPE_NLPORT: |
2190 | ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel " | 2110 | ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel " |
2191 | "topology detected at adapter %s " | 2111 | "topology detected at adapter %s " |
2192 | "unsupported, shutting down adapter\n", | 2112 | "unsupported, shutting down adapter\n", |
2193 | zfcp_get_busid_by_adapter(adapter)); | 2113 | zfcp_get_busid_by_adapter(adapter)); |
2194 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | 2114 | zfcp_erp_adapter_shutdown(adapter, 0, 127, fsf_req); |
2195 | "top-al"); | ||
2196 | zfcp_erp_adapter_shutdown(adapter, 0); | ||
2197 | return -EIO; | 2115 | return -EIO; |
2198 | case FC_PORTTYPE_NPORT: | 2116 | case FC_PORTTYPE_NPORT: |
2199 | ZFCP_LOG_NORMAL("Switched fabric fibrechannel " | 2117 | ZFCP_LOG_NORMAL("Switched fabric fibrechannel " |
@@ -2208,9 +2126,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2208 | "of a type known to the zfcp " | 2126 | "of a type known to the zfcp " |
2209 | "driver, shutting down adapter\n", | 2127 | "driver, shutting down adapter\n", |
2210 | zfcp_get_busid_by_adapter(adapter)); | 2128 | zfcp_get_busid_by_adapter(adapter)); |
2211 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | 2129 | zfcp_erp_adapter_shutdown(adapter, 0, 128, fsf_req); |
2212 | "unknown-topo"); | ||
2213 | zfcp_erp_adapter_shutdown(adapter, 0); | ||
2214 | return -EIO; | 2130 | return -EIO; |
2215 | } | 2131 | } |
2216 | bottom = &qtcb->bottom.config; | 2132 | bottom = &qtcb->bottom.config; |
@@ -2222,33 +2138,24 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2222 | bottom->max_qtcb_size, | 2138 | bottom->max_qtcb_size, |
2223 | zfcp_get_busid_by_adapter(adapter), | 2139 | zfcp_get_busid_by_adapter(adapter), |
2224 | sizeof(struct fsf_qtcb)); | 2140 | sizeof(struct fsf_qtcb)); |
2225 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | 2141 | zfcp_erp_adapter_shutdown(adapter, 0, 129, fsf_req); |
2226 | "qtcb-size"); | ||
2227 | debug_event(fsf_req->adapter->erp_dbf, 0, | ||
2228 | &bottom->max_qtcb_size, sizeof (u32)); | ||
2229 | zfcp_erp_adapter_shutdown(adapter, 0); | ||
2230 | return -EIO; | 2142 | return -EIO; |
2231 | } | 2143 | } |
2232 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, | 2144 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, |
2233 | &adapter->status); | 2145 | &adapter->status); |
2234 | break; | 2146 | break; |
2235 | case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: | 2147 | case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: |
2236 | debug_text_event(adapter->erp_dbf, 0, "xchg-inco"); | ||
2237 | |||
2238 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) | 2148 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) |
2239 | return -EIO; | 2149 | return -EIO; |
2240 | 2150 | ||
2241 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, | 2151 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, |
2242 | &adapter->status); | 2152 | &adapter->status); |
2243 | 2153 | ||
2244 | zfcp_fsf_link_down_info_eval(adapter, | 2154 | zfcp_fsf_link_down_info_eval(fsf_req, 42, |
2245 | &qtcb->header.fsf_status_qual.link_down_info); | 2155 | &qtcb->header.fsf_status_qual.link_down_info); |
2246 | break; | 2156 | break; |
2247 | default: | 2157 | default: |
2248 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng"); | 2158 | zfcp_erp_adapter_shutdown(adapter, 0, 130, fsf_req); |
2249 | debug_event(fsf_req->adapter->erp_dbf, 0, | ||
2250 | &fsf_req->qtcb->header.fsf_status, sizeof(u32)); | ||
2251 | zfcp_erp_adapter_shutdown(adapter, 0); | ||
2252 | return -EIO; | 2159 | return -EIO; |
2253 | } | 2160 | } |
2254 | return 0; | 2161 | return 0; |
@@ -2424,13 +2331,9 @@ zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2424 | case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: | 2331 | case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: |
2425 | zfcp_fsf_exchange_port_evaluate(fsf_req, 0); | 2332 | zfcp_fsf_exchange_port_evaluate(fsf_req, 0); |
2426 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | 2333 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); |
2427 | zfcp_fsf_link_down_info_eval(adapter, | 2334 | zfcp_fsf_link_down_info_eval(fsf_req, 43, |
2428 | &qtcb->header.fsf_status_qual.link_down_info); | 2335 | &qtcb->header.fsf_status_qual.link_down_info); |
2429 | break; | 2336 | break; |
2430 | default: | ||
2431 | debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng"); | ||
2432 | debug_event(adapter->erp_dbf, 0, | ||
2433 | &fsf_req->qtcb->header.fsf_status, sizeof(u32)); | ||
2434 | } | 2337 | } |
2435 | } | 2338 | } |
2436 | 2339 | ||
@@ -2528,8 +2431,6 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2528 | ZFCP_LOG_NORMAL("bug: remote port 0x%016Lx on adapter %s " | 2431 | ZFCP_LOG_NORMAL("bug: remote port 0x%016Lx on adapter %s " |
2529 | "is already open.\n", | 2432 | "is already open.\n", |
2530 | port->wwpn, zfcp_get_busid_by_port(port)); | 2433 | port->wwpn, zfcp_get_busid_by_port(port)); |
2531 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | ||
2532 | "fsf_s_popen"); | ||
2533 | /* | 2434 | /* |
2534 | * This is a bug, however operation should continue normally | 2435 | * This is a bug, however operation should continue normally |
2535 | * if it is simply ignored | 2436 | * if it is simply ignored |
@@ -2553,8 +2454,7 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2553 | break; | 2454 | break; |
2554 | } | 2455 | } |
2555 | } | 2456 | } |
2556 | debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_access"); | 2457 | zfcp_erp_port_access_denied(port, 57, fsf_req); |
2557 | zfcp_erp_port_access_denied(port); | ||
2558 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2458 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2559 | break; | 2459 | break; |
2560 | 2460 | ||
@@ -2563,24 +2463,18 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2563 | "The remote port 0x%016Lx on adapter %s " | 2463 | "The remote port 0x%016Lx on adapter %s " |
2564 | "could not be opened. Disabling it.\n", | 2464 | "could not be opened. Disabling it.\n", |
2565 | port->wwpn, zfcp_get_busid_by_port(port)); | 2465 | port->wwpn, zfcp_get_busid_by_port(port)); |
2566 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 2466 | zfcp_erp_port_failed(port, 31, fsf_req); |
2567 | "fsf_s_max_ports"); | ||
2568 | zfcp_erp_port_failed(port); | ||
2569 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2467 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2570 | break; | 2468 | break; |
2571 | 2469 | ||
2572 | case FSF_ADAPTER_STATUS_AVAILABLE: | 2470 | case FSF_ADAPTER_STATUS_AVAILABLE: |
2573 | switch (header->fsf_status_qual.word[0]) { | 2471 | switch (header->fsf_status_qual.word[0]) { |
2574 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 2472 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
2575 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | ||
2576 | "fsf_sq_ltest"); | ||
2577 | /* ERP strategy will escalate */ | 2473 | /* ERP strategy will escalate */ |
2578 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2474 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2579 | break; | 2475 | break; |
2580 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 2476 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
2581 | /* ERP strategy will escalate */ | 2477 | /* ERP strategy will escalate */ |
2582 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | ||
2583 | "fsf_sq_ulp"); | ||
2584 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2478 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2585 | break; | 2479 | break; |
2586 | case FSF_SQ_NO_RETRY_POSSIBLE: | 2480 | case FSF_SQ_NO_RETRY_POSSIBLE: |
@@ -2589,21 +2483,13 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2589 | "Disabling it.\n", | 2483 | "Disabling it.\n", |
2590 | port->wwpn, | 2484 | port->wwpn, |
2591 | zfcp_get_busid_by_port(port)); | 2485 | zfcp_get_busid_by_port(port)); |
2592 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | 2486 | zfcp_erp_port_failed(port, 32, fsf_req); |
2593 | "fsf_sq_no_retry"); | ||
2594 | zfcp_erp_port_failed(port); | ||
2595 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2487 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2596 | break; | 2488 | break; |
2597 | default: | 2489 | default: |
2598 | ZFCP_LOG_NORMAL | 2490 | ZFCP_LOG_NORMAL |
2599 | ("bug: Wrong status qualifier 0x%x arrived.\n", | 2491 | ("bug: Wrong status qualifier 0x%x arrived.\n", |
2600 | header->fsf_status_qual.word[0]); | 2492 | header->fsf_status_qual.word[0]); |
2601 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | ||
2602 | "fsf_sq_inval:"); | ||
2603 | debug_exception( | ||
2604 | fsf_req->adapter->erp_dbf, 0, | ||
2605 | &header->fsf_status_qual.word[0], | ||
2606 | sizeof (u32)); | ||
2607 | break; | 2493 | break; |
2608 | } | 2494 | } |
2609 | break; | 2495 | break; |
@@ -2646,17 +2532,12 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2646 | "warning: insufficient length of " | 2532 | "warning: insufficient length of " |
2647 | "PLOGI payload (%i)\n", | 2533 | "PLOGI payload (%i)\n", |
2648 | fsf_req->qtcb->bottom.support.els1_length); | 2534 | fsf_req->qtcb->bottom.support.els1_length); |
2649 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | ||
2650 | "fsf_s_short_plogi:"); | ||
2651 | /* skip sanity check and assume wwpn is ok */ | 2535 | /* skip sanity check and assume wwpn is ok */ |
2652 | } else { | 2536 | } else { |
2653 | if (plogi->serv_param.wwpn != port->wwpn) { | 2537 | if (plogi->serv_param.wwpn != port->wwpn) { |
2654 | ZFCP_LOG_INFO("warning: d_id of port " | 2538 | ZFCP_LOG_INFO("warning: d_id of port " |
2655 | "0x%016Lx changed during " | 2539 | "0x%016Lx changed during " |
2656 | "open\n", port->wwpn); | 2540 | "open\n", port->wwpn); |
2657 | debug_text_event( | ||
2658 | fsf_req->adapter->erp_dbf, 0, | ||
2659 | "fsf_s_did_change:"); | ||
2660 | atomic_clear_mask( | 2541 | atomic_clear_mask( |
2661 | ZFCP_STATUS_PORT_DID_DID, | 2542 | ZFCP_STATUS_PORT_DID_DID, |
2662 | &port->status); | 2543 | &port->status); |
@@ -2681,9 +2562,6 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2681 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " | 2562 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " |
2682 | "(debug info 0x%x)\n", | 2563 | "(debug info 0x%x)\n", |
2683 | header->fsf_status); | 2564 | header->fsf_status); |
2684 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_s_inval:"); | ||
2685 | debug_exception(fsf_req->adapter->erp_dbf, 0, | ||
2686 | &header->fsf_status, sizeof (u32)); | ||
2687 | break; | 2565 | break; |
2688 | } | 2566 | } |
2689 | 2567 | ||
@@ -2787,9 +2665,7 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2787 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 2665 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
2788 | (char *) &fsf_req->qtcb->header.fsf_status_qual, | 2666 | (char *) &fsf_req->qtcb->header.fsf_status_qual, |
2789 | sizeof (union fsf_status_qual)); | 2667 | sizeof (union fsf_status_qual)); |
2790 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 2668 | zfcp_erp_adapter_reopen(port->adapter, 0, 107, fsf_req); |
2791 | "fsf_s_phand_nv"); | ||
2792 | zfcp_erp_adapter_reopen(port->adapter, 0); | ||
2793 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2669 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2794 | break; | 2670 | break; |
2795 | 2671 | ||
@@ -2804,7 +2680,7 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2804 | ZFCP_LOG_TRACE("remote port 0x016%Lx on adapter %s closed, " | 2680 | ZFCP_LOG_TRACE("remote port 0x016%Lx on adapter %s closed, " |
2805 | "port handle 0x%x\n", port->wwpn, | 2681 | "port handle 0x%x\n", port->wwpn, |
2806 | zfcp_get_busid_by_port(port), port->handle); | 2682 | zfcp_get_busid_by_port(port), port->handle); |
2807 | zfcp_erp_modify_port_status(port, | 2683 | zfcp_erp_modify_port_status(port, 33, fsf_req, |
2808 | ZFCP_STATUS_COMMON_OPEN, | 2684 | ZFCP_STATUS_COMMON_OPEN, |
2809 | ZFCP_CLEAR); | 2685 | ZFCP_CLEAR); |
2810 | retval = 0; | 2686 | retval = 0; |
@@ -2814,10 +2690,6 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2814 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " | 2690 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " |
2815 | "(debug info 0x%x)\n", | 2691 | "(debug info 0x%x)\n", |
2816 | fsf_req->qtcb->header.fsf_status); | 2692 | fsf_req->qtcb->header.fsf_status); |
2817 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_s_inval:"); | ||
2818 | debug_exception(fsf_req->adapter->erp_dbf, 0, | ||
2819 | &fsf_req->qtcb->header.fsf_status, | ||
2820 | sizeof (u32)); | ||
2821 | break; | 2693 | break; |
2822 | } | 2694 | } |
2823 | 2695 | ||
@@ -2930,9 +2802,7 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2930 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 2802 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
2931 | (char *) &header->fsf_status_qual, | 2803 | (char *) &header->fsf_status_qual, |
2932 | sizeof (union fsf_status_qual)); | 2804 | sizeof (union fsf_status_qual)); |
2933 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 2805 | zfcp_erp_adapter_reopen(port->adapter, 0, 108, fsf_req); |
2934 | "fsf_s_phand_nv"); | ||
2935 | zfcp_erp_adapter_reopen(port->adapter, 0); | ||
2936 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2806 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2937 | break; | 2807 | break; |
2938 | 2808 | ||
@@ -2953,8 +2823,7 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2953 | break; | 2823 | break; |
2954 | } | 2824 | } |
2955 | } | 2825 | } |
2956 | debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_access"); | 2826 | zfcp_erp_port_access_denied(port, 58, fsf_req); |
2957 | zfcp_erp_port_access_denied(port); | ||
2958 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2827 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2959 | break; | 2828 | break; |
2960 | 2829 | ||
@@ -2964,35 +2833,32 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2964 | "to close it physically.\n", | 2833 | "to close it physically.\n", |
2965 | port->wwpn, | 2834 | port->wwpn, |
2966 | zfcp_get_busid_by_port(port)); | 2835 | zfcp_get_busid_by_port(port)); |
2967 | debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_pboxed"); | 2836 | zfcp_erp_port_boxed(port, 50, fsf_req); |
2968 | zfcp_erp_port_boxed(port); | ||
2969 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 2837 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | |
2970 | ZFCP_STATUS_FSFREQ_RETRY; | 2838 | ZFCP_STATUS_FSFREQ_RETRY; |
2839 | |||
2840 | /* can't use generic zfcp_erp_modify_port_status because | ||
2841 | * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ | ||
2842 | atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); | ||
2843 | list_for_each_entry(unit, &port->unit_list_head, list) | ||
2844 | atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, | ||
2845 | &unit->status); | ||
2971 | break; | 2846 | break; |
2972 | 2847 | ||
2973 | case FSF_ADAPTER_STATUS_AVAILABLE: | 2848 | case FSF_ADAPTER_STATUS_AVAILABLE: |
2974 | switch (header->fsf_status_qual.word[0]) { | 2849 | switch (header->fsf_status_qual.word[0]) { |
2975 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 2850 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
2976 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | ||
2977 | "fsf_sq_ltest"); | ||
2978 | /* This will now be escalated by ERP */ | 2851 | /* This will now be escalated by ERP */ |
2979 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2852 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2980 | break; | 2853 | break; |
2981 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 2854 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
2982 | /* ERP strategy will escalate */ | 2855 | /* ERP strategy will escalate */ |
2983 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | ||
2984 | "fsf_sq_ulp"); | ||
2985 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 2856 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
2986 | break; | 2857 | break; |
2987 | default: | 2858 | default: |
2988 | ZFCP_LOG_NORMAL | 2859 | ZFCP_LOG_NORMAL |
2989 | ("bug: Wrong status qualifier 0x%x arrived.\n", | 2860 | ("bug: Wrong status qualifier 0x%x arrived.\n", |
2990 | header->fsf_status_qual.word[0]); | 2861 | header->fsf_status_qual.word[0]); |
2991 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | ||
2992 | "fsf_sq_inval:"); | ||
2993 | debug_exception( | ||
2994 | fsf_req->adapter->erp_dbf, 0, | ||
2995 | &header->fsf_status_qual.word[0], sizeof (u32)); | ||
2996 | break; | 2862 | break; |
2997 | } | 2863 | } |
2998 | break; | 2864 | break; |
@@ -3015,9 +2881,6 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) | |||
3015 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " | 2881 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " |
3016 | "(debug info 0x%x)\n", | 2882 | "(debug info 0x%x)\n", |
3017 | header->fsf_status); | 2883 | header->fsf_status); |
3018 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_s_inval:"); | ||
3019 | debug_exception(fsf_req->adapter->erp_dbf, 0, | ||
3020 | &header->fsf_status, sizeof (u32)); | ||
3021 | break; | 2884 | break; |
3022 | } | 2885 | } |
3023 | 2886 | ||
@@ -3149,8 +3012,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3149 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 3012 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
3150 | (char *) &header->fsf_status_qual, | 3013 | (char *) &header->fsf_status_qual, |
3151 | sizeof (union fsf_status_qual)); | 3014 | sizeof (union fsf_status_qual)); |
3152 | debug_text_event(adapter->erp_dbf, 1, "fsf_s_ph_nv"); | 3015 | zfcp_erp_adapter_reopen(unit->port->adapter, 0, 109, fsf_req); |
3153 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); | ||
3154 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3016 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3155 | break; | 3017 | break; |
3156 | 3018 | ||
@@ -3159,8 +3021,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3159 | "remote port 0x%016Lx on adapter %s twice.\n", | 3021 | "remote port 0x%016Lx on adapter %s twice.\n", |
3160 | unit->fcp_lun, | 3022 | unit->fcp_lun, |
3161 | unit->port->wwpn, zfcp_get_busid_by_unit(unit)); | 3023 | unit->port->wwpn, zfcp_get_busid_by_unit(unit)); |
3162 | debug_text_exception(adapter->erp_dbf, 0, | ||
3163 | "fsf_s_uopen"); | ||
3164 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3024 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3165 | break; | 3025 | break; |
3166 | 3026 | ||
@@ -3182,8 +3042,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3182 | break; | 3042 | break; |
3183 | } | 3043 | } |
3184 | } | 3044 | } |
3185 | debug_text_event(adapter->erp_dbf, 1, "fsf_s_access"); | 3045 | zfcp_erp_unit_access_denied(unit, 59, fsf_req); |
3186 | zfcp_erp_unit_access_denied(unit); | ||
3187 | atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status); | 3046 | atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status); |
3188 | atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); | 3047 | atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); |
3189 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3048 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
@@ -3193,8 +3052,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3193 | ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s " | 3052 | ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s " |
3194 | "needs to be reopened\n", | 3053 | "needs to be reopened\n", |
3195 | unit->port->wwpn, zfcp_get_busid_by_unit(unit)); | 3054 | unit->port->wwpn, zfcp_get_busid_by_unit(unit)); |
3196 | debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed"); | 3055 | zfcp_erp_port_boxed(unit->port, 51, fsf_req); |
3197 | zfcp_erp_port_boxed(unit->port); | ||
3198 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 3056 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | |
3199 | ZFCP_STATUS_FSFREQ_RETRY; | 3057 | ZFCP_STATUS_FSFREQ_RETRY; |
3200 | break; | 3058 | break; |
@@ -3234,9 +3092,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3234 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 3092 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
3235 | (char *) &header->fsf_status_qual, | 3093 | (char *) &header->fsf_status_qual, |
3236 | sizeof (union fsf_status_qual)); | 3094 | sizeof (union fsf_status_qual)); |
3237 | debug_text_event(adapter->erp_dbf, 2, | 3095 | zfcp_erp_unit_access_denied(unit, 60, fsf_req); |
3238 | "fsf_s_l_sh_vio"); | ||
3239 | zfcp_erp_unit_access_denied(unit); | ||
3240 | atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status); | 3096 | atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status); |
3241 | atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); | 3097 | atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status); |
3242 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3098 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
@@ -3250,9 +3106,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3250 | unit->fcp_lun, | 3106 | unit->fcp_lun, |
3251 | unit->port->wwpn, | 3107 | unit->port->wwpn, |
3252 | zfcp_get_busid_by_unit(unit)); | 3108 | zfcp_get_busid_by_unit(unit)); |
3253 | debug_text_event(adapter->erp_dbf, 1, | 3109 | zfcp_erp_unit_failed(unit, 34, fsf_req); |
3254 | "fsf_s_max_units"); | ||
3255 | zfcp_erp_unit_failed(unit); | ||
3256 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3110 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3257 | break; | 3111 | break; |
3258 | 3112 | ||
@@ -3260,26 +3114,17 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3260 | switch (header->fsf_status_qual.word[0]) { | 3114 | switch (header->fsf_status_qual.word[0]) { |
3261 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 3115 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
3262 | /* Re-establish link to port */ | 3116 | /* Re-establish link to port */ |
3263 | debug_text_event(adapter->erp_dbf, 1, | ||
3264 | "fsf_sq_ltest"); | ||
3265 | zfcp_test_link(unit->port); | 3117 | zfcp_test_link(unit->port); |
3266 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3118 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3267 | break; | 3119 | break; |
3268 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 3120 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
3269 | /* ERP strategy will escalate */ | 3121 | /* ERP strategy will escalate */ |
3270 | debug_text_event(adapter->erp_dbf, 1, | ||
3271 | "fsf_sq_ulp"); | ||
3272 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3122 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3273 | break; | 3123 | break; |
3274 | default: | 3124 | default: |
3275 | ZFCP_LOG_NORMAL | 3125 | ZFCP_LOG_NORMAL |
3276 | ("bug: Wrong status qualifier 0x%x arrived.\n", | 3126 | ("bug: Wrong status qualifier 0x%x arrived.\n", |
3277 | header->fsf_status_qual.word[0]); | 3127 | header->fsf_status_qual.word[0]); |
3278 | debug_text_event(adapter->erp_dbf, 0, | ||
3279 | "fsf_sq_inval:"); | ||
3280 | debug_exception(adapter->erp_dbf, 0, | ||
3281 | &header->fsf_status_qual.word[0], | ||
3282 | sizeof (u32)); | ||
3283 | } | 3128 | } |
3284 | break; | 3129 | break; |
3285 | 3130 | ||
@@ -3331,15 +3176,15 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3331 | if (exclusive && !readwrite) { | 3176 | if (exclusive && !readwrite) { |
3332 | ZFCP_LOG_NORMAL("exclusive access of read-only " | 3177 | ZFCP_LOG_NORMAL("exclusive access of read-only " |
3333 | "unit not supported\n"); | 3178 | "unit not supported\n"); |
3334 | zfcp_erp_unit_failed(unit); | 3179 | zfcp_erp_unit_failed(unit, 35, fsf_req); |
3335 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3180 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3336 | zfcp_erp_unit_shutdown(unit, 0); | 3181 | zfcp_erp_unit_shutdown(unit, 0, 80, fsf_req); |
3337 | } else if (!exclusive && readwrite) { | 3182 | } else if (!exclusive && readwrite) { |
3338 | ZFCP_LOG_NORMAL("shared access of read-write " | 3183 | ZFCP_LOG_NORMAL("shared access of read-write " |
3339 | "unit not supported\n"); | 3184 | "unit not supported\n"); |
3340 | zfcp_erp_unit_failed(unit); | 3185 | zfcp_erp_unit_failed(unit, 36, fsf_req); |
3341 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3186 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3342 | zfcp_erp_unit_shutdown(unit, 0); | 3187 | zfcp_erp_unit_shutdown(unit, 0, 81, fsf_req); |
3343 | } | 3188 | } |
3344 | } | 3189 | } |
3345 | 3190 | ||
@@ -3350,9 +3195,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3350 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " | 3195 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " |
3351 | "(debug info 0x%x)\n", | 3196 | "(debug info 0x%x)\n", |
3352 | header->fsf_status); | 3197 | header->fsf_status); |
3353 | debug_text_event(adapter->erp_dbf, 0, "fsf_s_inval:"); | ||
3354 | debug_exception(adapter->erp_dbf, 0, | ||
3355 | &header->fsf_status, sizeof (u32)); | ||
3356 | break; | 3198 | break; |
3357 | } | 3199 | } |
3358 | 3200 | ||
@@ -3465,9 +3307,7 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3465 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 3307 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
3466 | (char *) &fsf_req->qtcb->header.fsf_status_qual, | 3308 | (char *) &fsf_req->qtcb->header.fsf_status_qual, |
3467 | sizeof (union fsf_status_qual)); | 3309 | sizeof (union fsf_status_qual)); |
3468 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3310 | zfcp_erp_adapter_reopen(unit->port->adapter, 0, 110, fsf_req); |
3469 | "fsf_s_phand_nv"); | ||
3470 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); | ||
3471 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3311 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3472 | break; | 3312 | break; |
3473 | 3313 | ||
@@ -3483,9 +3323,7 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3483 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 3323 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
3484 | (char *) &fsf_req->qtcb->header.fsf_status_qual, | 3324 | (char *) &fsf_req->qtcb->header.fsf_status_qual, |
3485 | sizeof (union fsf_status_qual)); | 3325 | sizeof (union fsf_status_qual)); |
3486 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3326 | zfcp_erp_port_reopen(unit->port, 0, 111, fsf_req); |
3487 | "fsf_s_lhand_nv"); | ||
3488 | zfcp_erp_port_reopen(unit->port, 0); | ||
3489 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3327 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3490 | break; | 3328 | break; |
3491 | 3329 | ||
@@ -3494,8 +3332,7 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3494 | "needs to be reopened\n", | 3332 | "needs to be reopened\n", |
3495 | unit->port->wwpn, | 3333 | unit->port->wwpn, |
3496 | zfcp_get_busid_by_unit(unit)); | 3334 | zfcp_get_busid_by_unit(unit)); |
3497 | debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_pboxed"); | 3335 | zfcp_erp_port_boxed(unit->port, 52, fsf_req); |
3498 | zfcp_erp_port_boxed(unit->port); | ||
3499 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 3336 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | |
3500 | ZFCP_STATUS_FSFREQ_RETRY; | 3337 | ZFCP_STATUS_FSFREQ_RETRY; |
3501 | break; | 3338 | break; |
@@ -3504,27 +3341,17 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3504 | switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) { | 3341 | switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) { |
3505 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 3342 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
3506 | /* re-establish link to port */ | 3343 | /* re-establish link to port */ |
3507 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | ||
3508 | "fsf_sq_ltest"); | ||
3509 | zfcp_test_link(unit->port); | 3344 | zfcp_test_link(unit->port); |
3510 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3345 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3511 | break; | 3346 | break; |
3512 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 3347 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
3513 | /* ERP strategy will escalate */ | 3348 | /* ERP strategy will escalate */ |
3514 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | ||
3515 | "fsf_sq_ulp"); | ||
3516 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3349 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3517 | break; | 3350 | break; |
3518 | default: | 3351 | default: |
3519 | ZFCP_LOG_NORMAL | 3352 | ZFCP_LOG_NORMAL |
3520 | ("bug: Wrong status qualifier 0x%x arrived.\n", | 3353 | ("bug: Wrong status qualifier 0x%x arrived.\n", |
3521 | fsf_req->qtcb->header.fsf_status_qual.word[0]); | 3354 | fsf_req->qtcb->header.fsf_status_qual.word[0]); |
3522 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | ||
3523 | "fsf_sq_inval:"); | ||
3524 | debug_exception( | ||
3525 | fsf_req->adapter->erp_dbf, 0, | ||
3526 | &fsf_req->qtcb->header.fsf_status_qual.word[0], | ||
3527 | sizeof (u32)); | ||
3528 | break; | 3355 | break; |
3529 | } | 3356 | } |
3530 | break; | 3357 | break; |
@@ -3545,10 +3372,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3545 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " | 3372 | ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented " |
3546 | "(debug info 0x%x)\n", | 3373 | "(debug info 0x%x)\n", |
3547 | fsf_req->qtcb->header.fsf_status); | 3374 | fsf_req->qtcb->header.fsf_status); |
3548 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_s_inval:"); | ||
3549 | debug_exception(fsf_req->adapter->erp_dbf, 0, | ||
3550 | &fsf_req->qtcb->header.fsf_status, | ||
3551 | sizeof (u32)); | ||
3552 | break; | 3375 | break; |
3553 | } | 3376 | } |
3554 | 3377 | ||
@@ -3703,7 +3526,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, | |||
3703 | zfcp_get_busid_by_unit(unit), | 3526 | zfcp_get_busid_by_unit(unit), |
3704 | unit->port->wwpn, | 3527 | unit->port->wwpn, |
3705 | unit->fcp_lun); | 3528 | unit->fcp_lun); |
3706 | zfcp_erp_unit_shutdown(unit, 0); | 3529 | zfcp_erp_unit_shutdown(unit, 0, 131, fsf_req); |
3707 | retval = -EINVAL; | 3530 | retval = -EINVAL; |
3708 | } | 3531 | } |
3709 | goto no_fit; | 3532 | goto no_fit; |
@@ -3739,8 +3562,8 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, | |||
3739 | send_failed: | 3562 | send_failed: |
3740 | no_fit: | 3563 | no_fit: |
3741 | failed_scsi_cmnd: | 3564 | failed_scsi_cmnd: |
3742 | unit_blocked: | ||
3743 | zfcp_unit_put(unit); | 3565 | zfcp_unit_put(unit); |
3566 | unit_blocked: | ||
3744 | zfcp_fsf_req_free(fsf_req); | 3567 | zfcp_fsf_req_free(fsf_req); |
3745 | fsf_req = NULL; | 3568 | fsf_req = NULL; |
3746 | scsi_cmnd->host_scribble = NULL; | 3569 | scsi_cmnd->host_scribble = NULL; |
@@ -3861,9 +3684,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3861 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 3684 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
3862 | (char *) &header->fsf_status_qual, | 3685 | (char *) &header->fsf_status_qual, |
3863 | sizeof (union fsf_status_qual)); | 3686 | sizeof (union fsf_status_qual)); |
3864 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3687 | zfcp_erp_adapter_reopen(unit->port->adapter, 0, 112, fsf_req); |
3865 | "fsf_s_phand_nv"); | ||
3866 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); | ||
3867 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3688 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3868 | break; | 3689 | break; |
3869 | 3690 | ||
@@ -3879,9 +3700,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3879 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, | 3700 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, |
3880 | (char *) &header->fsf_status_qual, | 3701 | (char *) &header->fsf_status_qual, |
3881 | sizeof (union fsf_status_qual)); | 3702 | sizeof (union fsf_status_qual)); |
3882 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3703 | zfcp_erp_port_reopen(unit->port, 0, 113, fsf_req); |
3883 | "fsf_s_uhand_nv"); | ||
3884 | zfcp_erp_port_reopen(unit->port, 0); | ||
3885 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3704 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3886 | break; | 3705 | break; |
3887 | 3706 | ||
@@ -3897,9 +3716,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3897 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, | 3716 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, |
3898 | (char *) &header->fsf_status_qual, | 3717 | (char *) &header->fsf_status_qual, |
3899 | sizeof (union fsf_status_qual)); | 3718 | sizeof (union fsf_status_qual)); |
3900 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3719 | zfcp_erp_adapter_reopen(unit->port->adapter, 0, 114, fsf_req); |
3901 | "fsf_s_hand_mis"); | ||
3902 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); | ||
3903 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3720 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3904 | break; | 3721 | break; |
3905 | 3722 | ||
@@ -3909,9 +3726,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3909 | zfcp_get_busid_by_unit(unit), | 3726 | zfcp_get_busid_by_unit(unit), |
3910 | ZFCP_FC_SERVICE_CLASS_DEFAULT); | 3727 | ZFCP_FC_SERVICE_CLASS_DEFAULT); |
3911 | /* stop operation for this adapter */ | 3728 | /* stop operation for this adapter */ |
3912 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | 3729 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 132, fsf_req); |
3913 | "fsf_s_class_nsup"); | ||
3914 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); | ||
3915 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3730 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3916 | break; | 3731 | break; |
3917 | 3732 | ||
@@ -3927,9 +3742,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3927 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 3742 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
3928 | (char *) &header->fsf_status_qual, | 3743 | (char *) &header->fsf_status_qual, |
3929 | sizeof (union fsf_status_qual)); | 3744 | sizeof (union fsf_status_qual)); |
3930 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3745 | zfcp_erp_port_reopen(unit->port, 0, 115, fsf_req); |
3931 | "fsf_s_fcp_lun_nv"); | ||
3932 | zfcp_erp_port_reopen(unit->port, 0); | ||
3933 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3746 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3934 | break; | 3747 | break; |
3935 | 3748 | ||
@@ -3951,8 +3764,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3951 | break; | 3764 | break; |
3952 | } | 3765 | } |
3953 | } | 3766 | } |
3954 | debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_access"); | 3767 | zfcp_erp_unit_access_denied(unit, 61, fsf_req); |
3955 | zfcp_erp_unit_access_denied(unit); | ||
3956 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3768 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3957 | break; | 3769 | break; |
3958 | 3770 | ||
@@ -3965,9 +3777,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3965 | zfcp_get_busid_by_unit(unit), | 3777 | zfcp_get_busid_by_unit(unit), |
3966 | fsf_req->qtcb->bottom.io.data_direction); | 3778 | fsf_req->qtcb->bottom.io.data_direction); |
3967 | /* stop operation for this adapter */ | 3779 | /* stop operation for this adapter */ |
3968 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | 3780 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, fsf_req); |
3969 | "fsf_s_dir_ind_nv"); | ||
3970 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); | ||
3971 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3781 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3972 | break; | 3782 | break; |
3973 | 3783 | ||
@@ -3980,9 +3790,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3980 | zfcp_get_busid_by_unit(unit), | 3790 | zfcp_get_busid_by_unit(unit), |
3981 | fsf_req->qtcb->bottom.io.fcp_cmnd_length); | 3791 | fsf_req->qtcb->bottom.io.fcp_cmnd_length); |
3982 | /* stop operation for this adapter */ | 3792 | /* stop operation for this adapter */ |
3983 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | 3793 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, fsf_req); |
3984 | "fsf_s_cmd_len_nv"); | ||
3985 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); | ||
3986 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3794 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3987 | break; | 3795 | break; |
3988 | 3796 | ||
@@ -3990,8 +3798,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3990 | ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s " | 3798 | ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s " |
3991 | "needs to be reopened\n", | 3799 | "needs to be reopened\n", |
3992 | unit->port->wwpn, zfcp_get_busid_by_unit(unit)); | 3800 | unit->port->wwpn, zfcp_get_busid_by_unit(unit)); |
3993 | debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_pboxed"); | 3801 | zfcp_erp_port_boxed(unit->port, 53, fsf_req); |
3994 | zfcp_erp_port_boxed(unit->port); | ||
3995 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 3802 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | |
3996 | ZFCP_STATUS_FSFREQ_RETRY; | 3803 | ZFCP_STATUS_FSFREQ_RETRY; |
3997 | break; | 3804 | break; |
@@ -4001,8 +3808,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
4001 | "wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n", | 3808 | "wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n", |
4002 | zfcp_get_busid_by_unit(unit), | 3809 | zfcp_get_busid_by_unit(unit), |
4003 | unit->port->wwpn, unit->fcp_lun); | 3810 | unit->port->wwpn, unit->fcp_lun); |
4004 | debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_lboxed"); | 3811 | zfcp_erp_unit_boxed(unit, 54, fsf_req); |
4005 | zfcp_erp_unit_boxed(unit); | ||
4006 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | 3812 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
4007 | | ZFCP_STATUS_FSFREQ_RETRY; | 3813 | | ZFCP_STATUS_FSFREQ_RETRY; |
4008 | break; | 3814 | break; |
@@ -4011,25 +3817,16 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
4011 | switch (header->fsf_status_qual.word[0]) { | 3817 | switch (header->fsf_status_qual.word[0]) { |
4012 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 3818 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
4013 | /* re-establish link to port */ | 3819 | /* re-establish link to port */ |
4014 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | ||
4015 | "fsf_sq_ltest"); | ||
4016 | zfcp_test_link(unit->port); | 3820 | zfcp_test_link(unit->port); |
4017 | break; | 3821 | break; |
4018 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: | 3822 | case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED: |
4019 | /* FIXME(hw) need proper specs for proper action */ | 3823 | /* FIXME(hw) need proper specs for proper action */ |
4020 | /* let scsi stack deal with retries and escalation */ | 3824 | /* let scsi stack deal with retries and escalation */ |
4021 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | ||
4022 | "fsf_sq_ulp"); | ||
4023 | break; | 3825 | break; |
4024 | default: | 3826 | default: |
4025 | ZFCP_LOG_NORMAL | 3827 | ZFCP_LOG_NORMAL |
4026 | ("Unknown status qualifier 0x%x arrived.\n", | 3828 | ("Unknown status qualifier 0x%x arrived.\n", |
4027 | header->fsf_status_qual.word[0]); | 3829 | header->fsf_status_qual.word[0]); |
4028 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | ||
4029 | "fsf_sq_inval:"); | ||
4030 | debug_exception(fsf_req->adapter->erp_dbf, 0, | ||
4031 | &header->fsf_status_qual.word[0], | ||
4032 | sizeof(u32)); | ||
4033 | break; | 3830 | break; |
4034 | } | 3831 | } |
4035 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3832 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
@@ -4040,12 +3837,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
4040 | 3837 | ||
4041 | case FSF_FCP_RSP_AVAILABLE: | 3838 | case FSF_FCP_RSP_AVAILABLE: |
4042 | break; | 3839 | break; |
4043 | |||
4044 | default: | ||
4045 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_s_inval:"); | ||
4046 | debug_exception(fsf_req->adapter->erp_dbf, 0, | ||
4047 | &header->fsf_status, sizeof(u32)); | ||
4048 | break; | ||
4049 | } | 3840 | } |
4050 | 3841 | ||
4051 | skip_fsfstatus: | 3842 | skip_fsfstatus: |
@@ -4625,9 +4416,6 @@ zfcp_fsf_control_file_handler(struct zfcp_fsf_req *fsf_req) | |||
4625 | "was presented on the adapter %s\n", | 4416 | "was presented on the adapter %s\n", |
4626 | header->fsf_status, | 4417 | header->fsf_status, |
4627 | zfcp_get_busid_by_adapter(adapter)); | 4418 | zfcp_get_busid_by_adapter(adapter)); |
4628 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_sq_inval"); | ||
4629 | debug_exception(fsf_req->adapter->erp_dbf, 0, | ||
4630 | &header->fsf_status_qual.word[0], sizeof(u32)); | ||
4631 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 4419 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
4632 | retval = -EINVAL; | 4420 | retval = -EINVAL; |
4633 | break; | 4421 | break; |
@@ -4817,7 +4605,6 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) | |||
4817 | volatile struct qdio_buffer_element *sbale; | 4605 | volatile struct qdio_buffer_element *sbale; |
4818 | int inc_seq_no; | 4606 | int inc_seq_no; |
4819 | int new_distance_from_int; | 4607 | int new_distance_from_int; |
4820 | u64 dbg_tmp[2]; | ||
4821 | int retval = 0; | 4608 | int retval = 0; |
4822 | 4609 | ||
4823 | adapter = fsf_req->adapter; | 4610 | adapter = fsf_req->adapter; |
@@ -4867,10 +4654,6 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) | |||
4867 | QDIO_FLAG_SYNC_OUTPUT, | 4654 | QDIO_FLAG_SYNC_OUTPUT, |
4868 | 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL); | 4655 | 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL); |
4869 | 4656 | ||
4870 | dbg_tmp[0] = (unsigned long) sbale[0].addr; | ||
4871 | dbg_tmp[1] = (u64) retval; | ||
4872 | debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16); | ||
4873 | |||
4874 | if (unlikely(retval)) { | 4657 | if (unlikely(retval)) { |
4875 | /* Queues are down..... */ | 4658 | /* Queues are down..... */ |
4876 | retval = -EIO; | 4659 | retval = -EIO; |
@@ -4885,7 +4668,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req) | |||
4885 | req_queue->free_index -= fsf_req->sbal_number; | 4668 | req_queue->free_index -= fsf_req->sbal_number; |
4886 | req_queue->free_index += QDIO_MAX_BUFFERS_PER_Q; | 4669 | req_queue->free_index += QDIO_MAX_BUFFERS_PER_Q; |
4887 | req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */ | 4670 | req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */ |
4888 | zfcp_erp_adapter_reopen(adapter, 0); | 4671 | zfcp_erp_adapter_reopen(adapter, 0, 116, fsf_req); |
4889 | } else { | 4672 | } else { |
4890 | req_queue->distance_from_int = new_distance_from_int; | 4673 | req_queue->distance_from_int = new_distance_from_int; |
4891 | /* | 4674 | /* |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 22fdc17e0d0e..8ca5f074c687 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -175,8 +175,9 @@ zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status, | |||
175 | * which is set again in case we have missed by a mile. | 175 | * which is set again in case we have missed by a mile. |
176 | */ | 176 | */ |
177 | zfcp_erp_adapter_reopen(adapter, | 177 | zfcp_erp_adapter_reopen(adapter, |
178 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | | 178 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | |
179 | ZFCP_STATUS_COMMON_ERP_FAILED); | 179 | ZFCP_STATUS_COMMON_ERP_FAILED, 140, |
180 | NULL); | ||
180 | } | 181 | } |
181 | return retval; | 182 | return retval; |
182 | } | 183 | } |
@@ -239,8 +240,6 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, | |||
239 | struct zfcp_fsf_req *fsf_req; | 240 | struct zfcp_fsf_req *fsf_req; |
240 | unsigned long flags; | 241 | unsigned long flags; |
241 | 242 | ||
242 | debug_long_event(adapter->erp_dbf, 4, req_id); | ||
243 | |||
244 | spin_lock_irqsave(&adapter->req_list_lock, flags); | 243 | spin_lock_irqsave(&adapter->req_list_lock, flags); |
245 | fsf_req = zfcp_reqlist_find(adapter, req_id); | 244 | fsf_req = zfcp_reqlist_find(adapter, req_id); |
246 | 245 | ||
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index b9daf5c05862..f81850624eed 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -31,6 +31,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *, | |||
31 | void (*done) (struct scsi_cmnd *)); | 31 | void (*done) (struct scsi_cmnd *)); |
32 | static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); | 32 | static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); |
33 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); | 33 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); |
34 | static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *); | ||
34 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); | 35 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); |
35 | static int zfcp_task_management_function(struct zfcp_unit *, u8, | 36 | static int zfcp_task_management_function(struct zfcp_unit *, u8, |
36 | struct scsi_cmnd *); | 37 | struct scsi_cmnd *); |
@@ -51,6 +52,7 @@ struct zfcp_data zfcp_data = { | |||
51 | .queuecommand = zfcp_scsi_queuecommand, | 52 | .queuecommand = zfcp_scsi_queuecommand, |
52 | .eh_abort_handler = zfcp_scsi_eh_abort_handler, | 53 | .eh_abort_handler = zfcp_scsi_eh_abort_handler, |
53 | .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, | 54 | .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, |
55 | .eh_target_reset_handler = zfcp_scsi_eh_target_reset_handler, | ||
54 | .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, | 56 | .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, |
55 | .can_queue = 4096, | 57 | .can_queue = 4096, |
56 | .this_id = -1, | 58 | .this_id = -1, |
@@ -179,11 +181,10 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) | |||
179 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; | 181 | struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; |
180 | 182 | ||
181 | if (unit) { | 183 | if (unit) { |
182 | zfcp_erp_wait(unit->port->adapter); | ||
183 | atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); | 184 | atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); |
184 | sdpnt->hostdata = NULL; | 185 | sdpnt->hostdata = NULL; |
185 | unit->device = NULL; | 186 | unit->device = NULL; |
186 | zfcp_erp_unit_failed(unit); | 187 | zfcp_erp_unit_failed(unit, 12, NULL); |
187 | zfcp_unit_put(unit); | 188 | zfcp_unit_put(unit); |
188 | } else | 189 | } else |
189 | ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at " | 190 | ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at " |
@@ -442,58 +443,32 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
442 | return retval; | 443 | return retval; |
443 | } | 444 | } |
444 | 445 | ||
445 | static int | 446 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) |
446 | zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) | ||
447 | { | 447 | { |
448 | int retval; | 448 | int retval; |
449 | struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata; | 449 | struct zfcp_unit *unit = scpnt->device->hostdata; |
450 | 450 | ||
451 | if (!unit) { | 451 | if (!unit) { |
452 | ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n"); | 452 | WARN_ON(1); |
453 | retval = SUCCESS; | 453 | return SUCCESS; |
454 | goto out; | ||
455 | } | 454 | } |
456 | ZFCP_LOG_NORMAL("resetting unit 0x%016Lx on port 0x%016Lx, adapter %s\n", | 455 | retval = zfcp_task_management_function(unit, |
457 | unit->fcp_lun, unit->port->wwpn, | 456 | FCP_LOGICAL_UNIT_RESET, |
458 | zfcp_get_busid_by_adapter(unit->port->adapter)); | 457 | scpnt); |
458 | return retval ? FAILED : SUCCESS; | ||
459 | } | ||
459 | 460 | ||
460 | /* | 461 | static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) |
461 | * If we do not know whether the unit supports 'logical unit reset' | 462 | { |
462 | * then try 'logical unit reset' and proceed with 'target reset' | 463 | int retval; |
463 | * if 'logical unit reset' fails. | 464 | struct zfcp_unit *unit = scpnt->device->hostdata; |
464 | * If the unit is known not to support 'logical unit reset' then | 465 | |
465 | * skip 'logical unit reset' and try 'target reset' immediately. | 466 | if (!unit) { |
466 | */ | 467 | WARN_ON(1); |
467 | if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET, | 468 | return SUCCESS; |
468 | &unit->status)) { | ||
469 | retval = zfcp_task_management_function(unit, | ||
470 | FCP_LOGICAL_UNIT_RESET, | ||
471 | scpnt); | ||
472 | if (retval) { | ||
473 | ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit); | ||
474 | if (retval == -ENOTSUPP) | ||
475 | atomic_set_mask | ||
476 | (ZFCP_STATUS_UNIT_NOTSUPPUNITRESET, | ||
477 | &unit->status); | ||
478 | /* fall through and try 'target reset' next */ | ||
479 | } else { | ||
480 | ZFCP_LOG_DEBUG("unit reset succeeded (unit=%p)\n", | ||
481 | unit); | ||
482 | /* avoid 'target reset' */ | ||
483 | retval = SUCCESS; | ||
484 | goto out; | ||
485 | } | ||
486 | } | 469 | } |
487 | retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt); | 470 | retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt); |
488 | if (retval) { | 471 | return retval ? FAILED : SUCCESS; |
489 | ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit); | ||
490 | retval = FAILED; | ||
491 | } else { | ||
492 | ZFCP_LOG_DEBUG("target reset succeeded (unit=%p)\n", unit); | ||
493 | retval = SUCCESS; | ||
494 | } | ||
495 | out: | ||
496 | return retval; | ||
497 | } | 472 | } |
498 | 473 | ||
499 | static int | 474 | static int |
@@ -553,7 +528,7 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) | |||
553 | unit->fcp_lun, unit->port->wwpn, | 528 | unit->fcp_lun, unit->port->wwpn, |
554 | zfcp_get_busid_by_adapter(unit->port->adapter)); | 529 | zfcp_get_busid_by_adapter(unit->port->adapter)); |
555 | 530 | ||
556 | zfcp_erp_adapter_reopen(adapter, 0); | 531 | zfcp_erp_adapter_reopen(adapter, 0, 141, scpnt); |
557 | zfcp_erp_wait(adapter); | 532 | zfcp_erp_wait(adapter); |
558 | 533 | ||
559 | return SUCCESS; | 534 | return SUCCESS; |
diff --git a/drivers/s390/scsi/zfcp_sysfs_adapter.c b/drivers/s390/scsi/zfcp_sysfs_adapter.c index 705c6d4428f3..ccbba4dd3a77 100644 --- a/drivers/s390/scsi/zfcp_sysfs_adapter.c +++ b/drivers/s390/scsi/zfcp_sysfs_adapter.c | |||
@@ -89,7 +89,7 @@ zfcp_sysfs_port_add_store(struct device *dev, struct device_attribute *attr, con | |||
89 | 89 | ||
90 | retval = 0; | 90 | retval = 0; |
91 | 91 | ||
92 | zfcp_erp_port_reopen(port, 0); | 92 | zfcp_erp_port_reopen(port, 0, 91, NULL); |
93 | zfcp_erp_wait(port->adapter); | 93 | zfcp_erp_wait(port->adapter); |
94 | zfcp_port_put(port); | 94 | zfcp_port_put(port); |
95 | out: | 95 | out: |
@@ -147,7 +147,7 @@ zfcp_sysfs_port_remove_store(struct device *dev, struct device_attribute *attr, | |||
147 | goto out; | 147 | goto out; |
148 | } | 148 | } |
149 | 149 | ||
150 | zfcp_erp_port_shutdown(port, 0); | 150 | zfcp_erp_port_shutdown(port, 0, 92, NULL); |
151 | zfcp_erp_wait(adapter); | 151 | zfcp_erp_wait(adapter); |
152 | zfcp_port_put(port); | 152 | zfcp_port_put(port); |
153 | zfcp_port_dequeue(port); | 153 | zfcp_port_dequeue(port); |
@@ -191,9 +191,10 @@ zfcp_sysfs_adapter_failed_store(struct device *dev, struct device_attribute *att | |||
191 | goto out; | 191 | goto out; |
192 | } | 192 | } |
193 | 193 | ||
194 | zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING, | 194 | zfcp_erp_modify_adapter_status(adapter, 44, NULL, |
195 | ZFCP_SET); | 195 | ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); |
196 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED); | 196 | zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 93, |
197 | NULL); | ||
197 | zfcp_erp_wait(adapter); | 198 | zfcp_erp_wait(adapter); |
198 | out: | 199 | out: |
199 | up(&zfcp_data.config_sema); | 200 | up(&zfcp_data.config_sema); |
diff --git a/drivers/s390/scsi/zfcp_sysfs_port.c b/drivers/s390/scsi/zfcp_sysfs_port.c index 1320c0591431..703c1b5cb602 100644 --- a/drivers/s390/scsi/zfcp_sysfs_port.c +++ b/drivers/s390/scsi/zfcp_sysfs_port.c | |||
@@ -94,7 +94,7 @@ zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, con | |||
94 | 94 | ||
95 | retval = 0; | 95 | retval = 0; |
96 | 96 | ||
97 | zfcp_erp_unit_reopen(unit, 0); | 97 | zfcp_erp_unit_reopen(unit, 0, 94, NULL); |
98 | zfcp_erp_wait(unit->port->adapter); | 98 | zfcp_erp_wait(unit->port->adapter); |
99 | zfcp_unit_put(unit); | 99 | zfcp_unit_put(unit); |
100 | out: | 100 | out: |
@@ -150,7 +150,7 @@ zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr, | |||
150 | goto out; | 150 | goto out; |
151 | } | 151 | } |
152 | 152 | ||
153 | zfcp_erp_unit_shutdown(unit, 0); | 153 | zfcp_erp_unit_shutdown(unit, 0, 95, NULL); |
154 | zfcp_erp_wait(unit->port->adapter); | 154 | zfcp_erp_wait(unit->port->adapter); |
155 | zfcp_unit_put(unit); | 155 | zfcp_unit_put(unit); |
156 | zfcp_unit_dequeue(unit); | 156 | zfcp_unit_dequeue(unit); |
@@ -193,8 +193,9 @@ zfcp_sysfs_port_failed_store(struct device *dev, struct device_attribute *attr, | |||
193 | goto out; | 193 | goto out; |
194 | } | 194 | } |
195 | 195 | ||
196 | zfcp_erp_modify_port_status(port, ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); | 196 | zfcp_erp_modify_port_status(port, 45, NULL, |
197 | zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED); | 197 | ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); |
198 | zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, 96, NULL); | ||
198 | zfcp_erp_wait(port->adapter); | 199 | zfcp_erp_wait(port->adapter); |
199 | out: | 200 | out: |
200 | up(&zfcp_data.config_sema); | 201 | up(&zfcp_data.config_sema); |
diff --git a/drivers/s390/scsi/zfcp_sysfs_unit.c b/drivers/s390/scsi/zfcp_sysfs_unit.c index 63f75ee95c33..80fb2c2cf48a 100644 --- a/drivers/s390/scsi/zfcp_sysfs_unit.c +++ b/drivers/s390/scsi/zfcp_sysfs_unit.c | |||
@@ -94,8 +94,9 @@ zfcp_sysfs_unit_failed_store(struct device *dev, struct device_attribute *attr, | |||
94 | goto out; | 94 | goto out; |
95 | } | 95 | } |
96 | 96 | ||
97 | zfcp_erp_modify_unit_status(unit, ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); | 97 | zfcp_erp_modify_unit_status(unit, 46, NULL, |
98 | zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED); | 98 | ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); |
99 | zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, 97, NULL); | ||
99 | zfcp_erp_wait(unit->port->adapter); | 100 | zfcp_erp_wait(unit->port->adapter); |
100 | out: | 101 | out: |
101 | up(&zfcp_data.config_sema); | 102 | up(&zfcp_data.config_sema); |
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index b4912d1cee2a..51c3ebf1c7d1 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c | |||
@@ -1838,12 +1838,11 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id, | |||
1838 | if (scsi_sg_count(srb)) { | 1838 | if (scsi_sg_count(srb)) { |
1839 | if ((scsi_sg_count(srb) == 1) && | 1839 | if ((scsi_sg_count(srb) == 1) && |
1840 | (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) { | 1840 | (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) { |
1841 | if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) { | 1841 | if (srb->sc_data_direction == DMA_TO_DEVICE || |
1842 | struct scatterlist *sg = scsi_sglist(srb); | 1842 | srb->sc_data_direction == DMA_BIDIRECTIONAL) |
1843 | char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; | 1843 | scsi_sg_copy_to_buffer(srb, |
1844 | memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length); | 1844 | tw_dev->generic_buffer_virt[request_id], |
1845 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | 1845 | TW_SECTOR_SIZE); |
1846 | } | ||
1847 | command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); | 1846 | command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]); |
1848 | command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH); | 1847 | command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH); |
1849 | } else { | 1848 | } else { |
@@ -1915,13 +1914,11 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re | |||
1915 | (cmd->sc_data_direction == DMA_FROM_DEVICE || | 1914 | (cmd->sc_data_direction == DMA_FROM_DEVICE || |
1916 | cmd->sc_data_direction == DMA_BIDIRECTIONAL)) { | 1915 | cmd->sc_data_direction == DMA_BIDIRECTIONAL)) { |
1917 | if (scsi_sg_count(cmd) == 1) { | 1916 | if (scsi_sg_count(cmd) == 1) { |
1918 | struct scatterlist *sg = scsi_sglist(tw_dev->srb[request_id]); | 1917 | unsigned long flags; |
1919 | char *buf; | 1918 | void *buf = tw_dev->generic_buffer_virt[request_id]; |
1920 | unsigned long flags = 0; | 1919 | |
1921 | local_irq_save(flags); | 1920 | local_irq_save(flags); |
1922 | buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; | 1921 | scsi_sg_copy_from_buffer(cmd, buf, TW_SECTOR_SIZE); |
1923 | memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length); | ||
1924 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | ||
1925 | local_irq_restore(flags); | 1922 | local_irq_restore(flags); |
1926 | } | 1923 | } |
1927 | } | 1924 | } |
@@ -2028,8 +2025,6 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id | |||
2028 | } | 2025 | } |
2029 | tw_dev = (TW_Device_Extension *)host->hostdata; | 2026 | tw_dev = (TW_Device_Extension *)host->hostdata; |
2030 | 2027 | ||
2031 | memset(tw_dev, 0, sizeof(TW_Device_Extension)); | ||
2032 | |||
2033 | /* Save values to device extension */ | 2028 | /* Save values to device extension */ |
2034 | tw_dev->host = host; | 2029 | tw_dev->host = host; |
2035 | tw_dev->tw_pci_dev = pdev; | 2030 | tw_dev->tw_pci_dev = pdev; |
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index d09532162217..adb98a297210 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c | |||
@@ -1463,18 +1463,10 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id, | |||
1463 | void *data, unsigned int len) | 1463 | void *data, unsigned int len) |
1464 | { | 1464 | { |
1465 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; | 1465 | struct scsi_cmnd *cmd = tw_dev->srb[request_id]; |
1466 | void *buf; | 1466 | unsigned long flags; |
1467 | unsigned int transfer_len; | ||
1468 | unsigned long flags = 0; | ||
1469 | struct scatterlist *sg = scsi_sglist(cmd); | ||
1470 | 1467 | ||
1471 | local_irq_save(flags); | 1468 | local_irq_save(flags); |
1472 | buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; | 1469 | scsi_sg_copy_from_buffer(cmd, data, len); |
1473 | transfer_len = min(sg->length, len); | ||
1474 | |||
1475 | memcpy(buf, data, transfer_len); | ||
1476 | |||
1477 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | ||
1478 | local_irq_restore(flags); | 1470 | local_irq_restore(flags); |
1479 | } | 1471 | } |
1480 | 1472 | ||
@@ -2294,8 +2286,6 @@ static int __devinit tw_probe(struct pci_dev *pdev, const struct pci_device_id * | |||
2294 | } | 2286 | } |
2295 | tw_dev = (TW_Device_Extension *)host->hostdata; | 2287 | tw_dev = (TW_Device_Extension *)host->hostdata; |
2296 | 2288 | ||
2297 | memset(tw_dev, 0, sizeof(TW_Device_Extension)); | ||
2298 | |||
2299 | /* Save values to device extension */ | 2289 | /* Save values to device extension */ |
2300 | tw_dev->host = host; | 2290 | tw_dev->host = host; |
2301 | tw_dev->tw_pci_dev = pdev; | 2291 | tw_dev->tw_pci_dev = pdev; |
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 4d3ebb1af490..2d689af24664 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c | |||
@@ -896,7 +896,7 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda | |||
896 | IRQ_Channel = PCI_Device->irq; | 896 | IRQ_Channel = PCI_Device->irq; |
897 | IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0); | 897 | IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0); |
898 | PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1); | 898 | PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1); |
899 | #ifndef CONFIG_SCSI_OMIT_FLASHPOINT | 899 | #ifdef CONFIG_SCSI_FLASHPOINT |
900 | if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) { | 900 | if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) { |
901 | BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0); | 901 | BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0); |
902 | BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); | 902 | BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address); |
@@ -1006,6 +1006,9 @@ static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter | |||
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | 1008 | ||
1009 | #else | ||
1010 | #define BusLogic_InitializeProbeInfoList(adapter) \ | ||
1011 | BusLogic_InitializeProbeInfoListISA(adapter) | ||
1009 | #endif /* CONFIG_PCI */ | 1012 | #endif /* CONFIG_PCI */ |
1010 | 1013 | ||
1011 | 1014 | ||
diff --git a/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h index bfbfb5c3a8f6..73f237a1ed94 100644 --- a/drivers/scsi/BusLogic.h +++ b/drivers/scsi/BusLogic.h | |||
@@ -34,23 +34,6 @@ | |||
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | /* | 36 | /* |
37 | FlashPoint support is only available for the Intel x86 Architecture with | ||
38 | CONFIG_PCI set. | ||
39 | */ | ||
40 | |||
41 | #ifndef __i386__ | ||
42 | #undef CONFIG_SCSI_OMIT_FLASHPOINT | ||
43 | #define CONFIG_SCSI_OMIT_FLASHPOINT | ||
44 | #endif | ||
45 | |||
46 | #ifndef CONFIG_PCI | ||
47 | #undef CONFIG_SCSI_OMIT_FLASHPOINT | ||
48 | #define CONFIG_SCSI_OMIT_FLASHPOINT | ||
49 | #define BusLogic_InitializeProbeInfoListISA BusLogic_InitializeProbeInfoList | ||
50 | #endif | ||
51 | |||
52 | |||
53 | /* | ||
54 | Define the maximum number of BusLogic Host Adapters supported by this driver. | 37 | Define the maximum number of BusLogic Host Adapters supported by this driver. |
55 | */ | 38 | */ |
56 | 39 | ||
@@ -178,7 +161,7 @@ static int BusLogic_HostAdapterAddressCount[3] = { 0, BusLogic_MultiMasterAddres | |||
178 | Define macros for testing the Host Adapter Type. | 161 | Define macros for testing the Host Adapter Type. |
179 | */ | 162 | */ |
180 | 163 | ||
181 | #ifndef CONFIG_SCSI_OMIT_FLASHPOINT | 164 | #ifdef CONFIG_SCSI_FLASHPOINT |
182 | 165 | ||
183 | #define BusLogic_MultiMasterHostAdapterP(HostAdapter) \ | 166 | #define BusLogic_MultiMasterHostAdapterP(HostAdapter) \ |
184 | (HostAdapter->HostAdapterType == BusLogic_MultiMaster) | 167 | (HostAdapter->HostAdapterType == BusLogic_MultiMaster) |
@@ -871,7 +854,7 @@ struct BusLogic_CCB { | |||
871 | void (*CallbackFunction) (struct BusLogic_CCB *); /* Bytes 40-43 */ | 854 | void (*CallbackFunction) (struct BusLogic_CCB *); /* Bytes 40-43 */ |
872 | u32 BaseAddress; /* Bytes 44-47 */ | 855 | u32 BaseAddress; /* Bytes 44-47 */ |
873 | enum BusLogic_CompletionCode CompletionCode; /* Byte 48 */ | 856 | enum BusLogic_CompletionCode CompletionCode; /* Byte 48 */ |
874 | #ifndef CONFIG_SCSI_OMIT_FLASHPOINT | 857 | #ifdef CONFIG_SCSI_FLASHPOINT |
875 | unsigned char:8; /* Byte 49 */ | 858 | unsigned char:8; /* Byte 49 */ |
876 | unsigned short OS_Flags; /* Bytes 50-51 */ | 859 | unsigned short OS_Flags; /* Bytes 50-51 */ |
877 | unsigned char Private[48]; /* Bytes 52-99 */ | 860 | unsigned char Private[48]; /* Bytes 52-99 */ |
diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c index 1c9078191d9e..b374e457e5e2 100644 --- a/drivers/scsi/FlashPoint.c +++ b/drivers/scsi/FlashPoint.c | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | 18 | ||
19 | #ifndef CONFIG_SCSI_OMIT_FLASHPOINT | 19 | #ifdef CONFIG_SCSI_FLASHPOINT |
20 | 20 | ||
21 | #define MAX_CARDS 8 | 21 | #define MAX_CARDS 8 |
22 | #undef BUSTYPE_PCI | 22 | #undef BUSTYPE_PCI |
@@ -7626,7 +7626,7 @@ FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle) | |||
7626 | #define FlashPoint_InterruptPending FlashPoint__InterruptPending | 7626 | #define FlashPoint_InterruptPending FlashPoint__InterruptPending |
7627 | #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt | 7627 | #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt |
7628 | 7628 | ||
7629 | #else /* CONFIG_SCSI_OMIT_FLASHPOINT */ | 7629 | #else /* !CONFIG_SCSI_FLASHPOINT */ |
7630 | 7630 | ||
7631 | /* | 7631 | /* |
7632 | Define prototypes for the FlashPoint SCCB Manager Functions. | 7632 | Define prototypes for the FlashPoint SCCB Manager Functions. |
@@ -7641,4 +7641,4 @@ extern bool FlashPoint_InterruptPending(FlashPoint_CardHandle_T); | |||
7641 | extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); | 7641 | extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T); |
7642 | extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); | 7642 | extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T); |
7643 | 7643 | ||
7644 | #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */ | 7644 | #endif /* CONFIG_SCSI_FLASHPOINT */ |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index b9d374082b65..7f78e3ea517d 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -588,18 +588,20 @@ config SCSI_BUSLOGIC | |||
588 | <http://www.tldp.org/docs.html#howto>, and the files | 588 | <http://www.tldp.org/docs.html#howto>, and the files |
589 | <file:Documentation/scsi/BusLogic.txt> and | 589 | <file:Documentation/scsi/BusLogic.txt> and |
590 | <file:Documentation/scsi/FlashPoint.txt> for more information. | 590 | <file:Documentation/scsi/FlashPoint.txt> for more information. |
591 | Note that support for FlashPoint is only available for 32-bit | ||
592 | x86 configurations. | ||
591 | 593 | ||
592 | To compile this driver as a module, choose M here: the | 594 | To compile this driver as a module, choose M here: the |
593 | module will be called BusLogic. | 595 | module will be called BusLogic. |
594 | 596 | ||
595 | config SCSI_OMIT_FLASHPOINT | 597 | config SCSI_FLASHPOINT |
596 | bool "Omit FlashPoint support" | 598 | bool "FlashPoint support" |
597 | depends on SCSI_BUSLOGIC | 599 | depends on SCSI_BUSLOGIC && PCI && X86_32 |
598 | help | 600 | help |
599 | This option allows you to omit the FlashPoint support from the | 601 | This option allows you to add FlashPoint support to the |
600 | BusLogic SCSI driver. The FlashPoint SCCB Manager code is | 602 | BusLogic SCSI driver. The FlashPoint SCCB Manager code is |
601 | substantial, so users of MultiMaster Host Adapters may wish to omit | 603 | substantial, so users of MultiMaster Host Adapters may not |
602 | it. | 604 | wish to include it. |
603 | 605 | ||
604 | config SCSI_DMX3191D | 606 | config SCSI_DMX3191D |
605 | tristate "DMX3191D SCSI support" | 607 | tristate "DMX3191D SCSI support" |
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 5ac3a3e8dfaf..07d572feceed 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c | |||
@@ -179,6 +179,9 @@ int __init a2091_detect(struct scsi_host_template *tpnt) | |||
179 | DMA(instance)->DAWR = DAWR_A2091; | 179 | DMA(instance)->DAWR = DAWR_A2091; |
180 | regs.SASR = &(DMA(instance)->SASR); | 180 | regs.SASR = &(DMA(instance)->SASR); |
181 | regs.SCMD = &(DMA(instance)->SCMD); | 181 | regs.SCMD = &(DMA(instance)->SCMD); |
182 | HDATA(instance)->no_sync = 0xff; | ||
183 | HDATA(instance)->fast = 0; | ||
184 | HDATA(instance)->dma_mode = CTRL_DMA; | ||
182 | wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10); | 185 | wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10); |
183 | request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, "A2091 SCSI", | 186 | request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, "A2091 SCSI", |
184 | instance); | 187 | instance); |
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index 3aeec963940b..8b449d8acacd 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c | |||
@@ -178,6 +178,9 @@ int __init a3000_detect(struct scsi_host_template *tpnt) | |||
178 | DMA(a3000_host)->DAWR = DAWR_A3000; | 178 | DMA(a3000_host)->DAWR = DAWR_A3000; |
179 | regs.SASR = &(DMA(a3000_host)->SASR); | 179 | regs.SASR = &(DMA(a3000_host)->SASR); |
180 | regs.SCMD = &(DMA(a3000_host)->SCMD); | 180 | regs.SCMD = &(DMA(a3000_host)->SCMD); |
181 | HDATA(a3000_host)->no_sync = 0xff; | ||
182 | HDATA(a3000_host)->fast = 0; | ||
183 | HDATA(a3000_host)->dma_mode = CTRL_DMA; | ||
181 | wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15); | 184 | wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15); |
182 | if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI", | 185 | if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI", |
183 | a3000_intr)) | 186 | a3000_intr)) |
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index c05092fd3a9d..369fcf78f396 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -205,7 +205,7 @@ MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health" | |||
205 | 205 | ||
206 | int aac_check_reset = 1; | 206 | int aac_check_reset = 1; |
207 | module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR); | 207 | module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR); |
208 | MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the" | 208 | MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the" |
209 | " adapter. a value of -1 forces the reset to adapters programmed to" | 209 | " adapter. a value of -1 forces the reset to adapters programmed to" |
210 | " ignore it."); | 210 | " ignore it."); |
211 | 211 | ||
@@ -379,24 +379,6 @@ int aac_get_containers(struct aac_dev *dev) | |||
379 | return status; | 379 | return status; |
380 | } | 380 | } |
381 | 381 | ||
382 | static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len) | ||
383 | { | ||
384 | void *buf; | ||
385 | int transfer_len; | ||
386 | struct scatterlist *sg = scsi_sglist(scsicmd); | ||
387 | |||
388 | buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset; | ||
389 | transfer_len = min(sg->length, len + offset); | ||
390 | |||
391 | transfer_len -= offset; | ||
392 | if (buf && transfer_len > 0) | ||
393 | memcpy(buf + offset, data, transfer_len); | ||
394 | |||
395 | flush_kernel_dcache_page(kmap_atomic_to_page(buf - sg->offset)); | ||
396 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | ||
397 | |||
398 | } | ||
399 | |||
400 | static void get_container_name_callback(void *context, struct fib * fibptr) | 382 | static void get_container_name_callback(void *context, struct fib * fibptr) |
401 | { | 383 | { |
402 | struct aac_get_name_resp * get_name_reply; | 384 | struct aac_get_name_resp * get_name_reply; |
@@ -419,14 +401,17 @@ static void get_container_name_callback(void *context, struct fib * fibptr) | |||
419 | while (*sp == ' ') | 401 | while (*sp == ' ') |
420 | ++sp; | 402 | ++sp; |
421 | if (*sp) { | 403 | if (*sp) { |
404 | struct inquiry_data inq; | ||
422 | char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]; | 405 | char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)]; |
423 | int count = sizeof(d); | 406 | int count = sizeof(d); |
424 | char *dp = d; | 407 | char *dp = d; |
425 | do { | 408 | do { |
426 | *dp++ = (*sp) ? *sp++ : ' '; | 409 | *dp++ = (*sp) ? *sp++ : ' '; |
427 | } while (--count > 0); | 410 | } while (--count > 0); |
428 | aac_internal_transfer(scsicmd, d, | 411 | |
429 | offsetof(struct inquiry_data, inqd_pid), sizeof(d)); | 412 | scsi_sg_copy_to_buffer(scsicmd, &inq, sizeof(inq)); |
413 | memcpy(inq.inqd_pid, d, sizeof(d)); | ||
414 | scsi_sg_copy_from_buffer(scsicmd, &inq, sizeof(inq)); | ||
430 | } | 415 | } |
431 | } | 416 | } |
432 | 417 | ||
@@ -811,7 +796,7 @@ static void get_container_serial_callback(void *context, struct fib * fibptr) | |||
811 | sp[2] = 0; | 796 | sp[2] = 0; |
812 | sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", | 797 | sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X", |
813 | le32_to_cpu(get_serial_reply->uid)); | 798 | le32_to_cpu(get_serial_reply->uid)); |
814 | aac_internal_transfer(scsicmd, sp, 0, sizeof(sp)); | 799 | scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp)); |
815 | } | 800 | } |
816 | 801 | ||
817 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 802 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
@@ -1986,8 +1971,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1986 | arr[4] = 0x0; | 1971 | arr[4] = 0x0; |
1987 | arr[5] = 0x80; | 1972 | arr[5] = 0x80; |
1988 | arr[1] = scsicmd->cmnd[2]; | 1973 | arr[1] = scsicmd->cmnd[2]; |
1989 | aac_internal_transfer(scsicmd, &inq_data, 0, | 1974 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, |
1990 | sizeof(inq_data)); | 1975 | sizeof(inq_data)); |
1991 | scsicmd->result = DID_OK << 16 | | 1976 | scsicmd->result = DID_OK << 16 | |
1992 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 1977 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
1993 | } else if (scsicmd->cmnd[2] == 0x80) { | 1978 | } else if (scsicmd->cmnd[2] == 0x80) { |
@@ -1995,8 +1980,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
1995 | arr[3] = setinqserial(dev, &arr[4], | 1980 | arr[3] = setinqserial(dev, &arr[4], |
1996 | scmd_id(scsicmd)); | 1981 | scmd_id(scsicmd)); |
1997 | arr[1] = scsicmd->cmnd[2]; | 1982 | arr[1] = scsicmd->cmnd[2]; |
1998 | aac_internal_transfer(scsicmd, &inq_data, 0, | 1983 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, |
1999 | sizeof(inq_data)); | 1984 | sizeof(inq_data)); |
2000 | return aac_get_container_serial(scsicmd); | 1985 | return aac_get_container_serial(scsicmd); |
2001 | } else { | 1986 | } else { |
2002 | /* vpd page not implemented */ | 1987 | /* vpd page not implemented */ |
@@ -2027,7 +2012,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2027 | if (cid == host->this_id) { | 2012 | if (cid == host->this_id) { |
2028 | setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types)); | 2013 | setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types)); |
2029 | inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ | 2014 | inq_data.inqd_pdt = INQD_PDT_PROC; /* Processor device */ |
2030 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | 2015 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, |
2016 | sizeof(inq_data)); | ||
2031 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 2017 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
2032 | scsicmd->scsi_done(scsicmd); | 2018 | scsicmd->scsi_done(scsicmd); |
2033 | return 0; | 2019 | return 0; |
@@ -2036,7 +2022,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2036 | return -1; | 2022 | return -1; |
2037 | setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); | 2023 | setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type); |
2038 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ | 2024 | inq_data.inqd_pdt = INQD_PDT_DA; /* Direct/random access device */ |
2039 | aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data)); | 2025 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data)); |
2040 | return aac_get_container_name(scsicmd); | 2026 | return aac_get_container_name(scsicmd); |
2041 | } | 2027 | } |
2042 | case SERVICE_ACTION_IN: | 2028 | case SERVICE_ACTION_IN: |
@@ -2047,6 +2033,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2047 | { | 2033 | { |
2048 | u64 capacity; | 2034 | u64 capacity; |
2049 | char cp[13]; | 2035 | char cp[13]; |
2036 | unsigned int alloc_len; | ||
2050 | 2037 | ||
2051 | dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); | 2038 | dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); |
2052 | capacity = fsa_dev_ptr[cid].size - 1; | 2039 | capacity = fsa_dev_ptr[cid].size - 1; |
@@ -2063,18 +2050,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2063 | cp[10] = 2; | 2050 | cp[10] = 2; |
2064 | cp[11] = 0; | 2051 | cp[11] = 0; |
2065 | cp[12] = 0; | 2052 | cp[12] = 0; |
2066 | aac_internal_transfer(scsicmd, cp, 0, | ||
2067 | min_t(size_t, scsicmd->cmnd[13], sizeof(cp))); | ||
2068 | if (sizeof(cp) < scsicmd->cmnd[13]) { | ||
2069 | unsigned int len, offset = sizeof(cp); | ||
2070 | 2053 | ||
2071 | memset(cp, 0, offset); | 2054 | alloc_len = ((scsicmd->cmnd[10] << 24) |
2072 | do { | 2055 | + (scsicmd->cmnd[11] << 16) |
2073 | len = min_t(size_t, scsicmd->cmnd[13] - offset, | 2056 | + (scsicmd->cmnd[12] << 8) + scsicmd->cmnd[13]); |
2074 | sizeof(cp)); | 2057 | |
2075 | aac_internal_transfer(scsicmd, cp, offset, len); | 2058 | alloc_len = min_t(size_t, alloc_len, sizeof(cp)); |
2076 | } while ((offset += len) < scsicmd->cmnd[13]); | 2059 | scsi_sg_copy_from_buffer(scsicmd, cp, alloc_len); |
2077 | } | 2060 | if (alloc_len < scsi_bufflen(scsicmd)) |
2061 | scsi_set_resid(scsicmd, | ||
2062 | scsi_bufflen(scsicmd) - alloc_len); | ||
2078 | 2063 | ||
2079 | /* Do not cache partition table for arrays */ | 2064 | /* Do not cache partition table for arrays */ |
2080 | scsicmd->device->removable = 1; | 2065 | scsicmd->device->removable = 1; |
@@ -2104,7 +2089,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2104 | cp[5] = 0; | 2089 | cp[5] = 0; |
2105 | cp[6] = 2; | 2090 | cp[6] = 2; |
2106 | cp[7] = 0; | 2091 | cp[7] = 0; |
2107 | aac_internal_transfer(scsicmd, cp, 0, sizeof(cp)); | 2092 | scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp)); |
2108 | /* Do not cache partition table for arrays */ | 2093 | /* Do not cache partition table for arrays */ |
2109 | scsicmd->device->removable = 1; | 2094 | scsicmd->device->removable = 1; |
2110 | 2095 | ||
@@ -2139,7 +2124,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2139 | if (mode_buf_length > scsicmd->cmnd[4]) | 2124 | if (mode_buf_length > scsicmd->cmnd[4]) |
2140 | mode_buf_length = scsicmd->cmnd[4]; | 2125 | mode_buf_length = scsicmd->cmnd[4]; |
2141 | } | 2126 | } |
2142 | aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length); | 2127 | scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length); |
2143 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 2128 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
2144 | scsicmd->scsi_done(scsicmd); | 2129 | scsicmd->scsi_done(scsicmd); |
2145 | 2130 | ||
@@ -2174,7 +2159,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) | |||
2174 | if (mode_buf_length > scsicmd->cmnd[8]) | 2159 | if (mode_buf_length > scsicmd->cmnd[8]) |
2175 | mode_buf_length = scsicmd->cmnd[8]; | 2160 | mode_buf_length = scsicmd->cmnd[8]; |
2176 | } | 2161 | } |
2177 | aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length); | 2162 | scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length); |
2178 | 2163 | ||
2179 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; | 2164 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; |
2180 | scsicmd->scsi_done(scsicmd); | 2165 | scsicmd->scsi_done(scsicmd); |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 47434499e82b..23a8e9f8dcb4 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -515,10 +515,12 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
515 | } | 515 | } |
516 | udelay(5); | 516 | udelay(5); |
517 | } | 517 | } |
518 | } else | 518 | } else if (down_interruptible(&fibptr->event_wait) == 0) { |
519 | (void)down_interruptible(&fibptr->event_wait); | 519 | fibptr->done = 2; |
520 | up(&fibptr->event_wait); | ||
521 | } | ||
520 | spin_lock_irqsave(&fibptr->event_lock, flags); | 522 | spin_lock_irqsave(&fibptr->event_lock, flags); |
521 | if (fibptr->done == 0) { | 523 | if ((fibptr->done == 0) || (fibptr->done == 2)) { |
522 | fibptr->done = 2; /* Tell interrupt we aborted */ | 524 | fibptr->done = 2; /* Tell interrupt we aborted */ |
523 | spin_unlock_irqrestore(&fibptr->event_lock, flags); | 525 | spin_unlock_irqrestore(&fibptr->event_lock, flags); |
524 | return -EINTR; | 526 | return -EINTR; |
@@ -594,7 +596,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid) | |||
594 | if (le32_to_cpu(*q->headers.consumer) >= q->entries) | 596 | if (le32_to_cpu(*q->headers.consumer) >= q->entries) |
595 | *q->headers.consumer = cpu_to_le32(1); | 597 | *q->headers.consumer = cpu_to_le32(1); |
596 | else | 598 | else |
597 | *q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1); | 599 | le32_add_cpu(q->headers.consumer, 1); |
598 | 600 | ||
599 | if (wasfull) { | 601 | if (wasfull) { |
600 | switch (qid) { | 602 | switch (qid) { |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 72fccd9f40df..0081aa357c8b 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -1413,6 +1413,10 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, | |||
1413 | unsigned long flags; | 1413 | unsigned long flags; |
1414 | int nseg; | 1414 | int nseg; |
1415 | 1415 | ||
1416 | nseg = scsi_dma_map(cmd); | ||
1417 | if (nseg < 0) | ||
1418 | return SCSI_MLQUEUE_HOST_BUSY; | ||
1419 | |||
1416 | ahd_lock(ahd, &flags); | 1420 | ahd_lock(ahd, &flags); |
1417 | 1421 | ||
1418 | /* | 1422 | /* |
@@ -1430,6 +1434,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, | |||
1430 | if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { | 1434 | if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) { |
1431 | ahd->flags |= AHD_RESOURCE_SHORTAGE; | 1435 | ahd->flags |= AHD_RESOURCE_SHORTAGE; |
1432 | ahd_unlock(ahd, &flags); | 1436 | ahd_unlock(ahd, &flags); |
1437 | scsi_dma_unmap(cmd); | ||
1433 | return SCSI_MLQUEUE_HOST_BUSY; | 1438 | return SCSI_MLQUEUE_HOST_BUSY; |
1434 | } | 1439 | } |
1435 | 1440 | ||
@@ -1485,8 +1490,6 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev, | |||
1485 | ahd_set_sense_residual(scb, 0); | 1490 | ahd_set_sense_residual(scb, 0); |
1486 | scb->sg_count = 0; | 1491 | scb->sg_count = 0; |
1487 | 1492 | ||
1488 | nseg = scsi_dma_map(cmd); | ||
1489 | BUG_ON(nseg < 0); | ||
1490 | if (nseg > 0) { | 1493 | if (nseg > 0) { |
1491 | void *sg = scb->sg_list; | 1494 | void *sg = scb->sg_list; |
1492 | struct scatterlist *cur_seg; | 1495 | struct scatterlist *cur_seg; |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 282aff6f852e..42ad48e09f02 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
@@ -1398,12 +1398,18 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, | |||
1398 | return SCSI_MLQUEUE_DEVICE_BUSY; | 1398 | return SCSI_MLQUEUE_DEVICE_BUSY; |
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | nseg = scsi_dma_map(cmd); | ||
1402 | if (nseg < 0) | ||
1403 | return SCSI_MLQUEUE_HOST_BUSY; | ||
1404 | |||
1401 | /* | 1405 | /* |
1402 | * Get an scb to use. | 1406 | * Get an scb to use. |
1403 | */ | 1407 | */ |
1404 | scb = ahc_get_scb(ahc); | 1408 | scb = ahc_get_scb(ahc); |
1405 | if (!scb) | 1409 | if (!scb) { |
1410 | scsi_dma_unmap(cmd); | ||
1406 | return SCSI_MLQUEUE_HOST_BUSY; | 1411 | return SCSI_MLQUEUE_HOST_BUSY; |
1412 | } | ||
1407 | 1413 | ||
1408 | scb->io_ctx = cmd; | 1414 | scb->io_ctx = cmd; |
1409 | scb->platform_data->dev = dev; | 1415 | scb->platform_data->dev = dev; |
@@ -1464,8 +1470,6 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, | |||
1464 | ahc_set_sense_residual(scb, 0); | 1470 | ahc_set_sense_residual(scb, 0); |
1465 | scb->sg_count = 0; | 1471 | scb->sg_count = 0; |
1466 | 1472 | ||
1467 | nseg = scsi_dma_map(cmd); | ||
1468 | BUG_ON(nseg < 0); | ||
1469 | if (nseg > 0) { | 1473 | if (nseg > 0) { |
1470 | struct ahc_dma_seg *sg; | 1474 | struct ahc_dma_seg *sg; |
1471 | struct scatterlist *cur_seg; | 1475 | struct scatterlist *cur_seg; |
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y index 6066998ed562..702e2dbd11fb 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y +++ b/drivers/scsi/aic7xxx/aicasm/aicasm_gram.y | |||
@@ -1837,7 +1837,7 @@ type_check(symbol_t *symbol, expression_t *expression, int opcode) | |||
1837 | int and_op; | 1837 | int and_op; |
1838 | 1838 | ||
1839 | and_op = FALSE; | 1839 | and_op = FALSE; |
1840 | if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ) | 1840 | if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || opcode == AIC_OP_JZ) |
1841 | and_op = TRUE; | 1841 | and_op = TRUE; |
1842 | 1842 | ||
1843 | /* | 1843 | /* |
diff --git a/drivers/scsi/aic94xx/aic94xx.h b/drivers/scsi/aic94xx/aic94xx.h index eb8efdcefe48..2ef459e9cda1 100644 --- a/drivers/scsi/aic94xx/aic94xx.h +++ b/drivers/scsi/aic94xx/aic94xx.h | |||
@@ -58,7 +58,6 @@ | |||
58 | 58 | ||
59 | extern struct kmem_cache *asd_dma_token_cache; | 59 | extern struct kmem_cache *asd_dma_token_cache; |
60 | extern struct kmem_cache *asd_ascb_cache; | 60 | extern struct kmem_cache *asd_ascb_cache; |
61 | extern char sas_addr_str[2*SAS_ADDR_SIZE + 1]; | ||
62 | 61 | ||
63 | static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr) | 62 | static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr) |
64 | { | 63 | { |
@@ -68,21 +67,6 @@ static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr) | |||
68 | *p = '\0'; | 67 | *p = '\0'; |
69 | } | 68 | } |
70 | 69 | ||
71 | static inline void asd_destringify_sas_addr(u8 *sas_addr, const char *p) | ||
72 | { | ||
73 | int i; | ||
74 | for (i = 0; i < SAS_ADDR_SIZE; i++) { | ||
75 | u8 h, l; | ||
76 | if (!*p) | ||
77 | break; | ||
78 | h = isdigit(*p) ? *p-'0' : *p-'A'+10; | ||
79 | p++; | ||
80 | l = isdigit(*p) ? *p-'0' : *p-'A'+10; | ||
81 | p++; | ||
82 | sas_addr[i] = (h<<4) | l; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | struct asd_ha_struct; | 70 | struct asd_ha_struct; |
87 | struct asd_ascb; | 71 | struct asd_ascb; |
88 | 72 | ||
diff --git a/drivers/scsi/aic94xx/aic94xx_dev.c b/drivers/scsi/aic94xx/aic94xx_dev.c index 72042cae7768..2e2ddec9c0b6 100644 --- a/drivers/scsi/aic94xx/aic94xx_dev.c +++ b/drivers/scsi/aic94xx/aic94xx_dev.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #define SET_DDB(_ddb, _ha) set_bit(_ddb, (_ha)->hw_prof.ddb_bitmap) | 35 | #define SET_DDB(_ddb, _ha) set_bit(_ddb, (_ha)->hw_prof.ddb_bitmap) |
36 | #define CLEAR_DDB(_ddb, _ha) clear_bit(_ddb, (_ha)->hw_prof.ddb_bitmap) | 36 | #define CLEAR_DDB(_ddb, _ha) clear_bit(_ddb, (_ha)->hw_prof.ddb_bitmap) |
37 | 37 | ||
38 | static inline int asd_get_ddb(struct asd_ha_struct *asd_ha) | 38 | static int asd_get_ddb(struct asd_ha_struct *asd_ha) |
39 | { | 39 | { |
40 | int ddb, i; | 40 | int ddb, i; |
41 | 41 | ||
@@ -71,7 +71,7 @@ out: | |||
71 | #define NCQ_DATA_SCB_PTR offsetof(struct asd_ddb_stp_sata_target_port, ncq_data_scb_ptr) | 71 | #define NCQ_DATA_SCB_PTR offsetof(struct asd_ddb_stp_sata_target_port, ncq_data_scb_ptr) |
72 | #define ITNL_TIMEOUT offsetof(struct asd_ddb_ssp_smp_target_port, itnl_timeout) | 72 | #define ITNL_TIMEOUT offsetof(struct asd_ddb_ssp_smp_target_port, itnl_timeout) |
73 | 73 | ||
74 | static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb) | 74 | static void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb) |
75 | { | 75 | { |
76 | if (!ddb || ddb >= 0xFFFF) | 76 | if (!ddb || ddb >= 0xFFFF) |
77 | return; | 77 | return; |
@@ -79,7 +79,7 @@ static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb) | |||
79 | CLEAR_DDB(ddb, asd_ha); | 79 | CLEAR_DDB(ddb, asd_ha); |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline void asd_set_ddb_type(struct domain_device *dev) | 82 | static void asd_set_ddb_type(struct domain_device *dev) |
83 | { | 83 | { |
84 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; | 84 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; |
85 | int ddb = (int) (unsigned long) dev->lldd_dev; | 85 | int ddb = (int) (unsigned long) dev->lldd_dev; |
@@ -109,7 +109,7 @@ static int asd_init_sata_tag_ddb(struct domain_device *dev) | |||
109 | return 0; | 109 | return 0; |
110 | } | 110 | } |
111 | 111 | ||
112 | static inline int asd_init_sata(struct domain_device *dev) | 112 | static int asd_init_sata(struct domain_device *dev) |
113 | { | 113 | { |
114 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; | 114 | struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; |
115 | int ddb = (int) (unsigned long) dev->lldd_dev; | 115 | int ddb = (int) (unsigned long) dev->lldd_dev; |
diff --git a/drivers/scsi/aic94xx/aic94xx_dump.c b/drivers/scsi/aic94xx/aic94xx_dump.c index 3d8c4ff1f2ef..67eeba3bdb06 100644 --- a/drivers/scsi/aic94xx/aic94xx_dump.c +++ b/drivers/scsi/aic94xx/aic94xx_dump.c | |||
@@ -738,6 +738,8 @@ static void asd_dump_lseq_state(struct asd_ha_struct *asd_ha, int lseq) | |||
738 | PRINT_LMIP_dword(asd_ha, lseq, DEV_PRES_TIMER_TERM_TS); | 738 | PRINT_LMIP_dword(asd_ha, lseq, DEV_PRES_TIMER_TERM_TS); |
739 | } | 739 | } |
740 | 740 | ||
741 | #if 0 | ||
742 | |||
741 | /** | 743 | /** |
742 | * asd_dump_ddb_site -- dump a CSEQ DDB site | 744 | * asd_dump_ddb_site -- dump a CSEQ DDB site |
743 | * @asd_ha: pointer to host adapter structure | 745 | * @asd_ha: pointer to host adapter structure |
@@ -880,6 +882,8 @@ void asd_dump_scb_sites(struct asd_ha_struct *asd_ha) | |||
880 | } | 882 | } |
881 | } | 883 | } |
882 | 884 | ||
885 | #endif /* 0 */ | ||
886 | |||
883 | /** | 887 | /** |
884 | * ads_dump_seq_state -- dump CSEQ and LSEQ states | 888 | * ads_dump_seq_state -- dump CSEQ and LSEQ states |
885 | * @asd_ha: pointer to host adapter structure | 889 | * @asd_ha: pointer to host adapter structure |
@@ -922,7 +926,9 @@ void asd_dump_frame_rcvd(struct asd_phy *phy, | |||
922 | spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); | 926 | spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags); |
923 | } | 927 | } |
924 | 928 | ||
925 | static inline void asd_dump_scb(struct asd_ascb *ascb, int ind) | 929 | #if 0 |
930 | |||
931 | static void asd_dump_scb(struct asd_ascb *ascb, int ind) | ||
926 | { | 932 | { |
927 | asd_printk("scb%d: vaddr: 0x%p, dma_handle: 0x%llx, next: 0x%llx, " | 933 | asd_printk("scb%d: vaddr: 0x%p, dma_handle: 0x%llx, next: 0x%llx, " |
928 | "index:%d, opcode:0x%02x\n", | 934 | "index:%d, opcode:0x%02x\n", |
@@ -956,4 +962,6 @@ void asd_dump_scb_list(struct asd_ascb *ascb, int num) | |||
956 | } | 962 | } |
957 | } | 963 | } |
958 | 964 | ||
965 | #endif /* 0 */ | ||
966 | |||
959 | #endif /* ASD_DEBUG */ | 967 | #endif /* ASD_DEBUG */ |
diff --git a/drivers/scsi/aic94xx/aic94xx_dump.h b/drivers/scsi/aic94xx/aic94xx_dump.h index 0c388e7da6bb..191a753d42a7 100644 --- a/drivers/scsi/aic94xx/aic94xx_dump.h +++ b/drivers/scsi/aic94xx/aic94xx_dump.h | |||
@@ -29,24 +29,15 @@ | |||
29 | 29 | ||
30 | #ifdef ASD_DEBUG | 30 | #ifdef ASD_DEBUG |
31 | 31 | ||
32 | void asd_dump_ddb_0(struct asd_ha_struct *asd_ha); | ||
33 | void asd_dump_target_ddb(struct asd_ha_struct *asd_ha, u16 site_no); | ||
34 | void asd_dump_scb_sites(struct asd_ha_struct *asd_ha); | ||
35 | void asd_dump_seq_state(struct asd_ha_struct *asd_ha, u8 lseq_mask); | 32 | void asd_dump_seq_state(struct asd_ha_struct *asd_ha, u8 lseq_mask); |
36 | void asd_dump_frame_rcvd(struct asd_phy *phy, | 33 | void asd_dump_frame_rcvd(struct asd_phy *phy, |
37 | struct done_list_struct *dl); | 34 | struct done_list_struct *dl); |
38 | void asd_dump_scb_list(struct asd_ascb *ascb, int num); | ||
39 | #else /* ASD_DEBUG */ | 35 | #else /* ASD_DEBUG */ |
40 | 36 | ||
41 | static inline void asd_dump_ddb_0(struct asd_ha_struct *asd_ha) { } | ||
42 | static inline void asd_dump_target_ddb(struct asd_ha_struct *asd_ha, | ||
43 | u16 site_no) { } | ||
44 | static inline void asd_dump_scb_sites(struct asd_ha_struct *asd_ha) { } | ||
45 | static inline void asd_dump_seq_state(struct asd_ha_struct *asd_ha, | 37 | static inline void asd_dump_seq_state(struct asd_ha_struct *asd_ha, |
46 | u8 lseq_mask) { } | 38 | u8 lseq_mask) { } |
47 | static inline void asd_dump_frame_rcvd(struct asd_phy *phy, | 39 | static inline void asd_dump_frame_rcvd(struct asd_phy *phy, |
48 | struct done_list_struct *dl) { } | 40 | struct done_list_struct *dl) { } |
49 | static inline void asd_dump_scb_list(struct asd_ascb *ascb, int num) { } | ||
50 | #endif /* ASD_DEBUG */ | 41 | #endif /* ASD_DEBUG */ |
51 | 42 | ||
52 | #endif /* _AIC94XX_DUMP_H_ */ | 43 | #endif /* _AIC94XX_DUMP_H_ */ |
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c index 098b5f39cd31..83a78222896d 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <linux/delay.h> | 28 | #include <linux/delay.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/firmware.h> | ||
30 | 31 | ||
31 | #include "aic94xx.h" | 32 | #include "aic94xx.h" |
32 | #include "aic94xx_reg.h" | 33 | #include "aic94xx_reg.h" |
@@ -38,16 +39,14 @@ u32 MBAR0_SWB_SIZE; | |||
38 | 39 | ||
39 | /* ---------- Initialization ---------- */ | 40 | /* ---------- Initialization ---------- */ |
40 | 41 | ||
41 | static void asd_get_user_sas_addr(struct asd_ha_struct *asd_ha) | 42 | static int asd_get_user_sas_addr(struct asd_ha_struct *asd_ha) |
42 | { | 43 | { |
43 | extern char sas_addr_str[]; | 44 | /* adapter came with a sas address */ |
44 | /* If the user has specified a WWN it overrides other settings | 45 | if (asd_ha->hw_prof.sas_addr[0]) |
45 | */ | 46 | return 0; |
46 | if (sas_addr_str[0] != '\0') | 47 | |
47 | asd_destringify_sas_addr(asd_ha->hw_prof.sas_addr, | 48 | return sas_request_addr(asd_ha->sas_ha.core.shost, |
48 | sas_addr_str); | 49 | asd_ha->hw_prof.sas_addr); |
49 | else if (asd_ha->hw_prof.sas_addr[0] != 0) | ||
50 | asd_stringify_sas_addr(sas_addr_str, asd_ha->hw_prof.sas_addr); | ||
51 | } | 50 | } |
52 | 51 | ||
53 | static void asd_propagate_sas_addr(struct asd_ha_struct *asd_ha) | 52 | static void asd_propagate_sas_addr(struct asd_ha_struct *asd_ha) |
@@ -251,7 +250,7 @@ static int asd_init_scbs(struct asd_ha_struct *asd_ha) | |||
251 | return 0; | 250 | return 0; |
252 | } | 251 | } |
253 | 252 | ||
254 | static inline void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha) | 253 | static void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha) |
255 | { | 254 | { |
256 | asd_ha->hw_prof.max_scbs = asd_get_cmdctx_size(asd_ha)/ASD_SCB_SIZE; | 255 | asd_ha->hw_prof.max_scbs = asd_get_cmdctx_size(asd_ha)/ASD_SCB_SIZE; |
257 | asd_ha->hw_prof.max_ddbs = asd_get_devctx_size(asd_ha)/ASD_DDB_SIZE; | 256 | asd_ha->hw_prof.max_ddbs = asd_get_devctx_size(asd_ha)/ASD_DDB_SIZE; |
@@ -657,8 +656,7 @@ int asd_init_hw(struct asd_ha_struct *asd_ha) | |||
657 | 656 | ||
658 | asd_init_ctxmem(asd_ha); | 657 | asd_init_ctxmem(asd_ha); |
659 | 658 | ||
660 | asd_get_user_sas_addr(asd_ha); | 659 | if (asd_get_user_sas_addr(asd_ha)) { |
661 | if (!asd_ha->hw_prof.sas_addr[0]) { | ||
662 | asd_printk("No SAS Address provided for %s\n", | 660 | asd_printk("No SAS Address provided for %s\n", |
663 | pci_name(asd_ha->pcidev)); | 661 | pci_name(asd_ha->pcidev)); |
664 | err = -ENODEV; | 662 | err = -ENODEV; |
@@ -773,7 +771,7 @@ static void asd_dl_tasklet_handler(unsigned long data) | |||
773 | * asd_process_donelist_isr -- schedule processing of done list entries | 771 | * asd_process_donelist_isr -- schedule processing of done list entries |
774 | * @asd_ha: pointer to host adapter structure | 772 | * @asd_ha: pointer to host adapter structure |
775 | */ | 773 | */ |
776 | static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha) | 774 | static void asd_process_donelist_isr(struct asd_ha_struct *asd_ha) |
777 | { | 775 | { |
778 | tasklet_schedule(&asd_ha->seq.dl_tasklet); | 776 | tasklet_schedule(&asd_ha->seq.dl_tasklet); |
779 | } | 777 | } |
@@ -782,7 +780,7 @@ static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha) | |||
782 | * asd_com_sas_isr -- process device communication interrupt (COMINT) | 780 | * asd_com_sas_isr -- process device communication interrupt (COMINT) |
783 | * @asd_ha: pointer to host adapter structure | 781 | * @asd_ha: pointer to host adapter structure |
784 | */ | 782 | */ |
785 | static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha) | 783 | static void asd_com_sas_isr(struct asd_ha_struct *asd_ha) |
786 | { | 784 | { |
787 | u32 comstat = asd_read_reg_dword(asd_ha, COMSTAT); | 785 | u32 comstat = asd_read_reg_dword(asd_ha, COMSTAT); |
788 | 786 | ||
@@ -821,7 +819,7 @@ static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha) | |||
821 | asd_chip_reset(asd_ha); | 819 | asd_chip_reset(asd_ha); |
822 | } | 820 | } |
823 | 821 | ||
824 | static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus) | 822 | static void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus) |
825 | { | 823 | { |
826 | static const char *halt_code[256] = { | 824 | static const char *halt_code[256] = { |
827 | "UNEXPECTED_INTERRUPT0", | 825 | "UNEXPECTED_INTERRUPT0", |
@@ -908,7 +906,7 @@ static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus) | |||
908 | * asd_dch_sas_isr -- process device channel interrupt (DEVINT) | 906 | * asd_dch_sas_isr -- process device channel interrupt (DEVINT) |
909 | * @asd_ha: pointer to host adapter structure | 907 | * @asd_ha: pointer to host adapter structure |
910 | */ | 908 | */ |
911 | static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha) | 909 | static void asd_dch_sas_isr(struct asd_ha_struct *asd_ha) |
912 | { | 910 | { |
913 | u32 dchstatus = asd_read_reg_dword(asd_ha, DCHSTATUS); | 911 | u32 dchstatus = asd_read_reg_dword(asd_ha, DCHSTATUS); |
914 | 912 | ||
@@ -923,7 +921,7 @@ static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha) | |||
923 | * ads_rbi_exsi_isr -- process external system interface interrupt (INITERR) | 921 | * ads_rbi_exsi_isr -- process external system interface interrupt (INITERR) |
924 | * @asd_ha: pointer to host adapter structure | 922 | * @asd_ha: pointer to host adapter structure |
925 | */ | 923 | */ |
926 | static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha) | 924 | static void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha) |
927 | { | 925 | { |
928 | u32 stat0r = asd_read_reg_dword(asd_ha, ASISTAT0R); | 926 | u32 stat0r = asd_read_reg_dword(asd_ha, ASISTAT0R); |
929 | 927 | ||
@@ -971,7 +969,7 @@ static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha) | |||
971 | * | 969 | * |
972 | * Asserted on PCIX errors: target abort, etc. | 970 | * Asserted on PCIX errors: target abort, etc. |
973 | */ | 971 | */ |
974 | static inline void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha) | 972 | static void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha) |
975 | { | 973 | { |
976 | u16 status; | 974 | u16 status; |
977 | u32 pcix_status; | 975 | u32 pcix_status; |
@@ -1044,8 +1042,8 @@ irqreturn_t asd_hw_isr(int irq, void *dev_id) | |||
1044 | 1042 | ||
1045 | /* ---------- SCB handling ---------- */ | 1043 | /* ---------- SCB handling ---------- */ |
1046 | 1044 | ||
1047 | static inline struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha, | 1045 | static struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha, |
1048 | gfp_t gfp_flags) | 1046 | gfp_t gfp_flags) |
1049 | { | 1047 | { |
1050 | extern struct kmem_cache *asd_ascb_cache; | 1048 | extern struct kmem_cache *asd_ascb_cache; |
1051 | struct asd_seq_data *seq = &asd_ha->seq; | 1049 | struct asd_seq_data *seq = &asd_ha->seq; |
@@ -1144,8 +1142,8 @@ struct asd_ascb *asd_ascb_alloc_list(struct asd_ha_struct | |||
1144 | * | 1142 | * |
1145 | * LOCKING: called with the pending list lock held. | 1143 | * LOCKING: called with the pending list lock held. |
1146 | */ | 1144 | */ |
1147 | static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha, | 1145 | static void asd_swap_head_scb(struct asd_ha_struct *asd_ha, |
1148 | struct asd_ascb *ascb) | 1146 | struct asd_ascb *ascb) |
1149 | { | 1147 | { |
1150 | struct asd_seq_data *seq = &asd_ha->seq; | 1148 | struct asd_seq_data *seq = &asd_ha->seq; |
1151 | struct asd_ascb *last = list_entry(ascb->list.prev, | 1149 | struct asd_ascb *last = list_entry(ascb->list.prev, |
@@ -1171,7 +1169,7 @@ static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha, | |||
1171 | * intended to be called from asd_post_ascb_list(), just prior to | 1169 | * intended to be called from asd_post_ascb_list(), just prior to |
1172 | * posting the SCBs to the sequencer. | 1170 | * posting the SCBs to the sequencer. |
1173 | */ | 1171 | */ |
1174 | static inline void asd_start_scb_timers(struct list_head *list) | 1172 | static void asd_start_scb_timers(struct list_head *list) |
1175 | { | 1173 | { |
1176 | struct asd_ascb *ascb; | 1174 | struct asd_ascb *ascb; |
1177 | list_for_each_entry(ascb, list, list) { | 1175 | list_for_each_entry(ascb, list, list) { |
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h index abc757559c1a..8c1c28239e93 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.h +++ b/drivers/scsi/aic94xx/aic94xx_hwi.h | |||
@@ -391,8 +391,6 @@ void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc); | |||
391 | void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op); | 391 | void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op); |
392 | void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op); | 392 | void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op); |
393 | int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask); | 393 | int asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask); |
394 | void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id, | ||
395 | u8 subfunc); | ||
396 | 394 | ||
397 | void asd_ascb_timedout(unsigned long data); | 395 | void asd_ascb_timedout(unsigned long data); |
398 | int asd_chip_hardrst(struct asd_ha_struct *asd_ha); | 396 | int asd_chip_hardrst(struct asd_ha_struct *asd_ha); |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 88d1e731b65e..90f5e0a6f2e3 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -56,8 +56,6 @@ MODULE_PARM_DESC(collector, "\n" | |||
56 | "\tThe aic94xx SAS LLDD supports both modes.\n" | 56 | "\tThe aic94xx SAS LLDD supports both modes.\n" |
57 | "\tDefault: 0 (Direct Mode).\n"); | 57 | "\tDefault: 0 (Direct Mode).\n"); |
58 | 58 | ||
59 | char sas_addr_str[2*SAS_ADDR_SIZE + 1] = ""; | ||
60 | |||
61 | static struct scsi_transport_template *aic94xx_transport_template; | 59 | static struct scsi_transport_template *aic94xx_transport_template; |
62 | static int asd_scan_finished(struct Scsi_Host *, unsigned long); | 60 | static int asd_scan_finished(struct Scsi_Host *, unsigned long); |
63 | static void asd_scan_start(struct Scsi_Host *); | 61 | static void asd_scan_start(struct Scsi_Host *); |
@@ -547,7 +545,7 @@ static struct asd_pcidev_struct { | |||
547 | }, | 545 | }, |
548 | }; | 546 | }; |
549 | 547 | ||
550 | static inline int asd_create_ha_caches(struct asd_ha_struct *asd_ha) | 548 | static int asd_create_ha_caches(struct asd_ha_struct *asd_ha) |
551 | { | 549 | { |
552 | asd_ha->scb_pool = dma_pool_create(ASD_DRIVER_NAME "_scb_pool", | 550 | asd_ha->scb_pool = dma_pool_create(ASD_DRIVER_NAME "_scb_pool", |
553 | &asd_ha->pcidev->dev, | 551 | &asd_ha->pcidev->dev, |
@@ -565,7 +563,7 @@ static inline int asd_create_ha_caches(struct asd_ha_struct *asd_ha) | |||
565 | * asd_free_edbs -- free empty data buffers | 563 | * asd_free_edbs -- free empty data buffers |
566 | * asd_ha: pointer to host adapter structure | 564 | * asd_ha: pointer to host adapter structure |
567 | */ | 565 | */ |
568 | static inline void asd_free_edbs(struct asd_ha_struct *asd_ha) | 566 | static void asd_free_edbs(struct asd_ha_struct *asd_ha) |
569 | { | 567 | { |
570 | struct asd_seq_data *seq = &asd_ha->seq; | 568 | struct asd_seq_data *seq = &asd_ha->seq; |
571 | int i; | 569 | int i; |
@@ -576,7 +574,7 @@ static inline void asd_free_edbs(struct asd_ha_struct *asd_ha) | |||
576 | seq->edb_arr = NULL; | 574 | seq->edb_arr = NULL; |
577 | } | 575 | } |
578 | 576 | ||
579 | static inline void asd_free_escbs(struct asd_ha_struct *asd_ha) | 577 | static void asd_free_escbs(struct asd_ha_struct *asd_ha) |
580 | { | 578 | { |
581 | struct asd_seq_data *seq = &asd_ha->seq; | 579 | struct asd_seq_data *seq = &asd_ha->seq; |
582 | int i; | 580 | int i; |
@@ -591,7 +589,7 @@ static inline void asd_free_escbs(struct asd_ha_struct *asd_ha) | |||
591 | seq->escb_arr = NULL; | 589 | seq->escb_arr = NULL; |
592 | } | 590 | } |
593 | 591 | ||
594 | static inline void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha) | 592 | static void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha) |
595 | { | 593 | { |
596 | int i; | 594 | int i; |
597 | 595 | ||
diff --git a/drivers/scsi/aic94xx/aic94xx_reg.c b/drivers/scsi/aic94xx/aic94xx_reg.c index f210dac3203d..56b17c22526e 100644 --- a/drivers/scsi/aic94xx/aic94xx_reg.c +++ b/drivers/scsi/aic94xx/aic94xx_reg.c | |||
@@ -32,8 +32,8 @@ | |||
32 | * Offset comes before value to remind that the operation of | 32 | * Offset comes before value to remind that the operation of |
33 | * this function is *offs = val. | 33 | * this function is *offs = val. |
34 | */ | 34 | */ |
35 | static inline void asd_write_byte(struct asd_ha_struct *asd_ha, | 35 | static void asd_write_byte(struct asd_ha_struct *asd_ha, |
36 | unsigned long offs, u8 val) | 36 | unsigned long offs, u8 val) |
37 | { | 37 | { |
38 | if (unlikely(asd_ha->iospace)) | 38 | if (unlikely(asd_ha->iospace)) |
39 | outb(val, | 39 | outb(val, |
@@ -43,8 +43,8 @@ static inline void asd_write_byte(struct asd_ha_struct *asd_ha, | |||
43 | wmb(); | 43 | wmb(); |
44 | } | 44 | } |
45 | 45 | ||
46 | static inline void asd_write_word(struct asd_ha_struct *asd_ha, | 46 | static void asd_write_word(struct asd_ha_struct *asd_ha, |
47 | unsigned long offs, u16 val) | 47 | unsigned long offs, u16 val) |
48 | { | 48 | { |
49 | if (unlikely(asd_ha->iospace)) | 49 | if (unlikely(asd_ha->iospace)) |
50 | outw(val, | 50 | outw(val, |
@@ -54,8 +54,8 @@ static inline void asd_write_word(struct asd_ha_struct *asd_ha, | |||
54 | wmb(); | 54 | wmb(); |
55 | } | 55 | } |
56 | 56 | ||
57 | static inline void asd_write_dword(struct asd_ha_struct *asd_ha, | 57 | static void asd_write_dword(struct asd_ha_struct *asd_ha, |
58 | unsigned long offs, u32 val) | 58 | unsigned long offs, u32 val) |
59 | { | 59 | { |
60 | if (unlikely(asd_ha->iospace)) | 60 | if (unlikely(asd_ha->iospace)) |
61 | outl(val, | 61 | outl(val, |
@@ -67,8 +67,7 @@ static inline void asd_write_dword(struct asd_ha_struct *asd_ha, | |||
67 | 67 | ||
68 | /* Reading from device address space. | 68 | /* Reading from device address space. |
69 | */ | 69 | */ |
70 | static inline u8 asd_read_byte(struct asd_ha_struct *asd_ha, | 70 | static u8 asd_read_byte(struct asd_ha_struct *asd_ha, unsigned long offs) |
71 | unsigned long offs) | ||
72 | { | 71 | { |
73 | u8 val; | 72 | u8 val; |
74 | if (unlikely(asd_ha->iospace)) | 73 | if (unlikely(asd_ha->iospace)) |
@@ -80,8 +79,8 @@ static inline u8 asd_read_byte(struct asd_ha_struct *asd_ha, | |||
80 | return val; | 79 | return val; |
81 | } | 80 | } |
82 | 81 | ||
83 | static inline u16 asd_read_word(struct asd_ha_struct *asd_ha, | 82 | static u16 asd_read_word(struct asd_ha_struct *asd_ha, |
84 | unsigned long offs) | 83 | unsigned long offs) |
85 | { | 84 | { |
86 | u16 val; | 85 | u16 val; |
87 | if (unlikely(asd_ha->iospace)) | 86 | if (unlikely(asd_ha->iospace)) |
@@ -93,8 +92,8 @@ static inline u16 asd_read_word(struct asd_ha_struct *asd_ha, | |||
93 | return val; | 92 | return val; |
94 | } | 93 | } |
95 | 94 | ||
96 | static inline u32 asd_read_dword(struct asd_ha_struct *asd_ha, | 95 | static u32 asd_read_dword(struct asd_ha_struct *asd_ha, |
97 | unsigned long offs) | 96 | unsigned long offs) |
98 | { | 97 | { |
99 | u32 val; | 98 | u32 val; |
100 | if (unlikely(asd_ha->iospace)) | 99 | if (unlikely(asd_ha->iospace)) |
@@ -124,22 +123,22 @@ static inline u32 asd_mem_offs_swb(void) | |||
124 | /* We know that the register wanted is in the range | 123 | /* We know that the register wanted is in the range |
125 | * of the sliding window. | 124 | * of the sliding window. |
126 | */ | 125 | */ |
127 | #define ASD_READ_SW(ww, type, ord) \ | 126 | #define ASD_READ_SW(ww, type, ord) \ |
128 | static inline type asd_read_##ww##_##ord (struct asd_ha_struct *asd_ha,\ | 127 | static type asd_read_##ww##_##ord(struct asd_ha_struct *asd_ha, \ |
129 | u32 reg) \ | 128 | u32 reg) \ |
130 | { \ | 129 | { \ |
131 | struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \ | 130 | struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \ |
132 | u32 map_offs=(reg - io_handle-> ww##_base )+asd_mem_offs_##ww ();\ | 131 | u32 map_offs = (reg - io_handle->ww##_base) + asd_mem_offs_##ww();\ |
133 | return asd_read_##ord (asd_ha, (unsigned long) map_offs); \ | 132 | return asd_read_##ord(asd_ha, (unsigned long)map_offs); \ |
134 | } | 133 | } |
135 | 134 | ||
136 | #define ASD_WRITE_SW(ww, type, ord) \ | 135 | #define ASD_WRITE_SW(ww, type, ord) \ |
137 | static inline void asd_write_##ww##_##ord (struct asd_ha_struct *asd_ha,\ | 136 | static void asd_write_##ww##_##ord(struct asd_ha_struct *asd_ha, \ |
138 | u32 reg, type val) \ | 137 | u32 reg, type val) \ |
139 | { \ | 138 | { \ |
140 | struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \ | 139 | struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0]; \ |
141 | u32 map_offs=(reg - io_handle-> ww##_base )+asd_mem_offs_##ww ();\ | 140 | u32 map_offs = (reg - io_handle->ww##_base) + asd_mem_offs_##ww();\ |
142 | asd_write_##ord (asd_ha, (unsigned long) map_offs, val); \ | 141 | asd_write_##ord(asd_ha, (unsigned long)map_offs, val); \ |
143 | } | 142 | } |
144 | 143 | ||
145 | ASD_READ_SW(swa, u8, byte); | 144 | ASD_READ_SW(swa, u8, byte); |
@@ -186,7 +185,7 @@ ASD_WRITE_SW(swc, u32, dword); | |||
186 | * @asd_ha: pointer to host adapter structure | 185 | * @asd_ha: pointer to host adapter structure |
187 | * @reg: register desired to be within range of the new window | 186 | * @reg: register desired to be within range of the new window |
188 | */ | 187 | */ |
189 | static inline void asd_move_swb(struct asd_ha_struct *asd_ha, u32 reg) | 188 | static void asd_move_swb(struct asd_ha_struct *asd_ha, u32 reg) |
190 | { | 189 | { |
191 | u32 base = reg & ~(MBAR0_SWB_SIZE-1); | 190 | u32 base = reg & ~(MBAR0_SWB_SIZE-1); |
192 | pci_write_config_dword(asd_ha->pcidev, PCI_CONF_MBAR0_SWB, base); | 191 | pci_write_config_dword(asd_ha->pcidev, PCI_CONF_MBAR0_SWB, base); |
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index ab350504ca5a..46643319c520 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c | |||
@@ -50,7 +50,7 @@ | |||
50 | | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \ | 50 | | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \ |
51 | | CURRENT_OOB_ERROR) | 51 | | CURRENT_OOB_ERROR) |
52 | 52 | ||
53 | static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode) | 53 | static void get_lrate_mode(struct asd_phy *phy, u8 oob_mode) |
54 | { | 54 | { |
55 | struct sas_phy *sas_phy = phy->sas_phy.phy; | 55 | struct sas_phy *sas_phy = phy->sas_phy.phy; |
56 | 56 | ||
@@ -81,7 +81,7 @@ static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode) | |||
81 | phy->sas_phy.oob_mode = SATA_OOB_MODE; | 81 | phy->sas_phy.oob_mode = SATA_OOB_MODE; |
82 | } | 82 | } |
83 | 83 | ||
84 | static inline void asd_phy_event_tasklet(struct asd_ascb *ascb, | 84 | static void asd_phy_event_tasklet(struct asd_ascb *ascb, |
85 | struct done_list_struct *dl) | 85 | struct done_list_struct *dl) |
86 | { | 86 | { |
87 | struct asd_ha_struct *asd_ha = ascb->ha; | 87 | struct asd_ha_struct *asd_ha = ascb->ha; |
@@ -125,8 +125,7 @@ static inline void asd_phy_event_tasklet(struct asd_ascb *ascb, | |||
125 | } | 125 | } |
126 | 126 | ||
127 | /* If phys are enabled sparsely, this will do the right thing. */ | 127 | /* If phys are enabled sparsely, this will do the right thing. */ |
128 | static inline unsigned ord_phy(struct asd_ha_struct *asd_ha, | 128 | static unsigned ord_phy(struct asd_ha_struct *asd_ha, struct asd_phy *phy) |
129 | struct asd_phy *phy) | ||
130 | { | 129 | { |
131 | u8 enabled_mask = asd_ha->hw_prof.enabled_phys; | 130 | u8 enabled_mask = asd_ha->hw_prof.enabled_phys; |
132 | int i, k = 0; | 131 | int i, k = 0; |
@@ -151,7 +150,7 @@ static inline unsigned ord_phy(struct asd_ha_struct *asd_ha, | |||
151 | * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame | 150 | * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame |
152 | * buffer. | 151 | * buffer. |
153 | */ | 152 | */ |
154 | static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr) | 153 | static void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr) |
155 | { | 154 | { |
156 | if (phy->sas_phy.frame_rcvd[0] == 0x34 | 155 | if (phy->sas_phy.frame_rcvd[0] == 0x34 |
157 | && phy->sas_phy.oob_mode == SATA_OOB_MODE) { | 156 | && phy->sas_phy.oob_mode == SATA_OOB_MODE) { |
@@ -232,9 +231,9 @@ static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy) | |||
232 | spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); | 231 | spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags); |
233 | } | 232 | } |
234 | 233 | ||
235 | static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, | 234 | static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, |
236 | struct done_list_struct *dl, | 235 | struct done_list_struct *dl, |
237 | int edb_id, int phy_id) | 236 | int edb_id, int phy_id) |
238 | { | 237 | { |
239 | unsigned long flags; | 238 | unsigned long flags; |
240 | int edb_el = edb_id + ascb->edb_index; | 239 | int edb_el = edb_id + ascb->edb_index; |
@@ -255,9 +254,9 @@ static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb, | |||
255 | sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); | 254 | sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED); |
256 | } | 255 | } |
257 | 256 | ||
258 | static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb, | 257 | static void asd_link_reset_err_tasklet(struct asd_ascb *ascb, |
259 | struct done_list_struct *dl, | 258 | struct done_list_struct *dl, |
260 | int phy_id) | 259 | int phy_id) |
261 | { | 260 | { |
262 | struct asd_ha_struct *asd_ha = ascb->ha; | 261 | struct asd_ha_struct *asd_ha = ascb->ha; |
263 | struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; | 262 | struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; |
@@ -308,9 +307,9 @@ out: | |||
308 | ; | 307 | ; |
309 | } | 308 | } |
310 | 309 | ||
311 | static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, | 310 | static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb, |
312 | struct done_list_struct *dl, | 311 | struct done_list_struct *dl, |
313 | int phy_id) | 312 | int phy_id) |
314 | { | 313 | { |
315 | unsigned long flags; | 314 | unsigned long flags; |
316 | struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha; | 315 | struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha; |
@@ -715,7 +714,7 @@ out: | |||
715 | asd_ascb_free(ascb); | 714 | asd_ascb_free(ascb); |
716 | } | 715 | } |
717 | 716 | ||
718 | static inline void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd) | 717 | static void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd) |
719 | { | 718 | { |
720 | /* disable all speeds, then enable defaults */ | 719 | /* disable all speeds, then enable defaults */ |
721 | *speed_mask = SAS_SPEED_60_DIS | SAS_SPEED_30_DIS | SAS_SPEED_15_DIS | 720 | *speed_mask = SAS_SPEED_60_DIS | SAS_SPEED_30_DIS | SAS_SPEED_15_DIS |
@@ -820,6 +819,8 @@ void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc) | |||
820 | 819 | ||
821 | /* ---------- INITIATE LINK ADM TASK ---------- */ | 820 | /* ---------- INITIATE LINK ADM TASK ---------- */ |
822 | 821 | ||
822 | #if 0 | ||
823 | |||
823 | static void link_adm_tasklet_complete(struct asd_ascb *ascb, | 824 | static void link_adm_tasklet_complete(struct asd_ascb *ascb, |
824 | struct done_list_struct *dl) | 825 | struct done_list_struct *dl) |
825 | { | 826 | { |
@@ -852,6 +853,8 @@ void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id, | |||
852 | ascb->tasklet_complete = link_adm_tasklet_complete; | 853 | ascb->tasklet_complete = link_adm_tasklet_complete; |
853 | } | 854 | } |
854 | 855 | ||
856 | #endif /* 0 */ | ||
857 | |||
855 | /* ---------- SCB timer ---------- */ | 858 | /* ---------- SCB timer ---------- */ |
856 | 859 | ||
857 | /** | 860 | /** |
diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index 2a4c933eb89c..4446e3d584dc 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/drivers/scsi/aic94xx/aic94xx_sds.c | |||
@@ -590,8 +590,8 @@ static int asd_reset_flash(struct asd_ha_struct *asd_ha) | |||
590 | return err; | 590 | return err; |
591 | } | 591 | } |
592 | 592 | ||
593 | static inline int asd_read_flash_seg(struct asd_ha_struct *asd_ha, | 593 | static int asd_read_flash_seg(struct asd_ha_struct *asd_ha, |
594 | void *buffer, u32 offs, int size) | 594 | void *buffer, u32 offs, int size) |
595 | { | 595 | { |
596 | asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs, | 596 | asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs, |
597 | size); | 597 | size); |
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c index c750fbf7013b..f4272ac4c685 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/drivers/scsi/aic94xx/aic94xx_seq.c | |||
@@ -60,7 +60,7 @@ static u16 last_scb_site_no; | |||
60 | * | 60 | * |
61 | * Return 0 on success, negative on failure. | 61 | * Return 0 on success, negative on failure. |
62 | */ | 62 | */ |
63 | int asd_pause_cseq(struct asd_ha_struct *asd_ha) | 63 | static int asd_pause_cseq(struct asd_ha_struct *asd_ha) |
64 | { | 64 | { |
65 | int count = PAUSE_TRIES; | 65 | int count = PAUSE_TRIES; |
66 | u32 arp2ctl; | 66 | u32 arp2ctl; |
@@ -87,7 +87,7 @@ int asd_pause_cseq(struct asd_ha_struct *asd_ha) | |||
87 | * | 87 | * |
88 | * Return 0 on success, negative on error. | 88 | * Return 0 on success, negative on error. |
89 | */ | 89 | */ |
90 | int asd_unpause_cseq(struct asd_ha_struct *asd_ha) | 90 | static int asd_unpause_cseq(struct asd_ha_struct *asd_ha) |
91 | { | 91 | { |
92 | u32 arp2ctl; | 92 | u32 arp2ctl; |
93 | int count = PAUSE_TRIES; | 93 | int count = PAUSE_TRIES; |
@@ -115,7 +115,7 @@ int asd_unpause_cseq(struct asd_ha_struct *asd_ha) | |||
115 | * | 115 | * |
116 | * Return 0 on success, negative on error. | 116 | * Return 0 on success, negative on error. |
117 | */ | 117 | */ |
118 | static inline int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq) | 118 | static int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq) |
119 | { | 119 | { |
120 | u32 arp2ctl; | 120 | u32 arp2ctl; |
121 | int count = PAUSE_TRIES; | 121 | int count = PAUSE_TRIES; |
@@ -143,7 +143,7 @@ static inline int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq) | |||
143 | * | 143 | * |
144 | * Return 0 on success, negative on failure. | 144 | * Return 0 on success, negative on failure. |
145 | */ | 145 | */ |
146 | int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask) | 146 | static int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask) |
147 | { | 147 | { |
148 | int lseq; | 148 | int lseq; |
149 | int err = 0; | 149 | int err = 0; |
@@ -164,7 +164,7 @@ int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask) | |||
164 | * | 164 | * |
165 | * Return 0 on success, negative on error. | 165 | * Return 0 on success, negative on error. |
166 | */ | 166 | */ |
167 | static inline int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq) | 167 | static int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq) |
168 | { | 168 | { |
169 | u32 arp2ctl; | 169 | u32 arp2ctl; |
170 | int count = PAUSE_TRIES; | 170 | int count = PAUSE_TRIES; |
@@ -186,27 +186,6 @@ static inline int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq) | |||
186 | } | 186 | } |
187 | 187 | ||
188 | 188 | ||
189 | /** | ||
190 | * asd_unpause_lseq - unpause the link sequencer(s) | ||
191 | * @asd_ha: pointer to host adapter structure | ||
192 | * @lseq_mask: mask of link sequencers of interest | ||
193 | * | ||
194 | * Return 0 on success, negative on failure. | ||
195 | */ | ||
196 | int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask) | ||
197 | { | ||
198 | int lseq; | ||
199 | int err = 0; | ||
200 | |||
201 | for_each_sequencer(lseq_mask, lseq_mask, lseq) { | ||
202 | err = asd_seq_unpause_lseq(asd_ha, lseq); | ||
203 | if (err) | ||
204 | return err; | ||
205 | } | ||
206 | |||
207 | return err; | ||
208 | } | ||
209 | |||
210 | /* ---------- Downloading CSEQ/LSEQ microcode ---------- */ | 189 | /* ---------- Downloading CSEQ/LSEQ microcode ---------- */ |
211 | 190 | ||
212 | static int asd_verify_cseq(struct asd_ha_struct *asd_ha, const u8 *_prog, | 191 | static int asd_verify_cseq(struct asd_ha_struct *asd_ha, const u8 *_prog, |
diff --git a/drivers/scsi/aic94xx/aic94xx_seq.h b/drivers/scsi/aic94xx/aic94xx_seq.h index 2ea6a0d52208..ad787c55525f 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.h +++ b/drivers/scsi/aic94xx/aic94xx_seq.h | |||
@@ -58,10 +58,6 @@ struct sequencer_file_header { | |||
58 | } __attribute__((packed)); | 58 | } __attribute__((packed)); |
59 | 59 | ||
60 | #ifdef __KERNEL__ | 60 | #ifdef __KERNEL__ |
61 | int asd_pause_cseq(struct asd_ha_struct *asd_ha); | ||
62 | int asd_unpause_cseq(struct asd_ha_struct *asd_ha); | ||
63 | int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); | ||
64 | int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask); | ||
65 | int asd_init_seqs(struct asd_ha_struct *asd_ha); | 61 | int asd_init_seqs(struct asd_ha_struct *asd_ha); |
66 | int asd_start_seqs(struct asd_ha_struct *asd_ha); | 62 | int asd_start_seqs(struct asd_ha_struct *asd_ha); |
67 | int asd_release_firmware(void); | 63 | int asd_release_firmware(void); |
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index 008df9ab92a5..326765c9caf8 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c | |||
@@ -33,7 +33,7 @@ static void asd_unbuild_ata_ascb(struct asd_ascb *a); | |||
33 | static void asd_unbuild_smp_ascb(struct asd_ascb *a); | 33 | static void asd_unbuild_smp_ascb(struct asd_ascb *a); |
34 | static void asd_unbuild_ssp_ascb(struct asd_ascb *a); | 34 | static void asd_unbuild_ssp_ascb(struct asd_ascb *a); |
35 | 35 | ||
36 | static inline void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num) | 36 | static void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num) |
37 | { | 37 | { |
38 | unsigned long flags; | 38 | unsigned long flags; |
39 | 39 | ||
@@ -51,9 +51,9 @@ static const u8 data_dir_flags[] = { | |||
51 | [PCI_DMA_NONE] = DATA_DIR_NONE, /* NO TRANSFER */ | 51 | [PCI_DMA_NONE] = DATA_DIR_NONE, /* NO TRANSFER */ |
52 | }; | 52 | }; |
53 | 53 | ||
54 | static inline int asd_map_scatterlist(struct sas_task *task, | 54 | static int asd_map_scatterlist(struct sas_task *task, |
55 | struct sg_el *sg_arr, | 55 | struct sg_el *sg_arr, |
56 | gfp_t gfp_flags) | 56 | gfp_t gfp_flags) |
57 | { | 57 | { |
58 | struct asd_ascb *ascb = task->lldd_task; | 58 | struct asd_ascb *ascb = task->lldd_task; |
59 | struct asd_ha_struct *asd_ha = ascb->ha; | 59 | struct asd_ha_struct *asd_ha = ascb->ha; |
@@ -131,7 +131,7 @@ err_unmap: | |||
131 | return res; | 131 | return res; |
132 | } | 132 | } |
133 | 133 | ||
134 | static inline void asd_unmap_scatterlist(struct asd_ascb *ascb) | 134 | static void asd_unmap_scatterlist(struct asd_ascb *ascb) |
135 | { | 135 | { |
136 | struct asd_ha_struct *asd_ha = ascb->ha; | 136 | struct asd_ha_struct *asd_ha = ascb->ha; |
137 | struct sas_task *task = ascb->uldd_task; | 137 | struct sas_task *task = ascb->uldd_task; |
@@ -527,7 +527,7 @@ static void asd_unbuild_ssp_ascb(struct asd_ascb *a) | |||
527 | 527 | ||
528 | /* ---------- Execute Task ---------- */ | 528 | /* ---------- Execute Task ---------- */ |
529 | 529 | ||
530 | static inline int asd_can_queue(struct asd_ha_struct *asd_ha, int num) | 530 | static int asd_can_queue(struct asd_ha_struct *asd_ha, int num) |
531 | { | 531 | { |
532 | int res = 0; | 532 | int res = 0; |
533 | unsigned long flags; | 533 | unsigned long flags; |
diff --git a/drivers/scsi/aic94xx/aic94xx_tmf.c b/drivers/scsi/aic94xx/aic94xx_tmf.c index b9ac8f703a1d..633ff40c736a 100644 --- a/drivers/scsi/aic94xx/aic94xx_tmf.c +++ b/drivers/scsi/aic94xx/aic94xx_tmf.c | |||
@@ -336,7 +336,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb, | |||
336 | asd_ascb_free(ascb); | 336 | asd_ascb_free(ascb); |
337 | } | 337 | } |
338 | 338 | ||
339 | static inline int asd_clear_nexus(struct sas_task *task) | 339 | static int asd_clear_nexus(struct sas_task *task) |
340 | { | 340 | { |
341 | int res = TMF_RESP_FUNC_FAILED; | 341 | int res = TMF_RESP_FUNC_FAILED; |
342 | int leftover; | 342 | int leftover; |
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index 3bedf2466bd1..8e53f02cc311 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c | |||
@@ -2983,7 +2983,6 @@ static struct scsi_host_template acornscsi_template = { | |||
2983 | .this_id = 7, | 2983 | .this_id = 7, |
2984 | .sg_tablesize = SG_ALL, | 2984 | .sg_tablesize = SG_ALL, |
2985 | .cmd_per_lun = 2, | 2985 | .cmd_per_lun = 2, |
2986 | .unchecked_isa_dma = 0, | ||
2987 | .use_clustering = DISABLE_CLUSTERING, | 2986 | .use_clustering = DISABLE_CLUSTERING, |
2988 | .proc_name = "acornscsi", | 2987 | .proc_name = "acornscsi", |
2989 | }; | 2988 | }; |
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index 49d838e90a24..a3398fe70a9c 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c | |||
@@ -222,7 +222,6 @@ static struct scsi_host_template cumanascsi_template = { | |||
222 | .this_id = 7, | 222 | .this_id = 7, |
223 | .sg_tablesize = SG_ALL, | 223 | .sg_tablesize = SG_ALL, |
224 | .cmd_per_lun = 2, | 224 | .cmd_per_lun = 2, |
225 | .unchecked_isa_dma = 0, | ||
226 | .use_clustering = DISABLE_CLUSTERING, | 225 | .use_clustering = DISABLE_CLUSTERING, |
227 | .proc_name = "CumanaSCSI-1", | 226 | .proc_name = "CumanaSCSI-1", |
228 | }; | 227 | }; |
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 7aad15436d24..92d1cb1b21cb 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c | |||
@@ -113,7 +113,7 @@ static const struct { | |||
113 | unsigned char asc; | 113 | unsigned char asc; |
114 | unsigned char ascq; | 114 | unsigned char ascq; |
115 | int errno; | 115 | int errno; |
116 | } err[] = { | 116 | } ch_err[] = { |
117 | /* Just filled in what looks right. Hav'nt checked any standard paper for | 117 | /* Just filled in what looks right. Hav'nt checked any standard paper for |
118 | these errno assignments, so they may be wrong... */ | 118 | these errno assignments, so they may be wrong... */ |
119 | { | 119 | { |
@@ -155,11 +155,11 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr) | |||
155 | /* Check to see if additional sense information is available */ | 155 | /* Check to see if additional sense information is available */ |
156 | if (scsi_sense_valid(sshdr) && | 156 | if (scsi_sense_valid(sshdr) && |
157 | sshdr->asc != 0) { | 157 | sshdr->asc != 0) { |
158 | for (i = 0; err[i].errno != 0; i++) { | 158 | for (i = 0; ch_err[i].errno != 0; i++) { |
159 | if (err[i].sense == sshdr->sense_key && | 159 | if (ch_err[i].sense == sshdr->sense_key && |
160 | err[i].asc == sshdr->asc && | 160 | ch_err[i].asc == sshdr->asc && |
161 | err[i].ascq == sshdr->ascq) { | 161 | ch_err[i].ascq == sshdr->ascq) { |
162 | errno = -err[i].errno; | 162 | errno = -ch_err[i].errno; |
163 | break; | 163 | break; |
164 | } | 164 | } |
165 | } | 165 | } |
@@ -721,8 +721,8 @@ static long ch_ioctl(struct file *file, | |||
721 | case CHIOGELEM: | 721 | case CHIOGELEM: |
722 | { | 722 | { |
723 | struct changer_get_element cge; | 723 | struct changer_get_element cge; |
724 | u_char cmd[12]; | 724 | u_char ch_cmd[12]; |
725 | u_char *buffer; | 725 | u_char *buffer; |
726 | unsigned int elem; | 726 | unsigned int elem; |
727 | int result,i; | 727 | int result,i; |
728 | 728 | ||
@@ -739,17 +739,18 @@ static long ch_ioctl(struct file *file, | |||
739 | mutex_lock(&ch->lock); | 739 | mutex_lock(&ch->lock); |
740 | 740 | ||
741 | voltag_retry: | 741 | voltag_retry: |
742 | memset(cmd,0,sizeof(cmd)); | 742 | memset(ch_cmd, 0, sizeof(ch_cmd)); |
743 | cmd[0] = READ_ELEMENT_STATUS; | 743 | ch_cmd[0] = READ_ELEMENT_STATUS; |
744 | cmd[1] = (ch->device->lun << 5) | | 744 | ch_cmd[1] = (ch->device->lun << 5) | |
745 | (ch->voltags ? 0x10 : 0) | | 745 | (ch->voltags ? 0x10 : 0) | |
746 | ch_elem_to_typecode(ch,elem); | 746 | ch_elem_to_typecode(ch,elem); |
747 | cmd[2] = (elem >> 8) & 0xff; | 747 | ch_cmd[2] = (elem >> 8) & 0xff; |
748 | cmd[3] = elem & 0xff; | 748 | ch_cmd[3] = elem & 0xff; |
749 | cmd[5] = 1; | 749 | ch_cmd[5] = 1; |
750 | cmd[9] = 255; | 750 | ch_cmd[9] = 255; |
751 | 751 | ||
752 | if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256, DMA_FROM_DEVICE))) { | 752 | result = ch_do_scsi(ch, ch_cmd, buffer, 256, DMA_FROM_DEVICE); |
753 | if (!result) { | ||
753 | cge.cge_status = buffer[18]; | 754 | cge.cge_status = buffer[18]; |
754 | cge.cge_flags = 0; | 755 | cge.cge_flags = 0; |
755 | if (buffer[18] & CESTATUS_EXCEPT) { | 756 | if (buffer[18] & CESTATUS_EXCEPT) { |
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index e351db6c0077..075e2397273c 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c | |||
@@ -4761,7 +4761,6 @@ static struct scsi_host_template dc395x_driver_template = { | |||
4761 | .cmd_per_lun = DC395x_MAX_CMD_PER_LUN, | 4761 | .cmd_per_lun = DC395x_MAX_CMD_PER_LUN, |
4762 | .eh_abort_handler = dc395x_eh_abort, | 4762 | .eh_abort_handler = dc395x_eh_abort, |
4763 | .eh_bus_reset_handler = dc395x_eh_bus_reset, | 4763 | .eh_bus_reset_handler = dc395x_eh_bus_reset, |
4764 | .unchecked_isa_dma = 0, | ||
4765 | .use_clustering = DISABLE_CLUSTERING, | 4764 | .use_clustering = DISABLE_CLUSTERING, |
4766 | }; | 4765 | }; |
4767 | 4766 | ||
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index b5a60926e556..952505c006df 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c | |||
@@ -815,8 +815,6 @@ static int register_pio_HBA(long base, struct get_conf *gc, struct pci_dev *pdev | |||
815 | else | 815 | else |
816 | hd->primary = 1; | 816 | hd->primary = 1; |
817 | 817 | ||
818 | sh->unchecked_isa_dma = 0; /* We can only do PIO */ | ||
819 | |||
820 | hd->next = NULL; /* build a linked list of all HBAs */ | 818 | hd->next = NULL; /* build a linked list of all HBAs */ |
821 | hd->prev = last_HBA; | 819 | hd->prev = last_HBA; |
822 | if (hd->prev != NULL) | 820 | if (hd->prev != NULL) |
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 0b2080d33575..c6d6e7c6559a 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -85,10 +85,10 @@ | |||
85 | 85 | ||
86 | /* The meaning of the Scsi_Pointer members in this driver is as follows: | 86 | /* The meaning of the Scsi_Pointer members in this driver is as follows: |
87 | * ptr: Chaining | 87 | * ptr: Chaining |
88 | * this_residual: gdth_bufflen | 88 | * this_residual: unused |
89 | * buffer: gdth_sglist | 89 | * buffer: unused |
90 | * dma_handle: unused | 90 | * dma_handle: unused |
91 | * buffers_residual: gdth_sg_count | 91 | * buffers_residual: unused |
92 | * Status: unused | 92 | * Status: unused |
93 | * Message: unused | 93 | * Message: unused |
94 | * have_data_in: unused | 94 | * have_data_in: unused |
@@ -372,47 +372,6 @@ static const struct file_operations gdth_fops = { | |||
372 | .release = gdth_close, | 372 | .release = gdth_close, |
373 | }; | 373 | }; |
374 | 374 | ||
375 | /* | ||
376 | * gdth scsi_command access wrappers. | ||
377 | * below 6 functions are used throughout the driver to access scsi_command's | ||
378 | * io parameters. The reason we do not use the regular accessors from | ||
379 | * scsi_cmnd.h is because of gdth_execute(). Since it is unrecommended for | ||
380 | * llds to directly set scsi_cmnd's IO members. This driver will use SCp | ||
381 | * members for IO parameters, and will copy scsi_cmnd's members to Scp | ||
382 | * members in queuecommand. For internal commands through gdth_execute() | ||
383 | * SCp's members will be set directly. | ||
384 | */ | ||
385 | static inline unsigned gdth_bufflen(struct scsi_cmnd *cmd) | ||
386 | { | ||
387 | return (unsigned)cmd->SCp.this_residual; | ||
388 | } | ||
389 | |||
390 | static inline void gdth_set_bufflen(struct scsi_cmnd *cmd, unsigned bufflen) | ||
391 | { | ||
392 | cmd->SCp.this_residual = bufflen; | ||
393 | } | ||
394 | |||
395 | static inline unsigned gdth_sg_count(struct scsi_cmnd *cmd) | ||
396 | { | ||
397 | return (unsigned)cmd->SCp.buffers_residual; | ||
398 | } | ||
399 | |||
400 | static inline void gdth_set_sg_count(struct scsi_cmnd *cmd, unsigned sg_count) | ||
401 | { | ||
402 | cmd->SCp.buffers_residual = sg_count; | ||
403 | } | ||
404 | |||
405 | static inline struct scatterlist *gdth_sglist(struct scsi_cmnd *cmd) | ||
406 | { | ||
407 | return cmd->SCp.buffer; | ||
408 | } | ||
409 | |||
410 | static inline void gdth_set_sglist(struct scsi_cmnd *cmd, | ||
411 | struct scatterlist *sglist) | ||
412 | { | ||
413 | cmd->SCp.buffer = sglist; | ||
414 | } | ||
415 | |||
416 | #include "gdth_proc.h" | 375 | #include "gdth_proc.h" |
417 | #include "gdth_proc.c" | 376 | #include "gdth_proc.c" |
418 | 377 | ||
@@ -591,125 +550,111 @@ static int __init gdth_search_isa(ulong32 bios_adr) | |||
591 | #endif /* CONFIG_ISA */ | 550 | #endif /* CONFIG_ISA */ |
592 | 551 | ||
593 | #ifdef CONFIG_PCI | 552 | #ifdef CONFIG_PCI |
594 | static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | 553 | static bool gdth_pci_registered; |
595 | ushort vendor, ushort dev); | ||
596 | 554 | ||
597 | static int __init gdth_search_pci(gdth_pci_str *pcistr) | 555 | static bool gdth_search_vortex(ushort device) |
598 | { | 556 | { |
599 | ushort device, cnt; | 557 | if (device <= PCI_DEVICE_ID_VORTEX_GDT6555) |
600 | 558 | return true; | |
601 | TRACE(("gdth_search_pci()\n")); | 559 | if (device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP && |
602 | 560 | device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP) | |
603 | cnt = 0; | 561 | return true; |
604 | for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device) | 562 | if (device == PCI_DEVICE_ID_VORTEX_GDTNEWRX || |
605 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device); | 563 | device == PCI_DEVICE_ID_VORTEX_GDTNEWRX2) |
606 | for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP; | 564 | return true; |
607 | device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device) | 565 | return false; |
608 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device); | ||
609 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, | ||
610 | PCI_DEVICE_ID_VORTEX_GDTNEWRX); | ||
611 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, | ||
612 | PCI_DEVICE_ID_VORTEX_GDTNEWRX2); | ||
613 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL, | ||
614 | PCI_DEVICE_ID_INTEL_SRC); | ||
615 | gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL, | ||
616 | PCI_DEVICE_ID_INTEL_SRC_XSCALE); | ||
617 | return cnt; | ||
618 | } | 566 | } |
619 | 567 | ||
568 | static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out); | ||
569 | static int gdth_pci_init_one(struct pci_dev *pdev, | ||
570 | const struct pci_device_id *ent); | ||
571 | static void gdth_pci_remove_one(struct pci_dev *pdev); | ||
572 | static void gdth_remove_one(gdth_ha_str *ha); | ||
573 | |||
620 | /* Vortex only makes RAID controllers. | 574 | /* Vortex only makes RAID controllers. |
621 | * We do not really want to specify all 550 ids here, so wildcard match. | 575 | * We do not really want to specify all 550 ids here, so wildcard match. |
622 | */ | 576 | */ |
623 | static struct pci_device_id gdthtable[] __maybe_unused = { | 577 | static const struct pci_device_id gdthtable[] = { |
624 | {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID}, | 578 | { PCI_VDEVICE(VORTEX, PCI_ANY_ID) }, |
625 | {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID}, | 579 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC) }, |
626 | {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID}, | 580 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC_XSCALE) }, |
627 | {0} | 581 | { } /* terminate list */ |
582 | }; | ||
583 | MODULE_DEVICE_TABLE(pci, gdthtable); | ||
584 | |||
585 | static struct pci_driver gdth_pci_driver = { | ||
586 | .name = "gdth", | ||
587 | .id_table = gdthtable, | ||
588 | .probe = gdth_pci_init_one, | ||
589 | .remove = gdth_pci_remove_one, | ||
628 | }; | 590 | }; |
629 | MODULE_DEVICE_TABLE(pci,gdthtable); | ||
630 | 591 | ||
631 | static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | 592 | static void gdth_pci_remove_one(struct pci_dev *pdev) |
632 | ushort vendor, ushort device) | ||
633 | { | 593 | { |
634 | ulong base0, base1, base2; | 594 | gdth_ha_str *ha = pci_get_drvdata(pdev); |
635 | struct pci_dev *pdev; | 595 | |
596 | pci_set_drvdata(pdev, NULL); | ||
597 | |||
598 | list_del(&ha->list); | ||
599 | gdth_remove_one(ha); | ||
600 | |||
601 | pci_disable_device(pdev); | ||
602 | } | ||
603 | |||
604 | static int gdth_pci_init_one(struct pci_dev *pdev, | ||
605 | const struct pci_device_id *ent) | ||
606 | { | ||
607 | ushort vendor = pdev->vendor; | ||
608 | ushort device = pdev->device; | ||
609 | ulong base0, base1, base2; | ||
610 | int rc; | ||
611 | gdth_pci_str gdth_pcistr; | ||
612 | gdth_ha_str *ha = NULL; | ||
636 | 613 | ||
637 | TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n", | 614 | TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n", |
638 | *cnt, vendor, device)); | 615 | gdth_ctr_count, vendor, device)); |
639 | 616 | ||
640 | pdev = NULL; | 617 | memset(&gdth_pcistr, 0, sizeof(gdth_pcistr)); |
641 | while ((pdev = pci_get_device(vendor, device, pdev)) | 618 | |
642 | != NULL) { | 619 | if (vendor == PCI_VENDOR_ID_VORTEX && !gdth_search_vortex(device)) |
643 | if (pci_enable_device(pdev)) | 620 | return -ENODEV; |
644 | continue; | 621 | |
645 | if (*cnt >= MAXHA) { | 622 | rc = pci_enable_device(pdev); |
646 | pci_dev_put(pdev); | 623 | if (rc) |
647 | return; | 624 | return rc; |
648 | } | 625 | |
626 | if (gdth_ctr_count >= MAXHA) | ||
627 | return -EBUSY; | ||
649 | 628 | ||
650 | /* GDT PCI controller found, resources are already in pdev */ | 629 | /* GDT PCI controller found, resources are already in pdev */ |
651 | pcistr[*cnt].pdev = pdev; | 630 | gdth_pcistr.pdev = pdev; |
652 | pcistr[*cnt].irq = pdev->irq; | ||
653 | base0 = pci_resource_flags(pdev, 0); | 631 | base0 = pci_resource_flags(pdev, 0); |
654 | base1 = pci_resource_flags(pdev, 1); | 632 | base1 = pci_resource_flags(pdev, 1); |
655 | base2 = pci_resource_flags(pdev, 2); | 633 | base2 = pci_resource_flags(pdev, 2); |
656 | if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */ | 634 | if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */ |
657 | device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */ | 635 | device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */ |
658 | if (!(base0 & IORESOURCE_MEM)) | 636 | if (!(base0 & IORESOURCE_MEM)) |
659 | continue; | 637 | return -ENODEV; |
660 | pcistr[*cnt].dpmem = pci_resource_start(pdev, 0); | 638 | gdth_pcistr.dpmem = pci_resource_start(pdev, 0); |
661 | } else { /* GDT6110, GDT6120, .. */ | 639 | } else { /* GDT6110, GDT6120, .. */ |
662 | if (!(base0 & IORESOURCE_MEM) || | 640 | if (!(base0 & IORESOURCE_MEM) || |
663 | !(base2 & IORESOURCE_MEM) || | 641 | !(base2 & IORESOURCE_MEM) || |
664 | !(base1 & IORESOURCE_IO)) | 642 | !(base1 & IORESOURCE_IO)) |
665 | continue; | 643 | return -ENODEV; |
666 | pcistr[*cnt].dpmem = pci_resource_start(pdev, 2); | 644 | gdth_pcistr.dpmem = pci_resource_start(pdev, 2); |
667 | pcistr[*cnt].io_mm = pci_resource_start(pdev, 0); | 645 | gdth_pcistr.io = pci_resource_start(pdev, 1); |
668 | pcistr[*cnt].io = pci_resource_start(pdev, 1); | ||
669 | } | 646 | } |
670 | TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", | 647 | TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n", |
671 | pcistr[*cnt].pdev->bus->number, | 648 | gdth_pcistr.pdev->bus->number, |
672 | PCI_SLOT(pcistr[*cnt].pdev->devfn), | 649 | PCI_SLOT(gdth_pcistr.pdev->devfn), |
673 | pcistr[*cnt].irq, pcistr[*cnt].dpmem)); | 650 | gdth_pcistr.irq, |
674 | (*cnt)++; | 651 | gdth_pcistr.dpmem)); |
675 | } | ||
676 | } | ||
677 | 652 | ||
678 | static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) | 653 | rc = gdth_pci_probe_one(&gdth_pcistr, &ha); |
679 | { | 654 | if (rc) |
680 | gdth_pci_str temp; | 655 | return rc; |
681 | int i, changed; | ||
682 | |||
683 | TRACE(("gdth_sort_pci() cnt %d\n",cnt)); | ||
684 | if (cnt == 0) | ||
685 | return; | ||
686 | 656 | ||
687 | do { | 657 | return 0; |
688 | changed = FALSE; | ||
689 | for (i = 0; i < cnt-1; ++i) { | ||
690 | if (!reverse_scan) { | ||
691 | if ((pcistr[i].pdev->bus->number > pcistr[i+1].pdev->bus->number) || | ||
692 | (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number && | ||
693 | PCI_SLOT(pcistr[i].pdev->devfn) > | ||
694 | PCI_SLOT(pcistr[i+1].pdev->devfn))) { | ||
695 | temp = pcistr[i]; | ||
696 | pcistr[i] = pcistr[i+1]; | ||
697 | pcistr[i+1] = temp; | ||
698 | changed = TRUE; | ||
699 | } | ||
700 | } else { | ||
701 | if ((pcistr[i].pdev->bus->number < pcistr[i+1].pdev->bus->number) || | ||
702 | (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number && | ||
703 | PCI_SLOT(pcistr[i].pdev->devfn) < | ||
704 | PCI_SLOT(pcistr[i+1].pdev->devfn))) { | ||
705 | temp = pcistr[i]; | ||
706 | pcistr[i] = pcistr[i+1]; | ||
707 | pcistr[i+1] = temp; | ||
708 | changed = TRUE; | ||
709 | } | ||
710 | } | ||
711 | } | ||
712 | } while (changed); | ||
713 | } | 658 | } |
714 | #endif /* CONFIG_PCI */ | 659 | #endif /* CONFIG_PCI */ |
715 | 660 | ||
@@ -909,7 +854,8 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
909 | #endif /* CONFIG_ISA */ | 854 | #endif /* CONFIG_ISA */ |
910 | 855 | ||
911 | #ifdef CONFIG_PCI | 856 | #ifdef CONFIG_PCI |
912 | static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | 857 | static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr, |
858 | gdth_ha_str *ha) | ||
913 | { | 859 | { |
914 | register gdt6_dpram_str __iomem *dp6_ptr; | 860 | register gdt6_dpram_str __iomem *dp6_ptr; |
915 | register gdt6c_dpram_str __iomem *dp6c_ptr; | 861 | register gdt6c_dpram_str __iomem *dp6c_ptr; |
@@ -921,14 +867,14 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
921 | 867 | ||
922 | TRACE(("gdth_init_pci()\n")); | 868 | TRACE(("gdth_init_pci()\n")); |
923 | 869 | ||
924 | if (pcistr->pdev->vendor == PCI_VENDOR_ID_INTEL) | 870 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) |
925 | ha->oem_id = OEM_ID_INTEL; | 871 | ha->oem_id = OEM_ID_INTEL; |
926 | else | 872 | else |
927 | ha->oem_id = OEM_ID_ICP; | 873 | ha->oem_id = OEM_ID_ICP; |
928 | ha->brd_phys = (pcistr->pdev->bus->number << 8) | (pcistr->pdev->devfn & 0xf8); | 874 | ha->brd_phys = (pdev->bus->number << 8) | (pdev->devfn & 0xf8); |
929 | ha->stype = (ulong32)pcistr->pdev->device; | 875 | ha->stype = (ulong32)pdev->device; |
930 | ha->irq = pcistr->irq; | 876 | ha->irq = pdev->irq; |
931 | ha->pdev = pcistr->pdev; | 877 | ha->pdev = pdev; |
932 | 878 | ||
933 | if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */ | 879 | if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */ |
934 | TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); | 880 | TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq)); |
@@ -956,8 +902,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
956 | continue; | 902 | continue; |
957 | } | 903 | } |
958 | iounmap(ha->brd); | 904 | iounmap(ha->brd); |
959 | pci_write_config_dword(pcistr->pdev, | 905 | pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i); |
960 | PCI_BASE_ADDRESS_0, i); | ||
961 | ha->brd = ioremap(i, sizeof(gdt6_dpram_str)); | 906 | ha->brd = ioremap(i, sizeof(gdt6_dpram_str)); |
962 | if (ha->brd == NULL) { | 907 | if (ha->brd == NULL) { |
963 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 908 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
@@ -1066,8 +1011,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1066 | continue; | 1011 | continue; |
1067 | } | 1012 | } |
1068 | iounmap(ha->brd); | 1013 | iounmap(ha->brd); |
1069 | pci_write_config_dword(pcistr->pdev, | 1014 | pci_write_config_dword(pdev, PCI_BASE_ADDRESS_2, i); |
1070 | PCI_BASE_ADDRESS_2, i); | ||
1071 | ha->brd = ioremap(i, sizeof(gdt6c_dpram_str)); | 1015 | ha->brd = ioremap(i, sizeof(gdt6c_dpram_str)); |
1072 | if (ha->brd == NULL) { | 1016 | if (ha->brd == NULL) { |
1073 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 1017 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
@@ -1159,16 +1103,16 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1159 | } | 1103 | } |
1160 | 1104 | ||
1161 | /* manipulate config. space to enable DPMEM, start RP controller */ | 1105 | /* manipulate config. space to enable DPMEM, start RP controller */ |
1162 | pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command); | 1106 | pci_read_config_word(pdev, PCI_COMMAND, &command); |
1163 | command |= 6; | 1107 | command |= 6; |
1164 | pci_write_config_word(pcistr->pdev, PCI_COMMAND, command); | 1108 | pci_write_config_word(pdev, PCI_COMMAND, command); |
1165 | if (pci_resource_start(pcistr->pdev, 8) == 1UL) | 1109 | if (pci_resource_start(pdev, 8) == 1UL) |
1166 | pci_resource_start(pcistr->pdev, 8) = 0UL; | 1110 | pci_resource_start(pdev, 8) = 0UL; |
1167 | i = 0xFEFF0001UL; | 1111 | i = 0xFEFF0001UL; |
1168 | pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i); | 1112 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, i); |
1169 | gdth_delay(1); | 1113 | gdth_delay(1); |
1170 | pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, | 1114 | pci_write_config_dword(pdev, PCI_ROM_ADDRESS, |
1171 | pci_resource_start(pcistr->pdev, 8)); | 1115 | pci_resource_start(pdev, 8)); |
1172 | 1116 | ||
1173 | dp6m_ptr = ha->brd; | 1117 | dp6m_ptr = ha->brd; |
1174 | 1118 | ||
@@ -1195,8 +1139,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1195 | continue; | 1139 | continue; |
1196 | } | 1140 | } |
1197 | iounmap(ha->brd); | 1141 | iounmap(ha->brd); |
1198 | pci_write_config_dword(pcistr->pdev, | 1142 | pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i); |
1199 | PCI_BASE_ADDRESS_0, i); | ||
1200 | ha->brd = ioremap(i, sizeof(gdt6m_dpram_str)); | 1143 | ha->brd = ioremap(i, sizeof(gdt6m_dpram_str)); |
1201 | if (ha->brd == NULL) { | 1144 | if (ha->brd == NULL) { |
1202 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 1145 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
@@ -2353,12 +2296,12 @@ static void gdth_next(gdth_ha_str *ha) | |||
2353 | static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, | 2296 | static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, |
2354 | char *buffer, ushort count) | 2297 | char *buffer, ushort count) |
2355 | { | 2298 | { |
2356 | ushort cpcount,i, max_sg = gdth_sg_count(scp); | 2299 | ushort cpcount,i, max_sg = scsi_sg_count(scp); |
2357 | ushort cpsum,cpnow; | 2300 | ushort cpsum,cpnow; |
2358 | struct scatterlist *sl; | 2301 | struct scatterlist *sl; |
2359 | char *address; | 2302 | char *address; |
2360 | 2303 | ||
2361 | cpcount = min_t(ushort, count, gdth_bufflen(scp)); | 2304 | cpcount = min_t(ushort, count, scsi_bufflen(scp)); |
2362 | 2305 | ||
2363 | if (cpcount) { | 2306 | if (cpcount) { |
2364 | cpsum=0; | 2307 | cpsum=0; |
@@ -2366,7 +2309,7 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, | |||
2366 | unsigned long flags; | 2309 | unsigned long flags; |
2367 | cpnow = (ushort)sl->length; | 2310 | cpnow = (ushort)sl->length; |
2368 | TRACE(("copy_internal() now %d sum %d count %d %d\n", | 2311 | TRACE(("copy_internal() now %d sum %d count %d %d\n", |
2369 | cpnow, cpsum, cpcount, gdth_bufflen(scp))); | 2312 | cpnow, cpsum, cpcount, scsi_bufflen(scp))); |
2370 | if (cpsum+cpnow > cpcount) | 2313 | if (cpsum+cpnow > cpcount) |
2371 | cpnow = cpcount - cpsum; | 2314 | cpnow = cpcount - cpsum; |
2372 | cpsum += cpnow; | 2315 | cpsum += cpnow; |
@@ -2589,10 +2532,10 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) | |||
2589 | cmdp->u.cache.BlockCnt = blockcnt; | 2532 | cmdp->u.cache.BlockCnt = blockcnt; |
2590 | } | 2533 | } |
2591 | 2534 | ||
2592 | if (gdth_bufflen(scp)) { | 2535 | if (scsi_bufflen(scp)) { |
2593 | cmndinfo->dma_dir = (read_write == 1 ? | 2536 | cmndinfo->dma_dir = (read_write == 1 ? |
2594 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | 2537 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); |
2595 | sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), | 2538 | sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp), |
2596 | cmndinfo->dma_dir); | 2539 | cmndinfo->dma_dir); |
2597 | if (mode64) { | 2540 | if (mode64) { |
2598 | struct scatterlist *sl; | 2541 | struct scatterlist *sl; |
@@ -2739,7 +2682,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) | |||
2739 | cmdp->u.raw64.lun = l; | 2682 | cmdp->u.raw64.lun = l; |
2740 | cmdp->u.raw64.bus = b; | 2683 | cmdp->u.raw64.bus = b; |
2741 | cmdp->u.raw64.priority = 0; | 2684 | cmdp->u.raw64.priority = 0; |
2742 | cmdp->u.raw64.sdlen = gdth_bufflen(scp); | 2685 | cmdp->u.raw64.sdlen = scsi_bufflen(scp); |
2743 | cmdp->u.raw64.sense_len = 16; | 2686 | cmdp->u.raw64.sense_len = 16; |
2744 | cmdp->u.raw64.sense_data = sense_paddr; | 2687 | cmdp->u.raw64.sense_data = sense_paddr; |
2745 | cmdp->u.raw64.direction = | 2688 | cmdp->u.raw64.direction = |
@@ -2756,7 +2699,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) | |||
2756 | cmdp->u.raw.bus = b; | 2699 | cmdp->u.raw.bus = b; |
2757 | cmdp->u.raw.priority = 0; | 2700 | cmdp->u.raw.priority = 0; |
2758 | cmdp->u.raw.link_p = 0; | 2701 | cmdp->u.raw.link_p = 0; |
2759 | cmdp->u.raw.sdlen = gdth_bufflen(scp); | 2702 | cmdp->u.raw.sdlen = scsi_bufflen(scp); |
2760 | cmdp->u.raw.sense_len = 16; | 2703 | cmdp->u.raw.sense_len = 16; |
2761 | cmdp->u.raw.sense_data = sense_paddr; | 2704 | cmdp->u.raw.sense_data = sense_paddr; |
2762 | cmdp->u.raw.direction = | 2705 | cmdp->u.raw.direction = |
@@ -2765,9 +2708,9 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) | |||
2765 | cmdp->u.raw.sg_ranz = 0; | 2708 | cmdp->u.raw.sg_ranz = 0; |
2766 | } | 2709 | } |
2767 | 2710 | ||
2768 | if (gdth_bufflen(scp)) { | 2711 | if (scsi_bufflen(scp)) { |
2769 | cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; | 2712 | cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; |
2770 | sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), | 2713 | sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp), |
2771 | cmndinfo->dma_dir); | 2714 | cmndinfo->dma_dir); |
2772 | if (mode64) { | 2715 | if (mode64) { |
2773 | struct scatterlist *sl; | 2716 | struct scatterlist *sl; |
@@ -3388,8 +3331,8 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, | |||
3388 | /* retry */ | 3331 | /* retry */ |
3389 | return 2; | 3332 | return 2; |
3390 | } | 3333 | } |
3391 | if (gdth_bufflen(scp)) | 3334 | if (scsi_bufflen(scp)) |
3392 | pci_unmap_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), | 3335 | pci_unmap_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp), |
3393 | cmndinfo->dma_dir); | 3336 | cmndinfo->dma_dir); |
3394 | 3337 | ||
3395 | if (cmndinfo->sense_paddr) | 3338 | if (cmndinfo->sense_paddr) |
@@ -4031,10 +3974,6 @@ static int gdth_queuecommand(struct scsi_cmnd *scp, | |||
4031 | gdth_update_timeout(scp, scp->timeout_per_command * 6); | 3974 | gdth_update_timeout(scp, scp->timeout_per_command * 6); |
4032 | cmndinfo->priority = DEFAULT_PRI; | 3975 | cmndinfo->priority = DEFAULT_PRI; |
4033 | 3976 | ||
4034 | gdth_set_bufflen(scp, scsi_bufflen(scp)); | ||
4035 | gdth_set_sg_count(scp, scsi_sg_count(scp)); | ||
4036 | gdth_set_sglist(scp, scsi_sglist(scp)); | ||
4037 | |||
4038 | return __gdth_queuecommand(ha, scp, cmndinfo); | 3977 | return __gdth_queuecommand(ha, scp, cmndinfo); |
4039 | } | 3978 | } |
4040 | 3979 | ||
@@ -4955,12 +4894,16 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot) | |||
4955 | #endif /* CONFIG_EISA */ | 4894 | #endif /* CONFIG_EISA */ |
4956 | 4895 | ||
4957 | #ifdef CONFIG_PCI | 4896 | #ifdef CONFIG_PCI |
4958 | static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | 4897 | static int gdth_pci_probe_one(gdth_pci_str *pcistr, |
4898 | gdth_ha_str **ha_out) | ||
4959 | { | 4899 | { |
4960 | struct Scsi_Host *shp; | 4900 | struct Scsi_Host *shp; |
4961 | gdth_ha_str *ha; | 4901 | gdth_ha_str *ha; |
4962 | dma_addr_t scratch_dma_handle = 0; | 4902 | dma_addr_t scratch_dma_handle = 0; |
4963 | int error, i; | 4903 | int error, i; |
4904 | struct pci_dev *pdev = pcistr->pdev; | ||
4905 | |||
4906 | *ha_out = NULL; | ||
4964 | 4907 | ||
4965 | shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); | 4908 | shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); |
4966 | if (!shp) | 4909 | if (!shp) |
@@ -4968,13 +4911,13 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | |||
4968 | ha = shost_priv(shp); | 4911 | ha = shost_priv(shp); |
4969 | 4912 | ||
4970 | error = -ENODEV; | 4913 | error = -ENODEV; |
4971 | if (!gdth_init_pci(&pcistr[ctr],ha)) | 4914 | if (!gdth_init_pci(pdev, pcistr, ha)) |
4972 | goto out_host_put; | 4915 | goto out_host_put; |
4973 | 4916 | ||
4974 | /* controller found and initialized */ | 4917 | /* controller found and initialized */ |
4975 | printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", | 4918 | printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", |
4976 | pcistr[ctr].pdev->bus->number, | 4919 | pdev->bus->number, |
4977 | PCI_SLOT(pcistr[ctr].pdev->devfn), | 4920 | PCI_SLOT(pdev->devfn), |
4978 | ha->irq); | 4921 | ha->irq); |
4979 | 4922 | ||
4980 | error = request_irq(ha->irq, gdth_interrupt, | 4923 | error = request_irq(ha->irq, gdth_interrupt, |
@@ -5019,7 +4962,7 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | |||
5019 | 4962 | ||
5020 | ha->scratch_busy = FALSE; | 4963 | ha->scratch_busy = FALSE; |
5021 | ha->req_first = NULL; | 4964 | ha->req_first = NULL; |
5022 | ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; | 4965 | ha->tid_cnt = pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; |
5023 | if (max_ids > 0 && max_ids < ha->tid_cnt) | 4966 | if (max_ids > 0 && max_ids < ha->tid_cnt) |
5024 | ha->tid_cnt = max_ids; | 4967 | ha->tid_cnt = max_ids; |
5025 | for (i = 0; i < GDTH_MAXCMDS; ++i) | 4968 | for (i = 0; i < GDTH_MAXCMDS; ++i) |
@@ -5039,16 +4982,16 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | |||
5039 | /* 64-bit DMA only supported from FW >= x.43 */ | 4982 | /* 64-bit DMA only supported from FW >= x.43 */ |
5040 | if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) || | 4983 | if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) || |
5041 | !ha->dma64_support) { | 4984 | !ha->dma64_support) { |
5042 | if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | 4985 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
5043 | printk(KERN_WARNING "GDT-PCI %d: " | 4986 | printk(KERN_WARNING "GDT-PCI %d: " |
5044 | "Unable to set 32-bit DMA\n", ha->hanum); | 4987 | "Unable to set 32-bit DMA\n", ha->hanum); |
5045 | goto out_free_coal_stat; | 4988 | goto out_free_coal_stat; |
5046 | } | 4989 | } |
5047 | } else { | 4990 | } else { |
5048 | shp->max_cmd_len = 16; | 4991 | shp->max_cmd_len = 16; |
5049 | if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { | 4992 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { |
5050 | printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum); | 4993 | printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum); |
5051 | } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | 4994 | } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
5052 | printk(KERN_WARNING "GDT-PCI %d: " | 4995 | printk(KERN_WARNING "GDT-PCI %d: " |
5053 | "Unable to set 64/32-bit DMA\n", ha->hanum); | 4996 | "Unable to set 64/32-bit DMA\n", ha->hanum); |
5054 | goto out_free_coal_stat; | 4997 | goto out_free_coal_stat; |
@@ -5062,13 +5005,17 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | |||
5062 | spin_lock_init(&ha->smp_lock); | 5005 | spin_lock_init(&ha->smp_lock); |
5063 | gdth_enable_int(ha); | 5006 | gdth_enable_int(ha); |
5064 | 5007 | ||
5065 | error = scsi_add_host(shp, &pcistr[ctr].pdev->dev); | 5008 | error = scsi_add_host(shp, &pdev->dev); |
5066 | if (error) | 5009 | if (error) |
5067 | goto out_free_coal_stat; | 5010 | goto out_free_coal_stat; |
5068 | list_add_tail(&ha->list, &gdth_instances); | 5011 | list_add_tail(&ha->list, &gdth_instances); |
5069 | 5012 | ||
5013 | pci_set_drvdata(ha->pdev, ha); | ||
5014 | |||
5070 | scsi_scan_host(shp); | 5015 | scsi_scan_host(shp); |
5071 | 5016 | ||
5017 | *ha_out = ha; | ||
5018 | |||
5072 | return 0; | 5019 | return 0; |
5073 | 5020 | ||
5074 | out_free_coal_stat: | 5021 | out_free_coal_stat: |
@@ -5185,16 +5132,8 @@ static int __init gdth_init(void) | |||
5185 | 5132 | ||
5186 | #ifdef CONFIG_PCI | 5133 | #ifdef CONFIG_PCI |
5187 | /* scanning for PCI controllers */ | 5134 | /* scanning for PCI controllers */ |
5188 | { | 5135 | if (pci_register_driver(&gdth_pci_driver) == 0) |
5189 | gdth_pci_str pcistr[MAXHA]; | 5136 | gdth_pci_registered = true; |
5190 | int cnt,ctr; | ||
5191 | |||
5192 | cnt = gdth_search_pci(pcistr); | ||
5193 | printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt); | ||
5194 | gdth_sort_pci(pcistr,cnt); | ||
5195 | for (ctr = 0; ctr < cnt; ++ctr) | ||
5196 | gdth_pci_probe_one(pcistr, ctr); | ||
5197 | } | ||
5198 | #endif /* CONFIG_PCI */ | 5137 | #endif /* CONFIG_PCI */ |
5199 | 5138 | ||
5200 | TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); | 5139 | TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); |
@@ -5227,6 +5166,11 @@ static void __exit gdth_exit(void) | |||
5227 | del_timer_sync(&gdth_timer); | 5166 | del_timer_sync(&gdth_timer); |
5228 | #endif | 5167 | #endif |
5229 | 5168 | ||
5169 | #ifdef CONFIG_PCI | ||
5170 | if (gdth_pci_registered) | ||
5171 | pci_unregister_driver(&gdth_pci_driver); | ||
5172 | #endif | ||
5173 | |||
5230 | list_for_each_entry(ha, &gdth_instances, list) | 5174 | list_for_each_entry(ha, &gdth_instances, list) |
5231 | gdth_remove_one(ha); | 5175 | gdth_remove_one(ha); |
5232 | } | 5176 | } |
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index 26e4e92515e0..ca92476727cf 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h | |||
@@ -839,8 +839,6 @@ typedef struct { | |||
839 | struct pci_dev *pdev; | 839 | struct pci_dev *pdev; |
840 | ulong dpmem; /* DPRAM address */ | 840 | ulong dpmem; /* DPRAM address */ |
841 | ulong io; /* IO address */ | 841 | ulong io; /* IO address */ |
842 | ulong io_mm; /* IO address mem. mapped */ | ||
843 | unchar irq; /* IRQ */ | ||
844 | } gdth_pci_str; | 842 | } gdth_pci_str; |
845 | 843 | ||
846 | 844 | ||
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 91f85226d08f..ca7363752401 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c | |||
@@ -322,6 +322,9 @@ int __init gvp11_detect(struct scsi_host_template *tpnt) | |||
322 | */ | 322 | */ |
323 | regs.SASR = &(DMA(instance)->SASR); | 323 | regs.SASR = &(DMA(instance)->SASR); |
324 | regs.SCMD = &(DMA(instance)->SCMD); | 324 | regs.SCMD = &(DMA(instance)->SCMD); |
325 | HDATA(instance)->no_sync = 0xff; | ||
326 | HDATA(instance)->fast = 0; | ||
327 | HDATA(instance)->dma_mode = CTRL_DMA; | ||
325 | wd33c93_init(instance, regs, dma_setup, dma_stop, | 328 | wd33c93_init(instance, regs, dma_setup, dma_stop, |
326 | (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10 | 329 | (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10 |
327 | : WD33C93_FS_12_15); | 330 | : WD33C93_FS_12_15); |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index ed7e0a1fc34d..1592640a87b5 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -347,7 +347,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
347 | shost->unchecked_isa_dma = sht->unchecked_isa_dma; | 347 | shost->unchecked_isa_dma = sht->unchecked_isa_dma; |
348 | shost->use_clustering = sht->use_clustering; | 348 | shost->use_clustering = sht->use_clustering; |
349 | shost->ordered_tag = sht->ordered_tag; | 349 | shost->ordered_tag = sht->ordered_tag; |
350 | shost->active_mode = sht->supported_mode; | ||
351 | 350 | ||
352 | if (sht->supported_mode == MODE_UNKNOWN) | 351 | if (sht->supported_mode == MODE_UNKNOWN) |
353 | /* means we didn't set it ... default to INITIATOR */ | 352 | /* means we didn't set it ... default to INITIATOR */ |
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index ff149ad6bc4e..beecda991682 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c | |||
@@ -338,7 +338,8 @@ static int iop_get_config_mv(struct hptiop_hba *hba, | |||
338 | req->header.size = | 338 | req->header.size = |
339 | cpu_to_le32(sizeof(struct hpt_iop_request_get_config)); | 339 | cpu_to_le32(sizeof(struct hpt_iop_request_get_config)); |
340 | req->header.result = cpu_to_le32(IOP_RESULT_PENDING); | 340 | req->header.result = cpu_to_le32(IOP_RESULT_PENDING); |
341 | req->header.context = cpu_to_le64(IOP_REQUEST_TYPE_GET_CONFIG<<5); | 341 | req->header.context = cpu_to_le32(IOP_REQUEST_TYPE_GET_CONFIG<<5); |
342 | req->header.context_hi32 = 0; | ||
342 | 343 | ||
343 | if (iop_send_sync_request_mv(hba, 0, 20000)) { | 344 | if (iop_send_sync_request_mv(hba, 0, 20000)) { |
344 | dprintk("Get config send cmd failed\n"); | 345 | dprintk("Get config send cmd failed\n"); |
@@ -392,7 +393,8 @@ static int iop_set_config_mv(struct hptiop_hba *hba, | |||
392 | req->header.size = | 393 | req->header.size = |
393 | cpu_to_le32(sizeof(struct hpt_iop_request_set_config)); | 394 | cpu_to_le32(sizeof(struct hpt_iop_request_set_config)); |
394 | req->header.result = cpu_to_le32(IOP_RESULT_PENDING); | 395 | req->header.result = cpu_to_le32(IOP_RESULT_PENDING); |
395 | req->header.context = cpu_to_le64(IOP_REQUEST_TYPE_SET_CONFIG<<5); | 396 | req->header.context = cpu_to_le32(IOP_REQUEST_TYPE_SET_CONFIG<<5); |
397 | req->header.context_hi32 = 0; | ||
396 | 398 | ||
397 | if (iop_send_sync_request_mv(hba, 0, 20000)) { | 399 | if (iop_send_sync_request_mv(hba, 0, 20000)) { |
398 | dprintk("Set config send cmd failed\n"); | 400 | dprintk("Set config send cmd failed\n"); |
@@ -903,7 +905,6 @@ static struct scsi_host_template driver_template = { | |||
903 | .eh_device_reset_handler = hptiop_reset, | 905 | .eh_device_reset_handler = hptiop_reset, |
904 | .eh_bus_reset_handler = hptiop_reset, | 906 | .eh_bus_reset_handler = hptiop_reset, |
905 | .info = hptiop_info, | 907 | .info = hptiop_info, |
906 | .unchecked_isa_dma = 0, | ||
907 | .emulated = 0, | 908 | .emulated = 0, |
908 | .use_clustering = ENABLE_CLUSTERING, | 909 | .use_clustering = ENABLE_CLUSTERING, |
909 | .proc_name = driver_name, | 910 | .proc_name = driver_name, |
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 0cc8868ea35d..dbae3fdb8506 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c | |||
@@ -2581,8 +2581,8 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c | |||
2581 | /* Map the sense buffer into bus memory */ | 2581 | /* Map the sense buffer into bus memory */ |
2582 | dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->sense_buffer, | 2582 | dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->sense_buffer, |
2583 | SENSE_SIZE, DMA_FROM_DEVICE); | 2583 | SENSE_SIZE, DMA_FROM_DEVICE); |
2584 | cblk->senseptr = cpu_to_le32((u32)dma_addr); | 2584 | cblk->senseptr = (u32)dma_addr; |
2585 | cblk->senselen = cpu_to_le32(SENSE_SIZE); | 2585 | cblk->senselen = SENSE_SIZE; |
2586 | cmnd->SCp.ptr = (char *)(unsigned long)dma_addr; | 2586 | cmnd->SCp.ptr = (char *)(unsigned long)dma_addr; |
2587 | cblk->cdblen = cmnd->cmd_len; | 2587 | cblk->cdblen = cmnd->cmd_len; |
2588 | 2588 | ||
@@ -2606,7 +2606,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c | |||
2606 | dma_addr = dma_map_single(&host->pci_dev->dev, &cblk->sglist[0], | 2606 | dma_addr = dma_map_single(&host->pci_dev->dev, &cblk->sglist[0], |
2607 | sizeof(struct sg_entry) * TOTAL_SG_ENTRY, | 2607 | sizeof(struct sg_entry) * TOTAL_SG_ENTRY, |
2608 | DMA_BIDIRECTIONAL); | 2608 | DMA_BIDIRECTIONAL); |
2609 | cblk->bufptr = cpu_to_le32((u32)dma_addr); | 2609 | cblk->bufptr = (u32)dma_addr; |
2610 | cmnd->SCp.dma_handle = dma_addr; | 2610 | cmnd->SCp.dma_handle = dma_addr; |
2611 | 2611 | ||
2612 | cblk->sglen = nseg; | 2612 | cblk->sglen = nseg; |
@@ -2616,7 +2616,8 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c | |||
2616 | sg = &cblk->sglist[0]; | 2616 | sg = &cblk->sglist[0]; |
2617 | scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) { | 2617 | scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) { |
2618 | sg->data = cpu_to_le32((u32)sg_dma_address(sglist)); | 2618 | sg->data = cpu_to_le32((u32)sg_dma_address(sglist)); |
2619 | total_len += sg->len = cpu_to_le32((u32)sg_dma_len(sglist)); | 2619 | sg->len = cpu_to_le32((u32)sg_dma_len(sglist)); |
2620 | total_len += sg_dma_len(sglist); | ||
2620 | ++sg; | 2621 | ++sg; |
2621 | } | 2622 | } |
2622 | 2623 | ||
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 7ed568f180ae..7c615c70ec5c 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c | |||
@@ -2377,7 +2377,7 @@ ips_get_bios_version(ips_ha_t * ha, int intr) | |||
2377 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) | 2377 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) |
2378 | return; | 2378 | return; |
2379 | 2379 | ||
2380 | outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); | 2380 | outl(1, ha->io_addr + IPS_REG_FLAP); |
2381 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 2381 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
2382 | udelay(25); /* 25 us */ | 2382 | udelay(25); /* 25 us */ |
2383 | 2383 | ||
@@ -2385,21 +2385,21 @@ ips_get_bios_version(ips_ha_t * ha, int intr) | |||
2385 | return; | 2385 | return; |
2386 | 2386 | ||
2387 | /* Get Major version */ | 2387 | /* Get Major version */ |
2388 | outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP); | 2388 | outl(0x1FF, ha->io_addr + IPS_REG_FLAP); |
2389 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 2389 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
2390 | udelay(25); /* 25 us */ | 2390 | udelay(25); /* 25 us */ |
2391 | 2391 | ||
2392 | major = inb(ha->io_addr + IPS_REG_FLDP); | 2392 | major = inb(ha->io_addr + IPS_REG_FLDP); |
2393 | 2393 | ||
2394 | /* Get Minor version */ | 2394 | /* Get Minor version */ |
2395 | outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP); | 2395 | outl(0x1FE, ha->io_addr + IPS_REG_FLAP); |
2396 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 2396 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
2397 | udelay(25); /* 25 us */ | 2397 | udelay(25); /* 25 us */ |
2398 | 2398 | ||
2399 | minor = inb(ha->io_addr + IPS_REG_FLDP); | 2399 | minor = inb(ha->io_addr + IPS_REG_FLDP); |
2400 | 2400 | ||
2401 | /* Get SubMinor version */ | 2401 | /* Get SubMinor version */ |
2402 | outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP); | 2402 | outl(0x1FD, ha->io_addr + IPS_REG_FLAP); |
2403 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 2403 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
2404 | udelay(25); /* 25 us */ | 2404 | udelay(25); /* 25 us */ |
2405 | 2405 | ||
@@ -3502,27 +3502,11 @@ ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr) | |||
3502 | static void | 3502 | static void |
3503 | ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count) | 3503 | ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count) |
3504 | { | 3504 | { |
3505 | int i; | 3505 | unsigned long flags; |
3506 | unsigned int min_cnt, xfer_cnt; | ||
3507 | char *cdata = (char *) data; | ||
3508 | unsigned char *buffer; | ||
3509 | unsigned long flags; | ||
3510 | struct scatterlist *sg = scsi_sglist(scmd); | ||
3511 | |||
3512 | for (i = 0, xfer_cnt = 0; | ||
3513 | (i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) { | ||
3514 | min_cnt = min(count - xfer_cnt, sg[i].length); | ||
3515 | |||
3516 | /* kmap_atomic() ensures addressability of the data buffer.*/ | ||
3517 | /* local_irq_save() protects the KM_IRQ0 address slot. */ | ||
3518 | local_irq_save(flags); | ||
3519 | buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset; | ||
3520 | memcpy(buffer, &cdata[xfer_cnt], min_cnt); | ||
3521 | kunmap_atomic(buffer - sg[i].offset, KM_IRQ0); | ||
3522 | local_irq_restore(flags); | ||
3523 | 3506 | ||
3524 | xfer_cnt += min_cnt; | 3507 | local_irq_save(flags); |
3525 | } | 3508 | scsi_sg_copy_from_buffer(scmd, data, count); |
3509 | local_irq_restore(flags); | ||
3526 | } | 3510 | } |
3527 | 3511 | ||
3528 | /****************************************************************************/ | 3512 | /****************************************************************************/ |
@@ -3535,27 +3519,11 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count) | |||
3535 | static void | 3519 | static void |
3536 | ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count) | 3520 | ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count) |
3537 | { | 3521 | { |
3538 | int i; | 3522 | unsigned long flags; |
3539 | unsigned int min_cnt, xfer_cnt; | ||
3540 | char *cdata = (char *) data; | ||
3541 | unsigned char *buffer; | ||
3542 | unsigned long flags; | ||
3543 | struct scatterlist *sg = scsi_sglist(scmd); | ||
3544 | |||
3545 | for (i = 0, xfer_cnt = 0; | ||
3546 | (i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) { | ||
3547 | min_cnt = min(count - xfer_cnt, sg[i].length); | ||
3548 | |||
3549 | /* kmap_atomic() ensures addressability of the data buffer.*/ | ||
3550 | /* local_irq_save() protects the KM_IRQ0 address slot. */ | ||
3551 | local_irq_save(flags); | ||
3552 | buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset; | ||
3553 | memcpy(&cdata[xfer_cnt], buffer, min_cnt); | ||
3554 | kunmap_atomic(buffer - sg[i].offset, KM_IRQ0); | ||
3555 | local_irq_restore(flags); | ||
3556 | 3523 | ||
3557 | xfer_cnt += min_cnt; | 3524 | local_irq_save(flags); |
3558 | } | 3525 | scsi_sg_copy_to_buffer(scmd, data, count); |
3526 | local_irq_restore(flags); | ||
3559 | } | 3527 | } |
3560 | 3528 | ||
3561 | /****************************************************************************/ | 3529 | /****************************************************************************/ |
@@ -3696,9 +3664,7 @@ ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb) | |||
3696 | scb->cmd.basic_io.sg_count = scb->sg_len; | 3664 | scb->cmd.basic_io.sg_count = scb->sg_len; |
3697 | 3665 | ||
3698 | if (scb->cmd.basic_io.lba) | 3666 | if (scb->cmd.basic_io.lba) |
3699 | scb->cmd.basic_io.lba = | 3667 | le32_add_cpu(&scb->cmd.basic_io.lba, |
3700 | cpu_to_le32(le32_to_cpu | ||
3701 | (scb->cmd.basic_io.lba) + | ||
3702 | le16_to_cpu(scb->cmd.basic_io. | 3668 | le16_to_cpu(scb->cmd.basic_io. |
3703 | sector_count)); | 3669 | sector_count)); |
3704 | else | 3670 | else |
@@ -3744,9 +3710,7 @@ ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb) | |||
3744 | scb->cmd.basic_io.sg_count = scb->sg_len; | 3710 | scb->cmd.basic_io.sg_count = scb->sg_len; |
3745 | 3711 | ||
3746 | if (scb->cmd.basic_io.lba) | 3712 | if (scb->cmd.basic_io.lba) |
3747 | scb->cmd.basic_io.lba = | 3713 | le32_add_cpu(&scb->cmd.basic_io.lba, |
3748 | cpu_to_le32(le32_to_cpu | ||
3749 | (scb->cmd.basic_io.lba) + | ||
3750 | le16_to_cpu(scb->cmd.basic_io. | 3714 | le16_to_cpu(scb->cmd.basic_io. |
3751 | sector_count)); | 3715 | sector_count)); |
3752 | else | 3716 | else |
@@ -4888,7 +4852,7 @@ ips_init_copperhead(ips_ha_t * ha) | |||
4888 | return (0); | 4852 | return (0); |
4889 | 4853 | ||
4890 | /* setup CCCR */ | 4854 | /* setup CCCR */ |
4891 | outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR); | 4855 | outl(0x1010, ha->io_addr + IPS_REG_CCCR); |
4892 | 4856 | ||
4893 | /* Enable busmastering */ | 4857 | /* Enable busmastering */ |
4894 | outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR); | 4858 | outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR); |
@@ -5270,12 +5234,12 @@ ips_statinit(ips_ha_t * ha) | |||
5270 | ha->adapt->p_status_tail = ha->adapt->status; | 5234 | ha->adapt->p_status_tail = ha->adapt->status; |
5271 | 5235 | ||
5272 | phys_status_start = ha->adapt->hw_status_start; | 5236 | phys_status_start = ha->adapt->hw_status_start; |
5273 | outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR); | 5237 | outl(phys_status_start, ha->io_addr + IPS_REG_SQSR); |
5274 | outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), | 5238 | outl(phys_status_start + IPS_STATUS_Q_SIZE, |
5275 | ha->io_addr + IPS_REG_SQER); | 5239 | ha->io_addr + IPS_REG_SQER); |
5276 | outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), | 5240 | outl(phys_status_start + IPS_STATUS_SIZE, |
5277 | ha->io_addr + IPS_REG_SQHR); | 5241 | ha->io_addr + IPS_REG_SQHR); |
5278 | outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR); | 5242 | outl(phys_status_start, ha->io_addr + IPS_REG_SQTR); |
5279 | 5243 | ||
5280 | ha->adapt->hw_status_tail = phys_status_start; | 5244 | ha->adapt->hw_status_tail = phys_status_start; |
5281 | } | 5245 | } |
@@ -5332,7 +5296,7 @@ ips_statupd_copperhead(ips_ha_t * ha) | |||
5332 | ha->adapt->hw_status_tail = ha->adapt->hw_status_start; | 5296 | ha->adapt->hw_status_tail = ha->adapt->hw_status_start; |
5333 | } | 5297 | } |
5334 | 5298 | ||
5335 | outl(cpu_to_le32(ha->adapt->hw_status_tail), | 5299 | outl(ha->adapt->hw_status_tail, |
5336 | ha->io_addr + IPS_REG_SQTR); | 5300 | ha->io_addr + IPS_REG_SQTR); |
5337 | 5301 | ||
5338 | return (ha->adapt->p_status_tail->value); | 5302 | return (ha->adapt->p_status_tail->value); |
@@ -5434,8 +5398,8 @@ ips_issue_copperhead(ips_ha_t * ha, ips_scb_t * scb) | |||
5434 | } /* end if */ | 5398 | } /* end if */ |
5435 | } /* end while */ | 5399 | } /* end while */ |
5436 | 5400 | ||
5437 | outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR); | 5401 | outl(scb->scb_busaddr, ha->io_addr + IPS_REG_CCSAR); |
5438 | outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR); | 5402 | outw(IPS_BIT_START_CMD, ha->io_addr + IPS_REG_CCCR); |
5439 | 5403 | ||
5440 | return (IPS_SUCCESS); | 5404 | return (IPS_SUCCESS); |
5441 | } | 5405 | } |
@@ -5520,7 +5484,7 @@ ips_issue_i2o(ips_ha_t * ha, ips_scb_t * scb) | |||
5520 | ips_name, ha->host_num, scb->cmd.basic_io.command_id); | 5484 | ips_name, ha->host_num, scb->cmd.basic_io.command_id); |
5521 | } | 5485 | } |
5522 | 5486 | ||
5523 | outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ); | 5487 | outl(scb->scb_busaddr, ha->io_addr + IPS_REG_I2O_INMSGQ); |
5524 | 5488 | ||
5525 | return (IPS_SUCCESS); | 5489 | return (IPS_SUCCESS); |
5526 | } | 5490 | } |
@@ -6412,7 +6376,7 @@ ips_program_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize, | |||
6412 | 6376 | ||
6413 | for (i = 0; i < buffersize; i++) { | 6377 | for (i = 0; i < buffersize; i++) { |
6414 | /* write a byte */ | 6378 | /* write a byte */ |
6415 | outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); | 6379 | outl(i + offset, ha->io_addr + IPS_REG_FLAP); |
6416 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 6380 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
6417 | udelay(25); /* 25 us */ | 6381 | udelay(25); /* 25 us */ |
6418 | 6382 | ||
@@ -6597,7 +6561,7 @@ ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize, | |||
6597 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) | 6561 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55) |
6598 | return (1); | 6562 | return (1); |
6599 | 6563 | ||
6600 | outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP); | 6564 | outl(1, ha->io_addr + IPS_REG_FLAP); |
6601 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 6565 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
6602 | udelay(25); /* 25 us */ | 6566 | udelay(25); /* 25 us */ |
6603 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) | 6567 | if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA) |
@@ -6606,7 +6570,7 @@ ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize, | |||
6606 | checksum = 0xff; | 6570 | checksum = 0xff; |
6607 | for (i = 2; i < buffersize; i++) { | 6571 | for (i = 2; i < buffersize; i++) { |
6608 | 6572 | ||
6609 | outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP); | 6573 | outl(i + offset, ha->io_addr + IPS_REG_FLAP); |
6610 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) | 6574 | if (ha->pcidev->revision == IPS_REVID_TROMBONE64) |
6611 | udelay(25); /* 25 us */ | 6575 | udelay(25); /* 25 us */ |
6612 | 6576 | ||
@@ -6842,7 +6806,6 @@ ips_register_scsi(int index) | |||
6842 | sh->sg_tablesize = sh->hostt->sg_tablesize; | 6806 | sh->sg_tablesize = sh->hostt->sg_tablesize; |
6843 | sh->can_queue = sh->hostt->can_queue; | 6807 | sh->can_queue = sh->hostt->can_queue; |
6844 | sh->cmd_per_lun = sh->hostt->cmd_per_lun; | 6808 | sh->cmd_per_lun = sh->hostt->cmd_per_lun; |
6845 | sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma; | ||
6846 | sh->use_clustering = sh->hostt->use_clustering; | 6809 | sh->use_clustering = sh->hostt->use_clustering; |
6847 | sh->max_sectors = 128; | 6810 | sh->max_sectors = 128; |
6848 | 6811 | ||
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 8a178674cb18..72b9b2a0eba3 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -528,6 +528,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
528 | struct iscsi_session *session = conn->session; | 528 | struct iscsi_session *session = conn->session; |
529 | struct scsi_cmnd *sc = ctask->sc; | 529 | struct scsi_cmnd *sc = ctask->sc; |
530 | int datasn = be32_to_cpu(rhdr->datasn); | 530 | int datasn = be32_to_cpu(rhdr->datasn); |
531 | unsigned total_in_length = scsi_in(sc)->length; | ||
531 | 532 | ||
532 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr); | 533 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr); |
533 | if (tcp_conn->in.datalen == 0) | 534 | if (tcp_conn->in.datalen == 0) |
@@ -542,10 +543,10 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
542 | tcp_ctask->exp_datasn++; | 543 | tcp_ctask->exp_datasn++; |
543 | 544 | ||
544 | tcp_ctask->data_offset = be32_to_cpu(rhdr->offset); | 545 | tcp_ctask->data_offset = be32_to_cpu(rhdr->offset); |
545 | if (tcp_ctask->data_offset + tcp_conn->in.datalen > scsi_bufflen(sc)) { | 546 | if (tcp_ctask->data_offset + tcp_conn->in.datalen > total_in_length) { |
546 | debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n", | 547 | debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n", |
547 | __FUNCTION__, tcp_ctask->data_offset, | 548 | __FUNCTION__, tcp_ctask->data_offset, |
548 | tcp_conn->in.datalen, scsi_bufflen(sc)); | 549 | tcp_conn->in.datalen, total_in_length); |
549 | return ISCSI_ERR_DATA_OFFSET; | 550 | return ISCSI_ERR_DATA_OFFSET; |
550 | } | 551 | } |
551 | 552 | ||
@@ -558,8 +559,8 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
558 | 559 | ||
559 | if (res_count > 0 && | 560 | if (res_count > 0 && |
560 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || | 561 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || |
561 | res_count <= scsi_bufflen(sc))) | 562 | res_count <= total_in_length)) |
562 | scsi_set_resid(sc, res_count); | 563 | scsi_in(sc)->resid = res_count; |
563 | else | 564 | else |
564 | sc->result = (DID_BAD_TARGET << 16) | | 565 | sc->result = (DID_BAD_TARGET << 16) | |
565 | rhdr->cmd_status; | 566 | rhdr->cmd_status; |
@@ -670,11 +671,11 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
670 | r2t->data_length, session->max_burst); | 671 | r2t->data_length, session->max_burst); |
671 | 672 | ||
672 | r2t->data_offset = be32_to_cpu(rhdr->data_offset); | 673 | r2t->data_offset = be32_to_cpu(rhdr->data_offset); |
673 | if (r2t->data_offset + r2t->data_length > scsi_bufflen(ctask->sc)) { | 674 | if (r2t->data_offset + r2t->data_length > scsi_out(ctask->sc)->length) { |
674 | iscsi_conn_printk(KERN_ERR, conn, | 675 | iscsi_conn_printk(KERN_ERR, conn, |
675 | "invalid R2T with data len %u at offset %u " | 676 | "invalid R2T with data len %u at offset %u " |
676 | "and total length %d\n", r2t->data_length, | 677 | "and total length %d\n", r2t->data_length, |
677 | r2t->data_offset, scsi_bufflen(ctask->sc)); | 678 | r2t->data_offset, scsi_out(ctask->sc)->length); |
678 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, | 679 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, |
679 | sizeof(void*)); | 680 | sizeof(void*)); |
680 | return ISCSI_ERR_DATALEN; | 681 | return ISCSI_ERR_DATALEN; |
@@ -771,6 +772,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | |||
771 | if (tcp_conn->in.datalen) { | 772 | if (tcp_conn->in.datalen) { |
772 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 773 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
773 | struct hash_desc *rx_hash = NULL; | 774 | struct hash_desc *rx_hash = NULL; |
775 | struct scsi_data_buffer *sdb = scsi_in(ctask->sc); | ||
774 | 776 | ||
775 | /* | 777 | /* |
776 | * Setup copy of Data-In into the Scsi_Cmnd | 778 | * Setup copy of Data-In into the Scsi_Cmnd |
@@ -788,8 +790,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | |||
788 | tcp_ctask->data_offset, | 790 | tcp_ctask->data_offset, |
789 | tcp_conn->in.datalen); | 791 | tcp_conn->in.datalen); |
790 | return iscsi_segment_seek_sg(&tcp_conn->in.segment, | 792 | return iscsi_segment_seek_sg(&tcp_conn->in.segment, |
791 | scsi_sglist(ctask->sc), | 793 | sdb->table.sgl, |
792 | scsi_sg_count(ctask->sc), | 794 | sdb->table.nents, |
793 | tcp_ctask->data_offset, | 795 | tcp_ctask->data_offset, |
794 | tcp_conn->in.datalen, | 796 | tcp_conn->in.datalen, |
795 | iscsi_tcp_process_data_in, | 797 | iscsi_tcp_process_data_in, |
@@ -1332,7 +1334,8 @@ iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask) | |||
1332 | return 0; | 1334 | return 0; |
1333 | 1335 | ||
1334 | /* If we have immediate data, attach a payload */ | 1336 | /* If we have immediate data, attach a payload */ |
1335 | err = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc), scsi_sg_count(sc), | 1337 | err = iscsi_tcp_send_data_prep(conn, scsi_out(sc)->table.sgl, |
1338 | scsi_out(sc)->table.nents, | ||
1336 | 0, ctask->imm_count); | 1339 | 0, ctask->imm_count); |
1337 | if (err) | 1340 | if (err) |
1338 | return err; | 1341 | return err; |
@@ -1386,6 +1389,7 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1386 | { | 1389 | { |
1387 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1390 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
1388 | struct scsi_cmnd *sc = ctask->sc; | 1391 | struct scsi_cmnd *sc = ctask->sc; |
1392 | struct scsi_data_buffer *sdb = scsi_out(sc); | ||
1389 | int rc = 0; | 1393 | int rc = 0; |
1390 | 1394 | ||
1391 | flush: | 1395 | flush: |
@@ -1412,9 +1416,8 @@ flush: | |||
1412 | ctask->itt, tcp_ctask->sent, ctask->data_count); | 1416 | ctask->itt, tcp_ctask->sent, ctask->data_count); |
1413 | 1417 | ||
1414 | iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr)); | 1418 | iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr)); |
1415 | rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc), | 1419 | rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl, |
1416 | scsi_sg_count(sc), | 1420 | sdb->table.nents, tcp_ctask->sent, |
1417 | tcp_ctask->sent, | ||
1418 | ctask->data_count); | 1421 | ctask->data_count); |
1419 | if (rc) | 1422 | if (rc) |
1420 | goto fail; | 1423 | goto fail; |
@@ -1460,8 +1463,8 @@ flush: | |||
1460 | iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr, | 1463 | iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr, |
1461 | sizeof(struct iscsi_hdr)); | 1464 | sizeof(struct iscsi_hdr)); |
1462 | 1465 | ||
1463 | rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc), | 1466 | rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl, |
1464 | scsi_sg_count(sc), | 1467 | sdb->table.nents, |
1465 | r2t->data_offset + r2t->sent, | 1468 | r2t->data_offset + r2t->sent, |
1466 | r2t->data_count); | 1469 | r2t->data_count); |
1467 | if (rc) | 1470 | if (rc) |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index bdd7de7da39a..010c1b9b178c 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -137,6 +137,70 @@ static int iscsi_add_hdr(struct iscsi_cmd_task *ctask, unsigned len) | |||
137 | return 0; | 137 | return 0; |
138 | } | 138 | } |
139 | 139 | ||
140 | /* | ||
141 | * make an extended cdb AHS | ||
142 | */ | ||
143 | static int iscsi_prep_ecdb_ahs(struct iscsi_cmd_task *ctask) | ||
144 | { | ||
145 | struct scsi_cmnd *cmd = ctask->sc; | ||
146 | unsigned rlen, pad_len; | ||
147 | unsigned short ahslength; | ||
148 | struct iscsi_ecdb_ahdr *ecdb_ahdr; | ||
149 | int rc; | ||
150 | |||
151 | ecdb_ahdr = iscsi_next_hdr(ctask); | ||
152 | rlen = cmd->cmd_len - ISCSI_CDB_SIZE; | ||
153 | |||
154 | BUG_ON(rlen > sizeof(ecdb_ahdr->ecdb)); | ||
155 | ahslength = rlen + sizeof(ecdb_ahdr->reserved); | ||
156 | |||
157 | pad_len = iscsi_padding(rlen); | ||
158 | |||
159 | rc = iscsi_add_hdr(ctask, sizeof(ecdb_ahdr->ahslength) + | ||
160 | sizeof(ecdb_ahdr->ahstype) + ahslength + pad_len); | ||
161 | if (rc) | ||
162 | return rc; | ||
163 | |||
164 | if (pad_len) | ||
165 | memset(&ecdb_ahdr->ecdb[rlen], 0, pad_len); | ||
166 | |||
167 | ecdb_ahdr->ahslength = cpu_to_be16(ahslength); | ||
168 | ecdb_ahdr->ahstype = ISCSI_AHSTYPE_CDB; | ||
169 | ecdb_ahdr->reserved = 0; | ||
170 | memcpy(ecdb_ahdr->ecdb, cmd->cmnd + ISCSI_CDB_SIZE, rlen); | ||
171 | |||
172 | debug_scsi("iscsi_prep_ecdb_ahs: varlen_cdb_len %d " | ||
173 | "rlen %d pad_len %d ahs_length %d iscsi_headers_size %u\n", | ||
174 | cmd->cmd_len, rlen, pad_len, ahslength, ctask->hdr_len); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int iscsi_prep_bidi_ahs(struct iscsi_cmd_task *ctask) | ||
180 | { | ||
181 | struct scsi_cmnd *sc = ctask->sc; | ||
182 | struct iscsi_rlength_ahdr *rlen_ahdr; | ||
183 | int rc; | ||
184 | |||
185 | rlen_ahdr = iscsi_next_hdr(ctask); | ||
186 | rc = iscsi_add_hdr(ctask, sizeof(*rlen_ahdr)); | ||
187 | if (rc) | ||
188 | return rc; | ||
189 | |||
190 | rlen_ahdr->ahslength = | ||
191 | cpu_to_be16(sizeof(rlen_ahdr->read_length) + | ||
192 | sizeof(rlen_ahdr->reserved)); | ||
193 | rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH; | ||
194 | rlen_ahdr->reserved = 0; | ||
195 | rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length); | ||
196 | |||
197 | debug_scsi("bidi-in rlen_ahdr->read_length(%d) " | ||
198 | "rlen_ahdr->ahslength(%d)\n", | ||
199 | be32_to_cpu(rlen_ahdr->read_length), | ||
200 | be16_to_cpu(rlen_ahdr->ahslength)); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
140 | /** | 204 | /** |
141 | * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu | 205 | * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu |
142 | * @ctask: iscsi cmd task | 206 | * @ctask: iscsi cmd task |
@@ -150,7 +214,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
150 | struct iscsi_session *session = conn->session; | 214 | struct iscsi_session *session = conn->session; |
151 | struct iscsi_cmd *hdr = ctask->hdr; | 215 | struct iscsi_cmd *hdr = ctask->hdr; |
152 | struct scsi_cmnd *sc = ctask->sc; | 216 | struct scsi_cmnd *sc = ctask->sc; |
153 | unsigned hdrlength; | 217 | unsigned hdrlength, cmd_len; |
154 | int rc; | 218 | int rc; |
155 | 219 | ||
156 | ctask->hdr_len = 0; | 220 | ctask->hdr_len = 0; |
@@ -161,17 +225,30 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
161 | hdr->flags = ISCSI_ATTR_SIMPLE; | 225 | hdr->flags = ISCSI_ATTR_SIMPLE; |
162 | int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); | 226 | int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); |
163 | hdr->itt = build_itt(ctask->itt, session->age); | 227 | hdr->itt = build_itt(ctask->itt, session->age); |
164 | hdr->data_length = cpu_to_be32(scsi_bufflen(sc)); | ||
165 | hdr->cmdsn = cpu_to_be32(session->cmdsn); | 228 | hdr->cmdsn = cpu_to_be32(session->cmdsn); |
166 | session->cmdsn++; | 229 | session->cmdsn++; |
167 | hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); | 230 | hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); |
168 | memcpy(hdr->cdb, sc->cmnd, sc->cmd_len); | 231 | cmd_len = sc->cmd_len; |
169 | if (sc->cmd_len < MAX_COMMAND_SIZE) | 232 | if (cmd_len < ISCSI_CDB_SIZE) |
170 | memset(&hdr->cdb[sc->cmd_len], 0, | 233 | memset(&hdr->cdb[cmd_len], 0, ISCSI_CDB_SIZE - cmd_len); |
171 | MAX_COMMAND_SIZE - sc->cmd_len); | 234 | else if (cmd_len > ISCSI_CDB_SIZE) { |
235 | rc = iscsi_prep_ecdb_ahs(ctask); | ||
236 | if (rc) | ||
237 | return rc; | ||
238 | cmd_len = ISCSI_CDB_SIZE; | ||
239 | } | ||
240 | memcpy(hdr->cdb, sc->cmnd, cmd_len); | ||
172 | 241 | ||
173 | ctask->imm_count = 0; | 242 | ctask->imm_count = 0; |
243 | if (scsi_bidi_cmnd(sc)) { | ||
244 | hdr->flags |= ISCSI_FLAG_CMD_READ; | ||
245 | rc = iscsi_prep_bidi_ahs(ctask); | ||
246 | if (rc) | ||
247 | return rc; | ||
248 | } | ||
174 | if (sc->sc_data_direction == DMA_TO_DEVICE) { | 249 | if (sc->sc_data_direction == DMA_TO_DEVICE) { |
250 | unsigned out_len = scsi_out(sc)->length; | ||
251 | hdr->data_length = cpu_to_be32(out_len); | ||
175 | hdr->flags |= ISCSI_FLAG_CMD_WRITE; | 252 | hdr->flags |= ISCSI_FLAG_CMD_WRITE; |
176 | /* | 253 | /* |
177 | * Write counters: | 254 | * Write counters: |
@@ -192,19 +269,19 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
192 | ctask->unsol_datasn = 0; | 269 | ctask->unsol_datasn = 0; |
193 | 270 | ||
194 | if (session->imm_data_en) { | 271 | if (session->imm_data_en) { |
195 | if (scsi_bufflen(sc) >= session->first_burst) | 272 | if (out_len >= session->first_burst) |
196 | ctask->imm_count = min(session->first_burst, | 273 | ctask->imm_count = min(session->first_burst, |
197 | conn->max_xmit_dlength); | 274 | conn->max_xmit_dlength); |
198 | else | 275 | else |
199 | ctask->imm_count = min(scsi_bufflen(sc), | 276 | ctask->imm_count = min(out_len, |
200 | conn->max_xmit_dlength); | 277 | conn->max_xmit_dlength); |
201 | hton24(hdr->dlength, ctask->imm_count); | 278 | hton24(hdr->dlength, ctask->imm_count); |
202 | } else | 279 | } else |
203 | zero_data(hdr->dlength); | 280 | zero_data(hdr->dlength); |
204 | 281 | ||
205 | if (!session->initial_r2t_en) { | 282 | if (!session->initial_r2t_en) { |
206 | ctask->unsol_count = min((session->first_burst), | 283 | ctask->unsol_count = min(session->first_burst, out_len) |
207 | (scsi_bufflen(sc))) - ctask->imm_count; | 284 | - ctask->imm_count; |
208 | ctask->unsol_offset = ctask->imm_count; | 285 | ctask->unsol_offset = ctask->imm_count; |
209 | } | 286 | } |
210 | 287 | ||
@@ -214,6 +291,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
214 | } else { | 291 | } else { |
215 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | 292 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; |
216 | zero_data(hdr->dlength); | 293 | zero_data(hdr->dlength); |
294 | hdr->data_length = cpu_to_be32(scsi_in(sc)->length); | ||
217 | 295 | ||
218 | if (sc->sc_data_direction == DMA_FROM_DEVICE) | 296 | if (sc->sc_data_direction == DMA_FROM_DEVICE) |
219 | hdr->flags |= ISCSI_FLAG_CMD_READ; | 297 | hdr->flags |= ISCSI_FLAG_CMD_READ; |
@@ -232,10 +310,12 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
232 | return EIO; | 310 | return EIO; |
233 | 311 | ||
234 | conn->scsicmd_pdus_cnt++; | 312 | conn->scsicmd_pdus_cnt++; |
235 | debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d " | 313 | debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x " |
236 | "cmdsn %d win %d]\n", | 314 | "len %d bidi_len %d cmdsn %d win %d]\n", |
237 | sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", | 315 | scsi_bidi_cmnd(sc) ? "bidirectional" : |
238 | conn->id, sc, sc->cmnd[0], ctask->itt, scsi_bufflen(sc), | 316 | sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", |
317 | conn->id, sc, sc->cmnd[0], ctask->itt, | ||
318 | scsi_bufflen(sc), scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0, | ||
239 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); | 319 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); |
240 | return 0; | 320 | return 0; |
241 | } | 321 | } |
@@ -298,7 +378,12 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
298 | conn->session->tt->cleanup_cmd_task(conn, ctask); | 378 | conn->session->tt->cleanup_cmd_task(conn, ctask); |
299 | 379 | ||
300 | sc->result = err; | 380 | sc->result = err; |
301 | scsi_set_resid(sc, scsi_bufflen(sc)); | 381 | if (!scsi_bidi_cmnd(sc)) |
382 | scsi_set_resid(sc, scsi_bufflen(sc)); | ||
383 | else { | ||
384 | scsi_out(sc)->resid = scsi_out(sc)->length; | ||
385 | scsi_in(sc)->resid = scsi_in(sc)->length; | ||
386 | } | ||
302 | if (conn->ctask == ctask) | 387 | if (conn->ctask == ctask) |
303 | conn->ctask = NULL; | 388 | conn->ctask = NULL; |
304 | /* release ref from queuecommand */ | 389 | /* release ref from queuecommand */ |
@@ -433,6 +518,18 @@ invalid_datalen: | |||
433 | min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); | 518 | min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE)); |
434 | } | 519 | } |
435 | 520 | ||
521 | if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW | | ||
522 | ISCSI_FLAG_CMD_BIDI_OVERFLOW)) { | ||
523 | int res_count = be32_to_cpu(rhdr->bi_residual_count); | ||
524 | |||
525 | if (scsi_bidi_cmnd(sc) && res_count > 0 && | ||
526 | (rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW || | ||
527 | res_count <= scsi_in(sc)->length)) | ||
528 | scsi_in(sc)->resid = res_count; | ||
529 | else | ||
530 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | ||
531 | } | ||
532 | |||
436 | if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW | | 533 | if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW | |
437 | ISCSI_FLAG_CMD_OVERFLOW)) { | 534 | ISCSI_FLAG_CMD_OVERFLOW)) { |
438 | int res_count = be32_to_cpu(rhdr->residual_count); | 535 | int res_count = be32_to_cpu(rhdr->residual_count); |
@@ -440,13 +537,11 @@ invalid_datalen: | |||
440 | if (res_count > 0 && | 537 | if (res_count > 0 && |
441 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || | 538 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || |
442 | res_count <= scsi_bufflen(sc))) | 539 | res_count <= scsi_bufflen(sc))) |
540 | /* write side for bidi or uni-io set_resid */ | ||
443 | scsi_set_resid(sc, res_count); | 541 | scsi_set_resid(sc, res_count); |
444 | else | 542 | else |
445 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | 543 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; |
446 | } else if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW | | 544 | } |
447 | ISCSI_FLAG_CMD_BIDI_OVERFLOW)) | ||
448 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | ||
449 | |||
450 | out: | 545 | out: |
451 | debug_scsi("done [sc %lx res %d itt 0x%x]\n", | 546 | debug_scsi("done [sc %lx res %d itt 0x%x]\n", |
452 | (long)sc, sc->result, ctask->itt); | 547 | (long)sc, sc->result, ctask->itt); |
@@ -1102,7 +1197,12 @@ reject: | |||
1102 | fault: | 1197 | fault: |
1103 | spin_unlock(&session->lock); | 1198 | spin_unlock(&session->lock); |
1104 | debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason); | 1199 | debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason); |
1105 | scsi_set_resid(sc, scsi_bufflen(sc)); | 1200 | if (!scsi_bidi_cmnd(sc)) |
1201 | scsi_set_resid(sc, scsi_bufflen(sc)); | ||
1202 | else { | ||
1203 | scsi_out(sc)->resid = scsi_out(sc)->length; | ||
1204 | scsi_in(sc)->resid = scsi_in(sc)->length; | ||
1205 | } | ||
1106 | sc->scsi_done(sc); | 1206 | sc->scsi_done(sc); |
1107 | spin_lock(host->host_lock); | 1207 | spin_lock(host->host_lock); |
1108 | return 0; | 1208 | return 0; |
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index a4811e4106df..744f06d04a36 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
@@ -691,7 +691,7 @@ static int sas_discover_sata_dev(struct domain_device *dev) | |||
691 | /* incomplete response */ | 691 | /* incomplete response */ |
692 | SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to " | 692 | SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to " |
693 | "dev %llx\n", SAS_ADDR(dev->sas_addr)); | 693 | "dev %llx\n", SAS_ADDR(dev->sas_addr)); |
694 | if (!le16_to_cpu(identify_x[83] & (1<<6))) | 694 | if (!(identify_x[83] & cpu_to_le16(1<<6))) |
695 | goto cont1; | 695 | goto cont1; |
696 | res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES, | 696 | res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES, |
697 | ATA_FEATURE_PUP_STBY_SPIN_UP, | 697 | ATA_FEATURE_PUP_STBY_SPIN_UP, |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 1f8241563c6c..601ec5b6a7f6 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -24,6 +24,8 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/kthread.h> | 26 | #include <linux/kthread.h> |
27 | #include <linux/firmware.h> | ||
28 | #include <linux/ctype.h> | ||
27 | 29 | ||
28 | #include "sas_internal.h" | 30 | #include "sas_internal.h" |
29 | 31 | ||
@@ -1064,6 +1066,45 @@ void sas_target_destroy(struct scsi_target *starget) | |||
1064 | return; | 1066 | return; |
1065 | } | 1067 | } |
1066 | 1068 | ||
1069 | static void sas_parse_addr(u8 *sas_addr, const char *p) | ||
1070 | { | ||
1071 | int i; | ||
1072 | for (i = 0; i < SAS_ADDR_SIZE; i++) { | ||
1073 | u8 h, l; | ||
1074 | if (!*p) | ||
1075 | break; | ||
1076 | h = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10; | ||
1077 | p++; | ||
1078 | l = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10; | ||
1079 | p++; | ||
1080 | sas_addr[i] = (h<<4) | l; | ||
1081 | } | ||
1082 | } | ||
1083 | |||
1084 | #define SAS_STRING_ADDR_SIZE 16 | ||
1085 | |||
1086 | int sas_request_addr(struct Scsi_Host *shost, u8 *addr) | ||
1087 | { | ||
1088 | int res; | ||
1089 | const struct firmware *fw; | ||
1090 | |||
1091 | res = request_firmware(&fw, "sas_addr", &shost->shost_gendev); | ||
1092 | if (res) | ||
1093 | return res; | ||
1094 | |||
1095 | if (fw->size < SAS_STRING_ADDR_SIZE) { | ||
1096 | res = -ENODEV; | ||
1097 | goto out; | ||
1098 | } | ||
1099 | |||
1100 | sas_parse_addr(addr, fw->data); | ||
1101 | |||
1102 | out: | ||
1103 | release_firmware(fw); | ||
1104 | return res; | ||
1105 | } | ||
1106 | EXPORT_SYMBOL_GPL(sas_request_addr); | ||
1107 | |||
1067 | EXPORT_SYMBOL_GPL(sas_queuecommand); | 1108 | EXPORT_SYMBOL_GPL(sas_queuecommand); |
1068 | EXPORT_SYMBOL_GPL(sas_target_alloc); | 1109 | EXPORT_SYMBOL_GPL(sas_target_alloc); |
1069 | EXPORT_SYMBOL_GPL(sas_slave_configure); | 1110 | EXPORT_SYMBOL_GPL(sas_slave_configure); |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 2ab2d24dcc15..ec0b0f6e5e1a 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | struct lpfc_sli2_slim; | 24 | struct lpfc_sli2_slim; |
25 | 25 | ||
26 | #define LPFC_MAX_TARGET 256 /* max number of targets supported */ | 26 | #define LPFC_MAX_TARGET 4096 /* max number of targets supported */ |
27 | #define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els | 27 | #define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els |
28 | requests */ | 28 | requests */ |
29 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact | 29 | #define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact |
@@ -268,7 +268,6 @@ struct lpfc_vport { | |||
268 | #define FC_NLP_MORE 0x40 /* More node to process in node tbl */ | 268 | #define FC_NLP_MORE 0x40 /* More node to process in node tbl */ |
269 | #define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ | 269 | #define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ |
270 | #define FC_FABRIC 0x100 /* We are fabric attached */ | 270 | #define FC_FABRIC 0x100 /* We are fabric attached */ |
271 | #define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */ | ||
272 | #define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */ | 271 | #define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */ |
273 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ | 272 | #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ |
274 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ | 273 | #define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ |
@@ -433,8 +432,6 @@ struct lpfc_hba { | |||
433 | 432 | ||
434 | uint32_t fc_eventTag; /* event tag for link attention */ | 433 | uint32_t fc_eventTag; /* event tag for link attention */ |
435 | 434 | ||
436 | |||
437 | struct timer_list fc_estabtmo; /* link establishment timer */ | ||
438 | /* These fields used to be binfo */ | 435 | /* These fields used to be binfo */ |
439 | uint32_t fc_pref_DID; /* preferred D_ID */ | 436 | uint32_t fc_pref_DID; /* preferred D_ID */ |
440 | uint8_t fc_pref_ALPA; /* preferred AL_PA */ | 437 | uint8_t fc_pref_ALPA; /* preferred AL_PA */ |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index b12a841703ca..74c9fc204211 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -1954,7 +1954,9 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1954 | (phba->sysfs_mbox.mbox->mb.mbxCommand != | 1954 | (phba->sysfs_mbox.mbox->mb.mbxCommand != |
1955 | MBX_DUMP_MEMORY && | 1955 | MBX_DUMP_MEMORY && |
1956 | phba->sysfs_mbox.mbox->mb.mbxCommand != | 1956 | phba->sysfs_mbox.mbox->mb.mbxCommand != |
1957 | MBX_RESTART)) { | 1957 | MBX_RESTART && |
1958 | phba->sysfs_mbox.mbox->mb.mbxCommand != | ||
1959 | MBX_WRITE_VPARMS)) { | ||
1958 | sysfs_mbox_idle(phba); | 1960 | sysfs_mbox_idle(phba); |
1959 | spin_unlock_irq(&phba->hbalock); | 1961 | spin_unlock_irq(&phba->hbalock); |
1960 | return -EPERM; | 1962 | return -EPERM; |
@@ -1962,7 +1964,11 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr, | |||
1962 | 1964 | ||
1963 | phba->sysfs_mbox.mbox->vport = vport; | 1965 | phba->sysfs_mbox.mbox->vport = vport; |
1964 | 1966 | ||
1965 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) { | 1967 | /* Don't allow mailbox commands to be sent when blocked |
1968 | * or when in the middle of discovery | ||
1969 | */ | ||
1970 | if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO || | ||
1971 | vport->fc_flag & FC_NDISC_ACTIVE) { | ||
1966 | sysfs_mbox_idle(phba); | 1972 | sysfs_mbox_idle(phba); |
1967 | spin_unlock_irq(&phba->hbalock); | 1973 | spin_unlock_irq(&phba->hbalock); |
1968 | return -EAGAIN; | 1974 | return -EAGAIN; |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 3d0ccd9b341d..153afae567b5 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -63,7 +63,7 @@ lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | |||
63 | { | 63 | { |
64 | if (!mp) { | 64 | if (!mp) { |
65 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 65 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
66 | "0146 Ignoring unsolicted CT No HBQ " | 66 | "0146 Ignoring unsolicited CT No HBQ " |
67 | "status = x%x\n", | 67 | "status = x%x\n", |
68 | piocbq->iocb.ulpStatus); | 68 | piocbq->iocb.ulpStatus); |
69 | } | 69 | } |
@@ -438,7 +438,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
438 | (!(vport->ct_flags & FC_CT_RFF_ID)) || | 438 | (!(vport->ct_flags & FC_CT_RFF_ID)) || |
439 | (!vport->cfg_restrict_login)) { | 439 | (!vport->cfg_restrict_login)) { |
440 | ndlp = lpfc_setup_disc_node(vport, Did); | 440 | ndlp = lpfc_setup_disc_node(vport, Did); |
441 | if (ndlp) { | 441 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
442 | lpfc_debugfs_disc_trc(vport, | 442 | lpfc_debugfs_disc_trc(vport, |
443 | LPFC_DISC_TRC_CT, | 443 | LPFC_DISC_TRC_CT, |
444 | "Parse GID_FTrsp: " | 444 | "Parse GID_FTrsp: " |
@@ -543,7 +543,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
543 | struct lpfc_dmabuf *outp; | 543 | struct lpfc_dmabuf *outp; |
544 | struct lpfc_sli_ct_request *CTrsp; | 544 | struct lpfc_sli_ct_request *CTrsp; |
545 | struct lpfc_nodelist *ndlp; | 545 | struct lpfc_nodelist *ndlp; |
546 | int rc, retry; | 546 | int rc; |
547 | 547 | ||
548 | /* First save ndlp, before we overwrite it */ | 548 | /* First save ndlp, before we overwrite it */ |
549 | ndlp = cmdiocb->context_un.ndlp; | 549 | ndlp = cmdiocb->context_un.ndlp; |
@@ -563,45 +563,29 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
563 | if (vport->load_flag & FC_UNLOADING) | 563 | if (vport->load_flag & FC_UNLOADING) |
564 | goto out; | 564 | goto out; |
565 | 565 | ||
566 | if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { | 566 | if (lpfc_els_chk_latt(vport)) { |
567 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 567 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
568 | "0216 Link event during NS query\n"); | 568 | "0216 Link event during NS query\n"); |
569 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 569 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
570 | goto out; | 570 | goto out; |
571 | } | 571 | } |
572 | 572 | if (lpfc_error_lost_link(irsp)) { | |
573 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | ||
574 | "0226 NS query failed due to link event\n"); | ||
575 | goto out; | ||
576 | } | ||
573 | if (irsp->ulpStatus) { | 577 | if (irsp->ulpStatus) { |
574 | /* Check for retry */ | 578 | /* Check for retry */ |
575 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { | 579 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { |
576 | retry = 1; | 580 | if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT || |
577 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { | 581 | irsp->un.ulpWord[4] != IOERR_NO_RESOURCES) |
578 | switch (irsp->un.ulpWord[4]) { | ||
579 | case IOERR_NO_RESOURCES: | ||
580 | /* We don't increment the retry | ||
581 | * count for this case. | ||
582 | */ | ||
583 | break; | ||
584 | case IOERR_LINK_DOWN: | ||
585 | case IOERR_SLI_ABORTED: | ||
586 | case IOERR_SLI_DOWN: | ||
587 | retry = 0; | ||
588 | break; | ||
589 | default: | ||
590 | vport->fc_ns_retry++; | ||
591 | } | ||
592 | } | ||
593 | else | ||
594 | vport->fc_ns_retry++; | 582 | vport->fc_ns_retry++; |
595 | 583 | ||
596 | if (retry) { | 584 | /* CT command is being retried */ |
597 | /* CT command is being retried */ | 585 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, |
598 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, | ||
599 | vport->fc_ns_retry, 0); | 586 | vport->fc_ns_retry, 0); |
600 | if (rc == 0) { | 587 | if (rc == 0) |
601 | /* success */ | 588 | goto out; |
602 | goto out; | ||
603 | } | ||
604 | } | ||
605 | } | 589 | } |
606 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 590 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
607 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 591 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -780,7 +764,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
780 | 764 | ||
781 | /* This is a target port, unregistered port, or the GFF_ID failed */ | 765 | /* This is a target port, unregistered port, or the GFF_ID failed */ |
782 | ndlp = lpfc_setup_disc_node(vport, did); | 766 | ndlp = lpfc_setup_disc_node(vport, did); |
783 | if (ndlp) { | 767 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
784 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 768 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
785 | "0242 Process x%x GFF " | 769 | "0242 Process x%x GFF " |
786 | "NameServer Rsp Data: x%x x%x x%x\n", | 770 | "NameServer Rsp Data: x%x x%x x%x\n", |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 783d1eea13ef..90272e65957a 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -503,6 +503,8 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) | |||
503 | ndlp->nlp_sid); | 503 | ndlp->nlp_sid); |
504 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) | 504 | if (ndlp->nlp_type & NLP_FCP_INITIATOR) |
505 | len += snprintf(buf+len, size-len, "FCP_INITIATOR "); | 505 | len += snprintf(buf+len, size-len, "FCP_INITIATOR "); |
506 | len += snprintf(buf+len, size-len, "usgmap:%x ", | ||
507 | ndlp->nlp_usg_map); | ||
506 | len += snprintf(buf+len, size-len, "refcnt:%x", | 508 | len += snprintf(buf+len, size-len, "refcnt:%x", |
507 | atomic_read(&ndlp->kref.refcount)); | 509 | atomic_read(&ndlp->kref.refcount)); |
508 | len += snprintf(buf+len, size-len, "\n"); | 510 | len += snprintf(buf+len, size-len, "\n"); |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index cbb68a942255..886c5f1b11d2 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -719,9 +719,9 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) | |||
719 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && | 719 | if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && |
720 | icmd->un.elsreq64.bdl.ulpIoTag32) { | 720 | icmd->un.elsreq64.bdl.ulpIoTag32) { |
721 | ndlp = (struct lpfc_nodelist *)(iocb->context1); | 721 | ndlp = (struct lpfc_nodelist *)(iocb->context1); |
722 | if (ndlp && (ndlp->nlp_DID == Fabric_DID)) { | 722 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
723 | (ndlp->nlp_DID == Fabric_DID)) | ||
723 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); | 724 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
724 | } | ||
725 | } | 725 | } |
726 | } | 726 | } |
727 | spin_unlock_irq(&phba->hbalock); | 727 | spin_unlock_irq(&phba->hbalock); |
@@ -829,7 +829,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
829 | struct fc_rport *rport; | 829 | struct fc_rport *rport; |
830 | struct serv_parm *sp; | 830 | struct serv_parm *sp; |
831 | uint8_t name[sizeof(struct lpfc_name)]; | 831 | uint8_t name[sizeof(struct lpfc_name)]; |
832 | uint32_t rc; | 832 | uint32_t rc, keepDID = 0; |
833 | 833 | ||
834 | /* Fabric nodes can have the same WWPN so we don't bother searching | 834 | /* Fabric nodes can have the same WWPN so we don't bother searching |
835 | * by WWPN. Just return the ndlp that was given to us. | 835 | * by WWPN. Just return the ndlp that was given to us. |
@@ -858,11 +858,17 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
858 | return ndlp; | 858 | return ndlp; |
859 | lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); | 859 | lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID); |
860 | } else if (!NLP_CHK_NODE_ACT(new_ndlp)) { | 860 | } else if (!NLP_CHK_NODE_ACT(new_ndlp)) { |
861 | rc = memcmp(&ndlp->nlp_portname, name, | ||
862 | sizeof(struct lpfc_name)); | ||
863 | if (!rc) | ||
864 | return ndlp; | ||
861 | new_ndlp = lpfc_enable_node(vport, new_ndlp, | 865 | new_ndlp = lpfc_enable_node(vport, new_ndlp, |
862 | NLP_STE_UNUSED_NODE); | 866 | NLP_STE_UNUSED_NODE); |
863 | if (!new_ndlp) | 867 | if (!new_ndlp) |
864 | return ndlp; | 868 | return ndlp; |
865 | } | 869 | keepDID = new_ndlp->nlp_DID; |
870 | } else | ||
871 | keepDID = new_ndlp->nlp_DID; | ||
866 | 872 | ||
867 | lpfc_unreg_rpi(vport, new_ndlp); | 873 | lpfc_unreg_rpi(vport, new_ndlp); |
868 | new_ndlp->nlp_DID = ndlp->nlp_DID; | 874 | new_ndlp->nlp_DID = ndlp->nlp_DID; |
@@ -893,12 +899,24 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
893 | } | 899 | } |
894 | new_ndlp->nlp_type = ndlp->nlp_type; | 900 | new_ndlp->nlp_type = ndlp->nlp_type; |
895 | } | 901 | } |
902 | /* We shall actually free the ndlp with both nlp_DID and | ||
903 | * nlp_portname fields equals 0 to avoid any ndlp on the | ||
904 | * nodelist never to be used. | ||
905 | */ | ||
906 | if (ndlp->nlp_DID == 0) { | ||
907 | spin_lock_irq(&phba->ndlp_lock); | ||
908 | NLP_SET_FREE_REQ(ndlp); | ||
909 | spin_unlock_irq(&phba->ndlp_lock); | ||
910 | } | ||
896 | 911 | ||
912 | /* Two ndlps cannot have the same did on the nodelist */ | ||
913 | ndlp->nlp_DID = keepDID; | ||
897 | lpfc_drop_node(vport, ndlp); | 914 | lpfc_drop_node(vport, ndlp); |
898 | } | 915 | } |
899 | else { | 916 | else { |
900 | lpfc_unreg_rpi(vport, ndlp); | 917 | lpfc_unreg_rpi(vport, ndlp); |
901 | ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ | 918 | /* Two ndlps cannot have the same did */ |
919 | ndlp->nlp_DID = keepDID; | ||
902 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 920 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
903 | } | 921 | } |
904 | return new_ndlp; | 922 | return new_ndlp; |
@@ -2091,7 +2109,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2091 | } | 2109 | } |
2092 | 2110 | ||
2093 | phba->fc_stat.elsXmitRetry++; | 2111 | phba->fc_stat.elsXmitRetry++; |
2094 | if (ndlp && delay) { | 2112 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && delay) { |
2095 | phba->fc_stat.elsDelayRetry++; | 2113 | phba->fc_stat.elsDelayRetry++; |
2096 | ndlp->nlp_retry = cmdiocb->retry; | 2114 | ndlp->nlp_retry = cmdiocb->retry; |
2097 | 2115 | ||
@@ -2121,7 +2139,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2121 | lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry); | 2139 | lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry); |
2122 | return 1; | 2140 | return 1; |
2123 | case ELS_CMD_PLOGI: | 2141 | case ELS_CMD_PLOGI: |
2124 | if (ndlp) { | 2142 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
2125 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2143 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2126 | lpfc_nlp_set_state(vport, ndlp, | 2144 | lpfc_nlp_set_state(vport, ndlp, |
2127 | NLP_STE_PLOGI_ISSUE); | 2145 | NLP_STE_PLOGI_ISSUE); |
@@ -2302,7 +2320,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2302 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 2320 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
2303 | kfree(mp); | 2321 | kfree(mp); |
2304 | mempool_free(pmb, phba->mbox_mem_pool); | 2322 | mempool_free(pmb, phba->mbox_mem_pool); |
2305 | if (ndlp) { | 2323 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
2306 | lpfc_nlp_put(ndlp); | 2324 | lpfc_nlp_put(ndlp); |
2307 | /* This is the end of the default RPI cleanup logic for this | 2325 | /* This is the end of the default RPI cleanup logic for this |
2308 | * ndlp. If no other discovery threads are using this ndlp. | 2326 | * ndlp. If no other discovery threads are using this ndlp. |
@@ -2335,7 +2353,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2335 | * function can have cmdiocb->contest1 (ndlp) field set to NULL. | 2353 | * function can have cmdiocb->contest1 (ndlp) field set to NULL. |
2336 | */ | 2354 | */ |
2337 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); | 2355 | pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt); |
2338 | if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { | 2356 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
2357 | (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { | ||
2339 | /* A LS_RJT associated with Default RPI cleanup has its own | 2358 | /* A LS_RJT associated with Default RPI cleanup has its own |
2340 | * seperate code path. | 2359 | * seperate code path. |
2341 | */ | 2360 | */ |
@@ -2344,7 +2363,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2344 | } | 2363 | } |
2345 | 2364 | ||
2346 | /* Check to see if link went down during discovery */ | 2365 | /* Check to see if link went down during discovery */ |
2347 | if (!ndlp || lpfc_els_chk_latt(vport)) { | 2366 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) { |
2348 | if (mbox) { | 2367 | if (mbox) { |
2349 | mp = (struct lpfc_dmabuf *) mbox->context1; | 2368 | mp = (struct lpfc_dmabuf *) mbox->context1; |
2350 | if (mp) { | 2369 | if (mp) { |
@@ -2353,7 +2372,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2353 | } | 2372 | } |
2354 | mempool_free(mbox, phba->mbox_mem_pool); | 2373 | mempool_free(mbox, phba->mbox_mem_pool); |
2355 | } | 2374 | } |
2356 | if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) | 2375 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
2376 | (ndlp->nlp_flag & NLP_RM_DFLT_RPI)) | ||
2357 | if (lpfc_nlp_not_used(ndlp)) { | 2377 | if (lpfc_nlp_not_used(ndlp)) { |
2358 | ndlp = NULL; | 2378 | ndlp = NULL; |
2359 | /* Indicate the node has already released, | 2379 | /* Indicate the node has already released, |
@@ -2443,7 +2463,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2443 | mempool_free(mbox, phba->mbox_mem_pool); | 2463 | mempool_free(mbox, phba->mbox_mem_pool); |
2444 | } | 2464 | } |
2445 | out: | 2465 | out: |
2446 | if (ndlp) { | 2466 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { |
2447 | spin_lock_irq(shost->host_lock); | 2467 | spin_lock_irq(shost->host_lock); |
2448 | ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); | 2468 | ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); |
2449 | spin_unlock_irq(shost->host_lock); | 2469 | spin_unlock_irq(shost->host_lock); |
@@ -3139,6 +3159,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3139 | /* Another thread is walking fc_rscn_id_list on this vport */ | 3159 | /* Another thread is walking fc_rscn_id_list on this vport */ |
3140 | spin_unlock_irq(shost->host_lock); | 3160 | spin_unlock_irq(shost->host_lock); |
3141 | vport->fc_flag |= FC_RSCN_DISCOVERY; | 3161 | vport->fc_flag |= FC_RSCN_DISCOVERY; |
3162 | /* Send back ACC */ | ||
3163 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); | ||
3142 | return 0; | 3164 | return 0; |
3143 | } | 3165 | } |
3144 | /* Indicate we are walking fc_rscn_id_list on this vport */ | 3166 | /* Indicate we are walking fc_rscn_id_list on this vport */ |
@@ -3928,7 +3950,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) | |||
3928 | else { | 3950 | else { |
3929 | struct lpfc_nodelist *ndlp; | 3951 | struct lpfc_nodelist *ndlp; |
3930 | ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext); | 3952 | ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext); |
3931 | if (ndlp) | 3953 | if (ndlp && NLP_CHK_NODE_ACT(ndlp)) |
3932 | remote_ID = ndlp->nlp_DID; | 3954 | remote_ID = ndlp->nlp_DID; |
3933 | } | 3955 | } |
3934 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 3956 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -4097,21 +4119,22 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
4097 | newnode = 1; | 4119 | newnode = 1; |
4098 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) | 4120 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) |
4099 | ndlp->nlp_type |= NLP_FABRIC; | 4121 | ndlp->nlp_type |= NLP_FABRIC; |
4100 | } else { | 4122 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { |
4101 | if (!NLP_CHK_NODE_ACT(ndlp)) { | 4123 | ndlp = lpfc_enable_node(vport, ndlp, |
4102 | ndlp = lpfc_enable_node(vport, ndlp, | 4124 | NLP_STE_UNUSED_NODE); |
4103 | NLP_STE_UNUSED_NODE); | 4125 | if (!ndlp) |
4104 | if (!ndlp) | 4126 | goto dropit; |
4105 | goto dropit; | 4127 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
4106 | } | 4128 | newnode = 1; |
4107 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { | 4129 | if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) |
4108 | /* This is simular to the new node path */ | 4130 | ndlp->nlp_type |= NLP_FABRIC; |
4109 | ndlp = lpfc_nlp_get(ndlp); | 4131 | } else if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) { |
4110 | if (!ndlp) | 4132 | /* This is similar to the new node path */ |
4111 | goto dropit; | 4133 | ndlp = lpfc_nlp_get(ndlp); |
4112 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 4134 | if (!ndlp) |
4113 | newnode = 1; | 4135 | goto dropit; |
4114 | } | 4136 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
4137 | newnode = 1; | ||
4115 | } | 4138 | } |
4116 | 4139 | ||
4117 | phba->fc_stat.elsRcvFrame++; | 4140 | phba->fc_stat.elsRcvFrame++; |
@@ -4451,7 +4474,6 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4451 | return; | 4474 | return; |
4452 | } | 4475 | } |
4453 | lpfc_nlp_init(vport, ndlp, NameServer_DID); | 4476 | lpfc_nlp_init(vport, ndlp, NameServer_DID); |
4454 | ndlp->nlp_type |= NLP_FABRIC; | ||
4455 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { | 4477 | } else if (!NLP_CHK_NODE_ACT(ndlp)) { |
4456 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); | 4478 | ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); |
4457 | if (!ndlp) { | 4479 | if (!ndlp) { |
@@ -4465,6 +4487,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4465 | return; | 4487 | return; |
4466 | } | 4488 | } |
4467 | } | 4489 | } |
4490 | ndlp->nlp_type |= NLP_FABRIC; | ||
4468 | 4491 | ||
4469 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); | 4492 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
4470 | 4493 | ||
@@ -4481,8 +4504,8 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4481 | if (ndlp_fdmi) { | 4504 | if (ndlp_fdmi) { |
4482 | lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); | 4505 | lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID); |
4483 | ndlp_fdmi->nlp_type |= NLP_FABRIC; | 4506 | ndlp_fdmi->nlp_type |= NLP_FABRIC; |
4484 | ndlp_fdmi->nlp_state = | 4507 | lpfc_nlp_set_state(vport, ndlp_fdmi, |
4485 | NLP_STE_PLOGI_ISSUE; | 4508 | NLP_STE_PLOGI_ISSUE); |
4486 | lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, | 4509 | lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, |
4487 | 0); | 4510 | 0); |
4488 | } | 4511 | } |
@@ -5074,39 +5097,3 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba) | |||
5074 | (piocb->iocb_cmpl) (phba, piocb, piocb); | 5097 | (piocb->iocb_cmpl) (phba, piocb, piocb); |
5075 | } | 5098 | } |
5076 | } | 5099 | } |
5077 | |||
5078 | |||
5079 | #if 0 | ||
5080 | void lpfc_fabric_abort_flogi(struct lpfc_hba *phba) | ||
5081 | { | ||
5082 | LIST_HEAD(completions); | ||
5083 | struct lpfc_iocbq *tmp_iocb, *piocb; | ||
5084 | IOCB_t *cmd; | ||
5085 | struct lpfc_nodelist *ndlp; | ||
5086 | |||
5087 | spin_lock_irq(&phba->hbalock); | ||
5088 | list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list, | ||
5089 | list) { | ||
5090 | |||
5091 | cmd = &piocb->iocb; | ||
5092 | ndlp = (struct lpfc_nodelist *) piocb->context1; | ||
5093 | if (cmd->ulpCommand == CMD_ELS_REQUEST64_CR && | ||
5094 | ndlp != NULL && | ||
5095 | ndlp->nlp_DID == Fabric_DID) | ||
5096 | list_move_tail(&piocb->list, &completions); | ||
5097 | } | ||
5098 | spin_unlock_irq(&phba->hbalock); | ||
5099 | |||
5100 | while (!list_empty(&completions)) { | ||
5101 | piocb = list_get_first(&completions, struct lpfc_iocbq, list); | ||
5102 | list_del_init(&piocb->list); | ||
5103 | |||
5104 | cmd = &piocb->iocb; | ||
5105 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | ||
5106 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | ||
5107 | (piocb->iocb_cmpl) (phba, piocb, piocb); | ||
5108 | } | ||
5109 | } | ||
5110 | #endif /* 0 */ | ||
5111 | |||
5112 | |||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 976653440fba..7cb68feb04fd 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -69,7 +69,7 @@ lpfc_terminate_rport_io(struct fc_rport *rport) | |||
69 | rdata = rport->dd_data; | 69 | rdata = rport->dd_data; |
70 | ndlp = rdata->pnode; | 70 | ndlp = rdata->pnode; |
71 | 71 | ||
72 | if (!ndlp) { | 72 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { |
73 | if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) | 73 | if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) |
74 | printk(KERN_ERR "Cannot find remote node" | 74 | printk(KERN_ERR "Cannot find remote node" |
75 | " to terminate I/O Data x%x\n", | 75 | " to terminate I/O Data x%x\n", |
@@ -114,7 +114,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
114 | 114 | ||
115 | rdata = rport->dd_data; | 115 | rdata = rport->dd_data; |
116 | ndlp = rdata->pnode; | 116 | ndlp = rdata->pnode; |
117 | if (!ndlp) | 117 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) |
118 | return; | 118 | return; |
119 | 119 | ||
120 | vport = ndlp->vport; | 120 | vport = ndlp->vport; |
@@ -243,8 +243,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
243 | if (warn_on) { | 243 | if (warn_on) { |
244 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 244 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
245 | "0203 Devloss timeout on " | 245 | "0203 Devloss timeout on " |
246 | "WWPN %x:%x:%x:%x:%x:%x:%x:%x " | 246 | "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " |
247 | "NPort x%x Data: x%x x%x x%x\n", | 247 | "NPort x%06x Data: x%x x%x x%x\n", |
248 | *name, *(name+1), *(name+2), *(name+3), | 248 | *name, *(name+1), *(name+2), *(name+3), |
249 | *(name+4), *(name+5), *(name+6), *(name+7), | 249 | *(name+4), *(name+5), *(name+6), *(name+7), |
250 | ndlp->nlp_DID, ndlp->nlp_flag, | 250 | ndlp->nlp_DID, ndlp->nlp_flag, |
@@ -252,8 +252,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
252 | } else { | 252 | } else { |
253 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 253 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
254 | "0204 Devloss timeout on " | 254 | "0204 Devloss timeout on " |
255 | "WWPN %x:%x:%x:%x:%x:%x:%x:%x " | 255 | "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " |
256 | "NPort x%x Data: x%x x%x x%x\n", | 256 | "NPort x%06x Data: x%x x%x x%x\n", |
257 | *name, *(name+1), *(name+2), *(name+3), | 257 | *name, *(name+1), *(name+2), *(name+3), |
258 | *(name+4), *(name+5), *(name+6), *(name+7), | 258 | *(name+4), *(name+5), *(name+6), *(name+7), |
259 | ndlp->nlp_DID, ndlp->nlp_flag, | 259 | ndlp->nlp_DID, ndlp->nlp_flag, |
@@ -399,7 +399,10 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
399 | vport = vports[i]; | 399 | vport = vports[i]; |
400 | if (vport == NULL) | 400 | if (vport == NULL) |
401 | break; | 401 | break; |
402 | spin_lock_irq(&vport->work_port_lock); | ||
402 | work_port_events = vport->work_port_events; | 403 | work_port_events = vport->work_port_events; |
404 | vport->work_port_events &= ~work_port_events; | ||
405 | spin_unlock_irq(&vport->work_port_lock); | ||
403 | if (work_port_events & WORKER_DISC_TMO) | 406 | if (work_port_events & WORKER_DISC_TMO) |
404 | lpfc_disc_timeout_handler(vport); | 407 | lpfc_disc_timeout_handler(vport); |
405 | if (work_port_events & WORKER_ELS_TMO) | 408 | if (work_port_events & WORKER_ELS_TMO) |
@@ -416,9 +419,6 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
416 | lpfc_ramp_down_queue_handler(phba); | 419 | lpfc_ramp_down_queue_handler(phba); |
417 | if (work_port_events & WORKER_RAMP_UP_QUEUE) | 420 | if (work_port_events & WORKER_RAMP_UP_QUEUE) |
418 | lpfc_ramp_up_queue_handler(phba); | 421 | lpfc_ramp_up_queue_handler(phba); |
419 | spin_lock_irq(&vport->work_port_lock); | ||
420 | vport->work_port_events &= ~work_port_events; | ||
421 | spin_unlock_irq(&vport->work_port_lock); | ||
422 | } | 422 | } |
423 | lpfc_destroy_vport_work_array(phba, vports); | 423 | lpfc_destroy_vport_work_array(phba, vports); |
424 | 424 | ||
@@ -430,10 +430,10 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
430 | if (pring->flag & LPFC_STOP_IOCB_EVENT) { | 430 | if (pring->flag & LPFC_STOP_IOCB_EVENT) { |
431 | pring->flag |= LPFC_DEFERRED_RING_EVENT; | 431 | pring->flag |= LPFC_DEFERRED_RING_EVENT; |
432 | } else { | 432 | } else { |
433 | pring->flag &= ~LPFC_DEFERRED_RING_EVENT; | ||
433 | lpfc_sli_handle_slow_ring_event(phba, pring, | 434 | lpfc_sli_handle_slow_ring_event(phba, pring, |
434 | (status & | 435 | (status & |
435 | HA_RXMASK)); | 436 | HA_RXMASK)); |
436 | pring->flag &= ~LPFC_DEFERRED_RING_EVENT; | ||
437 | } | 437 | } |
438 | /* | 438 | /* |
439 | * Turn on Ring interrupts | 439 | * Turn on Ring interrupts |
@@ -519,7 +519,9 @@ lpfc_do_work(void *p) | |||
519 | schedule(); | 519 | schedule(); |
520 | } | 520 | } |
521 | } | 521 | } |
522 | spin_lock_irq(&phba->hbalock); | ||
522 | phba->work_wait = NULL; | 523 | phba->work_wait = NULL; |
524 | spin_unlock_irq(&phba->hbalock); | ||
523 | return 0; | 525 | return 0; |
524 | } | 526 | } |
525 | 527 | ||
@@ -809,11 +811,9 @@ out: | |||
809 | mempool_free(pmb, phba->mbox_mem_pool); | 811 | mempool_free(pmb, phba->mbox_mem_pool); |
810 | 812 | ||
811 | spin_lock_irq(shost->host_lock); | 813 | spin_lock_irq(shost->host_lock); |
812 | vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK); | 814 | vport->fc_flag &= ~FC_ABORT_DISCOVERY; |
813 | spin_unlock_irq(shost->host_lock); | 815 | spin_unlock_irq(shost->host_lock); |
814 | 816 | ||
815 | del_timer_sync(&phba->fc_estabtmo); | ||
816 | |||
817 | lpfc_can_disctmo(vport); | 817 | lpfc_can_disctmo(vport); |
818 | 818 | ||
819 | /* turn on Link Attention interrupts */ | 819 | /* turn on Link Attention interrupts */ |
@@ -1340,10 +1340,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
1340 | i++) { | 1340 | i++) { |
1341 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) | 1341 | if (vports[i]->port_type == LPFC_PHYSICAL_PORT) |
1342 | continue; | 1342 | continue; |
1343 | if (phba->fc_topology == TOPOLOGY_LOOP) { | ||
1344 | lpfc_vport_set_state(vports[i], | ||
1345 | FC_VPORT_LINKDOWN); | ||
1346 | continue; | ||
1347 | } | ||
1343 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1348 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
1344 | lpfc_initial_fdisc(vports[i]); | 1349 | lpfc_initial_fdisc(vports[i]); |
1345 | else if (phba->sli3_options & | 1350 | else { |
1346 | LPFC_SLI3_NPIV_ENABLED) { | ||
1347 | lpfc_vport_set_state(vports[i], | 1351 | lpfc_vport_set_state(vports[i], |
1348 | FC_VPORT_NO_FABRIC_SUPP); | 1352 | FC_VPORT_NO_FABRIC_SUPP); |
1349 | lpfc_printf_vlog(vport, KERN_ERR, | 1353 | lpfc_printf_vlog(vport, KERN_ERR, |
@@ -2190,10 +2194,6 @@ lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
2190 | if (did == Bcast_DID) | 2194 | if (did == Bcast_DID) |
2191 | return 0; | 2195 | return 0; |
2192 | 2196 | ||
2193 | if (ndlp->nlp_DID == 0) { | ||
2194 | return 0; | ||
2195 | } | ||
2196 | |||
2197 | /* First check for Direct match */ | 2197 | /* First check for Direct match */ |
2198 | if (ndlp->nlp_DID == did) | 2198 | if (ndlp->nlp_DID == did) |
2199 | return 1; | 2199 | return 1; |
@@ -2301,7 +2301,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did) | |||
2301 | return ndlp; | 2301 | return ndlp; |
2302 | } | 2302 | } |
2303 | 2303 | ||
2304 | if (vport->fc_flag & FC_RSCN_MODE) { | 2304 | if ((vport->fc_flag & FC_RSCN_MODE) && |
2305 | !(vport->fc_flag & FC_NDISC_ACTIVE)) { | ||
2305 | if (lpfc_rscn_payload_check(vport, did)) { | 2306 | if (lpfc_rscn_payload_check(vport, did)) { |
2306 | /* If we've already recieved a PLOGI from this NPort | 2307 | /* If we've already recieved a PLOGI from this NPort |
2307 | * we don't need to try to discover it again. | 2308 | * we don't need to try to discover it again. |
@@ -2947,24 +2948,6 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) | |||
2947 | return NULL; | 2948 | return NULL; |
2948 | } | 2949 | } |
2949 | 2950 | ||
2950 | #if 0 | ||
2951 | /* | ||
2952 | * Search node lists for a remote port matching filter criteria | ||
2953 | * Caller needs to hold host_lock before calling this routine. | ||
2954 | */ | ||
2955 | struct lpfc_nodelist * | ||
2956 | lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) | ||
2957 | { | ||
2958 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2959 | struct lpfc_nodelist *ndlp; | ||
2960 | |||
2961 | spin_lock_irq(shost->host_lock); | ||
2962 | ndlp = __lpfc_find_node(vport, filter, param); | ||
2963 | spin_unlock_irq(shost->host_lock); | ||
2964 | return ndlp; | ||
2965 | } | ||
2966 | #endif /* 0 */ | ||
2967 | |||
2968 | /* | 2951 | /* |
2969 | * This routine looks up the ndlp lists for the given RPI. If rpi found it | 2952 | * This routine looks up the ndlp lists for the given RPI. If rpi found it |
2970 | * returns the node list element pointer else return NULL. | 2953 | * returns the node list element pointer else return NULL. |
@@ -2975,20 +2958,6 @@ __lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) | |||
2975 | return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); | 2958 | return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi); |
2976 | } | 2959 | } |
2977 | 2960 | ||
2978 | #if 0 | ||
2979 | struct lpfc_nodelist * | ||
2980 | lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) | ||
2981 | { | ||
2982 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
2983 | struct lpfc_nodelist *ndlp; | ||
2984 | |||
2985 | spin_lock_irq(shost->host_lock); | ||
2986 | ndlp = __lpfc_findnode_rpi(vport, rpi); | ||
2987 | spin_unlock_irq(shost->host_lock); | ||
2988 | return ndlp; | ||
2989 | } | ||
2990 | #endif /* 0 */ | ||
2991 | |||
2992 | /* | 2961 | /* |
2993 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it | 2962 | * This routine looks up the ndlp lists for the given WWPN. If WWPN found it |
2994 | * returns the node element list pointer else return NULL. | 2963 | * returns the node element list pointer else return NULL. |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 22843751c2ca..fa757b251f82 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -559,8 +559,10 @@ lpfc_hb_timeout(unsigned long ptr) | |||
559 | phba->pport->work_port_events |= WORKER_HB_TMO; | 559 | phba->pport->work_port_events |= WORKER_HB_TMO; |
560 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); | 560 | spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag); |
561 | 561 | ||
562 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
562 | if (phba->work_wait) | 563 | if (phba->work_wait) |
563 | wake_up(phba->work_wait); | 564 | wake_up(phba->work_wait); |
565 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
564 | return; | 566 | return; |
565 | } | 567 | } |
566 | 568 | ||
@@ -714,12 +716,10 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
714 | struct lpfc_vport *vport = phba->pport; | 716 | struct lpfc_vport *vport = phba->pport; |
715 | struct lpfc_sli *psli = &phba->sli; | 717 | struct lpfc_sli *psli = &phba->sli; |
716 | struct lpfc_sli_ring *pring; | 718 | struct lpfc_sli_ring *pring; |
717 | struct lpfc_vport **vports; | ||
718 | uint32_t event_data; | 719 | uint32_t event_data; |
719 | unsigned long temperature; | 720 | unsigned long temperature; |
720 | struct temp_event temp_event_data; | 721 | struct temp_event temp_event_data; |
721 | struct Scsi_Host *shost; | 722 | struct Scsi_Host *shost; |
722 | int i; | ||
723 | 723 | ||
724 | /* If the pci channel is offline, ignore possible errors, | 724 | /* If the pci channel is offline, ignore possible errors, |
725 | * since we cannot communicate with the pci card anyway. */ | 725 | * since we cannot communicate with the pci card anyway. */ |
@@ -729,25 +729,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
729 | if (!phba->cfg_enable_hba_reset) | 729 | if (!phba->cfg_enable_hba_reset) |
730 | return; | 730 | return; |
731 | 731 | ||
732 | if (phba->work_hs & HS_FFER6 || | 732 | if (phba->work_hs & HS_FFER6) { |
733 | phba->work_hs & HS_FFER5) { | ||
734 | /* Re-establishing Link */ | 733 | /* Re-establishing Link */ |
735 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, | 734 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, |
736 | "1301 Re-establishing Link " | 735 | "1301 Re-establishing Link " |
737 | "Data: x%x x%x x%x\n", | 736 | "Data: x%x x%x x%x\n", |
738 | phba->work_hs, | 737 | phba->work_hs, |
739 | phba->work_status[0], phba->work_status[1]); | 738 | phba->work_status[0], phba->work_status[1]); |
740 | vports = lpfc_create_vport_work_array(phba); | 739 | |
741 | if (vports != NULL) | ||
742 | for(i = 0; | ||
743 | i <= phba->max_vpi && vports[i] != NULL; | ||
744 | i++){ | ||
745 | shost = lpfc_shost_from_vport(vports[i]); | ||
746 | spin_lock_irq(shost->host_lock); | ||
747 | vports[i]->fc_flag |= FC_ESTABLISH_LINK; | ||
748 | spin_unlock_irq(shost->host_lock); | ||
749 | } | ||
750 | lpfc_destroy_vport_work_array(phba, vports); | ||
751 | spin_lock_irq(&phba->hbalock); | 740 | spin_lock_irq(&phba->hbalock); |
752 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 741 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
753 | spin_unlock_irq(&phba->hbalock); | 742 | spin_unlock_irq(&phba->hbalock); |
@@ -761,7 +750,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
761 | pring = &psli->ring[psli->fcp_ring]; | 750 | pring = &psli->ring[psli->fcp_ring]; |
762 | lpfc_sli_abort_iocb_ring(phba, pring); | 751 | lpfc_sli_abort_iocb_ring(phba, pring); |
763 | 752 | ||
764 | |||
765 | /* | 753 | /* |
766 | * There was a firmware error. Take the hba offline and then | 754 | * There was a firmware error. Take the hba offline and then |
767 | * attempt to restart it. | 755 | * attempt to restart it. |
@@ -770,7 +758,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba) | |||
770 | lpfc_offline(phba); | 758 | lpfc_offline(phba); |
771 | lpfc_sli_brdrestart(phba); | 759 | lpfc_sli_brdrestart(phba); |
772 | if (lpfc_online(phba) == 0) { /* Initialize the HBA */ | 760 | if (lpfc_online(phba) == 0) { /* Initialize the HBA */ |
773 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
774 | lpfc_unblock_mgmt_io(phba); | 761 | lpfc_unblock_mgmt_io(phba); |
775 | return; | 762 | return; |
776 | } | 763 | } |
@@ -1454,6 +1441,13 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
1454 | NLP_SET_FREE_REQ(ndlp); | 1441 | NLP_SET_FREE_REQ(ndlp); |
1455 | spin_unlock_irq(&phba->ndlp_lock); | 1442 | spin_unlock_irq(&phba->ndlp_lock); |
1456 | 1443 | ||
1444 | if (vport->port_type != LPFC_PHYSICAL_PORT && | ||
1445 | ndlp->nlp_DID == Fabric_DID) { | ||
1446 | /* Just free up ndlp with Fabric_DID for vports */ | ||
1447 | lpfc_nlp_put(ndlp); | ||
1448 | continue; | ||
1449 | } | ||
1450 | |||
1457 | if (ndlp->nlp_type & NLP_FABRIC) | 1451 | if (ndlp->nlp_type & NLP_FABRIC) |
1458 | lpfc_disc_state_machine(vport, ndlp, NULL, | 1452 | lpfc_disc_state_machine(vport, ndlp, NULL, |
1459 | NLP_EVT_DEVICE_RECOVERY); | 1453 | NLP_EVT_DEVICE_RECOVERY); |
@@ -1491,31 +1485,6 @@ lpfc_cleanup(struct lpfc_vport *vport) | |||
1491 | return; | 1485 | return; |
1492 | } | 1486 | } |
1493 | 1487 | ||
1494 | static void | ||
1495 | lpfc_establish_link_tmo(unsigned long ptr) | ||
1496 | { | ||
1497 | struct lpfc_hba *phba = (struct lpfc_hba *) ptr; | ||
1498 | struct lpfc_vport **vports; | ||
1499 | unsigned long iflag; | ||
1500 | int i; | ||
1501 | |||
1502 | /* Re-establishing Link, timer expired */ | ||
1503 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | ||
1504 | "1300 Re-establishing Link, timer expired " | ||
1505 | "Data: x%x x%x\n", | ||
1506 | phba->pport->fc_flag, phba->pport->port_state); | ||
1507 | vports = lpfc_create_vport_work_array(phba); | ||
1508 | if (vports != NULL) | ||
1509 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | ||
1510 | struct Scsi_Host *shost; | ||
1511 | shost = lpfc_shost_from_vport(vports[i]); | ||
1512 | spin_lock_irqsave(shost->host_lock, iflag); | ||
1513 | vports[i]->fc_flag &= ~FC_ESTABLISH_LINK; | ||
1514 | spin_unlock_irqrestore(shost->host_lock, iflag); | ||
1515 | } | ||
1516 | lpfc_destroy_vport_work_array(phba, vports); | ||
1517 | } | ||
1518 | |||
1519 | void | 1488 | void |
1520 | lpfc_stop_vport_timers(struct lpfc_vport *vport) | 1489 | lpfc_stop_vport_timers(struct lpfc_vport *vport) |
1521 | { | 1490 | { |
@@ -1529,7 +1498,6 @@ static void | |||
1529 | lpfc_stop_phba_timers(struct lpfc_hba *phba) | 1498 | lpfc_stop_phba_timers(struct lpfc_hba *phba) |
1530 | { | 1499 | { |
1531 | del_timer_sync(&phba->fcp_poll_timer); | 1500 | del_timer_sync(&phba->fcp_poll_timer); |
1532 | del_timer_sync(&phba->fc_estabtmo); | ||
1533 | lpfc_stop_vport_timers(phba->pport); | 1501 | lpfc_stop_vport_timers(phba->pport); |
1534 | del_timer_sync(&phba->sli.mbox_tmo); | 1502 | del_timer_sync(&phba->sli.mbox_tmo); |
1535 | del_timer_sync(&phba->fabric_block_timer); | 1503 | del_timer_sync(&phba->fabric_block_timer); |
@@ -2005,10 +1973,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
2005 | phba->max_vpi = LPFC_MAX_VPI; | 1973 | phba->max_vpi = LPFC_MAX_VPI; |
2006 | 1974 | ||
2007 | /* Initialize timers used by driver */ | 1975 | /* Initialize timers used by driver */ |
2008 | init_timer(&phba->fc_estabtmo); | ||
2009 | phba->fc_estabtmo.function = lpfc_establish_link_tmo; | ||
2010 | phba->fc_estabtmo.data = (unsigned long)phba; | ||
2011 | |||
2012 | init_timer(&phba->hb_tmofunc); | 1976 | init_timer(&phba->hb_tmofunc); |
2013 | phba->hb_tmofunc.function = lpfc_hb_timeout; | 1977 | phba->hb_tmofunc.function = lpfc_hb_timeout; |
2014 | phba->hb_tmofunc.data = (unsigned long)phba; | 1978 | phba->hb_tmofunc.data = (unsigned long)phba; |
@@ -2406,6 +2370,7 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |||
2406 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 2370 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
2407 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 2371 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
2408 | struct lpfc_sli *psli = &phba->sli; | 2372 | struct lpfc_sli *psli = &phba->sli; |
2373 | int error, retval; | ||
2409 | 2374 | ||
2410 | dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); | 2375 | dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); |
2411 | if (pci_enable_device_mem(pdev)) { | 2376 | if (pci_enable_device_mem(pdev)) { |
@@ -2416,15 +2381,40 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |||
2416 | 2381 | ||
2417 | pci_set_master(pdev); | 2382 | pci_set_master(pdev); |
2418 | 2383 | ||
2419 | /* Re-establishing Link */ | ||
2420 | spin_lock_irq(shost->host_lock); | ||
2421 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; | ||
2422 | spin_unlock_irq(shost->host_lock); | ||
2423 | |||
2424 | spin_lock_irq(&phba->hbalock); | 2384 | spin_lock_irq(&phba->hbalock); |
2425 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 2385 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
2426 | spin_unlock_irq(&phba->hbalock); | 2386 | spin_unlock_irq(&phba->hbalock); |
2427 | 2387 | ||
2388 | /* Enable configured interrupt method */ | ||
2389 | phba->intr_type = NONE; | ||
2390 | if (phba->cfg_use_msi == 2) { | ||
2391 | error = lpfc_enable_msix(phba); | ||
2392 | if (!error) | ||
2393 | phba->intr_type = MSIX; | ||
2394 | } | ||
2395 | |||
2396 | /* Fallback to MSI if MSI-X initialization failed */ | ||
2397 | if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { | ||
2398 | retval = pci_enable_msi(phba->pcidev); | ||
2399 | if (!retval) | ||
2400 | phba->intr_type = MSI; | ||
2401 | else | ||
2402 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
2403 | "0470 Enable MSI failed, continuing " | ||
2404 | "with IRQ\n"); | ||
2405 | } | ||
2406 | |||
2407 | /* MSI-X is the only case the doesn't need to call request_irq */ | ||
2408 | if (phba->intr_type != MSIX) { | ||
2409 | retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, | ||
2410 | IRQF_SHARED, LPFC_DRIVER_NAME, phba); | ||
2411 | if (retval) { | ||
2412 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
2413 | "0471 Enable interrupt handler " | ||
2414 | "failed\n"); | ||
2415 | } else if (phba->intr_type != MSI) | ||
2416 | phba->intr_type = INTx; | ||
2417 | } | ||
2428 | 2418 | ||
2429 | /* Take device offline; this will perform cleanup */ | 2419 | /* Take device offline; this will perform cleanup */ |
2430 | lpfc_offline(phba); | 2420 | lpfc_offline(phba); |
@@ -2445,9 +2435,7 @@ static void lpfc_io_resume(struct pci_dev *pdev) | |||
2445 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | 2435 | struct Scsi_Host *shost = pci_get_drvdata(pdev); |
2446 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | 2436 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; |
2447 | 2437 | ||
2448 | if (lpfc_online(phba) == 0) { | 2438 | lpfc_online(phba); |
2449 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
2450 | } | ||
2451 | } | 2439 | } |
2452 | 2440 | ||
2453 | static struct pci_device_id lpfc_id_table[] = { | 2441 | static struct pci_device_id lpfc_id_table[] = { |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index d513813f6697..d08c4c890744 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -451,7 +451,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
451 | spin_unlock_irq(shost->host_lock); | 451 | spin_unlock_irq(shost->host_lock); |
452 | 452 | ||
453 | if ((ndlp->nlp_flag & NLP_ADISC_SND) && | 453 | if ((ndlp->nlp_flag & NLP_ADISC_SND) && |
454 | (vport->num_disc_nodes)) { | 454 | (vport->num_disc_nodes)) { |
455 | /* Check to see if there are more | 455 | /* Check to see if there are more |
456 | * ADISCs to be sent | 456 | * ADISCs to be sent |
457 | */ | 457 | */ |
@@ -469,20 +469,23 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
469 | lpfc_end_rscn(vport); | 469 | lpfc_end_rscn(vport); |
470 | } | 470 | } |
471 | } | 471 | } |
472 | else if (vport->num_disc_nodes) { | 472 | } |
473 | /* Check to see if there are more | 473 | } else if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) && |
474 | * PLOGIs to be sent | 474 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
475 | */ | 475 | (vport->num_disc_nodes)) { |
476 | lpfc_more_plogi(vport); | 476 | spin_lock_irq(shost->host_lock); |
477 | 477 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | |
478 | if (vport->num_disc_nodes == 0) { | 478 | spin_unlock_irq(shost->host_lock); |
479 | spin_lock_irq(shost->host_lock); | 479 | /* Check to see if there are more |
480 | vport->fc_flag &= ~FC_NDISC_ACTIVE; | 480 | * PLOGIs to be sent |
481 | spin_unlock_irq(shost->host_lock); | 481 | */ |
482 | lpfc_can_disctmo(vport); | 482 | lpfc_more_plogi(vport); |
483 | lpfc_end_rscn(vport); | 483 | if (vport->num_disc_nodes == 0) { |
484 | } | 484 | spin_lock_irq(shost->host_lock); |
485 | } | 485 | vport->fc_flag &= ~FC_NDISC_ACTIVE; |
486 | spin_unlock_irq(shost->host_lock); | ||
487 | lpfc_can_disctmo(vport); | ||
488 | lpfc_end_rscn(vport); | ||
486 | } | 489 | } |
487 | } | 490 | } |
488 | 491 | ||
@@ -869,8 +872,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, | |||
869 | 872 | ||
870 | lp = (uint32_t *) prsp->virt; | 873 | lp = (uint32_t *) prsp->virt; |
871 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 874 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
872 | if (wwn_to_u64(sp->portName.u.wwn) == 0 || | 875 | |
873 | wwn_to_u64(sp->nodeName.u.wwn) == 0) { | 876 | /* Some switches have FDMI servers returning 0 for WWN */ |
877 | if ((ndlp->nlp_DID != FDMI_DID) && | ||
878 | (wwn_to_u64(sp->portName.u.wwn) == 0 || | ||
879 | wwn_to_u64(sp->nodeName.u.wwn) == 0)) { | ||
874 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 880 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
875 | "0142 PLOGI RSP: Invalid WWN.\n"); | 881 | "0142 PLOGI RSP: Invalid WWN.\n"); |
876 | goto out; | 882 | goto out; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 70255c11d3ad..0910a9ab76a5 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -169,6 +169,9 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba) | |||
169 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { | 169 | for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) { |
170 | shost = lpfc_shost_from_vport(vports[i]); | 170 | shost = lpfc_shost_from_vport(vports[i]); |
171 | shost_for_each_device(sdev, shost) { | 171 | shost_for_each_device(sdev, shost) { |
172 | if (vports[i]->cfg_lun_queue_depth <= | ||
173 | sdev->queue_depth) | ||
174 | continue; | ||
172 | if (sdev->ordered_tags) | 175 | if (sdev->ordered_tags) |
173 | scsi_adjust_queue_depth(sdev, | 176 | scsi_adjust_queue_depth(sdev, |
174 | MSG_ORDERED_TAG, | 177 | MSG_ORDERED_TAG, |
@@ -578,14 +581,14 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
578 | lpfc_cmd->result == IOERR_NO_RESOURCES || | 581 | lpfc_cmd->result == IOERR_NO_RESOURCES || |
579 | lpfc_cmd->result == RJT_LOGIN_REQUIRED) { | 582 | lpfc_cmd->result == RJT_LOGIN_REQUIRED) { |
580 | cmd->result = ScsiResult(DID_REQUEUE, 0); | 583 | cmd->result = ScsiResult(DID_REQUEUE, 0); |
581 | break; | 584 | break; |
582 | } /* else: fall through */ | 585 | } /* else: fall through */ |
583 | default: | 586 | default: |
584 | cmd->result = ScsiResult(DID_ERROR, 0); | 587 | cmd->result = ScsiResult(DID_ERROR, 0); |
585 | break; | 588 | break; |
586 | } | 589 | } |
587 | 590 | ||
588 | if ((pnode == NULL ) | 591 | if (!pnode || !NLP_CHK_NODE_ACT(pnode) |
589 | || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) | 592 | || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) |
590 | cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY); | 593 | cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY); |
591 | } else { | 594 | } else { |
@@ -606,6 +609,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
606 | result = cmd->result; | 609 | result = cmd->result; |
607 | sdev = cmd->device; | 610 | sdev = cmd->device; |
608 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); | 611 | lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); |
612 | spin_lock_irqsave(sdev->host->host_lock, flags); | ||
613 | lpfc_cmd->pCmd = NULL; /* This must be done before scsi_done */ | ||
614 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | ||
609 | cmd->scsi_done(cmd); | 615 | cmd->scsi_done(cmd); |
610 | 616 | ||
611 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { | 617 | if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { |
@@ -614,7 +620,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
614 | * wake up the thread. | 620 | * wake up the thread. |
615 | */ | 621 | */ |
616 | spin_lock_irqsave(sdev->host->host_lock, flags); | 622 | spin_lock_irqsave(sdev->host->host_lock, flags); |
617 | lpfc_cmd->pCmd = NULL; | ||
618 | if (lpfc_cmd->waitq) | 623 | if (lpfc_cmd->waitq) |
619 | wake_up(lpfc_cmd->waitq); | 624 | wake_up(lpfc_cmd->waitq); |
620 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | 625 | spin_unlock_irqrestore(sdev->host->host_lock, flags); |
@@ -626,7 +631,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
626 | if (!result) | 631 | if (!result) |
627 | lpfc_rampup_queue_depth(vport, sdev); | 632 | lpfc_rampup_queue_depth(vport, sdev); |
628 | 633 | ||
629 | if (!result && pnode != NULL && | 634 | if (!result && pnode && NLP_CHK_NODE_ACT(pnode) && |
630 | ((jiffies - pnode->last_ramp_up_time) > | 635 | ((jiffies - pnode->last_ramp_up_time) > |
631 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && | 636 | LPFC_Q_RAMP_UP_INTERVAL * HZ) && |
632 | ((jiffies - pnode->last_q_full_time) > | 637 | ((jiffies - pnode->last_q_full_time) > |
@@ -654,7 +659,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
654 | * Check for queue full. If the lun is reporting queue full, then | 659 | * Check for queue full. If the lun is reporting queue full, then |
655 | * back off the lun queue depth to prevent target overloads. | 660 | * back off the lun queue depth to prevent target overloads. |
656 | */ | 661 | */ |
657 | if (result == SAM_STAT_TASK_SET_FULL && pnode != NULL) { | 662 | if (result == SAM_STAT_TASK_SET_FULL && pnode && |
663 | NLP_CHK_NODE_ACT(pnode)) { | ||
658 | pnode->last_q_full_time = jiffies; | 664 | pnode->last_q_full_time = jiffies; |
659 | 665 | ||
660 | shost_for_each_device(tmp_sdev, sdev->host) { | 666 | shost_for_each_device(tmp_sdev, sdev->host) { |
@@ -684,7 +690,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
684 | * wake up the thread. | 690 | * wake up the thread. |
685 | */ | 691 | */ |
686 | spin_lock_irqsave(sdev->host->host_lock, flags); | 692 | spin_lock_irqsave(sdev->host->host_lock, flags); |
687 | lpfc_cmd->pCmd = NULL; | ||
688 | if (lpfc_cmd->waitq) | 693 | if (lpfc_cmd->waitq) |
689 | wake_up(lpfc_cmd->waitq); | 694 | wake_up(lpfc_cmd->waitq); |
690 | spin_unlock_irqrestore(sdev->host->host_lock, flags); | 695 | spin_unlock_irqrestore(sdev->host->host_lock, flags); |
@@ -704,6 +709,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
704 | int datadir = scsi_cmnd->sc_data_direction; | 709 | int datadir = scsi_cmnd->sc_data_direction; |
705 | char tag[2]; | 710 | char tag[2]; |
706 | 711 | ||
712 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) | ||
713 | return; | ||
714 | |||
707 | lpfc_cmd->fcp_rsp->rspSnsLen = 0; | 715 | lpfc_cmd->fcp_rsp->rspSnsLen = 0; |
708 | /* clear task management bits */ | 716 | /* clear task management bits */ |
709 | lpfc_cmd->fcp_cmnd->fcpCntl2 = 0; | 717 | lpfc_cmd->fcp_cmnd->fcpCntl2 = 0; |
@@ -785,9 +793,9 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport, | |||
785 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; | 793 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; |
786 | struct lpfc_nodelist *ndlp = rdata->pnode; | 794 | struct lpfc_nodelist *ndlp = rdata->pnode; |
787 | 795 | ||
788 | if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) { | 796 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || |
797 | ndlp->nlp_state != NLP_STE_MAPPED_NODE) | ||
789 | return 0; | 798 | return 0; |
790 | } | ||
791 | 799 | ||
792 | piocbq = &(lpfc_cmd->cur_iocbq); | 800 | piocbq = &(lpfc_cmd->cur_iocbq); |
793 | piocbq->vport = vport; | 801 | piocbq->vport = vport; |
@@ -842,7 +850,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport, | |||
842 | struct lpfc_iocbq *iocbqrsp; | 850 | struct lpfc_iocbq *iocbqrsp; |
843 | int ret; | 851 | int ret; |
844 | 852 | ||
845 | if (!rdata->pnode) | 853 | if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode)) |
846 | return FAILED; | 854 | return FAILED; |
847 | 855 | ||
848 | lpfc_cmd->rdata = rdata; | 856 | lpfc_cmd->rdata = rdata; |
@@ -959,7 +967,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) | |||
959 | * Catch race where our node has transitioned, but the | 967 | * Catch race where our node has transitioned, but the |
960 | * transport is still transitioning. | 968 | * transport is still transitioning. |
961 | */ | 969 | */ |
962 | if (!ndlp) { | 970 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { |
963 | cmnd->result = ScsiResult(DID_BUS_BUSY, 0); | 971 | cmnd->result = ScsiResult(DID_BUS_BUSY, 0); |
964 | goto out_fail_command; | 972 | goto out_fail_command; |
965 | } | 973 | } |
@@ -1146,7 +1154,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
1146 | * target is rediscovered or devloss timeout expires. | 1154 | * target is rediscovered or devloss timeout expires. |
1147 | */ | 1155 | */ |
1148 | while (1) { | 1156 | while (1) { |
1149 | if (!pnode) | 1157 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) |
1150 | goto out; | 1158 | goto out; |
1151 | 1159 | ||
1152 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { | 1160 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { |
@@ -1162,7 +1170,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd) | |||
1162 | goto out; | 1170 | goto out; |
1163 | } | 1171 | } |
1164 | pnode = rdata->pnode; | 1172 | pnode = rdata->pnode; |
1165 | if (!pnode) | 1173 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) |
1166 | goto out; | 1174 | goto out; |
1167 | } | 1175 | } |
1168 | if (pnode->nlp_state == NLP_STE_MAPPED_NODE) | 1176 | if (pnode->nlp_state == NLP_STE_MAPPED_NODE) |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index fc0d9501aba6..70a0a9eab211 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -2648,7 +2648,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2648 | spin_unlock_irq(&phba->pport->work_port_lock); | 2648 | spin_unlock_irq(&phba->pport->work_port_lock); |
2649 | spin_lock_irq(&phba->hbalock); | 2649 | spin_lock_irq(&phba->hbalock); |
2650 | phba->link_state = LPFC_LINK_UNKNOWN; | 2650 | phba->link_state = LPFC_LINK_UNKNOWN; |
2651 | phba->pport->fc_flag |= FC_ESTABLISH_LINK; | ||
2652 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | 2651 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; |
2653 | spin_unlock_irq(&phba->hbalock); | 2652 | spin_unlock_irq(&phba->hbalock); |
2654 | 2653 | ||
@@ -2669,8 +2668,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |||
2669 | lpfc_offline_prep(phba); | 2668 | lpfc_offline_prep(phba); |
2670 | lpfc_offline(phba); | 2669 | lpfc_offline(phba); |
2671 | lpfc_sli_brdrestart(phba); | 2670 | lpfc_sli_brdrestart(phba); |
2672 | if (lpfc_online(phba) == 0) /* Initialize the HBA */ | 2671 | lpfc_online(phba); |
2673 | mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60); | ||
2674 | lpfc_unblock_mgmt_io(phba); | 2672 | lpfc_unblock_mgmt_io(phba); |
2675 | return; | 2673 | return; |
2676 | } | 2674 | } |
@@ -2687,28 +2685,41 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2687 | unsigned long drvr_flag = 0; | 2685 | unsigned long drvr_flag = 0; |
2688 | volatile uint32_t word0, ldata; | 2686 | volatile uint32_t word0, ldata; |
2689 | void __iomem *to_slim; | 2687 | void __iomem *to_slim; |
2688 | int processing_queue = 0; | ||
2689 | |||
2690 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | ||
2691 | if (!pmbox) { | ||
2692 | /* processing mbox queue from intr_handler */ | ||
2693 | processing_queue = 1; | ||
2694 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
2695 | pmbox = lpfc_mbox_get(phba); | ||
2696 | if (!pmbox) { | ||
2697 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | ||
2698 | return MBX_SUCCESS; | ||
2699 | } | ||
2700 | } | ||
2690 | 2701 | ||
2691 | if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl && | 2702 | if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl && |
2692 | pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) { | 2703 | pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) { |
2693 | if(!pmbox->vport) { | 2704 | if(!pmbox->vport) { |
2705 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | ||
2694 | lpfc_printf_log(phba, KERN_ERR, | 2706 | lpfc_printf_log(phba, KERN_ERR, |
2695 | LOG_MBOX | LOG_VPORT, | 2707 | LOG_MBOX | LOG_VPORT, |
2696 | "1806 Mbox x%x failed. No vport\n", | 2708 | "1806 Mbox x%x failed. No vport\n", |
2697 | pmbox->mb.mbxCommand); | 2709 | pmbox->mb.mbxCommand); |
2698 | dump_stack(); | 2710 | dump_stack(); |
2699 | return MBX_NOT_FINISHED; | 2711 | goto out_not_finished; |
2700 | } | 2712 | } |
2701 | } | 2713 | } |
2702 | 2714 | ||
2703 | |||
2704 | /* If the PCI channel is in offline state, do not post mbox. */ | 2715 | /* If the PCI channel is in offline state, do not post mbox. */ |
2705 | if (unlikely(pci_channel_offline(phba->pcidev))) | 2716 | if (unlikely(pci_channel_offline(phba->pcidev))) { |
2706 | return MBX_NOT_FINISHED; | 2717 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2718 | goto out_not_finished; | ||
2719 | } | ||
2707 | 2720 | ||
2708 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | ||
2709 | psli = &phba->sli; | 2721 | psli = &phba->sli; |
2710 | 2722 | ||
2711 | |||
2712 | mb = &pmbox->mb; | 2723 | mb = &pmbox->mb; |
2713 | status = MBX_SUCCESS; | 2724 | status = MBX_SUCCESS; |
2714 | 2725 | ||
@@ -2717,14 +2728,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2717 | 2728 | ||
2718 | /* Mbox command <mbxCommand> cannot issue */ | 2729 | /* Mbox command <mbxCommand> cannot issue */ |
2719 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2730 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2720 | return MBX_NOT_FINISHED; | 2731 | goto out_not_finished; |
2721 | } | 2732 | } |
2722 | 2733 | ||
2723 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && | 2734 | if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT && |
2724 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { | 2735 | !(readl(phba->HCregaddr) & HC_MBINT_ENA)) { |
2725 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2736 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2726 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2737 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2727 | return MBX_NOT_FINISHED; | 2738 | goto out_not_finished; |
2728 | } | 2739 | } |
2729 | 2740 | ||
2730 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { | 2741 | if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) { |
@@ -2738,14 +2749,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2738 | 2749 | ||
2739 | /* Mbox command <mbxCommand> cannot issue */ | 2750 | /* Mbox command <mbxCommand> cannot issue */ |
2740 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2751 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2741 | return MBX_NOT_FINISHED; | 2752 | goto out_not_finished; |
2742 | } | 2753 | } |
2743 | 2754 | ||
2744 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { | 2755 | if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) { |
2745 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2756 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2746 | /* Mbox command <mbxCommand> cannot issue */ | 2757 | /* Mbox command <mbxCommand> cannot issue */ |
2747 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2758 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2748 | return MBX_NOT_FINISHED; | 2759 | goto out_not_finished; |
2749 | } | 2760 | } |
2750 | 2761 | ||
2751 | /* Another mailbox command is still being processed, queue this | 2762 | /* Another mailbox command is still being processed, queue this |
@@ -2792,7 +2803,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2792 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2803 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2793 | /* Mbox command <mbxCommand> cannot issue */ | 2804 | /* Mbox command <mbxCommand> cannot issue */ |
2794 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); | 2805 | LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag); |
2795 | return MBX_NOT_FINISHED; | 2806 | goto out_not_finished; |
2796 | } | 2807 | } |
2797 | /* timeout active mbox command */ | 2808 | /* timeout active mbox command */ |
2798 | mod_timer(&psli->mbox_tmo, (jiffies + | 2809 | mod_timer(&psli->mbox_tmo, (jiffies + |
@@ -2900,7 +2911,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2900 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 2911 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
2901 | spin_unlock_irqrestore(&phba->hbalock, | 2912 | spin_unlock_irqrestore(&phba->hbalock, |
2902 | drvr_flag); | 2913 | drvr_flag); |
2903 | return MBX_NOT_FINISHED; | 2914 | goto out_not_finished; |
2904 | } | 2915 | } |
2905 | 2916 | ||
2906 | /* Check if we took a mbox interrupt while we were | 2917 | /* Check if we took a mbox interrupt while we were |
@@ -2967,6 +2978,13 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag) | |||
2967 | 2978 | ||
2968 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2979 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
2969 | return status; | 2980 | return status; |
2981 | |||
2982 | out_not_finished: | ||
2983 | if (processing_queue) { | ||
2984 | pmbox->mb.mbxStatus = MBX_NOT_FINISHED; | ||
2985 | lpfc_mbox_cmpl_put(phba, pmbox); | ||
2986 | } | ||
2987 | return MBX_NOT_FINISHED; | ||
2970 | } | 2988 | } |
2971 | 2989 | ||
2972 | /* | 2990 | /* |
@@ -3463,26 +3481,21 @@ lpfc_sli_hba_down(struct lpfc_hba *phba) | |||
3463 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; | 3481 | phba->pport->work_port_events &= ~WORKER_MBOX_TMO; |
3464 | spin_unlock(&phba->pport->work_port_lock); | 3482 | spin_unlock(&phba->pport->work_port_lock); |
3465 | 3483 | ||
3484 | /* Return any pending or completed mbox cmds */ | ||
3485 | list_splice_init(&phba->sli.mboxq, &completions); | ||
3466 | if (psli->mbox_active) { | 3486 | if (psli->mbox_active) { |
3467 | list_add_tail(&psli->mbox_active->list, &completions); | 3487 | list_add_tail(&psli->mbox_active->list, &completions); |
3468 | psli->mbox_active = NULL; | 3488 | psli->mbox_active = NULL; |
3469 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | 3489 | psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; |
3470 | } | 3490 | } |
3471 | |||
3472 | /* Return any pending or completed mbox cmds */ | ||
3473 | list_splice_init(&phba->sli.mboxq, &completions); | ||
3474 | list_splice_init(&phba->sli.mboxq_cmpl, &completions); | 3491 | list_splice_init(&phba->sli.mboxq_cmpl, &completions); |
3475 | INIT_LIST_HEAD(&psli->mboxq); | ||
3476 | INIT_LIST_HEAD(&psli->mboxq_cmpl); | ||
3477 | |||
3478 | spin_unlock_irqrestore(&phba->hbalock, flags); | 3492 | spin_unlock_irqrestore(&phba->hbalock, flags); |
3479 | 3493 | ||
3480 | while (!list_empty(&completions)) { | 3494 | while (!list_empty(&completions)) { |
3481 | list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list); | 3495 | list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list); |
3482 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; | 3496 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; |
3483 | if (pmb->mbox_cmpl) { | 3497 | if (pmb->mbox_cmpl) |
3484 | pmb->mbox_cmpl(phba,pmb); | 3498 | pmb->mbox_cmpl(phba,pmb); |
3485 | } | ||
3486 | } | 3499 | } |
3487 | return 1; | 3500 | return 1; |
3488 | } | 3501 | } |
@@ -3613,6 +3626,15 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
3613 | irsp->ulpStatus, irsp->un.ulpWord[4]); | 3626 | irsp->ulpStatus, irsp->un.ulpWord[4]); |
3614 | 3627 | ||
3615 | /* | 3628 | /* |
3629 | * If the iocb is not found in Firmware queue the iocb | ||
3630 | * might have completed already. Do not free it again. | ||
3631 | */ | ||
3632 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { | ||
3633 | spin_unlock_irq(&phba->hbalock); | ||
3634 | lpfc_sli_release_iocbq(phba, cmdiocb); | ||
3635 | return; | ||
3636 | } | ||
3637 | /* | ||
3616 | * make sure we have the right iocbq before taking it | 3638 | * make sure we have the right iocbq before taking it |
3617 | * off the txcmplq and try to call completion routine. | 3639 | * off the txcmplq and try to call completion routine. |
3618 | */ | 3640 | */ |
@@ -4174,6 +4196,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4174 | phba->pport->stopped = 1; | 4196 | phba->pport->stopped = 1; |
4175 | } | 4197 | } |
4176 | 4198 | ||
4199 | spin_lock(&phba->hbalock); | ||
4177 | if ((work_ha_copy & HA_MBATT) && | 4200 | if ((work_ha_copy & HA_MBATT) && |
4178 | (phba->sli.mbox_active)) { | 4201 | (phba->sli.mbox_active)) { |
4179 | pmb = phba->sli.mbox_active; | 4202 | pmb = phba->sli.mbox_active; |
@@ -4184,6 +4207,7 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4184 | /* First check out the status word */ | 4207 | /* First check out the status word */ |
4185 | lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t)); | 4208 | lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t)); |
4186 | if (pmbox->mbxOwner != OWN_HOST) { | 4209 | if (pmbox->mbxOwner != OWN_HOST) { |
4210 | spin_unlock(&phba->hbalock); | ||
4187 | /* | 4211 | /* |
4188 | * Stray Mailbox Interrupt, mbxCommand <cmd> | 4212 | * Stray Mailbox Interrupt, mbxCommand <cmd> |
4189 | * mbxStatus <status> | 4213 | * mbxStatus <status> |
@@ -4199,10 +4223,10 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4199 | /* clear mailbox attention bit */ | 4223 | /* clear mailbox attention bit */ |
4200 | work_ha_copy &= ~HA_MBATT; | 4224 | work_ha_copy &= ~HA_MBATT; |
4201 | } else { | 4225 | } else { |
4226 | phba->sli.mbox_active = NULL; | ||
4227 | spin_unlock(&phba->hbalock); | ||
4202 | phba->last_completion_time = jiffies; | 4228 | phba->last_completion_time = jiffies; |
4203 | del_timer(&phba->sli.mbox_tmo); | 4229 | del_timer(&phba->sli.mbox_tmo); |
4204 | |||
4205 | phba->sli.mbox_active = NULL; | ||
4206 | if (pmb->mbox_cmpl) { | 4230 | if (pmb->mbox_cmpl) { |
4207 | lpfc_sli_pcimem_bcopy(mbox, pmbox, | 4231 | lpfc_sli_pcimem_bcopy(mbox, pmbox, |
4208 | MAILBOX_CMD_SIZE); | 4232 | MAILBOX_CMD_SIZE); |
@@ -4237,10 +4261,15 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4237 | pmb->context1 = mp; | 4261 | pmb->context1 = mp; |
4238 | pmb->context2 = ndlp; | 4262 | pmb->context2 = ndlp; |
4239 | pmb->vport = vport; | 4263 | pmb->vport = vport; |
4240 | spin_lock(&phba->hbalock); | 4264 | rc = lpfc_sli_issue_mbox(phba, |
4241 | phba->sli.sli_flag &= | 4265 | pmb, |
4242 | ~LPFC_SLI_MBOX_ACTIVE; | 4266 | MBX_NOWAIT); |
4243 | spin_unlock(&phba->hbalock); | 4267 | if (rc != MBX_BUSY) |
4268 | lpfc_printf_log(phba, | ||
4269 | KERN_ERR, | ||
4270 | LOG_MBOX | LOG_SLI, | ||
4271 | "0306 rc should have" | ||
4272 | "been MBX_BUSY"); | ||
4244 | goto send_current_mbox; | 4273 | goto send_current_mbox; |
4245 | } | 4274 | } |
4246 | } | 4275 | } |
@@ -4250,25 +4279,20 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
4250 | spin_unlock(&phba->pport->work_port_lock); | 4279 | spin_unlock(&phba->pport->work_port_lock); |
4251 | lpfc_mbox_cmpl_put(phba, pmb); | 4280 | lpfc_mbox_cmpl_put(phba, pmb); |
4252 | } | 4281 | } |
4253 | } | 4282 | } else |
4283 | spin_unlock(&phba->hbalock); | ||
4254 | if ((work_ha_copy & HA_MBATT) && | 4284 | if ((work_ha_copy & HA_MBATT) && |
4255 | (phba->sli.mbox_active == NULL)) { | 4285 | (phba->sli.mbox_active == NULL)) { |
4256 | send_next_mbox: | ||
4257 | spin_lock(&phba->hbalock); | ||
4258 | phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE; | ||
4259 | pmb = lpfc_mbox_get(phba); | ||
4260 | spin_unlock(&phba->hbalock); | ||
4261 | send_current_mbox: | 4286 | send_current_mbox: |
4262 | /* Process next mailbox command if there is one */ | 4287 | /* Process next mailbox command if there is one */ |
4263 | if (pmb != NULL) { | 4288 | do { |
4264 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | 4289 | rc = lpfc_sli_issue_mbox(phba, NULL, |
4265 | if (rc == MBX_NOT_FINISHED) { | 4290 | MBX_NOWAIT); |
4266 | pmb->mb.mbxStatus = MBX_NOT_FINISHED; | 4291 | } while (rc == MBX_NOT_FINISHED); |
4267 | lpfc_mbox_cmpl_put(phba, pmb); | 4292 | if (rc != MBX_SUCCESS) |
4268 | goto send_next_mbox; | 4293 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | |
4269 | } | 4294 | LOG_SLI, "0349 rc should be " |
4270 | } | 4295 | "MBX_SUCCESS"); |
4271 | |||
4272 | } | 4296 | } |
4273 | 4297 | ||
4274 | spin_lock(&phba->hbalock); | 4298 | spin_lock(&phba->hbalock); |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index ca540d1d041e..b22b893019f4 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
@@ -18,7 +18,7 @@ | |||
18 | * included with this package. * | 18 | * included with this package. * |
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | #define LPFC_DRIVER_VERSION "8.2.5" | 21 | #define LPFC_DRIVER_VERSION "8.2.6" |
22 | 22 | ||
23 | #define LPFC_DRIVER_NAME "lpfc" | 23 | #define LPFC_DRIVER_NAME "lpfc" |
24 | 24 | ||
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index 86d05beb00b8..6feaf59b0b1b 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c | |||
@@ -538,7 +538,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport) | |||
538 | /* Otherwise, we will perform fabric logo as needed */ | 538 | /* Otherwise, we will perform fabric logo as needed */ |
539 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && | 539 | if (ndlp && NLP_CHK_NODE_ACT(ndlp) && |
540 | ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && | 540 | ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && |
541 | phba->link_state >= LPFC_LINK_UP) { | 541 | phba->link_state >= LPFC_LINK_UP && |
542 | phba->fc_topology != TOPOLOGY_LOOP) { | ||
542 | if (vport->cfg_enable_da_id) { | 543 | if (vport->cfg_enable_da_id) { |
543 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); | 544 | timeout = msecs_to_jiffies(phba->fc_ratov * 2000); |
544 | if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0)) | 545 | if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0)) |
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 3b09ab21d701..0248919bc2df 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c | |||
@@ -592,7 +592,6 @@ static struct scsi_host_template driver_template = { | |||
592 | .this_id = 7, | 592 | .this_id = 7, |
593 | .sg_tablesize = SG_ALL, | 593 | .sg_tablesize = SG_ALL, |
594 | .cmd_per_lun = CMD_PER_LUN, | 594 | .cmd_per_lun = CMD_PER_LUN, |
595 | .unchecked_isa_dma = 0, | ||
596 | .use_clustering = DISABLE_CLUSTERING | 595 | .use_clustering = DISABLE_CLUSTERING |
597 | }; | 596 | }; |
598 | 597 | ||
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 77a62a1b12c3..b937e9cddb23 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -68,6 +68,8 @@ static struct pci_device_id megasas_pci_table[] = { | |||
68 | /* xscale IOP */ | 68 | /* xscale IOP */ |
69 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)}, | 69 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)}, |
70 | /* ppc IOP */ | 70 | /* ppc IOP */ |
71 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)}, | ||
72 | /* ppc IOP */ | ||
71 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, | 73 | {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)}, |
72 | /* xscale IOP, vega */ | 74 | /* xscale IOP, vega */ |
73 | {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)}, | 75 | {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)}, |
@@ -488,12 +490,13 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
488 | 490 | ||
489 | /** | 491 | /** |
490 | * megasas_get_frame_count - Computes the number of frames | 492 | * megasas_get_frame_count - Computes the number of frames |
493 | * @frame_type : type of frame- io or pthru frame | ||
491 | * @sge_count : number of sg elements | 494 | * @sge_count : number of sg elements |
492 | * | 495 | * |
493 | * Returns the number of frames required for numnber of sge's (sge_count) | 496 | * Returns the number of frames required for numnber of sge's (sge_count) |
494 | */ | 497 | */ |
495 | 498 | ||
496 | static u32 megasas_get_frame_count(u8 sge_count) | 499 | static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type) |
497 | { | 500 | { |
498 | int num_cnt; | 501 | int num_cnt; |
499 | int sge_bytes; | 502 | int sge_bytes; |
@@ -504,13 +507,22 @@ static u32 megasas_get_frame_count(u8 sge_count) | |||
504 | sizeof(struct megasas_sge32); | 507 | sizeof(struct megasas_sge32); |
505 | 508 | ||
506 | /* | 509 | /* |
507 | * Main frame can contain 2 SGEs for 64-bit SGLs and | 510 | * Main frame can contain 2 SGEs for 64-bit SGLs and |
508 | * 3 SGEs for 32-bit SGLs | 511 | * 3 SGEs for 32-bit SGLs for ldio & |
509 | */ | 512 | * 1 SGEs for 64-bit SGLs and |
510 | if (IS_DMA64) | 513 | * 2 SGEs for 32-bit SGLs for pthru frame |
511 | num_cnt = sge_count - 2; | 514 | */ |
512 | else | 515 | if (unlikely(frame_type == PTHRU_FRAME)) { |
513 | num_cnt = sge_count - 3; | 516 | if (IS_DMA64) |
517 | num_cnt = sge_count - 1; | ||
518 | else | ||
519 | num_cnt = sge_count - 2; | ||
520 | } else { | ||
521 | if (IS_DMA64) | ||
522 | num_cnt = sge_count - 2; | ||
523 | else | ||
524 | num_cnt = sge_count - 3; | ||
525 | } | ||
514 | 526 | ||
515 | if(num_cnt>0){ | 527 | if(num_cnt>0){ |
516 | sge_bytes = sge_sz * num_cnt; | 528 | sge_bytes = sge_sz * num_cnt; |
@@ -592,7 +604,8 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
592 | * Compute the total number of frames this command consumes. FW uses | 604 | * Compute the total number of frames this command consumes. FW uses |
593 | * this number to pull sufficient number of frames from host memory. | 605 | * this number to pull sufficient number of frames from host memory. |
594 | */ | 606 | */ |
595 | cmd->frame_count = megasas_get_frame_count(pthru->sge_count); | 607 | cmd->frame_count = megasas_get_frame_count(pthru->sge_count, |
608 | PTHRU_FRAME); | ||
596 | 609 | ||
597 | return cmd->frame_count; | 610 | return cmd->frame_count; |
598 | } | 611 | } |
@@ -709,7 +722,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
709 | * Compute the total number of frames this command consumes. FW uses | 722 | * Compute the total number of frames this command consumes. FW uses |
710 | * this number to pull sufficient number of frames from host memory. | 723 | * this number to pull sufficient number of frames from host memory. |
711 | */ | 724 | */ |
712 | cmd->frame_count = megasas_get_frame_count(ldio->sge_count); | 725 | cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME); |
713 | 726 | ||
714 | return cmd->frame_count; | 727 | return cmd->frame_count; |
715 | } | 728 | } |
@@ -1460,7 +1473,7 @@ megasas_transition_to_ready(struct megasas_instance* instance) | |||
1460 | instance->instancet->disable_intr(instance->reg_set); | 1473 | instance->instancet->disable_intr(instance->reg_set); |
1461 | writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell); | 1474 | writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell); |
1462 | 1475 | ||
1463 | max_wait = 10; | 1476 | max_wait = 60; |
1464 | cur_state = MFI_STATE_OPERATIONAL; | 1477 | cur_state = MFI_STATE_OPERATIONAL; |
1465 | break; | 1478 | break; |
1466 | 1479 | ||
@@ -1980,7 +1993,8 @@ static int megasas_init_mfi(struct megasas_instance *instance) | |||
1980 | 1993 | ||
1981 | switch(instance->pdev->device) | 1994 | switch(instance->pdev->device) |
1982 | { | 1995 | { |
1983 | case PCI_DEVICE_ID_LSI_SAS1078R: | 1996 | case PCI_DEVICE_ID_LSI_SAS1078R: |
1997 | case PCI_DEVICE_ID_LSI_SAS1078DE: | ||
1984 | instance->instancet = &megasas_instance_template_ppc; | 1998 | instance->instancet = &megasas_instance_template_ppc; |
1985 | break; | 1999 | break; |
1986 | case PCI_DEVICE_ID_LSI_SAS1064R: | 2000 | case PCI_DEVICE_ID_LSI_SAS1064R: |
@@ -2909,7 +2923,6 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, | |||
2909 | void *sense = NULL; | 2923 | void *sense = NULL; |
2910 | dma_addr_t sense_handle; | 2924 | dma_addr_t sense_handle; |
2911 | u32 *sense_ptr; | 2925 | u32 *sense_ptr; |
2912 | unsigned long *sense_buff; | ||
2913 | 2926 | ||
2914 | memset(kbuff_arr, 0, sizeof(kbuff_arr)); | 2927 | memset(kbuff_arr, 0, sizeof(kbuff_arr)); |
2915 | 2928 | ||
@@ -3014,14 +3027,14 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, | |||
3014 | */ | 3027 | */ |
3015 | if (ioc->sense_len) { | 3028 | if (ioc->sense_len) { |
3016 | /* | 3029 | /* |
3017 | * sense_buff points to the location that has the user | 3030 | * sense_ptr points to the location that has the user |
3018 | * sense buffer address | 3031 | * sense buffer address |
3019 | */ | 3032 | */ |
3020 | sense_buff = (unsigned long *) ((unsigned long)ioc->frame.raw + | 3033 | sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw + |
3021 | ioc->sense_off); | 3034 | ioc->sense_off); |
3022 | 3035 | ||
3023 | if (copy_to_user((void __user *)(unsigned long)(*sense_buff), | 3036 | if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)), |
3024 | sense, ioc->sense_len)) { | 3037 | sense, ioc->sense_len)) { |
3025 | printk(KERN_ERR "megasas: Failed to copy out to user " | 3038 | printk(KERN_ERR "megasas: Failed to copy out to user " |
3026 | "sense data\n"); | 3039 | "sense data\n"); |
3027 | error = -EFAULT; | 3040 | error = -EFAULT; |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 6466bdf548c2..3a997eb457bf 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -26,6 +26,7 @@ | |||
26 | * Device IDs | 26 | * Device IDs |
27 | */ | 27 | */ |
28 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 | 28 | #define PCI_DEVICE_ID_LSI_SAS1078R 0x0060 |
29 | #define PCI_DEVICE_ID_LSI_SAS1078DE 0x007C | ||
29 | #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 | 30 | #define PCI_DEVICE_ID_LSI_VERDE_ZCR 0x0413 |
30 | 31 | ||
31 | /* | 32 | /* |
@@ -542,6 +543,10 @@ struct megasas_ctrl_info { | |||
542 | 543 | ||
543 | #define MEGASAS_FW_BUSY 1 | 544 | #define MEGASAS_FW_BUSY 1 |
544 | 545 | ||
546 | /* Frame Type */ | ||
547 | #define IO_FRAME 0 | ||
548 | #define PTHRU_FRAME 1 | ||
549 | |||
545 | /* | 550 | /* |
546 | * When SCSI mid-layer calls driver's reset routine, driver waits for | 551 | * When SCSI mid-layer calls driver's reset routine, driver waits for |
547 | * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note | 552 | * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note |
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c index be41aadccae5..d722235111a8 100644 --- a/drivers/scsi/mvme147.c +++ b/drivers/scsi/mvme147.c | |||
@@ -82,6 +82,9 @@ int mvme147_detect(struct scsi_host_template *tpnt) | |||
82 | mvme147_host->irq = MVME147_IRQ_SCSI_PORT; | 82 | mvme147_host->irq = MVME147_IRQ_SCSI_PORT; |
83 | regs.SASR = (volatile unsigned char *)0xfffe4000; | 83 | regs.SASR = (volatile unsigned char *)0xfffe4000; |
84 | regs.SCMD = (volatile unsigned char *)0xfffe4001; | 84 | regs.SCMD = (volatile unsigned char *)0xfffe4001; |
85 | HDATA(mvme147_host)->no_sync = 0xff; | ||
86 | HDATA(mvme147_host)->fast = 0; | ||
87 | HDATA(mvme147_host)->dma_mode = CTRL_DMA; | ||
85 | wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10); | 88 | wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10); |
86 | 89 | ||
87 | if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr)) | 90 | if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr)) |
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index fad6cb5cba28..ce48e2d0193c 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <scsi/scsi_dbg.h> | 26 | #include <scsi/scsi_dbg.h> |
27 | #include <scsi/scsi_device.h> | 27 | #include <scsi/scsi_device.h> |
28 | #include <scsi/scsi_host.h> | 28 | #include <scsi/scsi_host.h> |
29 | #include <scsi/scsi_eh.h> | ||
29 | 30 | ||
30 | #include <asm/lv1call.h> | 31 | #include <asm/lv1call.h> |
31 | #include <asm/ps3stor.h> | 32 | #include <asm/ps3stor.h> |
@@ -90,78 +91,6 @@ static int ps3rom_slave_configure(struct scsi_device *scsi_dev) | |||
90 | return 0; | 91 | return 0; |
91 | } | 92 | } |
92 | 93 | ||
93 | /* | ||
94 | * copy data from device into scatter/gather buffer | ||
95 | */ | ||
96 | static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf) | ||
97 | { | ||
98 | int k, req_len, act_len, len, active; | ||
99 | void *kaddr; | ||
100 | struct scatterlist *sgpnt; | ||
101 | unsigned int buflen; | ||
102 | |||
103 | buflen = scsi_bufflen(cmd); | ||
104 | if (!buflen) | ||
105 | return 0; | ||
106 | |||
107 | if (!scsi_sglist(cmd)) | ||
108 | return -1; | ||
109 | |||
110 | active = 1; | ||
111 | req_len = act_len = 0; | ||
112 | scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) { | ||
113 | if (active) { | ||
114 | kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0); | ||
115 | len = sgpnt->length; | ||
116 | if ((req_len + len) > buflen) { | ||
117 | active = 0; | ||
118 | len = buflen - req_len; | ||
119 | } | ||
120 | memcpy(kaddr + sgpnt->offset, buf + req_len, len); | ||
121 | flush_kernel_dcache_page(sg_page(sgpnt)); | ||
122 | kunmap_atomic(kaddr, KM_IRQ0); | ||
123 | act_len += len; | ||
124 | } | ||
125 | req_len += sgpnt->length; | ||
126 | } | ||
127 | scsi_set_resid(cmd, buflen - act_len); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | /* | ||
132 | * copy data from scatter/gather into device's buffer | ||
133 | */ | ||
134 | static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf) | ||
135 | { | ||
136 | int k, req_len, len, fin; | ||
137 | void *kaddr; | ||
138 | struct scatterlist *sgpnt; | ||
139 | unsigned int buflen; | ||
140 | |||
141 | buflen = scsi_bufflen(cmd); | ||
142 | if (!buflen) | ||
143 | return 0; | ||
144 | |||
145 | if (!scsi_sglist(cmd)) | ||
146 | return -1; | ||
147 | |||
148 | req_len = fin = 0; | ||
149 | scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) { | ||
150 | kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0); | ||
151 | len = sgpnt->length; | ||
152 | if ((req_len + len) > buflen) { | ||
153 | len = buflen - req_len; | ||
154 | fin = 1; | ||
155 | } | ||
156 | memcpy(buf + req_len, kaddr + sgpnt->offset, len); | ||
157 | kunmap_atomic(kaddr, KM_IRQ0); | ||
158 | if (fin) | ||
159 | return req_len + len; | ||
160 | req_len += sgpnt->length; | ||
161 | } | ||
162 | return req_len; | ||
163 | } | ||
164 | |||
165 | static int ps3rom_atapi_request(struct ps3_storage_device *dev, | 94 | static int ps3rom_atapi_request(struct ps3_storage_device *dev, |
166 | struct scsi_cmnd *cmd) | 95 | struct scsi_cmnd *cmd) |
167 | { | 96 | { |
@@ -195,9 +124,7 @@ static int ps3rom_atapi_request(struct ps3_storage_device *dev, | |||
195 | else | 124 | else |
196 | atapi_cmnd.proto = PIO_DATA_OUT_PROTO; | 125 | atapi_cmnd.proto = PIO_DATA_OUT_PROTO; |
197 | atapi_cmnd.in_out = DIR_WRITE; | 126 | atapi_cmnd.in_out = DIR_WRITE; |
198 | res = fetch_to_dev_buffer(cmd, dev->bounce_buf); | 127 | scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size); |
199 | if (res < 0) | ||
200 | return DID_ERROR << 16; | ||
201 | break; | 128 | break; |
202 | 129 | ||
203 | default: | 130 | default: |
@@ -269,9 +196,7 @@ static int ps3rom_write_request(struct ps3_storage_device *dev, | |||
269 | dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n", | 196 | dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n", |
270 | __func__, __LINE__, sectors, start_sector); | 197 | __func__, __LINE__, sectors, start_sector); |
271 | 198 | ||
272 | res = fetch_to_dev_buffer(cmd, dev->bounce_buf); | 199 | scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size); |
273 | if (res < 0) | ||
274 | return DID_ERROR << 16; | ||
275 | 200 | ||
276 | res = lv1_storage_write(dev->sbd.dev_id, | 201 | res = lv1_storage_write(dev->sbd.dev_id, |
277 | dev->regions[dev->region_idx].id, start_sector, | 202 | dev->regions[dev->region_idx].id, start_sector, |
@@ -381,11 +306,13 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data) | |||
381 | if (!status) { | 306 | if (!status) { |
382 | /* OK, completed */ | 307 | /* OK, completed */ |
383 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) { | 308 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) { |
384 | res = fill_from_dev_buffer(cmd, dev->bounce_buf); | 309 | int len; |
385 | if (res) { | 310 | |
386 | cmd->result = DID_ERROR << 16; | 311 | len = scsi_sg_copy_from_buffer(cmd, |
387 | goto done; | 312 | dev->bounce_buf, |
388 | } | 313 | dev->bounce_size); |
314 | |||
315 | scsi_set_resid(cmd, scsi_bufflen(cmd) - len); | ||
389 | } | 316 | } |
390 | cmd->result = DID_OK << 16; | 317 | cmd->result = DID_OK << 16; |
391 | goto done; | 318 | goto done; |
@@ -404,11 +331,7 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data) | |||
404 | goto done; | 331 | goto done; |
405 | } | 332 | } |
406 | 333 | ||
407 | cmd->sense_buffer[0] = 0x70; | 334 | scsi_build_sense_buffer(0, cmd->sense_buffer, sense_key, asc, ascq); |
408 | cmd->sense_buffer[2] = sense_key; | ||
409 | cmd->sense_buffer[7] = 16 - 6; | ||
410 | cmd->sense_buffer[12] = asc; | ||
411 | cmd->sense_buffer[13] = ascq; | ||
412 | cmd->result = SAM_STAT_CHECK_CONDITION; | 335 | cmd->result = SAM_STAT_CHECK_CONDITION; |
413 | 336 | ||
414 | done: | 337 | done: |
@@ -427,7 +350,7 @@ static struct scsi_host_template ps3rom_host_template = { | |||
427 | .cmd_per_lun = 1, | 350 | .cmd_per_lun = 1, |
428 | .emulated = 1, /* only sg driver uses this */ | 351 | .emulated = 1, /* only sg driver uses this */ |
429 | .max_sectors = PS3ROM_MAX_SECTORS, | 352 | .max_sectors = PS3ROM_MAX_SECTORS, |
430 | .use_clustering = DISABLE_CLUSTERING, | 353 | .use_clustering = ENABLE_CLUSTERING, |
431 | .module = THIS_MODULE, | 354 | .module = THIS_MODULE, |
432 | }; | 355 | }; |
433 | 356 | ||
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 68c0d09ffe78..09ab3eac1c1a 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -333,7 +333,6 @@ | |||
333 | 333 | ||
334 | #include <linux/module.h> | 334 | #include <linux/module.h> |
335 | 335 | ||
336 | #include <linux/version.h> | ||
337 | #include <linux/types.h> | 336 | #include <linux/types.h> |
338 | #include <linux/string.h> | 337 | #include <linux/string.h> |
339 | #include <linux/errno.h> | 338 | #include <linux/errno.h> |
@@ -367,10 +366,6 @@ | |||
367 | #include <asm/sn/io.h> | 366 | #include <asm/sn/io.h> |
368 | #endif | 367 | #endif |
369 | 368 | ||
370 | #if LINUX_VERSION_CODE < 0x020600 | ||
371 | #error "Kernels older than 2.6.0 are no longer supported" | ||
372 | #endif | ||
373 | |||
374 | 369 | ||
375 | /* | 370 | /* |
376 | * Compile time Options: | 371 | * Compile time Options: |
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig index 8c865b9e02b5..6208d562890d 100644 --- a/drivers/scsi/qla2xxx/Kconfig +++ b/drivers/scsi/qla2xxx/Kconfig | |||
@@ -16,7 +16,8 @@ config SCSI_QLA_FC | |||
16 | 22xx ql2200_fw.bin | 16 | 22xx ql2200_fw.bin |
17 | 2300, 2312, 6312 ql2300_fw.bin | 17 | 2300, 2312, 6312 ql2300_fw.bin |
18 | 2322, 6322 ql2322_fw.bin | 18 | 2322, 6322 ql2322_fw.bin |
19 | 24xx ql2400_fw.bin | 19 | 24xx, 54xx ql2400_fw.bin |
20 | 25xx ql2500_fw.bin | ||
20 | 21 | ||
21 | Upon request, the driver caches the firmware image until | 22 | Upon request, the driver caches the firmware image until |
22 | the driver is unloaded. | 23 | the driver is unloaded. |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 4894dc886b62..413d8cd6a324 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -849,20 +849,20 @@ static void | |||
849 | qla2x00_get_host_speed(struct Scsi_Host *shost) | 849 | qla2x00_get_host_speed(struct Scsi_Host *shost) |
850 | { | 850 | { |
851 | scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); | 851 | scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); |
852 | uint32_t speed = 0; | 852 | u32 speed = FC_PORTSPEED_UNKNOWN; |
853 | 853 | ||
854 | switch (ha->link_data_rate) { | 854 | switch (ha->link_data_rate) { |
855 | case PORT_SPEED_1GB: | 855 | case PORT_SPEED_1GB: |
856 | speed = 1; | 856 | speed = FC_PORTSPEED_1GBIT; |
857 | break; | 857 | break; |
858 | case PORT_SPEED_2GB: | 858 | case PORT_SPEED_2GB: |
859 | speed = 2; | 859 | speed = FC_PORTSPEED_2GBIT; |
860 | break; | 860 | break; |
861 | case PORT_SPEED_4GB: | 861 | case PORT_SPEED_4GB: |
862 | speed = 4; | 862 | speed = FC_PORTSPEED_4GBIT; |
863 | break; | 863 | break; |
864 | case PORT_SPEED_8GB: | 864 | case PORT_SPEED_8GB: |
865 | speed = 8; | 865 | speed = FC_PORTSPEED_8GBIT; |
866 | break; | 866 | break; |
867 | } | 867 | } |
868 | fc_host_speed(shost) = speed; | 868 | fc_host_speed(shost) = speed; |
@@ -900,7 +900,8 @@ qla2x00_get_starget_node_name(struct scsi_target *starget) | |||
900 | u64 node_name = 0; | 900 | u64 node_name = 0; |
901 | 901 | ||
902 | list_for_each_entry(fcport, &ha->fcports, list) { | 902 | list_for_each_entry(fcport, &ha->fcports, list) { |
903 | if (starget->id == fcport->os_target_id) { | 903 | if (fcport->rport && |
904 | starget->id == fcport->rport->scsi_target_id) { | ||
904 | node_name = wwn_to_u64(fcport->node_name); | 905 | node_name = wwn_to_u64(fcport->node_name); |
905 | break; | 906 | break; |
906 | } | 907 | } |
@@ -918,7 +919,8 @@ qla2x00_get_starget_port_name(struct scsi_target *starget) | |||
918 | u64 port_name = 0; | 919 | u64 port_name = 0; |
919 | 920 | ||
920 | list_for_each_entry(fcport, &ha->fcports, list) { | 921 | list_for_each_entry(fcport, &ha->fcports, list) { |
921 | if (starget->id == fcport->os_target_id) { | 922 | if (fcport->rport && |
923 | starget->id == fcport->rport->scsi_target_id) { | ||
922 | port_name = wwn_to_u64(fcport->port_name); | 924 | port_name = wwn_to_u64(fcport->port_name); |
923 | break; | 925 | break; |
924 | } | 926 | } |
@@ -936,7 +938,8 @@ qla2x00_get_starget_port_id(struct scsi_target *starget) | |||
936 | uint32_t port_id = ~0U; | 938 | uint32_t port_id = ~0U; |
937 | 939 | ||
938 | list_for_each_entry(fcport, &ha->fcports, list) { | 940 | list_for_each_entry(fcport, &ha->fcports, list) { |
939 | if (starget->id == fcport->os_target_id) { | 941 | if (fcport->rport && |
942 | starget->id == fcport->rport->scsi_target_id) { | ||
940 | port_id = fcport->d_id.b.domain << 16 | | 943 | port_id = fcport->d_id.b.domain << 16 | |
941 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; | 944 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; |
942 | break; | 945 | break; |
@@ -1196,6 +1199,7 @@ struct fc_function_template qla2xxx_transport_functions = { | |||
1196 | .show_host_node_name = 1, | 1199 | .show_host_node_name = 1, |
1197 | .show_host_port_name = 1, | 1200 | .show_host_port_name = 1, |
1198 | .show_host_supported_classes = 1, | 1201 | .show_host_supported_classes = 1, |
1202 | .show_host_supported_speeds = 1, | ||
1199 | 1203 | ||
1200 | .get_host_port_id = qla2x00_get_host_port_id, | 1204 | .get_host_port_id = qla2x00_get_host_port_id, |
1201 | .show_host_port_id = 1, | 1205 | .show_host_port_id = 1, |
@@ -1276,9 +1280,23 @@ struct fc_function_template qla2xxx_transport_vport_functions = { | |||
1276 | void | 1280 | void |
1277 | qla2x00_init_host_attr(scsi_qla_host_t *ha) | 1281 | qla2x00_init_host_attr(scsi_qla_host_t *ha) |
1278 | { | 1282 | { |
1283 | u32 speed = FC_PORTSPEED_UNKNOWN; | ||
1284 | |||
1279 | fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); | 1285 | fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); |
1280 | fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); | 1286 | fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); |
1281 | fc_host_supported_classes(ha->host) = FC_COS_CLASS3; | 1287 | fc_host_supported_classes(ha->host) = FC_COS_CLASS3; |
1282 | fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;; | 1288 | fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;; |
1283 | fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; | 1289 | fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; |
1290 | |||
1291 | if (IS_QLA25XX(ha)) | ||
1292 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | | ||
1293 | FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | ||
1294 | else if (IS_QLA24XX_TYPE(ha)) | ||
1295 | speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT | | ||
1296 | FC_PORTSPEED_1GBIT; | ||
1297 | else if (IS_QLA23XX(ha)) | ||
1298 | speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT; | ||
1299 | else | ||
1300 | speed = FC_PORTSPEED_1GBIT; | ||
1301 | fc_host_supported_speeds(ha->host) = speed; | ||
1284 | } | 1302 | } |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index d88e98c476b0..9d12d9f26209 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -1410,125 +1410,3 @@ qla2x00_dump_buffer(uint8_t * b, uint32_t size) | |||
1410 | if (cnt % 16) | 1410 | if (cnt % 16) |
1411 | printk("\n"); | 1411 | printk("\n"); |
1412 | } | 1412 | } |
1413 | |||
1414 | /************************************************************************** | ||
1415 | * qla2x00_print_scsi_cmd | ||
1416 | * Dumps out info about the scsi cmd and srb. | ||
1417 | * Input | ||
1418 | * cmd : struct scsi_cmnd | ||
1419 | **************************************************************************/ | ||
1420 | void | ||
1421 | qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd) | ||
1422 | { | ||
1423 | int i; | ||
1424 | struct scsi_qla_host *ha; | ||
1425 | srb_t *sp; | ||
1426 | |||
1427 | ha = shost_priv(cmd->device->host); | ||
1428 | |||
1429 | sp = (srb_t *) cmd->SCp.ptr; | ||
1430 | printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble); | ||
1431 | printk(" chan=0x%02x, target=0x%02x, lun=0x%02x, cmd_len=0x%02x\n", | ||
1432 | cmd->device->channel, cmd->device->id, cmd->device->lun, | ||
1433 | cmd->cmd_len); | ||
1434 | printk(" CDB: "); | ||
1435 | for (i = 0; i < cmd->cmd_len; i++) { | ||
1436 | printk("0x%02x ", cmd->cmnd[i]); | ||
1437 | } | ||
1438 | printk("\n seg_cnt=%d, allowed=%d, retries=%d\n", | ||
1439 | scsi_sg_count(cmd), cmd->allowed, cmd->retries); | ||
1440 | printk(" request buffer=0x%p, request buffer len=0x%x\n", | ||
1441 | scsi_sglist(cmd), scsi_bufflen(cmd)); | ||
1442 | printk(" tag=%d, transfersize=0x%x\n", | ||
1443 | cmd->tag, cmd->transfersize); | ||
1444 | printk(" serial_number=%lx, SP=%p\n", cmd->serial_number, sp); | ||
1445 | printk(" data direction=%d\n", cmd->sc_data_direction); | ||
1446 | |||
1447 | if (!sp) | ||
1448 | return; | ||
1449 | |||
1450 | printk(" sp flags=0x%x\n", sp->flags); | ||
1451 | } | ||
1452 | |||
1453 | #if defined(QL_DEBUG_ROUTINES) | ||
1454 | /* | ||
1455 | * qla2x00_formatted_dump_buffer | ||
1456 | * Prints string plus buffer. | ||
1457 | * | ||
1458 | * Input: | ||
1459 | * string = Null terminated string (no newline at end). | ||
1460 | * buffer = buffer address. | ||
1461 | * wd_size = word size 8, 16, 32 or 64 bits | ||
1462 | * count = number of words. | ||
1463 | */ | ||
1464 | void | ||
1465 | qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer, | ||
1466 | uint8_t wd_size, uint32_t count) | ||
1467 | { | ||
1468 | uint32_t cnt; | ||
1469 | uint16_t *buf16; | ||
1470 | uint32_t *buf32; | ||
1471 | |||
1472 | if (strcmp(string, "") != 0) | ||
1473 | printk("%s\n",string); | ||
1474 | |||
1475 | switch (wd_size) { | ||
1476 | case 8: | ||
1477 | printk(" 0 1 2 3 4 5 6 7 " | ||
1478 | "8 9 Ah Bh Ch Dh Eh Fh\n"); | ||
1479 | printk("-----------------------------------------" | ||
1480 | "-------------------------------------\n"); | ||
1481 | |||
1482 | for (cnt = 1; cnt <= count; cnt++, buffer++) { | ||
1483 | printk("%02x",*buffer); | ||
1484 | if (cnt % 16 == 0) | ||
1485 | printk("\n"); | ||
1486 | else | ||
1487 | printk(" "); | ||
1488 | } | ||
1489 | if (cnt % 16 != 0) | ||
1490 | printk("\n"); | ||
1491 | break; | ||
1492 | case 16: | ||
1493 | printk(" 0 2 4 6 8 Ah " | ||
1494 | " Ch Eh\n"); | ||
1495 | printk("-----------------------------------------" | ||
1496 | "-------------\n"); | ||
1497 | |||
1498 | buf16 = (uint16_t *) buffer; | ||
1499 | for (cnt = 1; cnt <= count; cnt++, buf16++) { | ||
1500 | printk("%4x",*buf16); | ||
1501 | |||
1502 | if (cnt % 8 == 0) | ||
1503 | printk("\n"); | ||
1504 | else if (*buf16 < 10) | ||
1505 | printk(" "); | ||
1506 | else | ||
1507 | printk(" "); | ||
1508 | } | ||
1509 | if (cnt % 8 != 0) | ||
1510 | printk("\n"); | ||
1511 | break; | ||
1512 | case 32: | ||
1513 | printk(" 0 4 8 Ch\n"); | ||
1514 | printk("------------------------------------------\n"); | ||
1515 | |||
1516 | buf32 = (uint32_t *) buffer; | ||
1517 | for (cnt = 1; cnt <= count; cnt++, buf32++) { | ||
1518 | printk("%8x", *buf32); | ||
1519 | |||
1520 | if (cnt % 4 == 0) | ||
1521 | printk("\n"); | ||
1522 | else if (*buf32 < 10) | ||
1523 | printk(" "); | ||
1524 | else | ||
1525 | printk(" "); | ||
1526 | } | ||
1527 | if (cnt % 4 != 0) | ||
1528 | printk("\n"); | ||
1529 | break; | ||
1530 | default: | ||
1531 | break; | ||
1532 | } | ||
1533 | } | ||
1534 | #endif | ||
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 524598afc81c..2e9c0c097f5e 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -22,19 +22,7 @@ | |||
22 | /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */ | 22 | /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */ |
23 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ | 23 | /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */ |
24 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ | 24 | /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */ |
25 | /* | 25 | /* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */ |
26 | * Local Macro Definitions. | ||
27 | */ | ||
28 | #if defined(QL_DEBUG_LEVEL_1) || defined(QL_DEBUG_LEVEL_2) || \ | ||
29 | defined(QL_DEBUG_LEVEL_3) || defined(QL_DEBUG_LEVEL_4) || \ | ||
30 | defined(QL_DEBUG_LEVEL_5) || defined(QL_DEBUG_LEVEL_6) || \ | ||
31 | defined(QL_DEBUG_LEVEL_7) || defined(QL_DEBUG_LEVEL_8) || \ | ||
32 | defined(QL_DEBUG_LEVEL_9) || defined(QL_DEBUG_LEVEL_10) || \ | ||
33 | defined(QL_DEBUG_LEVEL_11) || defined(QL_DEBUG_LEVEL_12) || \ | ||
34 | defined(QL_DEBUG_LEVEL_13) || defined(QL_DEBUG_LEVEL_14) || \ | ||
35 | defined(QL_DEBUG_LEVEL_15) | ||
36 | #define QL_DEBUG_ROUTINES | ||
37 | #endif | ||
38 | 26 | ||
39 | /* | 27 | /* |
40 | * Macros use for debugging the driver. | 28 | * Macros use for debugging the driver. |
@@ -54,6 +42,7 @@ | |||
54 | #define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0) | 42 | #define DEBUG2_9_10(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
55 | #define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) | 43 | #define DEBUG2_11(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
56 | #define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0) | 44 | #define DEBUG2_13(x) do { if (ql2xextended_error_logging) { x; } } while (0) |
45 | #define DEBUG2_16(x) do { if (ql2xextended_error_logging) { x; } } while (0) | ||
57 | 46 | ||
58 | #if defined(QL_DEBUG_LEVEL_3) | 47 | #if defined(QL_DEBUG_LEVEL_3) |
59 | #define DEBUG3(x) do {x;} while (0) | 48 | #define DEBUG3(x) do {x;} while (0) |
@@ -133,6 +122,12 @@ | |||
133 | #define DEBUG15(x) do {} while (0) | 122 | #define DEBUG15(x) do {} while (0) |
134 | #endif | 123 | #endif |
135 | 124 | ||
125 | #if defined(QL_DEBUG_LEVEL_16) | ||
126 | #define DEBUG16(x) do {x;} while (0) | ||
127 | #else | ||
128 | #define DEBUG16(x) do {} while (0) | ||
129 | #endif | ||
130 | |||
136 | /* | 131 | /* |
137 | * Firmware Dump structure definition | 132 | * Firmware Dump structure definition |
138 | */ | 133 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3750319f4968..094d95f0764c 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
25 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
26 | #include <linux/aer.h> | 26 | #include <linux/aer.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <asm/semaphore.h> | 28 | #include <asm/semaphore.h> |
28 | 29 | ||
29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
@@ -192,9 +193,6 @@ typedef struct srb { | |||
192 | 193 | ||
193 | uint16_t flags; | 194 | uint16_t flags; |
194 | 195 | ||
195 | /* Single transfer DMA context */ | ||
196 | dma_addr_t dma_handle; | ||
197 | |||
198 | uint32_t request_sense_length; | 196 | uint32_t request_sense_length; |
199 | uint8_t *request_sense_ptr; | 197 | uint8_t *request_sense_ptr; |
200 | } srb_t; | 198 | } srb_t; |
@@ -1542,8 +1540,6 @@ typedef struct fc_port { | |||
1542 | atomic_t state; | 1540 | atomic_t state; |
1543 | uint32_t flags; | 1541 | uint32_t flags; |
1544 | 1542 | ||
1545 | unsigned int os_target_id; | ||
1546 | |||
1547 | int port_login_retry_count; | 1543 | int port_login_retry_count; |
1548 | int login_retry; | 1544 | int login_retry; |
1549 | atomic_t port_down_timer; | 1545 | atomic_t port_down_timer; |
@@ -1613,6 +1609,7 @@ typedef struct fc_port { | |||
1613 | #define CT_ACCEPT_RESPONSE 0x8002 | 1609 | #define CT_ACCEPT_RESPONSE 0x8002 |
1614 | #define CT_REASON_INVALID_COMMAND_CODE 0x01 | 1610 | #define CT_REASON_INVALID_COMMAND_CODE 0x01 |
1615 | #define CT_REASON_CANNOT_PERFORM 0x09 | 1611 | #define CT_REASON_CANNOT_PERFORM 0x09 |
1612 | #define CT_REASON_COMMAND_UNSUPPORTED 0x0b | ||
1616 | #define CT_EXPL_ALREADY_REGISTERED 0x10 | 1613 | #define CT_EXPL_ALREADY_REGISTERED 0x10 |
1617 | 1614 | ||
1618 | #define NS_N_PORT_TYPE 0x01 | 1615 | #define NS_N_PORT_TYPE 0x01 |
@@ -2063,7 +2060,8 @@ struct isp_operations { | |||
2063 | void (*disable_intrs) (struct scsi_qla_host *); | 2060 | void (*disable_intrs) (struct scsi_qla_host *); |
2064 | 2061 | ||
2065 | int (*abort_command) (struct scsi_qla_host *, srb_t *); | 2062 | int (*abort_command) (struct scsi_qla_host *, srb_t *); |
2066 | int (*abort_target) (struct fc_port *); | 2063 | int (*target_reset) (struct fc_port *, unsigned int); |
2064 | int (*lun_reset) (struct fc_port *, unsigned int); | ||
2067 | int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t, | 2065 | int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t, |
2068 | uint8_t, uint8_t, uint16_t *, uint8_t); | 2066 | uint8_t, uint8_t, uint16_t *, uint8_t); |
2069 | int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t, | 2067 | int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t, |
@@ -2117,6 +2115,46 @@ struct qla_msix_entry { | |||
2117 | 2115 | ||
2118 | #define WATCH_INTERVAL 1 /* number of seconds */ | 2116 | #define WATCH_INTERVAL 1 /* number of seconds */ |
2119 | 2117 | ||
2118 | /* Work events. */ | ||
2119 | enum qla_work_type { | ||
2120 | QLA_EVT_AEN, | ||
2121 | QLA_EVT_HWE_LOG, | ||
2122 | }; | ||
2123 | |||
2124 | |||
2125 | struct qla_work_evt { | ||
2126 | struct list_head list; | ||
2127 | enum qla_work_type type; | ||
2128 | u32 flags; | ||
2129 | #define QLA_EVT_FLAG_FREE 0x1 | ||
2130 | |||
2131 | union { | ||
2132 | struct { | ||
2133 | enum fc_host_event_code code; | ||
2134 | u32 data; | ||
2135 | } aen; | ||
2136 | struct { | ||
2137 | uint16_t code; | ||
2138 | uint16_t d1, d2, d3; | ||
2139 | } hwe; | ||
2140 | } u; | ||
2141 | }; | ||
2142 | |||
2143 | struct qla_chip_state_84xx { | ||
2144 | struct list_head list; | ||
2145 | struct kref kref; | ||
2146 | |||
2147 | void *bus; | ||
2148 | spinlock_t access_lock; | ||
2149 | struct mutex fw_update_mutex; | ||
2150 | uint32_t fw_update; | ||
2151 | uint32_t op_fw_version; | ||
2152 | uint32_t op_fw_size; | ||
2153 | uint32_t op_fw_seq_size; | ||
2154 | uint32_t diag_fw_version; | ||
2155 | uint32_t gold_fw_version; | ||
2156 | }; | ||
2157 | |||
2120 | /* | 2158 | /* |
2121 | * Linux Host Adapter structure | 2159 | * Linux Host Adapter structure |
2122 | */ | 2160 | */ |
@@ -2155,6 +2193,7 @@ typedef struct scsi_qla_host { | |||
2155 | uint32_t vsan_enabled :1; | 2193 | uint32_t vsan_enabled :1; |
2156 | uint32_t npiv_supported :1; | 2194 | uint32_t npiv_supported :1; |
2157 | uint32_t fce_enabled :1; | 2195 | uint32_t fce_enabled :1; |
2196 | uint32_t hw_event_marker_found :1; | ||
2158 | } flags; | 2197 | } flags; |
2159 | 2198 | ||
2160 | atomic_t loop_state; | 2199 | atomic_t loop_state; |
@@ -2204,6 +2243,7 @@ typedef struct scsi_qla_host { | |||
2204 | #define DFLG_NO_CABLE BIT_4 | 2243 | #define DFLG_NO_CABLE BIT_4 |
2205 | 2244 | ||
2206 | #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 | 2245 | #define PCI_DEVICE_ID_QLOGIC_ISP2532 0x2532 |
2246 | #define PCI_DEVICE_ID_QLOGIC_ISP8432 0x8432 | ||
2207 | uint32_t device_type; | 2247 | uint32_t device_type; |
2208 | #define DT_ISP2100 BIT_0 | 2248 | #define DT_ISP2100 BIT_0 |
2209 | #define DT_ISP2200 BIT_1 | 2249 | #define DT_ISP2200 BIT_1 |
@@ -2217,7 +2257,8 @@ typedef struct scsi_qla_host { | |||
2217 | #define DT_ISP5422 BIT_9 | 2257 | #define DT_ISP5422 BIT_9 |
2218 | #define DT_ISP5432 BIT_10 | 2258 | #define DT_ISP5432 BIT_10 |
2219 | #define DT_ISP2532 BIT_11 | 2259 | #define DT_ISP2532 BIT_11 |
2220 | #define DT_ISP_LAST (DT_ISP2532 << 1) | 2260 | #define DT_ISP8432 BIT_12 |
2261 | #define DT_ISP_LAST (DT_ISP8432 << 1) | ||
2221 | 2262 | ||
2222 | #define DT_IIDMA BIT_26 | 2263 | #define DT_IIDMA BIT_26 |
2223 | #define DT_FWI2 BIT_27 | 2264 | #define DT_FWI2 BIT_27 |
@@ -2239,12 +2280,16 @@ typedef struct scsi_qla_host { | |||
2239 | #define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422) | 2280 | #define IS_QLA5422(ha) (DT_MASK(ha) & DT_ISP5422) |
2240 | #define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432) | 2281 | #define IS_QLA5432(ha) (DT_MASK(ha) & DT_ISP5432) |
2241 | #define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532) | 2282 | #define IS_QLA2532(ha) (DT_MASK(ha) & DT_ISP2532) |
2283 | #define IS_QLA8432(ha) (DT_MASK(ha) & DT_ISP8432) | ||
2242 | 2284 | ||
2243 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ | 2285 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ |
2244 | IS_QLA6312(ha) || IS_QLA6322(ha)) | 2286 | IS_QLA6312(ha) || IS_QLA6322(ha)) |
2245 | #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) | 2287 | #define IS_QLA24XX(ha) (IS_QLA2422(ha) || IS_QLA2432(ha)) |
2246 | #define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha)) | 2288 | #define IS_QLA54XX(ha) (IS_QLA5422(ha) || IS_QLA5432(ha)) |
2247 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) | 2289 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) |
2290 | #define IS_QLA84XX(ha) (IS_QLA8432(ha)) | ||
2291 | #define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ | ||
2292 | IS_QLA84XX(ha)) | ||
2248 | 2293 | ||
2249 | #define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) | 2294 | #define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) |
2250 | #define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) | 2295 | #define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) |
@@ -2356,6 +2401,8 @@ typedef struct scsi_qla_host { | |||
2356 | uint32_t login_retry_count; | 2401 | uint32_t login_retry_count; |
2357 | int max_q_depth; | 2402 | int max_q_depth; |
2358 | 2403 | ||
2404 | struct list_head work_list; | ||
2405 | |||
2359 | /* Fibre Channel Device List. */ | 2406 | /* Fibre Channel Device List. */ |
2360 | struct list_head fcports; | 2407 | struct list_head fcports; |
2361 | 2408 | ||
@@ -2423,8 +2470,6 @@ typedef struct scsi_qla_host { | |||
2423 | #define MBX_TIMEDOUT BIT_5 | 2470 | #define MBX_TIMEDOUT BIT_5 |
2424 | #define MBX_ACCESS_TIMEDOUT BIT_6 | 2471 | #define MBX_ACCESS_TIMEDOUT BIT_6 |
2425 | 2472 | ||
2426 | mbx_cmd_t mc; | ||
2427 | |||
2428 | /* Basic firmware related information. */ | 2473 | /* Basic firmware related information. */ |
2429 | uint16_t fw_major_version; | 2474 | uint16_t fw_major_version; |
2430 | uint16_t fw_minor_version; | 2475 | uint16_t fw_minor_version; |
@@ -2458,6 +2503,10 @@ typedef struct scsi_qla_host { | |||
2458 | uint64_t fce_wr, fce_rd; | 2503 | uint64_t fce_wr, fce_rd; |
2459 | struct mutex fce_mutex; | 2504 | struct mutex fce_mutex; |
2460 | 2505 | ||
2506 | uint32_t hw_event_start; | ||
2507 | uint32_t hw_event_ptr; | ||
2508 | uint32_t hw_event_pause_errors; | ||
2509 | |||
2461 | uint8_t host_str[16]; | 2510 | uint8_t host_str[16]; |
2462 | uint32_t pci_attr; | 2511 | uint32_t pci_attr; |
2463 | uint16_t chip_revision; | 2512 | uint16_t chip_revision; |
@@ -2493,6 +2542,13 @@ typedef struct scsi_qla_host { | |||
2493 | uint8_t fcode_revision[16]; | 2542 | uint8_t fcode_revision[16]; |
2494 | uint32_t fw_revision[4]; | 2543 | uint32_t fw_revision[4]; |
2495 | 2544 | ||
2545 | uint16_t fdt_odd_index; | ||
2546 | uint32_t fdt_wrt_disable; | ||
2547 | uint32_t fdt_erase_cmd; | ||
2548 | uint32_t fdt_block_size; | ||
2549 | uint32_t fdt_unprotect_sec_cmd; | ||
2550 | uint32_t fdt_protect_sec_cmd; | ||
2551 | |||
2496 | /* Needed for BEACON */ | 2552 | /* Needed for BEACON */ |
2497 | uint16_t beacon_blink_led; | 2553 | uint16_t beacon_blink_led; |
2498 | uint8_t beacon_color_state; | 2554 | uint8_t beacon_color_state; |
@@ -2538,6 +2594,8 @@ typedef struct scsi_qla_host { | |||
2538 | #define VP_ERR_ADAP_NORESOURCES 5 | 2594 | #define VP_ERR_ADAP_NORESOURCES 5 |
2539 | uint16_t max_npiv_vports; /* 63 or 125 per topoloty */ | 2595 | uint16_t max_npiv_vports; /* 63 or 125 per topoloty */ |
2540 | int cur_vport_count; | 2596 | int cur_vport_count; |
2597 | |||
2598 | struct qla_chip_state_84xx *cs84xx; | ||
2541 | } scsi_qla_host_t; | 2599 | } scsi_qla_host_t; |
2542 | 2600 | ||
2543 | 2601 | ||
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 2cd899bfe84b..561a4411719d 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 9337e138ed63..078f2a15f40b 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -719,7 +719,7 @@ struct tsk_mgmt_entry { | |||
719 | 719 | ||
720 | uint16_t timeout; /* Command timeout. */ | 720 | uint16_t timeout; /* Command timeout. */ |
721 | 721 | ||
722 | uint8_t lun[8]; /* FCP LUN (BE). */ | 722 | struct scsi_lun lun; /* FCP LUN (BE). */ |
723 | 723 | ||
724 | uint32_t control_flags; /* Control Flags. */ | 724 | uint32_t control_flags; /* Control Flags. */ |
725 | #define TCF_NOTMCMD_TO_TARGET BIT_31 | 725 | #define TCF_NOTMCMD_TO_TARGET BIT_31 |
@@ -793,7 +793,19 @@ struct device_reg_24xx { | |||
793 | #define FA_VPD_NVRAM_ADDR 0x48000 | 793 | #define FA_VPD_NVRAM_ADDR 0x48000 |
794 | #define FA_FEATURE_ADDR 0x4C000 | 794 | #define FA_FEATURE_ADDR 0x4C000 |
795 | #define FA_FLASH_DESCR_ADDR 0x50000 | 795 | #define FA_FLASH_DESCR_ADDR 0x50000 |
796 | #define FA_HW_EVENT_ADDR 0x54000 | 796 | #define FA_HW_EVENT0_ADDR 0x54000 |
797 | #define FA_HW_EVENT1_ADDR 0x54200 | ||
798 | #define FA_HW_EVENT_SIZE 0x200 | ||
799 | #define FA_HW_EVENT_ENTRY_SIZE 4 | ||
800 | /* | ||
801 | * Flash Error Log Event Codes. | ||
802 | */ | ||
803 | #define HW_EVENT_RESET_ERR 0xF00B | ||
804 | #define HW_EVENT_ISP_ERR 0xF020 | ||
805 | #define HW_EVENT_PARITY_ERR 0xF022 | ||
806 | #define HW_EVENT_NVRAM_CHKSUM_ERR 0xF023 | ||
807 | #define HW_EVENT_FLASH_FW_ERR 0xF024 | ||
808 | |||
797 | #define FA_BOOT_LOG_ADDR 0x58000 | 809 | #define FA_BOOT_LOG_ADDR 0x58000 |
798 | #define FA_FW_DUMP0_ADDR 0x60000 | 810 | #define FA_FW_DUMP0_ADDR 0x60000 |
799 | #define FA_FW_DUMP1_ADDR 0x70000 | 811 | #define FA_FW_DUMP1_ADDR 0x70000 |
@@ -1174,4 +1186,159 @@ struct vf_evfp_entry_24xx { | |||
1174 | }; | 1186 | }; |
1175 | 1187 | ||
1176 | /* END MID Support ***********************************************************/ | 1188 | /* END MID Support ***********************************************************/ |
1189 | |||
1190 | /* Flash Description Table ***************************************************/ | ||
1191 | |||
1192 | struct qla_fdt_layout { | ||
1193 | uint8_t sig[4]; | ||
1194 | uint16_t version; | ||
1195 | uint16_t len; | ||
1196 | uint16_t checksum; | ||
1197 | uint8_t unused1[2]; | ||
1198 | uint8_t model[16]; | ||
1199 | uint16_t man_id; | ||
1200 | uint16_t id; | ||
1201 | uint8_t flags; | ||
1202 | uint8_t erase_cmd; | ||
1203 | uint8_t alt_erase_cmd; | ||
1204 | uint8_t wrt_enable_cmd; | ||
1205 | uint8_t wrt_enable_bits; | ||
1206 | uint8_t wrt_sts_reg_cmd; | ||
1207 | uint8_t unprotect_sec_cmd; | ||
1208 | uint8_t read_man_id_cmd; | ||
1209 | uint32_t block_size; | ||
1210 | uint32_t alt_block_size; | ||
1211 | uint32_t flash_size; | ||
1212 | uint32_t wrt_enable_data; | ||
1213 | uint8_t read_id_addr_len; | ||
1214 | uint8_t wrt_disable_bits; | ||
1215 | uint8_t read_dev_id_len; | ||
1216 | uint8_t chip_erase_cmd; | ||
1217 | uint16_t read_timeout; | ||
1218 | uint8_t protect_sec_cmd; | ||
1219 | uint8_t unused2[65]; | ||
1220 | }; | ||
1221 | |||
1222 | /* 84XX Support **************************************************************/ | ||
1223 | |||
1224 | #define MBA_ISP84XX_ALERT 0x800f /* Alert Notification. */ | ||
1225 | #define A84_PANIC_RECOVERY 0x1 | ||
1226 | #define A84_OP_LOGIN_COMPLETE 0x2 | ||
1227 | #define A84_DIAG_LOGIN_COMPLETE 0x3 | ||
1228 | #define A84_GOLD_LOGIN_COMPLETE 0x4 | ||
1229 | |||
1230 | #define MBC_ISP84XX_RESET 0x3a /* Reset. */ | ||
1231 | |||
1232 | #define FSTATE_REMOTE_FC_DOWN BIT_0 | ||
1233 | #define FSTATE_NSL_LINK_DOWN BIT_1 | ||
1234 | #define FSTATE_IS_DIAG_FW BIT_2 | ||
1235 | #define FSTATE_LOGGED_IN BIT_3 | ||
1236 | #define FSTATE_WAITING_FOR_VERIFY BIT_4 | ||
1237 | |||
1238 | #define VERIFY_CHIP_IOCB_TYPE 0x1B | ||
1239 | struct verify_chip_entry_84xx { | ||
1240 | uint8_t entry_type; | ||
1241 | uint8_t entry_count; | ||
1242 | uint8_t sys_defined; | ||
1243 | uint8_t entry_status; | ||
1244 | |||
1245 | uint32_t handle; | ||
1246 | |||
1247 | uint16_t options; | ||
1248 | #define VCO_DONT_UPDATE_FW BIT_0 | ||
1249 | #define VCO_FORCE_UPDATE BIT_1 | ||
1250 | #define VCO_DONT_RESET_UPDATE BIT_2 | ||
1251 | #define VCO_DIAG_FW BIT_3 | ||
1252 | #define VCO_END_OF_DATA BIT_14 | ||
1253 | #define VCO_ENABLE_DSD BIT_15 | ||
1254 | |||
1255 | uint16_t reserved_1; | ||
1256 | |||
1257 | uint16_t data_seg_cnt; | ||
1258 | uint16_t reserved_2[3]; | ||
1259 | |||
1260 | uint32_t fw_ver; | ||
1261 | uint32_t exchange_address; | ||
1262 | |||
1263 | uint32_t reserved_3[3]; | ||
1264 | uint32_t fw_size; | ||
1265 | uint32_t fw_seq_size; | ||
1266 | uint32_t relative_offset; | ||
1267 | |||
1268 | uint32_t dseg_address[2]; | ||
1269 | uint32_t dseg_length; | ||
1270 | }; | ||
1271 | |||
1272 | struct verify_chip_rsp_84xx { | ||
1273 | uint8_t entry_type; | ||
1274 | uint8_t entry_count; | ||
1275 | uint8_t sys_defined; | ||
1276 | uint8_t entry_status; | ||
1277 | |||
1278 | uint32_t handle; | ||
1279 | |||
1280 | uint16_t comp_status; | ||
1281 | #define CS_VCS_CHIP_FAILURE 0x3 | ||
1282 | #define CS_VCS_BAD_EXCHANGE 0x8 | ||
1283 | #define CS_VCS_SEQ_COMPLETEi 0x40 | ||
1284 | |||
1285 | uint16_t failure_code; | ||
1286 | #define VFC_CHECKSUM_ERROR 0x1 | ||
1287 | #define VFC_INVALID_LEN 0x2 | ||
1288 | #define VFC_ALREADY_IN_PROGRESS 0x8 | ||
1289 | |||
1290 | uint16_t reserved_1[4]; | ||
1291 | |||
1292 | uint32_t fw_ver; | ||
1293 | uint32_t exchange_address; | ||
1294 | |||
1295 | uint32_t reserved_2[6]; | ||
1296 | }; | ||
1297 | |||
1298 | #define ACCESS_CHIP_IOCB_TYPE 0x2B | ||
1299 | struct access_chip_84xx { | ||
1300 | uint8_t entry_type; | ||
1301 | uint8_t entry_count; | ||
1302 | uint8_t sys_defined; | ||
1303 | uint8_t entry_status; | ||
1304 | |||
1305 | uint32_t handle; | ||
1306 | |||
1307 | uint16_t options; | ||
1308 | #define ACO_DUMP_MEMORY 0x0 | ||
1309 | #define ACO_LOAD_MEMORY 0x1 | ||
1310 | #define ACO_CHANGE_CONFIG_PARAM 0x2 | ||
1311 | #define ACO_REQUEST_INFO 0x3 | ||
1312 | |||
1313 | uint16_t reserved1; | ||
1314 | |||
1315 | uint16_t dseg_count; | ||
1316 | uint16_t reserved2[3]; | ||
1317 | |||
1318 | uint32_t parameter1; | ||
1319 | uint32_t parameter2; | ||
1320 | uint32_t parameter3; | ||
1321 | |||
1322 | uint32_t reserved3[3]; | ||
1323 | uint32_t total_byte_cnt; | ||
1324 | uint32_t reserved4; | ||
1325 | |||
1326 | uint32_t dseg_address[2]; | ||
1327 | uint32_t dseg_length; | ||
1328 | }; | ||
1329 | |||
1330 | struct access_chip_rsp_84xx { | ||
1331 | uint8_t entry_type; | ||
1332 | uint8_t entry_count; | ||
1333 | uint8_t sys_defined; | ||
1334 | uint8_t entry_status; | ||
1335 | |||
1336 | uint32_t handle; | ||
1337 | |||
1338 | uint16_t comp_status; | ||
1339 | uint16_t failure_code; | ||
1340 | uint32_t residual_count; | ||
1341 | |||
1342 | uint32_t reserved[12]; | ||
1343 | }; | ||
1177 | #endif | 1344 | #endif |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 193f688ec3d7..a9571c214a9e 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -38,9 +38,6 @@ extern int qla2x00_loop_resync(scsi_qla_host_t *); | |||
38 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); | 38 | extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *); |
39 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); | 39 | extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *); |
40 | 40 | ||
41 | extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t); | ||
42 | |||
43 | extern void qla2x00_rescan_fcports(scsi_qla_host_t *); | ||
44 | extern void qla2x00_update_fcports(scsi_qla_host_t *); | 41 | extern void qla2x00_update_fcports(scsi_qla_host_t *); |
45 | 42 | ||
46 | extern int qla2x00_abort_isp(scsi_qla_host_t *); | 43 | extern int qla2x00_abort_isp(scsi_qla_host_t *); |
@@ -50,6 +47,8 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | |||
50 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); | 47 | extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *); |
51 | extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); | 48 | extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *); |
52 | 49 | ||
50 | extern void qla84xx_put_chip(struct scsi_qla_host *); | ||
51 | |||
53 | /* | 52 | /* |
54 | * Global Data in qla_os.c source file. | 53 | * Global Data in qla_os.c source file. |
55 | */ | 54 | */ |
@@ -67,6 +66,10 @@ extern int num_hosts; | |||
67 | 66 | ||
68 | extern int qla2x00_loop_reset(scsi_qla_host_t *); | 67 | extern int qla2x00_loop_reset(scsi_qla_host_t *); |
69 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); | 68 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); |
69 | extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum | ||
70 | fc_host_event_code, u32); | ||
71 | extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, | ||
72 | uint16_t, uint16_t); | ||
70 | 73 | ||
71 | /* | 74 | /* |
72 | * Global Functions in qla_mid.c source file. | 75 | * Global Functions in qla_mid.c source file. |
@@ -149,12 +152,17 @@ extern int | |||
149 | qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t); | 152 | qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t); |
150 | 153 | ||
151 | extern int | 154 | extern int |
155 | qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *, dma_addr_t, size_t, | ||
156 | uint32_t); | ||
157 | |||
158 | extern int | ||
152 | qla2x00_abort_command(scsi_qla_host_t *, srb_t *); | 159 | qla2x00_abort_command(scsi_qla_host_t *, srb_t *); |
153 | 160 | ||
154 | #if USE_ABORT_TGT | ||
155 | extern int | 161 | extern int |
156 | qla2x00_abort_target(fc_port_t *); | 162 | qla2x00_abort_target(struct fc_port *, unsigned int); |
157 | #endif | 163 | |
164 | extern int | ||
165 | qla2x00_lun_reset(struct fc_port *, unsigned int); | ||
158 | 166 | ||
159 | extern int | 167 | extern int |
160 | qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *, | 168 | qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *, |
@@ -220,7 +228,8 @@ qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *, | |||
220 | dma_addr_t); | 228 | dma_addr_t); |
221 | 229 | ||
222 | extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); | 230 | extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); |
223 | extern int qla24xx_abort_target(fc_port_t *); | 231 | extern int qla24xx_abort_target(struct fc_port *, unsigned int); |
232 | extern int qla24xx_lun_reset(struct fc_port *, unsigned int); | ||
224 | 233 | ||
225 | extern int | 234 | extern int |
226 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | 235 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); |
@@ -246,6 +255,8 @@ qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t); | |||
246 | extern int | 255 | extern int |
247 | qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); | 256 | qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *); |
248 | 257 | ||
258 | extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *); | ||
259 | |||
249 | /* | 260 | /* |
250 | * Global Function Prototypes in qla_isr.c source file. | 261 | * Global Function Prototypes in qla_isr.c source file. |
251 | */ | 262 | */ |
@@ -298,6 +309,11 @@ extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, | |||
298 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); | 309 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); |
299 | extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); | 310 | extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); |
300 | 311 | ||
312 | extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t, | ||
313 | uint16_t, uint16_t); | ||
314 | |||
315 | extern void qla2xxx_get_flash_info(scsi_qla_host_t *); | ||
316 | |||
301 | /* | 317 | /* |
302 | * Global Function Prototypes in qla_dbg.c source file. | 318 | * Global Function Prototypes in qla_dbg.c source file. |
303 | */ | 319 | */ |
@@ -307,7 +323,6 @@ extern void qla24xx_fw_dump(scsi_qla_host_t *, int); | |||
307 | extern void qla25xx_fw_dump(scsi_qla_host_t *, int); | 323 | extern void qla25xx_fw_dump(scsi_qla_host_t *, int); |
308 | extern void qla2x00_dump_regs(scsi_qla_host_t *); | 324 | extern void qla2x00_dump_regs(scsi_qla_host_t *); |
309 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); | 325 | extern void qla2x00_dump_buffer(uint8_t *, uint32_t); |
310 | extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *); | ||
311 | 326 | ||
312 | /* | 327 | /* |
313 | * Global Function Prototypes in qla_gs.c source file. | 328 | * Global Function Prototypes in qla_gs.c source file. |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index c1808763d40e..750d7ef83aae 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -1,17 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | static inline struct ct_sns_req * | ||
10 | qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t); | ||
11 | |||
12 | static inline struct sns_cmd_pkt * | ||
13 | qla2x00_prep_sns_cmd(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | ||
14 | |||
15 | static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); | 9 | static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); |
16 | static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); | 10 | static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); |
17 | static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *); | 11 | static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *); |
@@ -1538,7 +1532,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1538 | eiter->a.sup_speed = __constant_cpu_to_be32( | 1532 | eiter->a.sup_speed = __constant_cpu_to_be32( |
1539 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | 1533 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| |
1540 | FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB); | 1534 | FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB); |
1541 | else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) | 1535 | else if (IS_QLA24XX_TYPE(ha)) |
1542 | eiter->a.sup_speed = __constant_cpu_to_be32( | 1536 | eiter->a.sup_speed = __constant_cpu_to_be32( |
1543 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| | 1537 | FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB| |
1544 | FDMI_PORT_SPEED_4GB); | 1538 | FDMI_PORT_SPEED_4GB); |
@@ -1847,8 +1841,10 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list) | |||
1847 | "GPSC")) != QLA_SUCCESS) { | 1841 | "GPSC")) != QLA_SUCCESS) { |
1848 | /* FM command unsupported? */ | 1842 | /* FM command unsupported? */ |
1849 | if (rval == QLA_INVALID_COMMAND && | 1843 | if (rval == QLA_INVALID_COMMAND && |
1850 | ct_rsp->header.reason_code == | 1844 | (ct_rsp->header.reason_code == |
1851 | CT_REASON_INVALID_COMMAND_CODE) { | 1845 | CT_REASON_INVALID_COMMAND_CODE || |
1846 | ct_rsp->header.reason_code == | ||
1847 | CT_REASON_COMMAND_UNSUPPORTED)) { | ||
1852 | DEBUG2(printk("scsi(%ld): GPSC command " | 1848 | DEBUG2(printk("scsi(%ld): GPSC command " |
1853 | "unsupported, disabling query...\n", | 1849 | "unsupported, disabling query...\n", |
1854 | ha->host_no)); | 1850 | ha->host_no)); |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 364be7d06875..01e26087c1dd 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -15,14 +15,6 @@ | |||
15 | #include <asm/prom.h> | 15 | #include <asm/prom.h> |
16 | #endif | 16 | #endif |
17 | 17 | ||
18 | /* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */ | ||
19 | #ifndef EXT_IS_LUN_BIT_SET | ||
20 | #define EXT_IS_LUN_BIT_SET(P,L) \ | ||
21 | (((P)->mask[L/8] & (0x80 >> (L%8)))?1:0) | ||
22 | #define EXT_SET_LUN_BIT(P,L) \ | ||
23 | ((P)->mask[L/8] |= (0x80 >> (L%8))) | ||
24 | #endif | ||
25 | |||
26 | /* | 18 | /* |
27 | * QLogic ISP2x00 Hardware Support Function Prototypes. | 19 | * QLogic ISP2x00 Hardware Support Function Prototypes. |
28 | */ | 20 | */ |
@@ -45,6 +37,9 @@ static int qla2x00_restart_isp(scsi_qla_host_t *); | |||
45 | 37 | ||
46 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); | 38 | static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev); |
47 | 39 | ||
40 | static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *); | ||
41 | static int qla84xx_init_chip(scsi_qla_host_t *); | ||
42 | |||
48 | /****************************************************************************/ | 43 | /****************************************************************************/ |
49 | /* QLogic ISP2x00 Hardware Support Functions. */ | 44 | /* QLogic ISP2x00 Hardware Support Functions. */ |
50 | /****************************************************************************/ | 45 | /****************************************************************************/ |
@@ -114,6 +109,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
114 | rval = qla2x00_setup_chip(ha); | 109 | rval = qla2x00_setup_chip(ha); |
115 | if (rval) | 110 | if (rval) |
116 | return (rval); | 111 | return (rval); |
112 | qla2xxx_get_flash_info(ha); | ||
113 | } | ||
114 | if (IS_QLA84XX(ha)) { | ||
115 | ha->cs84xx = qla84xx_get_chip(ha); | ||
116 | if (!ha->cs84xx) { | ||
117 | qla_printk(KERN_ERR, ha, | ||
118 | "Unable to configure ISP84XX.\n"); | ||
119 | return QLA_FUNCTION_FAILED; | ||
120 | } | ||
117 | } | 121 | } |
118 | rval = qla2x00_init_rings(ha); | 122 | rval = qla2x00_init_rings(ha); |
119 | 123 | ||
@@ -500,6 +504,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha) | |||
500 | static inline void | 504 | static inline void |
501 | qla24xx_reset_risc(scsi_qla_host_t *ha) | 505 | qla24xx_reset_risc(scsi_qla_host_t *ha) |
502 | { | 506 | { |
507 | int hw_evt = 0; | ||
503 | unsigned long flags = 0; | 508 | unsigned long flags = 0; |
504 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 509 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
505 | uint32_t cnt, d2; | 510 | uint32_t cnt, d2; |
@@ -528,6 +533,8 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) | |||
528 | d2 = (uint32_t) RD_REG_WORD(®->mailbox0); | 533 | d2 = (uint32_t) RD_REG_WORD(®->mailbox0); |
529 | barrier(); | 534 | barrier(); |
530 | } | 535 | } |
536 | if (cnt == 0) | ||
537 | hw_evt = 1; | ||
531 | 538 | ||
532 | /* Wait for soft-reset to complete. */ | 539 | /* Wait for soft-reset to complete. */ |
533 | d2 = RD_REG_DWORD(®->ctrl_status); | 540 | d2 = RD_REG_DWORD(®->ctrl_status); |
@@ -536,6 +543,10 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) | |||
536 | d2 = RD_REG_DWORD(®->ctrl_status); | 543 | d2 = RD_REG_DWORD(®->ctrl_status); |
537 | barrier(); | 544 | barrier(); |
538 | } | 545 | } |
546 | if (cnt == 0 || hw_evt) | ||
547 | qla2xxx_hw_event_log(ha, HW_EVENT_RESET_ERR, | ||
548 | RD_REG_WORD(®->mailbox1), RD_REG_WORD(®->mailbox2), | ||
549 | RD_REG_WORD(®->mailbox3)); | ||
539 | 550 | ||
540 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); | 551 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); |
541 | RD_REG_DWORD(®->hccr); | 552 | RD_REG_DWORD(®->hccr); |
@@ -1243,10 +1254,10 @@ static int | |||
1243 | qla2x00_fw_ready(scsi_qla_host_t *ha) | 1254 | qla2x00_fw_ready(scsi_qla_host_t *ha) |
1244 | { | 1255 | { |
1245 | int rval; | 1256 | int rval; |
1246 | unsigned long wtime, mtime; | 1257 | unsigned long wtime, mtime, cs84xx_time; |
1247 | uint16_t min_wait; /* Minimum wait time if loop is down */ | 1258 | uint16_t min_wait; /* Minimum wait time if loop is down */ |
1248 | uint16_t wait_time; /* Wait time if loop is coming ready */ | 1259 | uint16_t wait_time; /* Wait time if loop is coming ready */ |
1249 | uint16_t fw_state; | 1260 | uint16_t state[3]; |
1250 | 1261 | ||
1251 | rval = QLA_SUCCESS; | 1262 | rval = QLA_SUCCESS; |
1252 | 1263 | ||
@@ -1275,12 +1286,34 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1275 | ha->host_no)); | 1286 | ha->host_no)); |
1276 | 1287 | ||
1277 | do { | 1288 | do { |
1278 | rval = qla2x00_get_firmware_state(ha, &fw_state); | 1289 | rval = qla2x00_get_firmware_state(ha, state); |
1279 | if (rval == QLA_SUCCESS) { | 1290 | if (rval == QLA_SUCCESS) { |
1280 | if (fw_state < FSTATE_LOSS_OF_SYNC) { | 1291 | if (state[0] < FSTATE_LOSS_OF_SYNC) { |
1281 | ha->device_flags &= ~DFLG_NO_CABLE; | 1292 | ha->device_flags &= ~DFLG_NO_CABLE; |
1282 | } | 1293 | } |
1283 | if (fw_state == FSTATE_READY) { | 1294 | if (IS_QLA84XX(ha) && state[0] != FSTATE_READY) { |
1295 | DEBUG16(printk("scsi(%ld): fw_state=%x " | ||
1296 | "84xx=%x.\n", ha->host_no, state[0], | ||
1297 | state[2])); | ||
1298 | if ((state[2] & FSTATE_LOGGED_IN) && | ||
1299 | (state[2] & FSTATE_WAITING_FOR_VERIFY)) { | ||
1300 | DEBUG16(printk("scsi(%ld): Sending " | ||
1301 | "verify iocb.\n", ha->host_no)); | ||
1302 | |||
1303 | cs84xx_time = jiffies; | ||
1304 | rval = qla84xx_init_chip(ha); | ||
1305 | if (rval != QLA_SUCCESS) | ||
1306 | break; | ||
1307 | |||
1308 | /* Add time taken to initialize. */ | ||
1309 | cs84xx_time = jiffies - cs84xx_time; | ||
1310 | wtime += cs84xx_time; | ||
1311 | mtime += cs84xx_time; | ||
1312 | DEBUG16(printk("scsi(%ld): Increasing " | ||
1313 | "wait time by %ld. New time %ld\n", | ||
1314 | ha->host_no, cs84xx_time, wtime)); | ||
1315 | } | ||
1316 | } else if (state[0] == FSTATE_READY) { | ||
1284 | DEBUG(printk("scsi(%ld): F/W Ready - OK \n", | 1317 | DEBUG(printk("scsi(%ld): F/W Ready - OK \n", |
1285 | ha->host_no)); | 1318 | ha->host_no)); |
1286 | 1319 | ||
@@ -1294,7 +1327,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1294 | rval = QLA_FUNCTION_FAILED; | 1327 | rval = QLA_FUNCTION_FAILED; |
1295 | 1328 | ||
1296 | if (atomic_read(&ha->loop_down_timer) && | 1329 | if (atomic_read(&ha->loop_down_timer) && |
1297 | fw_state != FSTATE_READY) { | 1330 | state[0] != FSTATE_READY) { |
1298 | /* Loop down. Timeout on min_wait for states | 1331 | /* Loop down. Timeout on min_wait for states |
1299 | * other than Wait for Login. | 1332 | * other than Wait for Login. |
1300 | */ | 1333 | */ |
@@ -1319,11 +1352,11 @@ qla2x00_fw_ready(scsi_qla_host_t *ha) | |||
1319 | msleep(500); | 1352 | msleep(500); |
1320 | 1353 | ||
1321 | DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", | 1354 | DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", |
1322 | ha->host_no, fw_state, jiffies)); | 1355 | ha->host_no, state[0], jiffies)); |
1323 | } while (1); | 1356 | } while (1); |
1324 | 1357 | ||
1325 | DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", | 1358 | DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n", |
1326 | ha->host_no, fw_state, jiffies)); | 1359 | ha->host_no, state[0], jiffies)); |
1327 | 1360 | ||
1328 | if (rval) { | 1361 | if (rval) { |
1329 | DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", | 1362 | DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n", |
@@ -1555,6 +1588,10 @@ qla2x00_nvram_config(scsi_qla_host_t *ha) | |||
1555 | qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " | 1588 | qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet " |
1556 | "invalid -- WWPN) defaults.\n"); | 1589 | "invalid -- WWPN) defaults.\n"); |
1557 | 1590 | ||
1591 | if (chksum) | ||
1592 | qla2xxx_hw_event_log(ha, HW_EVENT_NVRAM_CHKSUM_ERR, 0, | ||
1593 | MSW(chksum), LSW(chksum)); | ||
1594 | |||
1558 | /* | 1595 | /* |
1559 | * Set default initialization control block. | 1596 | * Set default initialization control block. |
1560 | */ | 1597 | */ |
@@ -2165,20 +2202,6 @@ cleanup_allocation: | |||
2165 | } | 2202 | } |
2166 | 2203 | ||
2167 | static void | 2204 | static void |
2168 | qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) | ||
2169 | { | ||
2170 | fc_port_t *fcport; | ||
2171 | |||
2172 | qla2x00_mark_all_devices_lost(ha, 0); | ||
2173 | list_for_each_entry(fcport, &ha->fcports, list) { | ||
2174 | if (fcport->port_type != FCT_TARGET) | ||
2175 | continue; | ||
2176 | |||
2177 | qla2x00_update_fcport(ha, fcport); | ||
2178 | } | ||
2179 | } | ||
2180 | |||
2181 | static void | ||
2182 | qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | 2205 | qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) |
2183 | { | 2206 | { |
2184 | #define LS_UNKNOWN 2 | 2207 | #define LS_UNKNOWN 2 |
@@ -2251,10 +2274,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2251 | if (fcport->port_type == FCT_TARGET) | 2274 | if (fcport->port_type == FCT_TARGET) |
2252 | rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; | 2275 | rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; |
2253 | fc_remote_port_rolechg(rport, rport_ids.roles); | 2276 | fc_remote_port_rolechg(rport, rport_ids.roles); |
2254 | |||
2255 | if (rport->scsi_target_id != -1 && | ||
2256 | rport->scsi_target_id < ha->host->max_id) | ||
2257 | fcport->os_target_id = rport->scsi_target_id; | ||
2258 | } | 2277 | } |
2259 | 2278 | ||
2260 | /* | 2279 | /* |
@@ -2434,7 +2453,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2434 | 2453 | ||
2435 | if (fcport->loop_id == FC_NO_LOOP_ID) { | 2454 | if (fcport->loop_id == FC_NO_LOOP_ID) { |
2436 | fcport->loop_id = next_loopid; | 2455 | fcport->loop_id = next_loopid; |
2437 | rval = qla2x00_find_new_loop_id(ha, fcport); | 2456 | rval = qla2x00_find_new_loop_id( |
2457 | to_qla_parent(ha), fcport); | ||
2438 | if (rval != QLA_SUCCESS) { | 2458 | if (rval != QLA_SUCCESS) { |
2439 | /* Ran out of IDs to use */ | 2459 | /* Ran out of IDs to use */ |
2440 | break; | 2460 | break; |
@@ -2459,7 +2479,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2459 | 2479 | ||
2460 | /* Find a new loop ID to use. */ | 2480 | /* Find a new loop ID to use. */ |
2461 | fcport->loop_id = next_loopid; | 2481 | fcport->loop_id = next_loopid; |
2462 | rval = qla2x00_find_new_loop_id(ha, fcport); | 2482 | rval = qla2x00_find_new_loop_id(to_qla_parent(ha), |
2483 | fcport); | ||
2463 | if (rval != QLA_SUCCESS) { | 2484 | if (rval != QLA_SUCCESS) { |
2464 | /* Ran out of IDs to use */ | 2485 | /* Ran out of IDs to use */ |
2465 | break; | 2486 | break; |
@@ -3193,25 +3214,6 @@ qla2x00_loop_resync(scsi_qla_host_t *ha) | |||
3193 | } | 3214 | } |
3194 | 3215 | ||
3195 | void | 3216 | void |
3196 | qla2x00_rescan_fcports(scsi_qla_host_t *ha) | ||
3197 | { | ||
3198 | int rescan_done; | ||
3199 | fc_port_t *fcport; | ||
3200 | |||
3201 | rescan_done = 0; | ||
3202 | list_for_each_entry(fcport, &ha->fcports, list) { | ||
3203 | if ((fcport->flags & FCF_RESCAN_NEEDED) == 0) | ||
3204 | continue; | ||
3205 | |||
3206 | qla2x00_update_fcport(ha, fcport); | ||
3207 | fcport->flags &= ~FCF_RESCAN_NEEDED; | ||
3208 | |||
3209 | rescan_done = 1; | ||
3210 | } | ||
3211 | qla2x00_probe_for_all_luns(ha); | ||
3212 | } | ||
3213 | |||
3214 | void | ||
3215 | qla2x00_update_fcports(scsi_qla_host_t *ha) | 3217 | qla2x00_update_fcports(scsi_qla_host_t *ha) |
3216 | { | 3218 | { |
3217 | fc_port_t *fcport; | 3219 | fc_port_t *fcport; |
@@ -4044,16 +4046,16 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) | |||
4044 | if (!ha->parent) | 4046 | if (!ha->parent) |
4045 | return -EINVAL; | 4047 | return -EINVAL; |
4046 | 4048 | ||
4047 | rval = qla2x00_fw_ready(ha); | 4049 | rval = qla2x00_fw_ready(ha->parent); |
4048 | if (rval == QLA_SUCCESS) { | 4050 | if (rval == QLA_SUCCESS) { |
4049 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 4051 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
4050 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | 4052 | qla2x00_marker(ha->parent, 0, 0, MK_SYNC_ALL); |
4051 | } | 4053 | } |
4052 | 4054 | ||
4053 | ha->flags.management_server_logged_in = 0; | 4055 | ha->flags.management_server_logged_in = 0; |
4054 | 4056 | ||
4055 | /* Login to SNS first */ | 4057 | /* Login to SNS first */ |
4056 | qla24xx_login_fabric(ha, NPH_SNS, 0xff, 0xff, 0xfc, | 4058 | qla24xx_login_fabric(ha->parent, NPH_SNS, 0xff, 0xff, 0xfc, |
4057 | mb, BIT_1); | 4059 | mb, BIT_1); |
4058 | if (mb[0] != MBS_COMMAND_COMPLETE) { | 4060 | if (mb[0] != MBS_COMMAND_COMPLETE) { |
4059 | DEBUG15(qla_printk(KERN_INFO, ha, | 4061 | DEBUG15(qla_printk(KERN_INFO, ha, |
@@ -4067,7 +4069,77 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) | |||
4067 | atomic_set(&ha->loop_state, LOOP_UP); | 4069 | atomic_set(&ha->loop_state, LOOP_UP); |
4068 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 4070 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
4069 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 4071 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); |
4070 | rval = qla2x00_loop_resync(ha); | 4072 | rval = qla2x00_loop_resync(ha->parent); |
4071 | 4073 | ||
4072 | return rval; | 4074 | return rval; |
4073 | } | 4075 | } |
4076 | |||
4077 | /* 84XX Support **************************************************************/ | ||
4078 | |||
4079 | static LIST_HEAD(qla_cs84xx_list); | ||
4080 | static DEFINE_MUTEX(qla_cs84xx_mutex); | ||
4081 | |||
4082 | static struct qla_chip_state_84xx * | ||
4083 | qla84xx_get_chip(struct scsi_qla_host *ha) | ||
4084 | { | ||
4085 | struct qla_chip_state_84xx *cs84xx; | ||
4086 | |||
4087 | mutex_lock(&qla_cs84xx_mutex); | ||
4088 | |||
4089 | /* Find any shared 84xx chip. */ | ||
4090 | list_for_each_entry(cs84xx, &qla_cs84xx_list, list) { | ||
4091 | if (cs84xx->bus == ha->pdev->bus) { | ||
4092 | kref_get(&cs84xx->kref); | ||
4093 | goto done; | ||
4094 | } | ||
4095 | } | ||
4096 | |||
4097 | cs84xx = kzalloc(sizeof(*cs84xx), GFP_KERNEL); | ||
4098 | if (!cs84xx) | ||
4099 | goto done; | ||
4100 | |||
4101 | kref_init(&cs84xx->kref); | ||
4102 | spin_lock_init(&cs84xx->access_lock); | ||
4103 | mutex_init(&cs84xx->fw_update_mutex); | ||
4104 | cs84xx->bus = ha->pdev->bus; | ||
4105 | |||
4106 | list_add_tail(&cs84xx->list, &qla_cs84xx_list); | ||
4107 | done: | ||
4108 | mutex_unlock(&qla_cs84xx_mutex); | ||
4109 | return cs84xx; | ||
4110 | } | ||
4111 | |||
4112 | static void | ||
4113 | __qla84xx_chip_release(struct kref *kref) | ||
4114 | { | ||
4115 | struct qla_chip_state_84xx *cs84xx = | ||
4116 | container_of(kref, struct qla_chip_state_84xx, kref); | ||
4117 | |||
4118 | mutex_lock(&qla_cs84xx_mutex); | ||
4119 | list_del(&cs84xx->list); | ||
4120 | mutex_unlock(&qla_cs84xx_mutex); | ||
4121 | kfree(cs84xx); | ||
4122 | } | ||
4123 | |||
4124 | void | ||
4125 | qla84xx_put_chip(struct scsi_qla_host *ha) | ||
4126 | { | ||
4127 | if (ha->cs84xx) | ||
4128 | kref_put(&ha->cs84xx->kref, __qla84xx_chip_release); | ||
4129 | } | ||
4130 | |||
4131 | static int | ||
4132 | qla84xx_init_chip(scsi_qla_host_t *ha) | ||
4133 | { | ||
4134 | int rval; | ||
4135 | uint16_t status[2]; | ||
4136 | |||
4137 | mutex_lock(&ha->cs84xx->fw_update_mutex); | ||
4138 | |||
4139 | rval = qla84xx_verify_chip(ha, status); | ||
4140 | |||
4141 | mutex_unlock(&ha->cs84xx->fw_update_mutex); | ||
4142 | |||
4143 | return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED: | ||
4144 | QLA_SUCCESS; | ||
4145 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 5d1a3f7c408f..e9bae27737d1 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
@@ -1,11 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | static __inline__ uint16_t qla2x00_debounce_register(volatile uint16_t __iomem *); | ||
9 | /* | 8 | /* |
10 | * qla2x00_debounce_register | 9 | * qla2x00_debounce_register |
11 | * Debounce register. | 10 | * Debounce register. |
@@ -32,94 +31,12 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr) | |||
32 | return (first); | 31 | return (first); |
33 | } | 32 | } |
34 | 33 | ||
35 | static __inline__ int qla2x00_normalize_dma_addr( | ||
36 | dma_addr_t *e_addr, uint32_t *e_len, | ||
37 | dma_addr_t *ne_addr, uint32_t *ne_len); | ||
38 | |||
39 | /** | ||
40 | * qla2x00_normalize_dma_addr() - Normalize an DMA address. | ||
41 | * @e_addr: Raw DMA address | ||
42 | * @e_len: Raw DMA length | ||
43 | * @ne_addr: Normalized second DMA address | ||
44 | * @ne_len: Normalized second DMA length | ||
45 | * | ||
46 | * If the address does not span a 4GB page boundary, the contents of @ne_addr | ||
47 | * and @ne_len are undefined. @e_len is updated to reflect a normalization. | ||
48 | * | ||
49 | * Example: | ||
50 | * | ||
51 | * ffffabc0ffffeeee (e_addr) start of DMA address | ||
52 | * 0000000020000000 (e_len) length of DMA transfer | ||
53 | * ffffabc11fffeeed end of DMA transfer | ||
54 | * | ||
55 | * Is the 4GB boundary crossed? | ||
56 | * | ||
57 | * ffffabc0ffffeeee (e_addr) | ||
58 | * ffffabc11fffeeed (e_addr + e_len - 1) | ||
59 | * 00000001e0000003 ((e_addr ^ (e_addr + e_len - 1)) | ||
60 | * 0000000100000000 ((e_addr ^ (e_addr + e_len - 1)) & ~(0xffffffff) | ||
61 | * | ||
62 | * Compute start of second DMA segment: | ||
63 | * | ||
64 | * ffffabc0ffffeeee (e_addr) | ||
65 | * ffffabc1ffffeeee (0x100000000 + e_addr) | ||
66 | * ffffabc100000000 (0x100000000 + e_addr) & ~(0xffffffff) | ||
67 | * ffffabc100000000 (ne_addr) | ||
68 | * | ||
69 | * Compute length of second DMA segment: | ||
70 | * | ||
71 | * 00000000ffffeeee (e_addr & 0xffffffff) | ||
72 | * 0000000000001112 (0x100000000 - (e_addr & 0xffffffff)) | ||
73 | * 000000001fffeeee (e_len - (0x100000000 - (e_addr & 0xffffffff)) | ||
74 | * 000000001fffeeee (ne_len) | ||
75 | * | ||
76 | * Adjust length of first DMA segment | ||
77 | * | ||
78 | * 0000000020000000 (e_len) | ||
79 | * 0000000000001112 (e_len - ne_len) | ||
80 | * 0000000000001112 (e_len) | ||
81 | * | ||
82 | * Returns non-zero if the specified address was normalized, else zero. | ||
83 | */ | ||
84 | static __inline__ int | ||
85 | qla2x00_normalize_dma_addr( | ||
86 | dma_addr_t *e_addr, uint32_t *e_len, | ||
87 | dma_addr_t *ne_addr, uint32_t *ne_len) | ||
88 | { | ||
89 | int normalized; | ||
90 | |||
91 | normalized = 0; | ||
92 | if ((*e_addr ^ (*e_addr + *e_len - 1)) & ~(0xFFFFFFFFULL)) { | ||
93 | /* Compute normalized crossed address and len */ | ||
94 | *ne_addr = (0x100000000ULL + *e_addr) & ~(0xFFFFFFFFULL); | ||
95 | *ne_len = *e_len - (0x100000000ULL - (*e_addr & 0xFFFFFFFFULL)); | ||
96 | *e_len -= *ne_len; | ||
97 | |||
98 | normalized++; | ||
99 | } | ||
100 | return (normalized); | ||
101 | } | ||
102 | |||
103 | static __inline__ void qla2x00_poll(scsi_qla_host_t *); | ||
104 | static inline void | 34 | static inline void |
105 | qla2x00_poll(scsi_qla_host_t *ha) | 35 | qla2x00_poll(scsi_qla_host_t *ha) |
106 | { | 36 | { |
107 | ha->isp_ops->intr_handler(0, ha); | 37 | ha->isp_ops->intr_handler(0, ha); |
108 | } | 38 | } |
109 | 39 | ||
110 | static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *); | ||
111 | /* | ||
112 | * This routine will wait for fabric devices for | ||
113 | * the reset delay. | ||
114 | */ | ||
115 | static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *ha) | ||
116 | { | ||
117 | uint16_t fw_state; | ||
118 | |||
119 | qla2x00_get_firmware_state(ha, &fw_state); | ||
120 | } | ||
121 | |||
122 | static __inline__ scsi_qla_host_t * to_qla_parent(scsi_qla_host_t *); | ||
123 | static __inline__ scsi_qla_host_t * | 40 | static __inline__ scsi_qla_host_t * |
124 | to_qla_parent(scsi_qla_host_t *ha) | 41 | to_qla_parent(scsi_qla_host_t *ha) |
125 | { | 42 | { |
@@ -152,7 +69,6 @@ qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked) | |||
152 | return (QLA_SUCCESS); | 69 | return (QLA_SUCCESS); |
153 | } | 70 | } |
154 | 71 | ||
155 | static inline uint8_t *host_to_fcp_swap(uint8_t *, uint32_t); | ||
156 | static inline uint8_t * | 72 | static inline uint8_t * |
157 | host_to_fcp_swap(uint8_t *fcp, uint32_t bsize) | 73 | host_to_fcp_swap(uint8_t *fcp, uint32_t bsize) |
158 | { | 74 | { |
@@ -166,7 +82,6 @@ host_to_fcp_swap(uint8_t *fcp, uint32_t bsize) | |||
166 | return fcp; | 82 | return fcp; |
167 | } | 83 | } |
168 | 84 | ||
169 | static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t); | ||
170 | static inline int | 85 | static inline int |
171 | qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id) | 86 | qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id) |
172 | { | 87 | { |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 024c662ec34d..5489d5024673 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -11,9 +11,6 @@ | |||
11 | 11 | ||
12 | #include <scsi/scsi_tcq.h> | 12 | #include <scsi/scsi_tcq.h> |
13 | 13 | ||
14 | static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd); | ||
15 | static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *); | ||
16 | static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *); | ||
17 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); | 14 | static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha); |
18 | static void qla2x00_isp_cmd(scsi_qla_host_t *ha); | 15 | static void qla2x00_isp_cmd(scsi_qla_host_t *ha); |
19 | 16 | ||
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index f0337036c7bb..285479b62d8f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -14,9 +14,6 @@ static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); | |||
14 | static void qla2x00_status_entry(scsi_qla_host_t *, void *); | 14 | static void qla2x00_status_entry(scsi_qla_host_t *, void *); |
15 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); | 15 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); |
16 | static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); | 16 | static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); |
17 | static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *); | ||
18 | |||
19 | static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *); | ||
20 | 17 | ||
21 | /** | 18 | /** |
22 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. | 19 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. |
@@ -33,7 +30,6 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
33 | scsi_qla_host_t *ha; | 30 | scsi_qla_host_t *ha; |
34 | struct device_reg_2xxx __iomem *reg; | 31 | struct device_reg_2xxx __iomem *reg; |
35 | int status; | 32 | int status; |
36 | unsigned long flags; | ||
37 | unsigned long iter; | 33 | unsigned long iter; |
38 | uint16_t hccr; | 34 | uint16_t hccr; |
39 | uint16_t mb[4]; | 35 | uint16_t mb[4]; |
@@ -48,7 +44,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
48 | reg = &ha->iobase->isp; | 44 | reg = &ha->iobase->isp; |
49 | status = 0; | 45 | status = 0; |
50 | 46 | ||
51 | spin_lock_irqsave(&ha->hardware_lock, flags); | 47 | spin_lock(&ha->hardware_lock); |
52 | for (iter = 50; iter--; ) { | 48 | for (iter = 50; iter--; ) { |
53 | hccr = RD_REG_WORD(®->hccr); | 49 | hccr = RD_REG_WORD(®->hccr); |
54 | if (hccr & HCCR_RISC_PAUSE) { | 50 | if (hccr & HCCR_RISC_PAUSE) { |
@@ -99,7 +95,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
99 | RD_REG_WORD(®->hccr); | 95 | RD_REG_WORD(®->hccr); |
100 | } | 96 | } |
101 | } | 97 | } |
102 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 98 | spin_unlock(&ha->hardware_lock); |
103 | 99 | ||
104 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 100 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
105 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 101 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -125,7 +121,6 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
125 | scsi_qla_host_t *ha; | 121 | scsi_qla_host_t *ha; |
126 | struct device_reg_2xxx __iomem *reg; | 122 | struct device_reg_2xxx __iomem *reg; |
127 | int status; | 123 | int status; |
128 | unsigned long flags; | ||
129 | unsigned long iter; | 124 | unsigned long iter; |
130 | uint32_t stat; | 125 | uint32_t stat; |
131 | uint16_t hccr; | 126 | uint16_t hccr; |
@@ -141,7 +136,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
141 | reg = &ha->iobase->isp; | 136 | reg = &ha->iobase->isp; |
142 | status = 0; | 137 | status = 0; |
143 | 138 | ||
144 | spin_lock_irqsave(&ha->hardware_lock, flags); | 139 | spin_lock(&ha->hardware_lock); |
145 | for (iter = 50; iter--; ) { | 140 | for (iter = 50; iter--; ) { |
146 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 141 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
147 | if (stat & HSR_RISC_PAUSED) { | 142 | if (stat & HSR_RISC_PAUSED) { |
@@ -211,7 +206,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
211 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | 206 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); |
212 | RD_REG_WORD_RELAXED(®->hccr); | 207 | RD_REG_WORD_RELAXED(®->hccr); |
213 | } | 208 | } |
214 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 209 | spin_unlock(&ha->hardware_lock); |
215 | 210 | ||
216 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 211 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
217 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 212 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -276,6 +271,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
276 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 271 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
277 | uint32_t rscn_entry, host_pid; | 272 | uint32_t rscn_entry, host_pid; |
278 | uint8_t rscn_queue_index; | 273 | uint8_t rscn_queue_index; |
274 | unsigned long flags; | ||
275 | scsi_qla_host_t *vha; | ||
276 | int i; | ||
279 | 277 | ||
280 | /* Setup to process RIO completion. */ | 278 | /* Setup to process RIO completion. */ |
281 | handle_cnt = 0; | 279 | handle_cnt = 0; |
@@ -351,6 +349,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
351 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", | 349 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", |
352 | mb[1], mb[2], mb[3]); | 350 | mb[1], mb[2], mb[3]); |
353 | 351 | ||
352 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
354 | ha->isp_ops->fw_dump(ha, 1); | 353 | ha->isp_ops->fw_dump(ha, 1); |
355 | 354 | ||
356 | if (IS_FWI2_CAPABLE(ha)) { | 355 | if (IS_FWI2_CAPABLE(ha)) { |
@@ -375,6 +374,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
375 | ha->host_no)); | 374 | ha->host_no)); |
376 | qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); | 375 | qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); |
377 | 376 | ||
377 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
378 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 378 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
379 | break; | 379 | break; |
380 | 380 | ||
@@ -383,6 +383,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
383 | ha->host_no)); | 383 | ha->host_no)); |
384 | qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); | 384 | qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); |
385 | 385 | ||
386 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | ||
386 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 387 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
387 | break; | 388 | break; |
388 | 389 | ||
@@ -410,6 +411,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
410 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); | 411 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); |
411 | 412 | ||
412 | ha->flags.management_server_logged_in = 0; | 413 | ha->flags.management_server_logged_in = 0; |
414 | qla2x00_post_aen_work(ha, FCH_EVT_LIP, mb[1]); | ||
413 | break; | 415 | break; |
414 | 416 | ||
415 | case MBA_LOOP_UP: /* Loop Up Event */ | 417 | case MBA_LOOP_UP: /* Loop Up Event */ |
@@ -429,12 +431,14 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
429 | link_speed); | 431 | link_speed); |
430 | 432 | ||
431 | ha->flags.management_server_logged_in = 0; | 433 | ha->flags.management_server_logged_in = 0; |
434 | qla2x00_post_aen_work(ha, FCH_EVT_LINKUP, ha->link_data_rate); | ||
432 | break; | 435 | break; |
433 | 436 | ||
434 | case MBA_LOOP_DOWN: /* Loop Down Event */ | 437 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
435 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n", | 438 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN " |
436 | ha->host_no, mb[1])); | 439 | "(%x %x %x).\n", ha->host_no, mb[1], mb[2], mb[3])); |
437 | qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]); | 440 | qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n", |
441 | mb[1], mb[2], mb[3]); | ||
438 | 442 | ||
439 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 443 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { |
440 | atomic_set(&ha->loop_state, LOOP_DOWN); | 444 | atomic_set(&ha->loop_state, LOOP_DOWN); |
@@ -452,6 +456,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
452 | ha->link_data_rate = PORT_SPEED_UNKNOWN; | 456 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
453 | if (ql2xfdmienable) | 457 | if (ql2xfdmienable) |
454 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 458 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
459 | qla2x00_post_aen_work(ha, FCH_EVT_LINKDOWN, 0); | ||
455 | break; | 460 | break; |
456 | 461 | ||
457 | case MBA_LIP_RESET: /* LIP reset occurred */ | 462 | case MBA_LIP_RESET: /* LIP reset occurred */ |
@@ -475,6 +480,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
475 | 480 | ||
476 | ha->operating_mode = LOOP; | 481 | ha->operating_mode = LOOP; |
477 | ha->flags.management_server_logged_in = 0; | 482 | ha->flags.management_server_logged_in = 0; |
483 | qla2x00_post_aen_work(ha, FCH_EVT_LIPRESET, mb[1]); | ||
478 | break; | 484 | break; |
479 | 485 | ||
480 | case MBA_POINT_TO_POINT: /* Point-to-Point */ | 486 | case MBA_POINT_TO_POINT: /* Point-to-Point */ |
@@ -538,6 +544,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
538 | break; | 544 | break; |
539 | 545 | ||
540 | case MBA_PORT_UPDATE: /* Port database update */ | 546 | case MBA_PORT_UPDATE: /* Port database update */ |
547 | if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { | ||
548 | for_each_mapped_vp_idx(ha, i) { | ||
549 | list_for_each_entry(vha, &ha->vp_list, | ||
550 | vp_list) { | ||
551 | if ((mb[3] & 0xff) | ||
552 | == vha->vp_idx) { | ||
553 | ha = vha; | ||
554 | break; | ||
555 | } | ||
556 | } | ||
557 | } | ||
558 | } | ||
541 | /* | 559 | /* |
542 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET | 560 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET |
543 | * event etc. earlier indicating loop is down) then process | 561 | * event etc. earlier indicating loop is down) then process |
@@ -572,12 +590,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
572 | break; | 590 | break; |
573 | 591 | ||
574 | case MBA_RSCN_UPDATE: /* State Change Registration */ | 592 | case MBA_RSCN_UPDATE: /* State Change Registration */ |
575 | /* Check if the Vport has issued a SCR */ | 593 | if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { |
576 | if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags)) | 594 | for_each_mapped_vp_idx(ha, i) { |
577 | break; | 595 | list_for_each_entry(vha, &ha->vp_list, |
578 | /* Only handle SCNs for our Vport index. */ | 596 | vp_list) { |
579 | if (ha->flags.npiv_supported && ha->vp_idx != mb[3]) | 597 | if ((mb[3] & 0xff) |
580 | break; | 598 | == vha->vp_idx) { |
599 | ha = vha; | ||
600 | break; | ||
601 | } | ||
602 | } | ||
603 | } | ||
604 | } | ||
581 | 605 | ||
582 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", | 606 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", |
583 | ha->host_no)); | 607 | ha->host_no)); |
@@ -612,6 +636,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
612 | 636 | ||
613 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 637 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
614 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 638 | set_bit(RSCN_UPDATE, &ha->dpc_flags); |
639 | qla2x00_post_aen_work(ha, FCH_EVT_RSCN, rscn_entry); | ||
615 | break; | 640 | break; |
616 | 641 | ||
617 | /* case MBA_RIO_RESPONSE: */ | 642 | /* case MBA_RIO_RESPONSE: */ |
@@ -637,6 +662,42 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
637 | DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", | 662 | DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", |
638 | ha->host_no, mb[1], mb[2])); | 663 | ha->host_no, mb[1], mb[2])); |
639 | break; | 664 | break; |
665 | |||
666 | case MBA_ISP84XX_ALERT: | ||
667 | DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- " | ||
668 | "%04x %04x %04x\n", ha->host_no, mb[1], mb[2], mb[3])); | ||
669 | |||
670 | spin_lock_irqsave(&ha->cs84xx->access_lock, flags); | ||
671 | switch (mb[1]) { | ||
672 | case A84_PANIC_RECOVERY: | ||
673 | qla_printk(KERN_INFO, ha, "Alert 84XX: panic recovery " | ||
674 | "%04x %04x\n", mb[2], mb[3]); | ||
675 | break; | ||
676 | case A84_OP_LOGIN_COMPLETE: | ||
677 | ha->cs84xx->op_fw_version = mb[3] << 16 | mb[2]; | ||
678 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" | ||
679 | "firmware version %x\n", ha->cs84xx->op_fw_version)); | ||
680 | break; | ||
681 | case A84_DIAG_LOGIN_COMPLETE: | ||
682 | ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; | ||
683 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:" | ||
684 | "diagnostic firmware version %x\n", | ||
685 | ha->cs84xx->diag_fw_version)); | ||
686 | break; | ||
687 | case A84_GOLD_LOGIN_COMPLETE: | ||
688 | ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2]; | ||
689 | ha->cs84xx->fw_update = 1; | ||
690 | DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX: gold " | ||
691 | "firmware version %x\n", | ||
692 | ha->cs84xx->gold_fw_version)); | ||
693 | break; | ||
694 | default: | ||
695 | qla_printk(KERN_ERR, ha, | ||
696 | "Alert 84xx: Invalid Alert %04x %04x %04x\n", | ||
697 | mb[1], mb[2], mb[3]); | ||
698 | } | ||
699 | spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags); | ||
700 | break; | ||
640 | } | 701 | } |
641 | 702 | ||
642 | if (!ha->parent && ha->num_vhosts) | 703 | if (!ha->parent && ha->num_vhosts) |
@@ -803,9 +864,6 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha) | |||
803 | case STATUS_CONT_TYPE: | 864 | case STATUS_CONT_TYPE: |
804 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); | 865 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); |
805 | break; | 866 | break; |
806 | case MS_IOCB_TYPE: | ||
807 | qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt); | ||
808 | break; | ||
809 | default: | 867 | default: |
810 | /* Type Not Supported. */ | 868 | /* Type Not Supported. */ |
811 | DEBUG4(printk(KERN_WARNING | 869 | DEBUG4(printk(KERN_WARNING |
@@ -1340,44 +1398,6 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) | |||
1340 | } | 1398 | } |
1341 | 1399 | ||
1342 | /** | 1400 | /** |
1343 | * qla2x00_ms_entry() - Process a Management Server entry. | ||
1344 | * @ha: SCSI driver HA context | ||
1345 | * @index: Response queue out pointer | ||
1346 | */ | ||
1347 | static void | ||
1348 | qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt) | ||
1349 | { | ||
1350 | srb_t *sp; | ||
1351 | |||
1352 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | ||
1353 | __func__, ha->host_no, pkt, pkt->handle1)); | ||
1354 | |||
1355 | /* Validate handle. */ | ||
1356 | if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS) | ||
1357 | sp = ha->outstanding_cmds[pkt->handle1]; | ||
1358 | else | ||
1359 | sp = NULL; | ||
1360 | |||
1361 | if (sp == NULL) { | ||
1362 | DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1363 | ha->host_no)); | ||
1364 | qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n"); | ||
1365 | |||
1366 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1367 | return; | ||
1368 | } | ||
1369 | |||
1370 | CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status); | ||
1371 | CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status; | ||
1372 | |||
1373 | /* Free outstanding command slot. */ | ||
1374 | ha->outstanding_cmds[pkt->handle1] = NULL; | ||
1375 | |||
1376 | qla2x00_sp_compl(ha, sp); | ||
1377 | } | ||
1378 | |||
1379 | |||
1380 | /** | ||
1381 | * qla24xx_mbx_completion() - Process mailbox command completions. | 1401 | * qla24xx_mbx_completion() - Process mailbox command completions. |
1382 | * @ha: SCSI driver HA context | 1402 | * @ha: SCSI driver HA context |
1383 | * @mb0: Mailbox0 register | 1403 | * @mb0: Mailbox0 register |
@@ -1449,9 +1469,6 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) | |||
1449 | case STATUS_CONT_TYPE: | 1469 | case STATUS_CONT_TYPE: |
1450 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); | 1470 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); |
1451 | break; | 1471 | break; |
1452 | case MS_IOCB_TYPE: | ||
1453 | qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt); | ||
1454 | break; | ||
1455 | case VP_RPT_ID_IOCB_TYPE: | 1472 | case VP_RPT_ID_IOCB_TYPE: |
1456 | qla24xx_report_id_acquisition(ha, | 1473 | qla24xx_report_id_acquisition(ha, |
1457 | (struct vp_rpt_id_entry_24xx *)pkt); | 1474 | (struct vp_rpt_id_entry_24xx *)pkt); |
@@ -1533,7 +1550,6 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1533 | scsi_qla_host_t *ha; | 1550 | scsi_qla_host_t *ha; |
1534 | struct device_reg_24xx __iomem *reg; | 1551 | struct device_reg_24xx __iomem *reg; |
1535 | int status; | 1552 | int status; |
1536 | unsigned long flags; | ||
1537 | unsigned long iter; | 1553 | unsigned long iter; |
1538 | uint32_t stat; | 1554 | uint32_t stat; |
1539 | uint32_t hccr; | 1555 | uint32_t hccr; |
@@ -1549,13 +1565,19 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1549 | reg = &ha->iobase->isp24; | 1565 | reg = &ha->iobase->isp24; |
1550 | status = 0; | 1566 | status = 0; |
1551 | 1567 | ||
1552 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1568 | spin_lock(&ha->hardware_lock); |
1553 | for (iter = 50; iter--; ) { | 1569 | for (iter = 50; iter--; ) { |
1554 | stat = RD_REG_DWORD(®->host_status); | 1570 | stat = RD_REG_DWORD(®->host_status); |
1555 | if (stat & HSRX_RISC_PAUSED) { | 1571 | if (stat & HSRX_RISC_PAUSED) { |
1556 | if (pci_channel_offline(ha->pdev)) | 1572 | if (pci_channel_offline(ha->pdev)) |
1557 | break; | 1573 | break; |
1558 | 1574 | ||
1575 | if (ha->hw_event_pause_errors == 0) | ||
1576 | qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, | ||
1577 | 0, MSW(stat), LSW(stat)); | ||
1578 | else if (ha->hw_event_pause_errors < 0xffffffff) | ||
1579 | ha->hw_event_pause_errors++; | ||
1580 | |||
1559 | hccr = RD_REG_DWORD(®->hccr); | 1581 | hccr = RD_REG_DWORD(®->hccr); |
1560 | 1582 | ||
1561 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1583 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
@@ -1597,7 +1619,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1597 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1619 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1598 | RD_REG_DWORD_RELAXED(®->hccr); | 1620 | RD_REG_DWORD_RELAXED(®->hccr); |
1599 | } | 1621 | } |
1600 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1622 | spin_unlock(&ha->hardware_lock); |
1601 | 1623 | ||
1602 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1624 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1603 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1625 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -1608,66 +1630,21 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1608 | return IRQ_HANDLED; | 1630 | return IRQ_HANDLED; |
1609 | } | 1631 | } |
1610 | 1632 | ||
1611 | /** | ||
1612 | * qla24xx_ms_entry() - Process a Management Server entry. | ||
1613 | * @ha: SCSI driver HA context | ||
1614 | * @index: Response queue out pointer | ||
1615 | */ | ||
1616 | static void | ||
1617 | qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt) | ||
1618 | { | ||
1619 | srb_t *sp; | ||
1620 | |||
1621 | DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n", | ||
1622 | __func__, ha->host_no, pkt, pkt->handle)); | ||
1623 | |||
1624 | DEBUG9(printk("%s: ct pkt dump:\n", __func__)); | ||
1625 | DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx))); | ||
1626 | |||
1627 | /* Validate handle. */ | ||
1628 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) | ||
1629 | sp = ha->outstanding_cmds[pkt->handle]; | ||
1630 | else | ||
1631 | sp = NULL; | ||
1632 | |||
1633 | if (sp == NULL) { | ||
1634 | DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1635 | ha->host_no)); | ||
1636 | DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n", | ||
1637 | ha->host_no)); | ||
1638 | qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n", | ||
1639 | pkt->handle); | ||
1640 | |||
1641 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
1642 | return; | ||
1643 | } | ||
1644 | |||
1645 | CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status); | ||
1646 | CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status; | ||
1647 | |||
1648 | /* Free outstanding command slot. */ | ||
1649 | ha->outstanding_cmds[pkt->handle] = NULL; | ||
1650 | |||
1651 | qla2x00_sp_compl(ha, sp); | ||
1652 | } | ||
1653 | |||
1654 | static irqreturn_t | 1633 | static irqreturn_t |
1655 | qla24xx_msix_rsp_q(int irq, void *dev_id) | 1634 | qla24xx_msix_rsp_q(int irq, void *dev_id) |
1656 | { | 1635 | { |
1657 | scsi_qla_host_t *ha; | 1636 | scsi_qla_host_t *ha; |
1658 | struct device_reg_24xx __iomem *reg; | 1637 | struct device_reg_24xx __iomem *reg; |
1659 | unsigned long flags; | ||
1660 | 1638 | ||
1661 | ha = dev_id; | 1639 | ha = dev_id; |
1662 | reg = &ha->iobase->isp24; | 1640 | reg = &ha->iobase->isp24; |
1663 | 1641 | ||
1664 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1642 | spin_lock(&ha->hardware_lock); |
1665 | 1643 | ||
1666 | qla24xx_process_response_queue(ha); | 1644 | qla24xx_process_response_queue(ha); |
1667 | |||
1668 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1645 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1669 | 1646 | ||
1670 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1647 | spin_unlock(&ha->hardware_lock); |
1671 | 1648 | ||
1672 | return IRQ_HANDLED; | 1649 | return IRQ_HANDLED; |
1673 | } | 1650 | } |
@@ -1678,7 +1655,6 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1678 | scsi_qla_host_t *ha; | 1655 | scsi_qla_host_t *ha; |
1679 | struct device_reg_24xx __iomem *reg; | 1656 | struct device_reg_24xx __iomem *reg; |
1680 | int status; | 1657 | int status; |
1681 | unsigned long flags; | ||
1682 | uint32_t stat; | 1658 | uint32_t stat; |
1683 | uint32_t hccr; | 1659 | uint32_t hccr; |
1684 | uint16_t mb[4]; | 1660 | uint16_t mb[4]; |
@@ -1687,13 +1663,19 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1687 | reg = &ha->iobase->isp24; | 1663 | reg = &ha->iobase->isp24; |
1688 | status = 0; | 1664 | status = 0; |
1689 | 1665 | ||
1690 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1666 | spin_lock(&ha->hardware_lock); |
1691 | do { | 1667 | do { |
1692 | stat = RD_REG_DWORD(®->host_status); | 1668 | stat = RD_REG_DWORD(®->host_status); |
1693 | if (stat & HSRX_RISC_PAUSED) { | 1669 | if (stat & HSRX_RISC_PAUSED) { |
1694 | if (pci_channel_offline(ha->pdev)) | 1670 | if (pci_channel_offline(ha->pdev)) |
1695 | break; | 1671 | break; |
1696 | 1672 | ||
1673 | if (ha->hw_event_pause_errors == 0) | ||
1674 | qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, | ||
1675 | 0, MSW(stat), LSW(stat)); | ||
1676 | else if (ha->hw_event_pause_errors < 0xffffffff) | ||
1677 | ha->hw_event_pause_errors++; | ||
1678 | |||
1697 | hccr = RD_REG_DWORD(®->hccr); | 1679 | hccr = RD_REG_DWORD(®->hccr); |
1698 | 1680 | ||
1699 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1681 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
@@ -1734,7 +1716,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1734 | } | 1716 | } |
1735 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1717 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1736 | } while (0); | 1718 | } while (0); |
1737 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1719 | spin_unlock(&ha->hardware_lock); |
1738 | 1720 | ||
1739 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1721 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
1740 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { | 1722 | (status & MBX_INTERRUPT) && ha->flags.mbox_int) { |
@@ -1821,10 +1803,9 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1821 | { | 1803 | { |
1822 | int ret; | 1804 | int ret; |
1823 | device_reg_t __iomem *reg = ha->iobase; | 1805 | device_reg_t __iomem *reg = ha->iobase; |
1824 | unsigned long flags; | ||
1825 | 1806 | ||
1826 | /* If possible, enable MSI-X. */ | 1807 | /* If possible, enable MSI-X. */ |
1827 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha)) | 1808 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) |
1828 | goto skip_msix; | 1809 | goto skip_msix; |
1829 | 1810 | ||
1830 | if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || | 1811 | if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || |
@@ -1859,7 +1840,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1859 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); | 1840 | "MSI-X: Falling back-to INTa mode -- %d.\n", ret); |
1860 | skip_msix: | 1841 | skip_msix: |
1861 | 1842 | ||
1862 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha)) | 1843 | if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) |
1863 | goto skip_msi; | 1844 | goto skip_msi; |
1864 | 1845 | ||
1865 | ret = pci_enable_msi(ha->pdev); | 1846 | ret = pci_enable_msi(ha->pdev); |
@@ -1882,7 +1863,7 @@ skip_msi: | |||
1882 | clear_risc_ints: | 1863 | clear_risc_ints: |
1883 | 1864 | ||
1884 | ha->isp_ops->disable_intrs(ha); | 1865 | ha->isp_ops->disable_intrs(ha); |
1885 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1866 | spin_lock_irq(&ha->hardware_lock); |
1886 | if (IS_FWI2_CAPABLE(ha)) { | 1867 | if (IS_FWI2_CAPABLE(ha)) { |
1887 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); | 1868 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); |
1888 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); | 1869 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_RISC_INT); |
@@ -1891,7 +1872,7 @@ clear_risc_ints: | |||
1891 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT); | 1872 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_RISC_INT); |
1892 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); | 1873 | WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); |
1893 | } | 1874 | } |
1894 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1875 | spin_unlock_irq(&ha->hardware_lock); |
1895 | ha->isp_ops->enable_intrs(ha); | 1876 | ha->isp_ops->enable_intrs(ha); |
1896 | 1877 | ||
1897 | fail: | 1878 | fail: |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index bb103580e1ba..7d0a8a4c7719 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -310,7 +310,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr, | |||
310 | } | 310 | } |
311 | 311 | ||
312 | mcp->in_mb = MBX_0; | 312 | mcp->in_mb = MBX_0; |
313 | mcp->tov = 30; | 313 | mcp->tov = MBX_TOV_SECONDS; |
314 | mcp->flags = 0; | 314 | mcp->flags = 0; |
315 | rval = qla2x00_mailbox_command(ha, mcp); | 315 | rval = qla2x00_mailbox_command(ha, mcp); |
316 | 316 | ||
@@ -367,7 +367,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
367 | } | 367 | } |
368 | } | 368 | } |
369 | 369 | ||
370 | mcp->tov = 30; | 370 | mcp->tov = MBX_TOV_SECONDS; |
371 | mcp->flags = 0; | 371 | mcp->flags = 0; |
372 | rval = qla2x00_mailbox_command(ha, mcp); | 372 | rval = qla2x00_mailbox_command(ha, mcp); |
373 | 373 | ||
@@ -417,7 +417,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor, | |||
417 | mcp->out_mb = MBX_0; | 417 | mcp->out_mb = MBX_0; |
418 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 418 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
419 | mcp->flags = 0; | 419 | mcp->flags = 0; |
420 | mcp->tov = 30; | 420 | mcp->tov = MBX_TOV_SECONDS; |
421 | rval = qla2x00_mailbox_command(ha, mcp); | 421 | rval = qla2x00_mailbox_command(ha, mcp); |
422 | 422 | ||
423 | /* Return mailbox data. */ | 423 | /* Return mailbox data. */ |
@@ -466,7 +466,7 @@ qla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) | |||
466 | mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; | 466 | mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; |
467 | mcp->out_mb = MBX_0; | 467 | mcp->out_mb = MBX_0; |
468 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 468 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
469 | mcp->tov = 30; | 469 | mcp->tov = MBX_TOV_SECONDS; |
470 | mcp->flags = 0; | 470 | mcp->flags = 0; |
471 | rval = qla2x00_mailbox_command(ha, mcp); | 471 | rval = qla2x00_mailbox_command(ha, mcp); |
472 | 472 | ||
@@ -524,7 +524,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) | |||
524 | mcp->mb[12] = 0; /* Undocumented, but used */ | 524 | mcp->mb[12] = 0; /* Undocumented, but used */ |
525 | mcp->out_mb |= MBX_12|MBX_11|MBX_10; | 525 | mcp->out_mb |= MBX_12|MBX_11|MBX_10; |
526 | } | 526 | } |
527 | mcp->tov = 30; | 527 | mcp->tov = MBX_TOV_SECONDS; |
528 | mcp->flags = 0; | 528 | mcp->flags = 0; |
529 | rval = qla2x00_mailbox_command(ha, mcp); | 529 | rval = qla2x00_mailbox_command(ha, mcp); |
530 | 530 | ||
@@ -576,7 +576,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
576 | mcp->mb[7] = 0x2525; | 576 | mcp->mb[7] = 0x2525; |
577 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 577 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
578 | mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 578 | mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
579 | mcp->tov = 30; | 579 | mcp->tov = MBX_TOV_SECONDS; |
580 | mcp->flags = 0; | 580 | mcp->flags = 0; |
581 | rval = qla2x00_mailbox_command(ha, mcp); | 581 | rval = qla2x00_mailbox_command(ha, mcp); |
582 | 582 | ||
@@ -587,6 +587,14 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha) | |||
587 | if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || | 587 | if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || |
588 | mcp->mb[7] != 0x2525) | 588 | mcp->mb[7] != 0x2525) |
589 | rval = QLA_FUNCTION_FAILED; | 589 | rval = QLA_FUNCTION_FAILED; |
590 | if (rval == QLA_FUNCTION_FAILED) { | ||
591 | struct device_reg_24xx __iomem *reg = | ||
592 | &ha->iobase->isp24; | ||
593 | |||
594 | qla2xxx_hw_event_log(ha, HW_EVENT_ISP_ERR, 0, | ||
595 | LSW(RD_REG_DWORD(®->hccr)), | ||
596 | LSW(RD_REG_DWORD(®->istatus))); | ||
597 | } | ||
590 | } | 598 | } |
591 | 599 | ||
592 | if (rval != QLA_SUCCESS) { | 600 | if (rval != QLA_SUCCESS) { |
@@ -640,7 +648,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
640 | mcp->in_mb |= MBX_1; | 648 | mcp->in_mb |= MBX_1; |
641 | } | 649 | } |
642 | 650 | ||
643 | mcp->tov = 30; | 651 | mcp->tov = MBX_TOV_SECONDS; |
644 | mcp->flags = 0; | 652 | mcp->flags = 0; |
645 | rval = qla2x00_mailbox_command(ha, mcp); | 653 | rval = qla2x00_mailbox_command(ha, mcp); |
646 | 654 | ||
@@ -674,8 +682,8 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
674 | * Kernel context. | 682 | * Kernel context. |
675 | */ | 683 | */ |
676 | int | 684 | int |
677 | qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | 685 | qla2x00_issue_iocb_timeout(scsi_qla_host_t *ha, void *buffer, |
678 | size_t size) | 686 | dma_addr_t phys_addr, size_t size, uint32_t tov) |
679 | { | 687 | { |
680 | int rval; | 688 | int rval; |
681 | mbx_cmd_t mc; | 689 | mbx_cmd_t mc; |
@@ -689,7 +697,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
689 | mcp->mb[7] = LSW(MSD(phys_addr)); | 697 | mcp->mb[7] = LSW(MSD(phys_addr)); |
690 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 698 | mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
691 | mcp->in_mb = MBX_2|MBX_0; | 699 | mcp->in_mb = MBX_2|MBX_0; |
692 | mcp->tov = 30; | 700 | mcp->tov = tov; |
693 | mcp->flags = 0; | 701 | mcp->flags = 0; |
694 | rval = qla2x00_mailbox_command(ha, mcp); | 702 | rval = qla2x00_mailbox_command(ha, mcp); |
695 | 703 | ||
@@ -710,6 +718,14 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, | |||
710 | return rval; | 718 | return rval; |
711 | } | 719 | } |
712 | 720 | ||
721 | int | ||
722 | qla2x00_issue_iocb(scsi_qla_host_t *ha, void *buffer, dma_addr_t phys_addr, | ||
723 | size_t size) | ||
724 | { | ||
725 | return qla2x00_issue_iocb_timeout(ha, buffer, phys_addr, size, | ||
726 | MBX_TOV_SECONDS); | ||
727 | } | ||
728 | |||
713 | /* | 729 | /* |
714 | * qla2x00_abort_command | 730 | * qla2x00_abort_command |
715 | * Abort command aborts a specified IOCB. | 731 | * Abort command aborts a specified IOCB. |
@@ -760,7 +776,7 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
760 | mcp->mb[6] = (uint16_t)sp->cmd->device->lun; | 776 | mcp->mb[6] = (uint16_t)sp->cmd->device->lun; |
761 | mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 777 | mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
762 | mcp->in_mb = MBX_0; | 778 | mcp->in_mb = MBX_0; |
763 | mcp->tov = 30; | 779 | mcp->tov = MBX_TOV_SECONDS; |
764 | mcp->flags = 0; | 780 | mcp->flags = 0; |
765 | rval = qla2x00_mailbox_command(ha, mcp); | 781 | rval = qla2x00_mailbox_command(ha, mcp); |
766 | 782 | ||
@@ -776,36 +792,20 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
776 | return rval; | 792 | return rval; |
777 | } | 793 | } |
778 | 794 | ||
779 | #if USE_ABORT_TGT | ||
780 | /* | ||
781 | * qla2x00_abort_target | ||
782 | * Issue abort target mailbox command. | ||
783 | * | ||
784 | * Input: | ||
785 | * ha = adapter block pointer. | ||
786 | * | ||
787 | * Returns: | ||
788 | * qla2x00 local function return status code. | ||
789 | * | ||
790 | * Context: | ||
791 | * Kernel context. | ||
792 | */ | ||
793 | int | 795 | int |
794 | qla2x00_abort_target(fc_port_t *fcport) | 796 | qla2x00_abort_target(struct fc_port *fcport, unsigned int l) |
795 | { | 797 | { |
796 | int rval; | 798 | int rval, rval2; |
797 | mbx_cmd_t mc; | 799 | mbx_cmd_t mc; |
798 | mbx_cmd_t *mcp = &mc; | 800 | mbx_cmd_t *mcp = &mc; |
799 | scsi_qla_host_t *ha; | 801 | scsi_qla_host_t *ha; |
800 | 802 | ||
801 | if (fcport == NULL) | ||
802 | return 0; | ||
803 | |||
804 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | 803 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
805 | 804 | ||
805 | l = l; | ||
806 | ha = fcport->ha; | 806 | ha = fcport->ha; |
807 | mcp->mb[0] = MBC_ABORT_TARGET; | 807 | mcp->mb[0] = MBC_ABORT_TARGET; |
808 | mcp->out_mb = MBX_2|MBX_1|MBX_0; | 808 | mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0; |
809 | if (HAS_EXTENDED_IDS(ha)) { | 809 | if (HAS_EXTENDED_IDS(ha)) { |
810 | mcp->mb[1] = fcport->loop_id; | 810 | mcp->mb[1] = fcport->loop_id; |
811 | mcp->mb[10] = 0; | 811 | mcp->mb[10] = 0; |
@@ -814,27 +814,70 @@ qla2x00_abort_target(fc_port_t *fcport) | |||
814 | mcp->mb[1] = fcport->loop_id << 8; | 814 | mcp->mb[1] = fcport->loop_id << 8; |
815 | } | 815 | } |
816 | mcp->mb[2] = ha->loop_reset_delay; | 816 | mcp->mb[2] = ha->loop_reset_delay; |
817 | mcp->mb[9] = ha->vp_idx; | ||
817 | 818 | ||
818 | mcp->in_mb = MBX_0; | 819 | mcp->in_mb = MBX_0; |
819 | mcp->tov = 30; | 820 | mcp->tov = MBX_TOV_SECONDS; |
820 | mcp->flags = 0; | 821 | mcp->flags = 0; |
821 | rval = qla2x00_mailbox_command(ha, mcp); | 822 | rval = qla2x00_mailbox_command(ha, mcp); |
823 | if (rval != QLA_SUCCESS) { | ||
824 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, | ||
825 | ha->host_no, rval)); | ||
826 | } | ||
822 | 827 | ||
823 | /* Issue marker command. */ | 828 | /* Issue marker IOCB. */ |
824 | ha->marker_needed = 1; | 829 | rval2 = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); |
830 | if (rval2 != QLA_SUCCESS) { | ||
831 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | ||
832 | "(%x).\n", __func__, ha->host_no, rval2)); | ||
833 | } else { | ||
834 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
835 | } | ||
836 | |||
837 | return rval; | ||
838 | } | ||
839 | |||
840 | int | ||
841 | qla2x00_lun_reset(struct fc_port *fcport, unsigned int l) | ||
842 | { | ||
843 | int rval, rval2; | ||
844 | mbx_cmd_t mc; | ||
845 | mbx_cmd_t *mcp = &mc; | ||
846 | scsi_qla_host_t *ha; | ||
847 | |||
848 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | ||
849 | |||
850 | ha = fcport->ha; | ||
851 | mcp->mb[0] = MBC_LUN_RESET; | ||
852 | mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0; | ||
853 | if (HAS_EXTENDED_IDS(ha)) | ||
854 | mcp->mb[1] = fcport->loop_id; | ||
855 | else | ||
856 | mcp->mb[1] = fcport->loop_id << 8; | ||
857 | mcp->mb[2] = l; | ||
858 | mcp->mb[3] = 0; | ||
859 | mcp->mb[9] = ha->vp_idx; | ||
825 | 860 | ||
861 | mcp->in_mb = MBX_0; | ||
862 | mcp->tov = MBX_TOV_SECONDS; | ||
863 | mcp->flags = 0; | ||
864 | rval = qla2x00_mailbox_command(ha, mcp); | ||
826 | if (rval != QLA_SUCCESS) { | 865 | if (rval != QLA_SUCCESS) { |
827 | DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", | 866 | DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, |
828 | ha->host_no, rval)); | 867 | ha->host_no, rval)); |
868 | } | ||
869 | |||
870 | /* Issue marker IOCB. */ | ||
871 | rval2 = qla2x00_marker(ha, fcport->loop_id, l, MK_SYNC_ID_LUN); | ||
872 | if (rval2 != QLA_SUCCESS) { | ||
873 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | ||
874 | "(%x).\n", __func__, ha->host_no, rval2)); | ||
829 | } else { | 875 | } else { |
830 | /*EMPTY*/ | 876 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
831 | DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", | ||
832 | ha->host_no)); | ||
833 | } | 877 | } |
834 | 878 | ||
835 | return rval; | 879 | return rval; |
836 | } | 880 | } |
837 | #endif | ||
838 | 881 | ||
839 | /* | 882 | /* |
840 | * qla2x00_get_adapter_id | 883 | * qla2x00_get_adapter_id |
@@ -871,7 +914,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
871 | mcp->mb[9] = ha->vp_idx; | 914 | mcp->mb[9] = ha->vp_idx; |
872 | mcp->out_mb = MBX_9|MBX_0; | 915 | mcp->out_mb = MBX_9|MBX_0; |
873 | mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 916 | mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
874 | mcp->tov = 30; | 917 | mcp->tov = MBX_TOV_SECONDS; |
875 | mcp->flags = 0; | 918 | mcp->flags = 0; |
876 | rval = qla2x00_mailbox_command(ha, mcp); | 919 | rval = qla2x00_mailbox_command(ha, mcp); |
877 | if (mcp->mb[0] == MBS_COMMAND_ERROR) | 920 | if (mcp->mb[0] == MBS_COMMAND_ERROR) |
@@ -928,7 +971,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, | |||
928 | mcp->mb[0] = MBC_GET_RETRY_COUNT; | 971 | mcp->mb[0] = MBC_GET_RETRY_COUNT; |
929 | mcp->out_mb = MBX_0; | 972 | mcp->out_mb = MBX_0; |
930 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 973 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
931 | mcp->tov = 30; | 974 | mcp->tov = MBX_TOV_SECONDS; |
932 | mcp->flags = 0; | 975 | mcp->flags = 0; |
933 | rval = qla2x00_mailbox_command(ha, mcp); | 976 | rval = qla2x00_mailbox_command(ha, mcp); |
934 | 977 | ||
@@ -995,7 +1038,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) | |||
995 | mcp->in_mb = MBX_5|MBX_4|MBX_0; | 1038 | mcp->in_mb = MBX_5|MBX_4|MBX_0; |
996 | mcp->buf_size = size; | 1039 | mcp->buf_size = size; |
997 | mcp->flags = MBX_DMA_OUT; | 1040 | mcp->flags = MBX_DMA_OUT; |
998 | mcp->tov = 30; | 1041 | mcp->tov = MBX_TOV_SECONDS; |
999 | rval = qla2x00_mailbox_command(ha, mcp); | 1042 | rval = qla2x00_mailbox_command(ha, mcp); |
1000 | 1043 | ||
1001 | if (rval != QLA_SUCCESS) { | 1044 | if (rval != QLA_SUCCESS) { |
@@ -1173,7 +1216,7 @@ gpd_error_out: | |||
1173 | * Kernel context. | 1216 | * Kernel context. |
1174 | */ | 1217 | */ |
1175 | int | 1218 | int |
1176 | qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | 1219 | qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *states) |
1177 | { | 1220 | { |
1178 | int rval; | 1221 | int rval; |
1179 | mbx_cmd_t mc; | 1222 | mbx_cmd_t mc; |
@@ -1184,13 +1227,15 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) | |||
1184 | 1227 | ||
1185 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; | 1228 | mcp->mb[0] = MBC_GET_FIRMWARE_STATE; |
1186 | mcp->out_mb = MBX_0; | 1229 | mcp->out_mb = MBX_0; |
1187 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 1230 | mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
1188 | mcp->tov = 30; | 1231 | mcp->tov = MBX_TOV_SECONDS; |
1189 | mcp->flags = 0; | 1232 | mcp->flags = 0; |
1190 | rval = qla2x00_mailbox_command(ha, mcp); | 1233 | rval = qla2x00_mailbox_command(ha, mcp); |
1191 | 1234 | ||
1192 | /* Return firmware state. */ | 1235 | /* Return firmware states. */ |
1193 | *dptr = mcp->mb[1]; | 1236 | states[0] = mcp->mb[1]; |
1237 | states[1] = mcp->mb[2]; | ||
1238 | states[2] = mcp->mb[3]; | ||
1194 | 1239 | ||
1195 | if (rval != QLA_SUCCESS) { | 1240 | if (rval != QLA_SUCCESS) { |
1196 | /*EMPTY*/ | 1241 | /*EMPTY*/ |
@@ -1246,7 +1291,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, | |||
1246 | } | 1291 | } |
1247 | 1292 | ||
1248 | mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 1293 | mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
1249 | mcp->tov = 30; | 1294 | mcp->tov = MBX_TOV_SECONDS; |
1250 | mcp->flags = 0; | 1295 | mcp->flags = 0; |
1251 | rval = qla2x00_mailbox_command(ha, mcp); | 1296 | rval = qla2x00_mailbox_command(ha, mcp); |
1252 | 1297 | ||
@@ -1318,7 +1363,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha) | |||
1318 | mcp->mb[3] = 0; | 1363 | mcp->mb[3] = 0; |
1319 | } | 1364 | } |
1320 | mcp->in_mb = MBX_0; | 1365 | mcp->in_mb = MBX_0; |
1321 | mcp->tov = 30; | 1366 | mcp->tov = MBX_TOV_SECONDS; |
1322 | mcp->flags = 0; | 1367 | mcp->flags = 0; |
1323 | rval = qla2x00_mailbox_command(ha, mcp); | 1368 | rval = qla2x00_mailbox_command(ha, mcp); |
1324 | 1369 | ||
@@ -1743,7 +1788,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, | |||
1743 | } | 1788 | } |
1744 | 1789 | ||
1745 | mcp->in_mb = MBX_1|MBX_0; | 1790 | mcp->in_mb = MBX_1|MBX_0; |
1746 | mcp->tov = 30; | 1791 | mcp->tov = MBX_TOV_SECONDS; |
1747 | mcp->flags = 0; | 1792 | mcp->flags = 0; |
1748 | rval = qla2x00_mailbox_command(ha, mcp); | 1793 | rval = qla2x00_mailbox_command(ha, mcp); |
1749 | 1794 | ||
@@ -1791,7 +1836,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha) | |||
1791 | mcp->mb[3] = 0; | 1836 | mcp->mb[3] = 0; |
1792 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; | 1837 | mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; |
1793 | mcp->in_mb = MBX_0; | 1838 | mcp->in_mb = MBX_0; |
1794 | mcp->tov = 30; | 1839 | mcp->tov = MBX_TOV_SECONDS; |
1795 | mcp->flags = 0; | 1840 | mcp->flags = 0; |
1796 | rval = qla2x00_mailbox_command(ha, mcp); | 1841 | rval = qla2x00_mailbox_command(ha, mcp); |
1797 | 1842 | ||
@@ -1852,7 +1897,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1852 | mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; | 1897 | mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; |
1853 | } | 1898 | } |
1854 | mcp->in_mb = MBX_1|MBX_0; | 1899 | mcp->in_mb = MBX_1|MBX_0; |
1855 | mcp->tov = 30; | 1900 | mcp->tov = MBX_TOV_SECONDS; |
1856 | mcp->flags = 0; | 1901 | mcp->flags = 0; |
1857 | rval = qla2x00_mailbox_command(ha, mcp); | 1902 | rval = qla2x00_mailbox_command(ha, mcp); |
1858 | 1903 | ||
@@ -1896,7 +1941,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | |||
1896 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; | 1941 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; |
1897 | mcp->out_mb = MBX_0; | 1942 | mcp->out_mb = MBX_0; |
1898 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 1943 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
1899 | mcp->tov = 30; | 1944 | mcp->tov = MBX_TOV_SECONDS; |
1900 | mcp->flags = 0; | 1945 | mcp->flags = 0; |
1901 | rval = qla2x00_mailbox_command(ha, mcp); | 1946 | rval = qla2x00_mailbox_command(ha, mcp); |
1902 | 1947 | ||
@@ -2036,7 +2081,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2036 | mcp->mb[1] = loop_id << 8; | 2081 | mcp->mb[1] = loop_id << 8; |
2037 | mcp->out_mb |= MBX_1; | 2082 | mcp->out_mb |= MBX_1; |
2038 | } | 2083 | } |
2039 | mcp->tov = 30; | 2084 | mcp->tov = MBX_TOV_SECONDS; |
2040 | mcp->flags = IOCTL_CMD; | 2085 | mcp->flags = IOCTL_CMD; |
2041 | rval = qla2x00_mailbox_command(ha, mcp); | 2086 | rval = qla2x00_mailbox_command(ha, mcp); |
2042 | 2087 | ||
@@ -2082,7 +2127,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, struct link_statistics *stats, | |||
2082 | mcp->mb[10] = 0; | 2127 | mcp->mb[10] = 0; |
2083 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; | 2128 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; |
2084 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | 2129 | mcp->in_mb = MBX_2|MBX_1|MBX_0; |
2085 | mcp->tov = 30; | 2130 | mcp->tov = MBX_TOV_SECONDS; |
2086 | mcp->flags = IOCTL_CMD; | 2131 | mcp->flags = IOCTL_CMD; |
2087 | rval = qla2x00_mailbox_command(ha, mcp); | 2132 | rval = qla2x00_mailbox_command(ha, mcp); |
2088 | 2133 | ||
@@ -2180,17 +2225,15 @@ struct tsk_mgmt_cmd { | |||
2180 | } p; | 2225 | } p; |
2181 | }; | 2226 | }; |
2182 | 2227 | ||
2183 | int | 2228 | static int |
2184 | qla24xx_abort_target(fc_port_t *fcport) | 2229 | __qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport, |
2230 | unsigned int l) | ||
2185 | { | 2231 | { |
2186 | int rval; | 2232 | int rval, rval2; |
2187 | struct tsk_mgmt_cmd *tsk; | 2233 | struct tsk_mgmt_cmd *tsk; |
2188 | dma_addr_t tsk_dma; | 2234 | dma_addr_t tsk_dma; |
2189 | scsi_qla_host_t *ha, *pha; | 2235 | scsi_qla_host_t *ha, *pha; |
2190 | 2236 | ||
2191 | if (fcport == NULL) | ||
2192 | return 0; | ||
2193 | |||
2194 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); | 2237 | DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no)); |
2195 | 2238 | ||
2196 | ha = fcport->ha; | 2239 | ha = fcport->ha; |
@@ -2207,47 +2250,61 @@ qla24xx_abort_target(fc_port_t *fcport) | |||
2207 | tsk->p.tsk.entry_count = 1; | 2250 | tsk->p.tsk.entry_count = 1; |
2208 | tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); | 2251 | tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); |
2209 | tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); | 2252 | tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); |
2210 | tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET); | 2253 | tsk->p.tsk.control_flags = cpu_to_le32(type); |
2211 | tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; | 2254 | tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; |
2212 | tsk->p.tsk.port_id[1] = fcport->d_id.b.area; | 2255 | tsk->p.tsk.port_id[1] = fcport->d_id.b.area; |
2213 | tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; | 2256 | tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; |
2214 | tsk->p.tsk.vp_index = fcport->vp_idx; | 2257 | tsk->p.tsk.vp_index = fcport->vp_idx; |
2258 | if (type == TCF_LUN_RESET) { | ||
2259 | int_to_scsilun(l, &tsk->p.tsk.lun); | ||
2260 | host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun, | ||
2261 | sizeof(tsk->p.tsk.lun)); | ||
2262 | } | ||
2215 | 2263 | ||
2216 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); | 2264 | rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); |
2217 | if (rval != QLA_SUCCESS) { | 2265 | if (rval != QLA_SUCCESS) { |
2218 | DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " | 2266 | DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB " |
2219 | "(%x).\n", __func__, ha->host_no, rval)); | 2267 | "(%x).\n", __func__, ha->host_no, name, rval)); |
2220 | goto atarget_done; | ||
2221 | } else if (tsk->p.sts.entry_status != 0) { | 2268 | } else if (tsk->p.sts.entry_status != 0) { |
2222 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2269 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2223 | "-- error status (%x).\n", __func__, ha->host_no, | 2270 | "-- error status (%x).\n", __func__, ha->host_no, |
2224 | tsk->p.sts.entry_status)); | 2271 | tsk->p.sts.entry_status)); |
2225 | rval = QLA_FUNCTION_FAILED; | 2272 | rval = QLA_FUNCTION_FAILED; |
2226 | goto atarget_done; | ||
2227 | } else if (tsk->p.sts.comp_status != | 2273 | } else if (tsk->p.sts.comp_status != |
2228 | __constant_cpu_to_le16(CS_COMPLETE)) { | 2274 | __constant_cpu_to_le16(CS_COMPLETE)) { |
2229 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " | 2275 | DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " |
2230 | "-- completion status (%x).\n", __func__, | 2276 | "-- completion status (%x).\n", __func__, |
2231 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); | 2277 | ha->host_no, le16_to_cpu(tsk->p.sts.comp_status))); |
2232 | rval = QLA_FUNCTION_FAILED; | 2278 | rval = QLA_FUNCTION_FAILED; |
2233 | goto atarget_done; | ||
2234 | } | 2279 | } |
2235 | 2280 | ||
2236 | /* Issue marker IOCB. */ | 2281 | /* Issue marker IOCB. */ |
2237 | rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); | 2282 | rval2 = qla2x00_marker(ha, fcport->loop_id, l, |
2238 | if (rval != QLA_SUCCESS) { | 2283 | type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID); |
2284 | if (rval2 != QLA_SUCCESS) { | ||
2239 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " | 2285 | DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " |
2240 | "(%x).\n", __func__, ha->host_no, rval)); | 2286 | "(%x).\n", __func__, ha->host_no, rval2)); |
2241 | } else { | 2287 | } else { |
2242 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | 2288 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); |
2243 | } | 2289 | } |
2244 | 2290 | ||
2245 | atarget_done: | ||
2246 | dma_pool_free(pha->s_dma_pool, tsk, tsk_dma); | 2291 | dma_pool_free(pha->s_dma_pool, tsk, tsk_dma); |
2247 | 2292 | ||
2248 | return rval; | 2293 | return rval; |
2249 | } | 2294 | } |
2250 | 2295 | ||
2296 | int | ||
2297 | qla24xx_abort_target(struct fc_port *fcport, unsigned int l) | ||
2298 | { | ||
2299 | return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l); | ||
2300 | } | ||
2301 | |||
2302 | int | ||
2303 | qla24xx_lun_reset(struct fc_port *fcport, unsigned int l) | ||
2304 | { | ||
2305 | return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l); | ||
2306 | } | ||
2307 | |||
2251 | #if 0 | 2308 | #if 0 |
2252 | 2309 | ||
2253 | int | 2310 | int |
@@ -2304,7 +2361,7 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g, | |||
2304 | mcp->mb[4] = sw_em_4g | BIT_15; | 2361 | mcp->mb[4] = sw_em_4g | BIT_15; |
2305 | mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2362 | mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2306 | mcp->in_mb = MBX_0; | 2363 | mcp->in_mb = MBX_0; |
2307 | mcp->tov = 30; | 2364 | mcp->tov = MBX_TOV_SECONDS; |
2308 | mcp->flags = 0; | 2365 | mcp->flags = 0; |
2309 | rval = qla2x00_mailbox_command(ha, mcp); | 2366 | rval = qla2x00_mailbox_command(ha, mcp); |
2310 | 2367 | ||
@@ -2372,7 +2429,7 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *ha, dma_addr_t eft_dma, | |||
2372 | mcp->mb[7] = TC_AEN_DISABLE; | 2429 | mcp->mb[7] = TC_AEN_DISABLE; |
2373 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2430 | mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2374 | mcp->in_mb = MBX_1|MBX_0; | 2431 | mcp->in_mb = MBX_1|MBX_0; |
2375 | mcp->tov = 30; | 2432 | mcp->tov = MBX_TOV_SECONDS; |
2376 | mcp->flags = 0; | 2433 | mcp->flags = 0; |
2377 | rval = qla2x00_mailbox_command(ha, mcp); | 2434 | rval = qla2x00_mailbox_command(ha, mcp); |
2378 | if (rval != QLA_SUCCESS) { | 2435 | if (rval != QLA_SUCCESS) { |
@@ -2401,7 +2458,7 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *ha) | |||
2401 | mcp->mb[1] = TC_EFT_DISABLE; | 2458 | mcp->mb[1] = TC_EFT_DISABLE; |
2402 | mcp->out_mb = MBX_1|MBX_0; | 2459 | mcp->out_mb = MBX_1|MBX_0; |
2403 | mcp->in_mb = MBX_1|MBX_0; | 2460 | mcp->in_mb = MBX_1|MBX_0; |
2404 | mcp->tov = 30; | 2461 | mcp->tov = MBX_TOV_SECONDS; |
2405 | mcp->flags = 0; | 2462 | mcp->flags = 0; |
2406 | rval = qla2x00_mailbox_command(ha, mcp); | 2463 | rval = qla2x00_mailbox_command(ha, mcp); |
2407 | if (rval != QLA_SUCCESS) { | 2464 | if (rval != QLA_SUCCESS) { |
@@ -2441,7 +2498,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *ha, dma_addr_t fce_dma, | |||
2441 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| | 2498 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| |
2442 | MBX_1|MBX_0; | 2499 | MBX_1|MBX_0; |
2443 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2500 | mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2444 | mcp->tov = 30; | 2501 | mcp->tov = MBX_TOV_SECONDS; |
2445 | mcp->flags = 0; | 2502 | mcp->flags = 0; |
2446 | rval = qla2x00_mailbox_command(ha, mcp); | 2503 | rval = qla2x00_mailbox_command(ha, mcp); |
2447 | if (rval != QLA_SUCCESS) { | 2504 | if (rval != QLA_SUCCESS) { |
@@ -2477,7 +2534,7 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *ha, uint64_t *wr, uint64_t *rd) | |||
2477 | mcp->out_mb = MBX_2|MBX_1|MBX_0; | 2534 | mcp->out_mb = MBX_2|MBX_1|MBX_0; |
2478 | mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| | 2535 | mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2| |
2479 | MBX_1|MBX_0; | 2536 | MBX_1|MBX_0; |
2480 | mcp->tov = 30; | 2537 | mcp->tov = MBX_TOV_SECONDS; |
2481 | mcp->flags = 0; | 2538 | mcp->flags = 0; |
2482 | rval = qla2x00_mailbox_command(ha, mcp); | 2539 | rval = qla2x00_mailbox_command(ha, mcp); |
2483 | if (rval != QLA_SUCCESS) { | 2540 | if (rval != QLA_SUCCESS) { |
@@ -2525,7 +2582,7 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr, | |||
2525 | mcp->mb[10] = 0; | 2582 | mcp->mb[10] = 0; |
2526 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 2583 | mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
2527 | mcp->in_mb = MBX_0; | 2584 | mcp->in_mb = MBX_0; |
2528 | mcp->tov = 30; | 2585 | mcp->tov = MBX_TOV_SECONDS; |
2529 | mcp->flags = 0; | 2586 | mcp->flags = 0; |
2530 | rval = qla2x00_mailbox_command(ha, mcp); | 2587 | rval = qla2x00_mailbox_command(ha, mcp); |
2531 | 2588 | ||
@@ -2559,7 +2616,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id, | |||
2559 | mcp->mb[4] = mcp->mb[5] = 0; | 2616 | mcp->mb[4] = mcp->mb[5] = 0; |
2560 | mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 2617 | mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
2561 | mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; | 2618 | mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; |
2562 | mcp->tov = 30; | 2619 | mcp->tov = MBX_TOV_SECONDS; |
2563 | mcp->flags = 0; | 2620 | mcp->flags = 0; |
2564 | rval = qla2x00_mailbox_command(ha, mcp); | 2621 | rval = qla2x00_mailbox_command(ha, mcp); |
2565 | 2622 | ||
@@ -2877,7 +2934,7 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, | |||
2877 | } | 2934 | } |
2878 | 2935 | ||
2879 | mcp->in_mb = MBX_0; | 2936 | mcp->in_mb = MBX_0; |
2880 | mcp->tov = 30; | 2937 | mcp->tov = MBX_TOV_SECONDS; |
2881 | mcp->flags = 0; | 2938 | mcp->flags = 0; |
2882 | rval = qla2x00_mailbox_command(ha, mcp); | 2939 | rval = qla2x00_mailbox_command(ha, mcp); |
2883 | 2940 | ||
@@ -2890,3 +2947,104 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, | |||
2890 | 2947 | ||
2891 | return rval; | 2948 | return rval; |
2892 | } | 2949 | } |
2950 | |||
2951 | /* 84XX Support **************************************************************/ | ||
2952 | |||
2953 | struct cs84xx_mgmt_cmd { | ||
2954 | union { | ||
2955 | struct verify_chip_entry_84xx req; | ||
2956 | struct verify_chip_rsp_84xx rsp; | ||
2957 | } p; | ||
2958 | }; | ||
2959 | |||
2960 | int | ||
2961 | qla84xx_verify_chip(struct scsi_qla_host *ha, uint16_t *status) | ||
2962 | { | ||
2963 | int rval, retry; | ||
2964 | struct cs84xx_mgmt_cmd *mn; | ||
2965 | dma_addr_t mn_dma; | ||
2966 | uint16_t options; | ||
2967 | unsigned long flags; | ||
2968 | |||
2969 | DEBUG16(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2970 | |||
2971 | mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); | ||
2972 | if (mn == NULL) { | ||
2973 | DEBUG2_3(printk("%s(%ld): failed to allocate Verify ISP84XX " | ||
2974 | "IOCB.\n", __func__, ha->host_no)); | ||
2975 | return QLA_MEMORY_ALLOC_FAILED; | ||
2976 | } | ||
2977 | |||
2978 | /* Force Update? */ | ||
2979 | options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0; | ||
2980 | /* Diagnostic firmware? */ | ||
2981 | /* options |= MENLO_DIAG_FW; */ | ||
2982 | /* We update the firmware with only one data sequence. */ | ||
2983 | options |= VCO_END_OF_DATA; | ||
2984 | |||
2985 | retry = 0; | ||
2986 | do { | ||
2987 | memset(mn, 0, sizeof(*mn)); | ||
2988 | mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE; | ||
2989 | mn->p.req.entry_count = 1; | ||
2990 | mn->p.req.options = cpu_to_le16(options); | ||
2991 | |||
2992 | DEBUG16(printk("%s(%ld): Dump of Verify Request.\n", __func__, | ||
2993 | ha->host_no)); | ||
2994 | DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, | ||
2995 | sizeof(*mn))); | ||
2996 | |||
2997 | rval = qla2x00_issue_iocb_timeout(ha, mn, mn_dma, 0, 120); | ||
2998 | if (rval != QLA_SUCCESS) { | ||
2999 | DEBUG2_16(printk("%s(%ld): failed to issue Verify " | ||
3000 | "IOCB (%x).\n", __func__, ha->host_no, rval)); | ||
3001 | goto verify_done; | ||
3002 | } | ||
3003 | |||
3004 | DEBUG16(printk("%s(%ld): Dump of Verify Response.\n", __func__, | ||
3005 | ha->host_no)); | ||
3006 | DEBUG16(qla2x00_dump_buffer((uint8_t *)mn, | ||
3007 | sizeof(*mn))); | ||
3008 | |||
3009 | status[0] = le16_to_cpu(mn->p.rsp.comp_status); | ||
3010 | status[1] = status[0] == CS_VCS_CHIP_FAILURE ? | ||
3011 | le16_to_cpu(mn->p.rsp.failure_code) : 0; | ||
3012 | DEBUG2_16(printk("%s(%ld): cs=%x fc=%x\n", __func__, | ||
3013 | ha->host_no, status[0], status[1])); | ||
3014 | |||
3015 | if (status[0] != CS_COMPLETE) { | ||
3016 | rval = QLA_FUNCTION_FAILED; | ||
3017 | if (!(options & VCO_DONT_UPDATE_FW)) { | ||
3018 | DEBUG2_16(printk("%s(%ld): Firmware update " | ||
3019 | "failed. Retrying without update " | ||
3020 | "firmware.\n", __func__, ha->host_no)); | ||
3021 | options |= VCO_DONT_UPDATE_FW; | ||
3022 | options &= ~VCO_FORCE_UPDATE; | ||
3023 | retry = 1; | ||
3024 | } | ||
3025 | } else { | ||
3026 | DEBUG2_16(printk("%s(%ld): firmware updated to %x.\n", | ||
3027 | __func__, ha->host_no, | ||
3028 | le32_to_cpu(mn->p.rsp.fw_ver))); | ||
3029 | |||
3030 | /* NOTE: we only update OP firmware. */ | ||
3031 | spin_lock_irqsave(&ha->cs84xx->access_lock, flags); | ||
3032 | ha->cs84xx->op_fw_version = | ||
3033 | le32_to_cpu(mn->p.rsp.fw_ver); | ||
3034 | spin_unlock_irqrestore(&ha->cs84xx->access_lock, | ||
3035 | flags); | ||
3036 | } | ||
3037 | } while (retry); | ||
3038 | |||
3039 | verify_done: | ||
3040 | dma_pool_free(ha->s_dma_pool, mn, mn_dma); | ||
3041 | |||
3042 | if (rval != QLA_SUCCESS) { | ||
3043 | DEBUG2_16(printk("%s(%ld): failed=%x.\n", __func__, | ||
3044 | ha->host_no, rval)); | ||
3045 | } else { | ||
3046 | DEBUG16(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
3047 | } | ||
3048 | |||
3049 | return rval; | ||
3050 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index cf784cdafb01..f2b04979e5f0 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -1,20 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * QLOGIC LINUX SOFTWARE | 2 | * QLogic Fibre Channel HBA Driver |
3 | * | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * QLogic ISP2x00 device driver for Linux 2.6.x | ||
5 | * Copyright (C) 2003-2005 QLogic Corporation | ||
6 | * (www.qlogic.com) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2, or (at your option) any | ||
11 | * later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | ||
18 | */ | 6 | */ |
19 | #include "qla_def.h" | 7 | #include "qla_def.h" |
20 | 8 | ||
@@ -28,8 +16,6 @@ | |||
28 | #include <scsi/scsicam.h> | 16 | #include <scsi/scsicam.h> |
29 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
30 | 18 | ||
31 | void qla2x00_vp_stop_timer(scsi_qla_host_t *); | ||
32 | |||
33 | void | 19 | void |
34 | qla2x00_vp_stop_timer(scsi_qla_host_t *vha) | 20 | qla2x00_vp_stop_timer(scsi_qla_host_t *vha) |
35 | { | 21 | { |
@@ -268,9 +254,17 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha) | |||
268 | static int | 254 | static int |
269 | qla2x00_do_dpc_vp(scsi_qla_host_t *vha) | 255 | qla2x00_do_dpc_vp(scsi_qla_host_t *vha) |
270 | { | 256 | { |
257 | scsi_qla_host_t *ha = vha->parent; | ||
258 | |||
271 | if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { | 259 | if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) { |
272 | /* VP acquired. complete port configuration */ | 260 | /* VP acquired. complete port configuration */ |
273 | qla24xx_configure_vp(vha); | 261 | if (atomic_read(&ha->loop_state) == LOOP_READY) { |
262 | qla24xx_configure_vp(vha); | ||
263 | } else { | ||
264 | set_bit(VP_IDX_ACQUIRED, &vha->vp_flags); | ||
265 | set_bit(VP_DPC_NEEDED, &ha->dpc_flags); | ||
266 | } | ||
267 | |||
274 | return 0; | 268 | return 0; |
275 | } | 269 | } |
276 | 270 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 3c1b43356adb..8b33b163b1d4 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -26,9 +26,6 @@ char qla2x00_version_str[40]; | |||
26 | */ | 26 | */ |
27 | static struct kmem_cache *srb_cachep; | 27 | static struct kmem_cache *srb_cachep; |
28 | 28 | ||
29 | /* | ||
30 | * Ioctl related information. | ||
31 | */ | ||
32 | int num_hosts; | 29 | int num_hosts; |
33 | int ql2xlogintimeout = 20; | 30 | int ql2xlogintimeout = 20; |
34 | module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); | 31 | module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); |
@@ -103,9 +100,9 @@ static int qla24xx_queuecommand(struct scsi_cmnd *cmd, | |||
103 | void (*fn)(struct scsi_cmnd *)); | 100 | void (*fn)(struct scsi_cmnd *)); |
104 | static int qla2xxx_eh_abort(struct scsi_cmnd *); | 101 | static int qla2xxx_eh_abort(struct scsi_cmnd *); |
105 | static int qla2xxx_eh_device_reset(struct scsi_cmnd *); | 102 | static int qla2xxx_eh_device_reset(struct scsi_cmnd *); |
103 | static int qla2xxx_eh_target_reset(struct scsi_cmnd *); | ||
106 | static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); | 104 | static int qla2xxx_eh_bus_reset(struct scsi_cmnd *); |
107 | static int qla2xxx_eh_host_reset(struct scsi_cmnd *); | 105 | static int qla2xxx_eh_host_reset(struct scsi_cmnd *); |
108 | static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *); | ||
109 | 106 | ||
110 | static int qla2x00_change_queue_depth(struct scsi_device *, int); | 107 | static int qla2x00_change_queue_depth(struct scsi_device *, int); |
111 | static int qla2x00_change_queue_type(struct scsi_device *, int); | 108 | static int qla2x00_change_queue_type(struct scsi_device *, int); |
@@ -117,6 +114,7 @@ static struct scsi_host_template qla2x00_driver_template = { | |||
117 | 114 | ||
118 | .eh_abort_handler = qla2xxx_eh_abort, | 115 | .eh_abort_handler = qla2xxx_eh_abort, |
119 | .eh_device_reset_handler = qla2xxx_eh_device_reset, | 116 | .eh_device_reset_handler = qla2xxx_eh_device_reset, |
117 | .eh_target_reset_handler = qla2xxx_eh_target_reset, | ||
120 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, | 118 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, |
121 | .eh_host_reset_handler = qla2xxx_eh_host_reset, | 119 | .eh_host_reset_handler = qla2xxx_eh_host_reset, |
122 | 120 | ||
@@ -148,6 +146,7 @@ struct scsi_host_template qla24xx_driver_template = { | |||
148 | 146 | ||
149 | .eh_abort_handler = qla2xxx_eh_abort, | 147 | .eh_abort_handler = qla2xxx_eh_abort, |
150 | .eh_device_reset_handler = qla2xxx_eh_device_reset, | 148 | .eh_device_reset_handler = qla2xxx_eh_device_reset, |
149 | .eh_target_reset_handler = qla2xxx_eh_target_reset, | ||
151 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, | 150 | .eh_bus_reset_handler = qla2xxx_eh_bus_reset, |
152 | .eh_host_reset_handler = qla2xxx_eh_host_reset, | 151 | .eh_host_reset_handler = qla2xxx_eh_host_reset, |
153 | 152 | ||
@@ -253,9 +252,9 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str) | |||
253 | 252 | ||
254 | strcpy(str, "PCIe ("); | 253 | strcpy(str, "PCIe ("); |
255 | if (lspeed == 1) | 254 | if (lspeed == 1) |
256 | strcat(str, "2.5Gb/s "); | 255 | strcat(str, "2.5GT/s "); |
257 | else if (lspeed == 2) | 256 | else if (lspeed == 2) |
258 | strcat(str, "5.0Gb/s "); | 257 | strcat(str, "5.0GT/s "); |
259 | else | 258 | else |
260 | strcat(str, "<unknown> "); | 259 | strcat(str, "<unknown> "); |
261 | snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); | 260 | snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth); |
@@ -340,6 +339,8 @@ qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) | |||
340 | strcat(str, "[T10 CRC] "); | 339 | strcat(str, "[T10 CRC] "); |
341 | if (ha->fw_attributes & BIT_5) | 340 | if (ha->fw_attributes & BIT_5) |
342 | strcat(str, "[VI] "); | 341 | strcat(str, "[VI] "); |
342 | if (ha->fw_attributes & BIT_10) | ||
343 | strcat(str, "[84XX] "); | ||
343 | if (ha->fw_attributes & BIT_13) | 344 | if (ha->fw_attributes & BIT_13) |
344 | strcat(str, "[Experimental]"); | 345 | strcat(str, "[Experimental]"); |
345 | return str; | 346 | return str; |
@@ -570,8 +571,6 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha) | |||
570 | else | 571 | else |
571 | return_status = QLA_FUNCTION_FAILED; | 572 | return_status = QLA_FUNCTION_FAILED; |
572 | 573 | ||
573 | DEBUG2(printk("%s return_status=%d\n",__func__,return_status)); | ||
574 | |||
575 | return (return_status); | 574 | return (return_status); |
576 | } | 575 | } |
577 | 576 | ||
@@ -685,7 +684,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
685 | 684 | ||
686 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", | 685 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n", |
687 | __func__, ha->host_no, sp, serial)); | 686 | __func__, ha->host_no, sp, serial)); |
688 | DEBUG3(qla2x00_print_scsi_cmd(cmd)); | ||
689 | 687 | ||
690 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 688 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
691 | if (ha->isp_ops->abort_command(ha, sp)) { | 689 | if (ha->isp_ops->abort_command(ha, sp)) { |
@@ -719,190 +717,122 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
719 | return ret; | 717 | return ret; |
720 | } | 718 | } |
721 | 719 | ||
722 | /************************************************************************** | 720 | enum nexus_wait_type { |
723 | * qla2x00_eh_wait_for_pending_target_commands | 721 | WAIT_HOST = 0, |
724 | * | 722 | WAIT_TARGET, |
725 | * Description: | 723 | WAIT_LUN, |
726 | * Waits for all the commands to come back from the specified target. | 724 | }; |
727 | * | 725 | |
728 | * Input: | ||
729 | * ha - pointer to scsi_qla_host structure. | ||
730 | * t - target | ||
731 | * Returns: | ||
732 | * Either SUCCESS or FAILED. | ||
733 | * | ||
734 | * Note: | ||
735 | **************************************************************************/ | ||
736 | static int | 726 | static int |
737 | qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | 727 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t, |
728 | unsigned int l, enum nexus_wait_type type) | ||
738 | { | 729 | { |
739 | int cnt; | 730 | int cnt, match, status; |
740 | int status; | 731 | srb_t *sp; |
741 | srb_t *sp; | ||
742 | struct scsi_cmnd *cmd; | ||
743 | unsigned long flags; | 732 | unsigned long flags; |
744 | scsi_qla_host_t *pha = to_qla_parent(ha); | 733 | scsi_qla_host_t *pha = to_qla_parent(ha); |
745 | 734 | ||
746 | status = 0; | 735 | status = QLA_SUCCESS; |
747 | 736 | spin_lock_irqsave(&pha->hardware_lock, flags); | |
748 | /* | 737 | for (cnt = 1; status == QLA_SUCCESS && cnt < MAX_OUTSTANDING_COMMANDS; |
749 | * Waiting for all commands for the designated target in the active | 738 | cnt++) { |
750 | * array | ||
751 | */ | ||
752 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
753 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
754 | sp = pha->outstanding_cmds[cnt]; | 739 | sp = pha->outstanding_cmds[cnt]; |
755 | if (sp) { | 740 | if (!sp) |
756 | cmd = sp->cmd; | 741 | continue; |
757 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 742 | if (ha->vp_idx != sp->ha->vp_idx) |
758 | if (cmd->device->id == t && | 743 | continue; |
759 | ha->vp_idx == sp->ha->vp_idx) { | 744 | match = 0; |
760 | if (!qla2x00_eh_wait_on_command(ha, cmd)) { | 745 | switch (type) { |
761 | status = 1; | 746 | case WAIT_HOST: |
762 | break; | 747 | match = 1; |
763 | } | 748 | break; |
764 | } | 749 | case WAIT_TARGET: |
765 | } else { | 750 | match = sp->cmd->device->id == t; |
766 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | 751 | break; |
752 | case WAIT_LUN: | ||
753 | match = (sp->cmd->device->id == t && | ||
754 | sp->cmd->device->lun == l); | ||
755 | break; | ||
767 | } | 756 | } |
757 | if (!match) | ||
758 | continue; | ||
759 | |||
760 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | ||
761 | status = qla2x00_eh_wait_on_command(ha, sp->cmd); | ||
762 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
768 | } | 763 | } |
769 | return (status); | 764 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
765 | |||
766 | return status; | ||
770 | } | 767 | } |
771 | 768 | ||
769 | static char *reset_errors[] = { | ||
770 | "HBA not online", | ||
771 | "HBA not ready", | ||
772 | "Task management failed", | ||
773 | "Waiting for command completions", | ||
774 | }; | ||
772 | 775 | ||
773 | /************************************************************************** | ||
774 | * qla2xxx_eh_device_reset | ||
775 | * | ||
776 | * Description: | ||
777 | * The device reset function will reset the target and abort any | ||
778 | * executing commands. | ||
779 | * | ||
780 | * NOTE: The use of SP is undefined within this context. Do *NOT* | ||
781 | * attempt to use this value, even if you determine it is | ||
782 | * non-null. | ||
783 | * | ||
784 | * Input: | ||
785 | * cmd = Linux SCSI command packet of the command that cause the | ||
786 | * bus device reset. | ||
787 | * | ||
788 | * Returns: | ||
789 | * SUCCESS/FAILURE (defined as macro in scsi.h). | ||
790 | * | ||
791 | **************************************************************************/ | ||
792 | static int | 776 | static int |
793 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | 777 | __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type, |
778 | struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int)) | ||
794 | { | 779 | { |
795 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | 780 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
796 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 781 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
797 | int ret = FAILED; | 782 | int err; |
798 | unsigned int id, lun; | ||
799 | unsigned long serial; | ||
800 | 783 | ||
801 | qla2x00_block_error_handler(cmd); | 784 | qla2x00_block_error_handler(cmd); |
802 | 785 | ||
803 | id = cmd->device->id; | ||
804 | lun = cmd->device->lun; | ||
805 | serial = cmd->serial_number; | ||
806 | |||
807 | if (!fcport) | 786 | if (!fcport) |
808 | return ret; | 787 | return FAILED; |
809 | 788 | ||
810 | qla_printk(KERN_INFO, ha, | 789 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET ISSUED.\n", |
811 | "scsi(%ld:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, id, lun); | 790 | ha->host_no, cmd->device->id, cmd->device->lun, name); |
812 | 791 | ||
792 | err = 0; | ||
813 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) | 793 | if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) |
814 | goto eh_dev_reset_done; | 794 | goto eh_reset_failed; |
815 | 795 | err = 1; | |
816 | if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) { | 796 | if (qla2x00_wait_for_loop_ready(ha) != QLA_SUCCESS) |
817 | if (qla2x00_device_reset(ha, fcport) == 0) | 797 | goto eh_reset_failed; |
818 | ret = SUCCESS; | 798 | err = 2; |
819 | 799 | if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS) | |
820 | #if defined(LOGOUT_AFTER_DEVICE_RESET) | 800 | goto eh_reset_failed; |
821 | if (ret == SUCCESS) { | 801 | err = 3; |
822 | if (fcport->flags & FC_FABRIC_DEVICE) { | 802 | if (qla2x00_eh_wait_for_pending_commands(ha, cmd->device->id, |
823 | ha->isp_ops->fabric_logout(ha, fcport->loop_id); | 803 | cmd->device->lun, type) != QLA_SUCCESS) |
824 | qla2x00_mark_device_lost(ha, fcport, 0, 0); | 804 | goto eh_reset_failed; |
825 | } | 805 | |
826 | } | 806 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n", |
827 | #endif | 807 | ha->host_no, cmd->device->id, cmd->device->lun, name); |
828 | } else { | 808 | |
829 | DEBUG2(printk(KERN_INFO | 809 | return SUCCESS; |
830 | "%s failed: loop not ready\n",__func__)); | 810 | |
831 | } | 811 | eh_reset_failed: |
832 | 812 | qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n", | |
833 | if (ret == FAILED) { | 813 | ha->host_no, cmd->device->id, cmd->device->lun, name, |
834 | DEBUG3(printk("%s(%ld): device reset failed\n", | 814 | reset_errors[err]); |
835 | __func__, ha->host_no)); | 815 | return FAILED; |
836 | qla_printk(KERN_INFO, ha, "%s: device reset failed\n", | 816 | } |
837 | __func__); | ||
838 | 817 | ||
839 | goto eh_dev_reset_done; | 818 | static int |
840 | } | 819 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) |
820 | { | ||
821 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); | ||
841 | 822 | ||
842 | /* Flush outstanding commands. */ | 823 | return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd, |
843 | if (qla2x00_eh_wait_for_pending_target_commands(ha, id)) | 824 | ha->isp_ops->lun_reset); |
844 | ret = FAILED; | ||
845 | if (ret == FAILED) { | ||
846 | DEBUG3(printk("%s(%ld): failed while waiting for commands\n", | ||
847 | __func__, ha->host_no)); | ||
848 | qla_printk(KERN_INFO, ha, | ||
849 | "%s: failed while waiting for commands\n", __func__); | ||
850 | } else | ||
851 | qla_printk(KERN_INFO, ha, | ||
852 | "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no, | ||
853 | id, lun); | ||
854 | eh_dev_reset_done: | ||
855 | return ret; | ||
856 | } | 825 | } |
857 | 826 | ||
858 | /************************************************************************** | ||
859 | * qla2x00_eh_wait_for_pending_commands | ||
860 | * | ||
861 | * Description: | ||
862 | * Waits for all the commands to come back from the specified host. | ||
863 | * | ||
864 | * Input: | ||
865 | * ha - pointer to scsi_qla_host structure. | ||
866 | * | ||
867 | * Returns: | ||
868 | * 1 : SUCCESS | ||
869 | * 0 : FAILED | ||
870 | * | ||
871 | * Note: | ||
872 | **************************************************************************/ | ||
873 | static int | 827 | static int |
874 | qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) | 828 | qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) |
875 | { | 829 | { |
876 | int cnt; | 830 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
877 | int status; | ||
878 | srb_t *sp; | ||
879 | struct scsi_cmnd *cmd; | ||
880 | unsigned long flags; | ||
881 | |||
882 | status = 1; | ||
883 | 831 | ||
884 | /* | 832 | return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd, |
885 | * Waiting for all commands for the designated target in the active | 833 | ha->isp_ops->target_reset); |
886 | * array | ||
887 | */ | ||
888 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
889 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
890 | sp = ha->outstanding_cmds[cnt]; | ||
891 | if (sp) { | ||
892 | cmd = sp->cmd; | ||
893 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
894 | status = qla2x00_eh_wait_on_command(ha, cmd); | ||
895 | if (status == 0) | ||
896 | break; | ||
897 | } | ||
898 | else { | ||
899 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
900 | } | ||
901 | } | ||
902 | return (status); | ||
903 | } | 834 | } |
904 | 835 | ||
905 | |||
906 | /************************************************************************** | 836 | /************************************************************************** |
907 | * qla2xxx_eh_bus_reset | 837 | * qla2xxx_eh_bus_reset |
908 | * | 838 | * |
@@ -953,7 +883,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | |||
953 | goto eh_bus_reset_done; | 883 | goto eh_bus_reset_done; |
954 | 884 | ||
955 | /* Flush outstanding commands. */ | 885 | /* Flush outstanding commands. */ |
956 | if (!qla2x00_eh_wait_for_pending_commands(pha)) | 886 | if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) != |
887 | QLA_SUCCESS) | ||
957 | ret = FAILED; | 888 | ret = FAILED; |
958 | 889 | ||
959 | eh_bus_reset_done: | 890 | eh_bus_reset_done: |
@@ -1024,7 +955,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1024 | clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); | 955 | clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags); |
1025 | 956 | ||
1026 | /* Waiting for our command in done_queue to be returned to OS.*/ | 957 | /* Waiting for our command in done_queue to be returned to OS.*/ |
1027 | if (qla2x00_eh_wait_for_pending_commands(pha)) | 958 | if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) == |
959 | QLA_SUCCESS) | ||
1028 | ret = SUCCESS; | 960 | ret = SUCCESS; |
1029 | 961 | ||
1030 | if (ha->parent) | 962 | if (ha->parent) |
@@ -1080,7 +1012,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) | |||
1080 | if (fcport->port_type != FCT_TARGET) | 1012 | if (fcport->port_type != FCT_TARGET) |
1081 | continue; | 1013 | continue; |
1082 | 1014 | ||
1083 | ret = qla2x00_device_reset(ha, fcport); | 1015 | ret = ha->isp_ops->target_reset(fcport, 0); |
1084 | if (ret != QLA_SUCCESS) { | 1016 | if (ret != QLA_SUCCESS) { |
1085 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " | 1017 | DEBUG2_3(printk("%s(%ld): bus_reset failed: " |
1086 | "target_reset=%d d_id=%x.\n", __func__, | 1018 | "target_reset=%d d_id=%x.\n", __func__, |
@@ -1095,26 +1027,6 @@ qla2x00_loop_reset(scsi_qla_host_t *ha) | |||
1095 | return QLA_SUCCESS; | 1027 | return QLA_SUCCESS; |
1096 | } | 1028 | } |
1097 | 1029 | ||
1098 | /* | ||
1099 | * qla2x00_device_reset | ||
1100 | * Issue bus device reset message to the target. | ||
1101 | * | ||
1102 | * Input: | ||
1103 | * ha = adapter block pointer. | ||
1104 | * t = SCSI ID. | ||
1105 | * TARGET_QUEUE_LOCK must be released. | ||
1106 | * ADAPTER_STATE_LOCK must be released. | ||
1107 | * | ||
1108 | * Context: | ||
1109 | * Kernel context. | ||
1110 | */ | ||
1111 | static int | ||
1112 | qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport) | ||
1113 | { | ||
1114 | /* Abort Target command will clear Reservation */ | ||
1115 | return ha->isp_ops->abort_target(reset_fcport); | ||
1116 | } | ||
1117 | |||
1118 | void | 1030 | void |
1119 | qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res) | 1031 | qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res) |
1120 | { | 1032 | { |
@@ -1292,7 +1204,8 @@ static struct isp_operations qla2100_isp_ops = { | |||
1292 | .enable_intrs = qla2x00_enable_intrs, | 1204 | .enable_intrs = qla2x00_enable_intrs, |
1293 | .disable_intrs = qla2x00_disable_intrs, | 1205 | .disable_intrs = qla2x00_disable_intrs, |
1294 | .abort_command = qla2x00_abort_command, | 1206 | .abort_command = qla2x00_abort_command, |
1295 | .abort_target = qla2x00_abort_target, | 1207 | .target_reset = qla2x00_abort_target, |
1208 | .lun_reset = qla2x00_lun_reset, | ||
1296 | .fabric_login = qla2x00_login_fabric, | 1209 | .fabric_login = qla2x00_login_fabric, |
1297 | .fabric_logout = qla2x00_fabric_logout, | 1210 | .fabric_logout = qla2x00_fabric_logout, |
1298 | .calc_req_entries = qla2x00_calc_iocbs_32, | 1211 | .calc_req_entries = qla2x00_calc_iocbs_32, |
@@ -1325,7 +1238,8 @@ static struct isp_operations qla2300_isp_ops = { | |||
1325 | .enable_intrs = qla2x00_enable_intrs, | 1238 | .enable_intrs = qla2x00_enable_intrs, |
1326 | .disable_intrs = qla2x00_disable_intrs, | 1239 | .disable_intrs = qla2x00_disable_intrs, |
1327 | .abort_command = qla2x00_abort_command, | 1240 | .abort_command = qla2x00_abort_command, |
1328 | .abort_target = qla2x00_abort_target, | 1241 | .target_reset = qla2x00_abort_target, |
1242 | .lun_reset = qla2x00_lun_reset, | ||
1329 | .fabric_login = qla2x00_login_fabric, | 1243 | .fabric_login = qla2x00_login_fabric, |
1330 | .fabric_logout = qla2x00_fabric_logout, | 1244 | .fabric_logout = qla2x00_fabric_logout, |
1331 | .calc_req_entries = qla2x00_calc_iocbs_32, | 1245 | .calc_req_entries = qla2x00_calc_iocbs_32, |
@@ -1358,7 +1272,8 @@ static struct isp_operations qla24xx_isp_ops = { | |||
1358 | .enable_intrs = qla24xx_enable_intrs, | 1272 | .enable_intrs = qla24xx_enable_intrs, |
1359 | .disable_intrs = qla24xx_disable_intrs, | 1273 | .disable_intrs = qla24xx_disable_intrs, |
1360 | .abort_command = qla24xx_abort_command, | 1274 | .abort_command = qla24xx_abort_command, |
1361 | .abort_target = qla24xx_abort_target, | 1275 | .target_reset = qla24xx_abort_target, |
1276 | .lun_reset = qla24xx_lun_reset, | ||
1362 | .fabric_login = qla24xx_login_fabric, | 1277 | .fabric_login = qla24xx_login_fabric, |
1363 | .fabric_logout = qla24xx_fabric_logout, | 1278 | .fabric_logout = qla24xx_fabric_logout, |
1364 | .calc_req_entries = NULL, | 1279 | .calc_req_entries = NULL, |
@@ -1391,7 +1306,8 @@ static struct isp_operations qla25xx_isp_ops = { | |||
1391 | .enable_intrs = qla24xx_enable_intrs, | 1306 | .enable_intrs = qla24xx_enable_intrs, |
1392 | .disable_intrs = qla24xx_disable_intrs, | 1307 | .disable_intrs = qla24xx_disable_intrs, |
1393 | .abort_command = qla24xx_abort_command, | 1308 | .abort_command = qla24xx_abort_command, |
1394 | .abort_target = qla24xx_abort_target, | 1309 | .target_reset = qla24xx_abort_target, |
1310 | .lun_reset = qla24xx_lun_reset, | ||
1395 | .fabric_login = qla24xx_login_fabric, | 1311 | .fabric_login = qla24xx_login_fabric, |
1396 | .fabric_logout = qla24xx_fabric_logout, | 1312 | .fabric_logout = qla24xx_fabric_logout, |
1397 | .calc_req_entries = NULL, | 1313 | .calc_req_entries = NULL, |
@@ -1464,6 +1380,13 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha) | |||
1464 | ha->device_type |= DT_IIDMA; | 1380 | ha->device_type |= DT_IIDMA; |
1465 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | 1381 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
1466 | break; | 1382 | break; |
1383 | case PCI_DEVICE_ID_QLOGIC_ISP8432: | ||
1384 | ha->device_type |= DT_ISP8432; | ||
1385 | ha->device_type |= DT_ZIO_SUPPORTED; | ||
1386 | ha->device_type |= DT_FWI2; | ||
1387 | ha->device_type |= DT_IIDMA; | ||
1388 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | ||
1389 | break; | ||
1467 | case PCI_DEVICE_ID_QLOGIC_ISP5422: | 1390 | case PCI_DEVICE_ID_QLOGIC_ISP5422: |
1468 | ha->device_type |= DT_ISP5422; | 1391 | ha->device_type |= DT_ISP5422; |
1469 | ha->device_type |= DT_FWI2; | 1392 | ha->device_type |= DT_FWI2; |
@@ -1587,6 +1510,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1587 | sht = &qla2x00_driver_template; | 1510 | sht = &qla2x00_driver_template; |
1588 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || | 1511 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || |
1589 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || | 1512 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || |
1513 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 || | ||
1590 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || | 1514 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 || |
1591 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || | 1515 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 || |
1592 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { | 1516 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) { |
@@ -1677,7 +1601,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1677 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) | 1601 | if (IS_QLA2322(ha) || IS_QLA6322(ha)) |
1678 | ha->optrom_size = OPTROM_SIZE_2322; | 1602 | ha->optrom_size = OPTROM_SIZE_2322; |
1679 | ha->isp_ops = &qla2300_isp_ops; | 1603 | ha->isp_ops = &qla2300_isp_ops; |
1680 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 1604 | } else if (IS_QLA24XX_TYPE(ha)) { |
1681 | host->max_id = MAX_TARGETS_2200; | 1605 | host->max_id = MAX_TARGETS_2200; |
1682 | ha->mbx_count = MAILBOX_REGISTER_COUNT; | 1606 | ha->mbx_count = MAILBOX_REGISTER_COUNT; |
1683 | ha->request_q_length = REQUEST_ENTRY_CNT_24XX; | 1607 | ha->request_q_length = REQUEST_ENTRY_CNT_24XX; |
@@ -1699,6 +1623,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1699 | ha->gid_list_info_size = 8; | 1623 | ha->gid_list_info_size = 8; |
1700 | ha->optrom_size = OPTROM_SIZE_25XX; | 1624 | ha->optrom_size = OPTROM_SIZE_25XX; |
1701 | ha->isp_ops = &qla25xx_isp_ops; | 1625 | ha->isp_ops = &qla25xx_isp_ops; |
1626 | ha->hw_event_start = PCI_FUNC(pdev->devfn) ? | ||
1627 | FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR; | ||
1702 | } | 1628 | } |
1703 | host->can_queue = ha->request_q_length + 128; | 1629 | host->can_queue = ha->request_q_length + 128; |
1704 | 1630 | ||
@@ -1713,6 +1639,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1713 | INIT_LIST_HEAD(&ha->list); | 1639 | INIT_LIST_HEAD(&ha->list); |
1714 | INIT_LIST_HEAD(&ha->fcports); | 1640 | INIT_LIST_HEAD(&ha->fcports); |
1715 | INIT_LIST_HEAD(&ha->vp_list); | 1641 | INIT_LIST_HEAD(&ha->vp_list); |
1642 | INIT_LIST_HEAD(&ha->work_list); | ||
1716 | 1643 | ||
1717 | set_bit(0, (unsigned long *) ha->vp_idx_map); | 1644 | set_bit(0, (unsigned long *) ha->vp_idx_map); |
1718 | 1645 | ||
@@ -1819,6 +1746,8 @@ qla2x00_remove_one(struct pci_dev *pdev) | |||
1819 | 1746 | ||
1820 | qla2x00_dfs_remove(ha); | 1747 | qla2x00_dfs_remove(ha); |
1821 | 1748 | ||
1749 | qla84xx_put_chip(ha); | ||
1750 | |||
1822 | qla2x00_free_sysfs_attr(ha); | 1751 | qla2x00_free_sysfs_attr(ha); |
1823 | 1752 | ||
1824 | fc_remove_host(ha->host); | 1753 | fc_remove_host(ha->host); |
@@ -2206,6 +2135,97 @@ qla2x00_mem_free(scsi_qla_host_t *ha) | |||
2206 | kfree(ha->nvram); | 2135 | kfree(ha->nvram); |
2207 | } | 2136 | } |
2208 | 2137 | ||
2138 | struct qla_work_evt * | ||
2139 | qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type, | ||
2140 | int locked) | ||
2141 | { | ||
2142 | struct qla_work_evt *e; | ||
2143 | |||
2144 | e = kzalloc(sizeof(struct qla_work_evt), locked ? GFP_ATOMIC: | ||
2145 | GFP_KERNEL); | ||
2146 | if (!e) | ||
2147 | return NULL; | ||
2148 | |||
2149 | INIT_LIST_HEAD(&e->list); | ||
2150 | e->type = type; | ||
2151 | e->flags = QLA_EVT_FLAG_FREE; | ||
2152 | return e; | ||
2153 | } | ||
2154 | |||
2155 | int | ||
2156 | qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) | ||
2157 | { | ||
2158 | unsigned long flags; | ||
2159 | |||
2160 | if (!locked) | ||
2161 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
2162 | list_add_tail(&e->list, &ha->work_list); | ||
2163 | qla2xxx_wake_dpc(ha); | ||
2164 | if (!locked) | ||
2165 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
2166 | return QLA_SUCCESS; | ||
2167 | } | ||
2168 | |||
2169 | int | ||
2170 | qla2x00_post_aen_work(struct scsi_qla_host *ha, enum fc_host_event_code code, | ||
2171 | u32 data) | ||
2172 | { | ||
2173 | struct qla_work_evt *e; | ||
2174 | |||
2175 | e = qla2x00_alloc_work(ha, QLA_EVT_AEN, 1); | ||
2176 | if (!e) | ||
2177 | return QLA_FUNCTION_FAILED; | ||
2178 | |||
2179 | e->u.aen.code = code; | ||
2180 | e->u.aen.data = data; | ||
2181 | return qla2x00_post_work(ha, e, 1); | ||
2182 | } | ||
2183 | |||
2184 | int | ||
2185 | qla2x00_post_hwe_work(struct scsi_qla_host *ha, uint16_t code, uint16_t d1, | ||
2186 | uint16_t d2, uint16_t d3) | ||
2187 | { | ||
2188 | struct qla_work_evt *e; | ||
2189 | |||
2190 | e = qla2x00_alloc_work(ha, QLA_EVT_HWE_LOG, 1); | ||
2191 | if (!e) | ||
2192 | return QLA_FUNCTION_FAILED; | ||
2193 | |||
2194 | e->u.hwe.code = code; | ||
2195 | e->u.hwe.d1 = d1; | ||
2196 | e->u.hwe.d2 = d2; | ||
2197 | e->u.hwe.d3 = d3; | ||
2198 | return qla2x00_post_work(ha, e, 1); | ||
2199 | } | ||
2200 | |||
2201 | static void | ||
2202 | qla2x00_do_work(struct scsi_qla_host *ha) | ||
2203 | { | ||
2204 | struct qla_work_evt *e; | ||
2205 | |||
2206 | spin_lock_irq(&ha->hardware_lock); | ||
2207 | while (!list_empty(&ha->work_list)) { | ||
2208 | e = list_entry(ha->work_list.next, struct qla_work_evt, list); | ||
2209 | list_del_init(&e->list); | ||
2210 | spin_unlock_irq(&ha->hardware_lock); | ||
2211 | |||
2212 | switch (e->type) { | ||
2213 | case QLA_EVT_AEN: | ||
2214 | fc_host_post_event(ha->host, fc_get_event_number(), | ||
2215 | e->u.aen.code, e->u.aen.data); | ||
2216 | break; | ||
2217 | case QLA_EVT_HWE_LOG: | ||
2218 | qla2xxx_hw_event_log(ha, e->u.hwe.code, e->u.hwe.d1, | ||
2219 | e->u.hwe.d2, e->u.hwe.d3); | ||
2220 | break; | ||
2221 | } | ||
2222 | if (e->flags & QLA_EVT_FLAG_FREE) | ||
2223 | kfree(e); | ||
2224 | spin_lock_irq(&ha->hardware_lock); | ||
2225 | } | ||
2226 | spin_unlock_irq(&ha->hardware_lock); | ||
2227 | } | ||
2228 | |||
2209 | /************************************************************************** | 2229 | /************************************************************************** |
2210 | * qla2x00_do_dpc | 2230 | * qla2x00_do_dpc |
2211 | * This kernel thread is a task that is schedule by the interrupt handler | 2231 | * This kernel thread is a task that is schedule by the interrupt handler |
@@ -2257,6 +2277,8 @@ qla2x00_do_dpc(void *data) | |||
2257 | continue; | 2277 | continue; |
2258 | } | 2278 | } |
2259 | 2279 | ||
2280 | qla2x00_do_work(ha); | ||
2281 | |||
2260 | if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) { | 2282 | if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) { |
2261 | 2283 | ||
2262 | DEBUG(printk("scsi(%ld): dpc: sched " | 2284 | DEBUG(printk("scsi(%ld): dpc: sched " |
@@ -2291,12 +2313,6 @@ qla2x00_do_dpc(void *data) | |||
2291 | if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) | 2313 | if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) |
2292 | qla2x00_update_fcports(ha); | 2314 | qla2x00_update_fcports(ha); |
2293 | 2315 | ||
2294 | if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) { | ||
2295 | DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n", | ||
2296 | ha->host_no)); | ||
2297 | qla2x00_loop_reset(ha); | ||
2298 | } | ||
2299 | |||
2300 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && | 2316 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && |
2301 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { | 2317 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { |
2302 | 2318 | ||
@@ -2367,19 +2383,6 @@ qla2x00_do_dpc(void *data) | |||
2367 | ha->host_no)); | 2383 | ha->host_no)); |
2368 | } | 2384 | } |
2369 | 2385 | ||
2370 | if ((test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags)) && | ||
2371 | atomic_read(&ha->loop_state) != LOOP_DOWN) { | ||
2372 | |||
2373 | clear_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags); | ||
2374 | DEBUG(printk("scsi(%ld): qla2x00_login_retry()\n", | ||
2375 | ha->host_no)); | ||
2376 | |||
2377 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | ||
2378 | |||
2379 | DEBUG(printk("scsi(%ld): qla2x00_login_retry - end\n", | ||
2380 | ha->host_no)); | ||
2381 | } | ||
2382 | |||
2383 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { | 2386 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { |
2384 | 2387 | ||
2385 | DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n", | 2388 | DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n", |
@@ -2397,18 +2400,6 @@ qla2x00_do_dpc(void *data) | |||
2397 | ha->host_no)); | 2400 | ha->host_no)); |
2398 | } | 2401 | } |
2399 | 2402 | ||
2400 | if (test_and_clear_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags)) { | ||
2401 | |||
2402 | DEBUG(printk("scsi(%ld): Rescan flagged fcports...\n", | ||
2403 | ha->host_no)); | ||
2404 | |||
2405 | qla2x00_rescan_fcports(ha); | ||
2406 | |||
2407 | DEBUG(printk("scsi(%ld): Rescan flagged fcports..." | ||
2408 | "end.\n", | ||
2409 | ha->host_no)); | ||
2410 | } | ||
2411 | |||
2412 | if (!ha->interrupts_on) | 2403 | if (!ha->interrupts_on) |
2413 | ha->isp_ops->enable_intrs(ha); | 2404 | ha->isp_ops->enable_intrs(ha); |
2414 | 2405 | ||
@@ -2586,7 +2577,8 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2586 | set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags); | 2577 | set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags); |
2587 | start_dpc++; | 2578 | start_dpc++; |
2588 | 2579 | ||
2589 | if (!(ha->device_flags & DFLG_NO_CABLE)) { | 2580 | if (!(ha->device_flags & DFLG_NO_CABLE) && |
2581 | !ha->parent) { | ||
2590 | DEBUG(printk("scsi(%ld): Loop down - " | 2582 | DEBUG(printk("scsi(%ld): Loop down - " |
2591 | "aborting ISP.\n", | 2583 | "aborting ISP.\n", |
2592 | ha->host_no)); | 2584 | ha->host_no)); |
@@ -2610,10 +2602,8 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2610 | /* Schedule the DPC routine if needed */ | 2602 | /* Schedule the DPC routine if needed */ |
2611 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || | 2603 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || |
2612 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || | 2604 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || |
2613 | test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) || | ||
2614 | test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || | 2605 | test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || |
2615 | start_dpc || | 2606 | start_dpc || |
2616 | test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || | ||
2617 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || | 2607 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || |
2618 | test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || | 2608 | test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) || |
2619 | test_bit(VP_DPC_NEEDED, &ha->dpc_flags) || | 2609 | test_bit(VP_DPC_NEEDED, &ha->dpc_flags) || |
@@ -2665,7 +2655,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) | |||
2665 | blob = &qla_fw_blobs[FW_ISP2300]; | 2655 | blob = &qla_fw_blobs[FW_ISP2300]; |
2666 | } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) { | 2656 | } else if (IS_QLA2322(ha) || IS_QLA6322(ha)) { |
2667 | blob = &qla_fw_blobs[FW_ISP2322]; | 2657 | blob = &qla_fw_blobs[FW_ISP2322]; |
2668 | } else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { | 2658 | } else if (IS_QLA24XX_TYPE(ha)) { |
2669 | blob = &qla_fw_blobs[FW_ISP24XX]; | 2659 | blob = &qla_fw_blobs[FW_ISP24XX]; |
2670 | } else if (IS_QLA25XX(ha)) { | 2660 | } else if (IS_QLA25XX(ha)) { |
2671 | blob = &qla_fw_blobs[FW_ISP25XX]; | 2661 | blob = &qla_fw_blobs[FW_ISP25XX]; |
@@ -2815,6 +2805,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { | |||
2815 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) }, | 2805 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) }, |
2816 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) }, | 2806 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) }, |
2817 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, | 2807 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) }, |
2808 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8432) }, | ||
2818 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, | 2809 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) }, |
2819 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, | 2810 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) }, |
2820 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) }, | 2811 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) }, |
diff --git a/drivers/scsi/qla2xxx/qla_settings.h b/drivers/scsi/qla2xxx/qla_settings.h index 249e4d90fdc5..2801c2664b40 100644 --- a/drivers/scsi/qla2xxx/qla_settings.h +++ b/drivers/scsi/qla2xxx/qla_settings.h | |||
@@ -1,26 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | /* | ||
8 | * Compile time Options: | ||
9 | * 0 - Disable and 1 - Enable | ||
10 | */ | ||
11 | #define DEBUG_QLA2100 0 /* For Debug of qla2x00 */ | ||
12 | |||
13 | #define USE_ABORT_TGT 1 /* Use Abort Target mbx cmd */ | ||
14 | |||
15 | #define MAX_RETRIES_OF_ISP_ABORT 5 | 7 | #define MAX_RETRIES_OF_ISP_ABORT 5 |
16 | 8 | ||
17 | /* Max time to wait for the loop to be in LOOP_READY state */ | 9 | /* Max time to wait for the loop to be in LOOP_READY state */ |
18 | #define MAX_LOOP_TIMEOUT (60 * 5) | 10 | #define MAX_LOOP_TIMEOUT (60 * 5) |
19 | 11 | ||
20 | /* | ||
21 | * Some vendor subsystems do not recover properly after a device reset. Define | ||
22 | * the following to force a logout after a successful device reset. | ||
23 | */ | ||
24 | #undef LOGOUT_AFTER_DEVICE_RESET | ||
25 | |||
26 | #include "qla_version.h" | 12 | #include "qla_version.h" |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 26822c8807ee..1728ab3ccb20 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -543,79 +543,174 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, | |||
543 | } | 543 | } |
544 | } | 544 | } |
545 | 545 | ||
546 | static int | 546 | void |
547 | qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | 547 | qla2xxx_get_flash_info(scsi_qla_host_t *ha) |
548 | uint32_t dwords) | ||
549 | { | 548 | { |
550 | int ret; | 549 | #define FLASH_BLK_SIZE_32K 0x8000 |
551 | uint32_t liter, miter; | 550 | #define FLASH_BLK_SIZE_64K 0x10000 |
552 | uint32_t sec_mask, rest_addr, conf_addr; | 551 | uint16_t cnt, chksum; |
553 | uint32_t fdata, findex, cnt; | 552 | uint16_t *wptr; |
553 | struct qla_fdt_layout *fdt; | ||
554 | uint8_t man_id, flash_id; | 554 | uint8_t man_id, flash_id; |
555 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
556 | dma_addr_t optrom_dma; | ||
557 | void *optrom = NULL; | ||
558 | uint32_t *s, *d; | ||
559 | 555 | ||
560 | ret = QLA_SUCCESS; | 556 | if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) |
557 | return; | ||
561 | 558 | ||
562 | /* Prepare burst-capable write on supported ISPs. */ | 559 | wptr = (uint16_t *)ha->request_ring; |
563 | if (IS_QLA25XX(ha) && !(faddr & 0xfff) && | 560 | fdt = (struct qla_fdt_layout *)ha->request_ring; |
564 | dwords > OPTROM_BURST_DWORDS) { | 561 | ha->isp_ops->read_optrom(ha, (uint8_t *)ha->request_ring, |
565 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | 562 | FA_FLASH_DESCR_ADDR << 2, OPTROM_BURST_SIZE); |
566 | &optrom_dma, GFP_KERNEL); | 563 | if (*wptr == __constant_cpu_to_le16(0xffff)) |
567 | if (!optrom) { | 564 | goto no_flash_data; |
568 | qla_printk(KERN_DEBUG, ha, | 565 | if (fdt->sig[0] != 'Q' || fdt->sig[1] != 'L' || fdt->sig[2] != 'I' || |
569 | "Unable to allocate memory for optrom burst write " | 566 | fdt->sig[3] != 'D') |
570 | "(%x KB).\n", OPTROM_BURST_SIZE / 1024); | 567 | goto no_flash_data; |
571 | } | 568 | |
569 | for (cnt = 0, chksum = 0; cnt < sizeof(struct qla_fdt_layout) >> 1; | ||
570 | cnt++) | ||
571 | chksum += le16_to_cpu(*wptr++); | ||
572 | if (chksum) { | ||
573 | DEBUG2(qla_printk(KERN_INFO, ha, "Inconsistent FDT detected: " | ||
574 | "checksum=0x%x id=%c version=0x%x.\n", chksum, fdt->sig[0], | ||
575 | le16_to_cpu(fdt->version))); | ||
576 | DEBUG9(qla2x00_dump_buffer((uint8_t *)fdt, sizeof(*fdt))); | ||
577 | goto no_flash_data; | ||
572 | } | 578 | } |
573 | 579 | ||
574 | qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); | 580 | ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f; |
575 | DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__, | 581 | ha->fdt_wrt_disable = fdt->wrt_disable_bits; |
576 | ha->host_no, man_id, flash_id)); | 582 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd); |
583 | ha->fdt_block_size = le32_to_cpu(fdt->block_size); | ||
584 | if (fdt->unprotect_sec_cmd) { | ||
585 | ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0300 | | ||
586 | fdt->unprotect_sec_cmd); | ||
587 | ha->fdt_protect_sec_cmd = fdt->protect_sec_cmd ? | ||
588 | flash_conf_to_access_addr(0x0300 | fdt->protect_sec_cmd): | ||
589 | flash_conf_to_access_addr(0x0336); | ||
590 | } | ||
577 | 591 | ||
578 | conf_addr = flash_conf_to_access_addr(0x03d8); | 592 | DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x " |
593 | "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", | ||
594 | le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd, | ||
595 | ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd, | ||
596 | ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size)); | ||
597 | return; | ||
598 | |||
599 | no_flash_data: | ||
600 | qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); | ||
601 | ha->fdt_wrt_disable = 0x9c; | ||
602 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x03d8); | ||
579 | switch (man_id) { | 603 | switch (man_id) { |
580 | case 0xbf: /* STT flash. */ | 604 | case 0xbf: /* STT flash. */ |
581 | if (flash_id == 0x8e) { | 605 | if (flash_id == 0x8e) |
582 | rest_addr = 0x3fff; | 606 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
583 | sec_mask = 0x7c000; | 607 | else |
584 | } else { | 608 | ha->fdt_block_size = FLASH_BLK_SIZE_32K; |
585 | rest_addr = 0x1fff; | 609 | |
586 | sec_mask = 0x7e000; | ||
587 | } | ||
588 | if (flash_id == 0x80) | 610 | if (flash_id == 0x80) |
589 | conf_addr = flash_conf_to_access_addr(0x0352); | 611 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0352); |
590 | break; | 612 | break; |
591 | case 0x13: /* ST M25P80. */ | 613 | case 0x13: /* ST M25P80. */ |
592 | rest_addr = 0x3fff; | 614 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
593 | sec_mask = 0x7c000; | ||
594 | break; | 615 | break; |
595 | case 0x1f: // Atmel 26DF081A | 616 | case 0x1f: /* Atmel 26DF081A. */ |
596 | rest_addr = 0x3fff; | 617 | ha->fdt_odd_index = 1; |
597 | sec_mask = 0x7c000; | 618 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
598 | conf_addr = flash_conf_to_access_addr(0x0320); | 619 | ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320); |
620 | ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339); | ||
621 | ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336); | ||
599 | break; | 622 | break; |
600 | default: | 623 | default: |
601 | /* Default to 64 kb sector size. */ | 624 | /* Default to 64 kb sector size. */ |
602 | rest_addr = 0x3fff; | 625 | ha->fdt_block_size = FLASH_BLK_SIZE_64K; |
603 | sec_mask = 0x7c000; | ||
604 | break; | 626 | break; |
605 | } | 627 | } |
606 | 628 | ||
629 | DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x " | ||
630 | "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id, | ||
631 | ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd, | ||
632 | ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable, | ||
633 | ha->fdt_block_size)); | ||
634 | } | ||
635 | |||
636 | static void | ||
637 | qla24xx_unprotect_flash(scsi_qla_host_t *ha) | ||
638 | { | ||
639 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
640 | |||
607 | /* Enable flash write. */ | 641 | /* Enable flash write. */ |
608 | WRT_REG_DWORD(®->ctrl_status, | 642 | WRT_REG_DWORD(®->ctrl_status, |
609 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); | 643 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); |
610 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | 644 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ |
611 | 645 | ||
646 | if (!ha->fdt_wrt_disable) | ||
647 | return; | ||
648 | |||
612 | /* Disable flash write-protection. */ | 649 | /* Disable flash write-protection. */ |
613 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); | 650 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); |
614 | /* Some flash parts need an additional zero-write to clear bits.*/ | 651 | /* Some flash parts need an additional zero-write to clear bits.*/ |
615 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); | 652 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); |
653 | } | ||
654 | |||
655 | static void | ||
656 | qla24xx_protect_flash(scsi_qla_host_t *ha) | ||
657 | { | ||
658 | uint32_t cnt; | ||
659 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
660 | |||
661 | if (!ha->fdt_wrt_disable) | ||
662 | goto skip_wrt_protect; | ||
663 | |||
664 | /* Enable flash write-protection and wait for completion. */ | ||
665 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), | ||
666 | ha->fdt_wrt_disable); | ||
667 | for (cnt = 300; cnt && | ||
668 | qla24xx_read_flash_dword(ha, | ||
669 | flash_conf_to_access_addr(0x005)) & BIT_0; | ||
670 | cnt--) { | ||
671 | udelay(10); | ||
672 | } | ||
673 | |||
674 | skip_wrt_protect: | ||
675 | /* Disable flash write. */ | ||
676 | WRT_REG_DWORD(®->ctrl_status, | ||
677 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | ||
678 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | ||
679 | } | ||
680 | |||
681 | static int | ||
682 | qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | ||
683 | uint32_t dwords) | ||
684 | { | ||
685 | int ret; | ||
686 | uint32_t liter, miter; | ||
687 | uint32_t sec_mask, rest_addr; | ||
688 | uint32_t fdata, findex; | ||
689 | dma_addr_t optrom_dma; | ||
690 | void *optrom = NULL; | ||
691 | uint32_t *s, *d; | ||
692 | |||
693 | ret = QLA_SUCCESS; | ||
694 | |||
695 | /* Prepare burst-capable write on supported ISPs. */ | ||
696 | if (IS_QLA25XX(ha) && !(faddr & 0xfff) && | ||
697 | dwords > OPTROM_BURST_DWORDS) { | ||
698 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | ||
699 | &optrom_dma, GFP_KERNEL); | ||
700 | if (!optrom) { | ||
701 | qla_printk(KERN_DEBUG, ha, | ||
702 | "Unable to allocate memory for optrom burst write " | ||
703 | "(%x KB).\n", OPTROM_BURST_SIZE / 1024); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | rest_addr = (ha->fdt_block_size >> 2) - 1; | ||
708 | sec_mask = 0x80000 - (ha->fdt_block_size >> 2); | ||
709 | |||
710 | qla24xx_unprotect_flash(ha); | ||
616 | 711 | ||
617 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { | 712 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { |
618 | if (man_id == 0x1f) { | 713 | if (ha->fdt_odd_index) { |
619 | findex = faddr << 2; | 714 | findex = faddr << 2; |
620 | fdata = findex & sec_mask; | 715 | fdata = findex & sec_mask; |
621 | } else { | 716 | } else { |
@@ -625,13 +720,13 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
625 | 720 | ||
626 | /* Are we at the beginning of a sector? */ | 721 | /* Are we at the beginning of a sector? */ |
627 | if ((findex & rest_addr) == 0) { | 722 | if ((findex & rest_addr) == 0) { |
628 | /* Do sector unprotect at 4K boundry for Atmel part. */ | 723 | /* Do sector unprotect. */ |
629 | if (man_id == 0x1f) | 724 | if (ha->fdt_unprotect_sec_cmd) |
630 | qla24xx_write_flash_dword(ha, | 725 | qla24xx_write_flash_dword(ha, |
631 | flash_conf_to_access_addr(0x0339), | 726 | ha->fdt_unprotect_sec_cmd, |
632 | (fdata & 0xff00) | ((fdata << 16) & | 727 | (fdata & 0xff00) | ((fdata << 16) & |
633 | 0xff0000) | ((fdata >> 16) & 0xff)); | 728 | 0xff0000) | ((fdata >> 16) & 0xff)); |
634 | ret = qla24xx_write_flash_dword(ha, conf_addr, | 729 | ret = qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd, |
635 | (fdata & 0xff00) |((fdata << 16) & | 730 | (fdata & 0xff00) |((fdata << 16) & |
636 | 0xff0000) | ((fdata >> 16) & 0xff)); | 731 | 0xff0000) | ((fdata >> 16) & 0xff)); |
637 | if (ret != QLA_SUCCESS) { | 732 | if (ret != QLA_SUCCESS) { |
@@ -681,28 +776,16 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
681 | break; | 776 | break; |
682 | } | 777 | } |
683 | 778 | ||
684 | /* Do sector protect at 4K boundry for Atmel part. */ | 779 | /* Do sector protect. */ |
685 | if (man_id == 0x1f && | 780 | if (ha->fdt_unprotect_sec_cmd && |
686 | ((faddr & rest_addr) == rest_addr)) | 781 | ((faddr & rest_addr) == rest_addr)) |
687 | qla24xx_write_flash_dword(ha, | 782 | qla24xx_write_flash_dword(ha, |
688 | flash_conf_to_access_addr(0x0336), | 783 | ha->fdt_protect_sec_cmd, |
689 | (fdata & 0xff00) | ((fdata << 16) & | 784 | (fdata & 0xff00) | ((fdata << 16) & |
690 | 0xff0000) | ((fdata >> 16) & 0xff)); | 785 | 0xff0000) | ((fdata >> 16) & 0xff)); |
691 | } | 786 | } |
692 | 787 | ||
693 | /* Enable flash write-protection and wait for completion. */ | 788 | qla24xx_protect_flash(ha); |
694 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c); | ||
695 | for (cnt = 300; cnt && | ||
696 | qla24xx_read_flash_dword(ha, | ||
697 | flash_conf_to_access_addr(0x005)) & BIT_0; | ||
698 | cnt--) { | ||
699 | udelay(10); | ||
700 | } | ||
701 | |||
702 | /* Disable flash write. */ | ||
703 | WRT_REG_DWORD(®->ctrl_status, | ||
704 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | ||
705 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | ||
706 | 789 | ||
707 | if (optrom) | 790 | if (optrom) |
708 | dma_free_coherent(&ha->pdev->dev, | 791 | dma_free_coherent(&ha->pdev->dev, |
@@ -2221,3 +2304,107 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf) | |||
2221 | 2304 | ||
2222 | return ret; | 2305 | return ret; |
2223 | } | 2306 | } |
2307 | |||
2308 | static int | ||
2309 | qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata) | ||
2310 | { | ||
2311 | uint32_t d[2], faddr; | ||
2312 | |||
2313 | /* Locate first empty entry. */ | ||
2314 | for (;;) { | ||
2315 | if (ha->hw_event_ptr >= | ||
2316 | ha->hw_event_start + FA_HW_EVENT_SIZE) { | ||
2317 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2318 | "HW event -- Log Full!\n")); | ||
2319 | return QLA_MEMORY_ALLOC_FAILED; | ||
2320 | } | ||
2321 | |||
2322 | qla24xx_read_flash_data(ha, d, ha->hw_event_ptr, 2); | ||
2323 | faddr = flash_data_to_access_addr(ha->hw_event_ptr); | ||
2324 | ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE; | ||
2325 | if (d[0] == __constant_cpu_to_le32(0xffffffff) && | ||
2326 | d[1] == __constant_cpu_to_le32(0xffffffff)) { | ||
2327 | qla24xx_unprotect_flash(ha); | ||
2328 | |||
2329 | qla24xx_write_flash_dword(ha, faddr++, | ||
2330 | cpu_to_le32(jiffies)); | ||
2331 | qla24xx_write_flash_dword(ha, faddr++, 0); | ||
2332 | qla24xx_write_flash_dword(ha, faddr++, *fdata++); | ||
2333 | qla24xx_write_flash_dword(ha, faddr++, *fdata); | ||
2334 | |||
2335 | qla24xx_protect_flash(ha); | ||
2336 | break; | ||
2337 | } | ||
2338 | } | ||
2339 | return QLA_SUCCESS; | ||
2340 | } | ||
2341 | |||
2342 | int | ||
2343 | qla2xxx_hw_event_log(scsi_qla_host_t *ha, uint16_t code, uint16_t d1, | ||
2344 | uint16_t d2, uint16_t d3) | ||
2345 | { | ||
2346 | #define QMARK(a, b, c, d) \ | ||
2347 | cpu_to_le32(LSB(a) << 24 | LSB(b) << 16 | LSB(c) << 8 | LSB(d)) | ||
2348 | |||
2349 | int rval; | ||
2350 | uint32_t marker[2], fdata[4]; | ||
2351 | |||
2352 | if (ha->hw_event_start == 0) | ||
2353 | return QLA_FUNCTION_FAILED; | ||
2354 | |||
2355 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2356 | "HW event -- code=%x, d1=%x, d2=%x, d3=%x.\n", code, d1, d2, d3)); | ||
2357 | |||
2358 | /* If marker not already found, locate or write. */ | ||
2359 | if (!ha->flags.hw_event_marker_found) { | ||
2360 | /* Create marker. */ | ||
2361 | marker[0] = QMARK('L', ha->fw_major_version, | ||
2362 | ha->fw_minor_version, ha->fw_subminor_version); | ||
2363 | marker[1] = QMARK(QLA_DRIVER_MAJOR_VER, QLA_DRIVER_MINOR_VER, | ||
2364 | QLA_DRIVER_PATCH_VER, QLA_DRIVER_BETA_VER); | ||
2365 | |||
2366 | /* Locate marker. */ | ||
2367 | ha->hw_event_ptr = ha->hw_event_start; | ||
2368 | for (;;) { | ||
2369 | qla24xx_read_flash_data(ha, fdata, ha->hw_event_ptr, | ||
2370 | 4); | ||
2371 | if (fdata[0] == __constant_cpu_to_le32(0xffffffff) && | ||
2372 | fdata[1] == __constant_cpu_to_le32(0xffffffff)) | ||
2373 | break; | ||
2374 | ha->hw_event_ptr += FA_HW_EVENT_ENTRY_SIZE; | ||
2375 | if (ha->hw_event_ptr >= | ||
2376 | ha->hw_event_start + FA_HW_EVENT_SIZE) { | ||
2377 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2378 | "HW event -- Log Full!\n")); | ||
2379 | return QLA_MEMORY_ALLOC_FAILED; | ||
2380 | } | ||
2381 | if (fdata[2] == marker[0] && fdata[3] == marker[1]) { | ||
2382 | ha->flags.hw_event_marker_found = 1; | ||
2383 | break; | ||
2384 | } | ||
2385 | } | ||
2386 | /* No marker, write it. */ | ||
2387 | if (!ha->flags.hw_event_marker_found) { | ||
2388 | rval = qla2xxx_hw_event_store(ha, marker); | ||
2389 | if (rval != QLA_SUCCESS) { | ||
2390 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2391 | "HW event -- Failed marker write=%x.!\n", | ||
2392 | rval)); | ||
2393 | return rval; | ||
2394 | } | ||
2395 | ha->flags.hw_event_marker_found = 1; | ||
2396 | } | ||
2397 | } | ||
2398 | |||
2399 | /* Store error. */ | ||
2400 | fdata[0] = cpu_to_le32(code << 16 | d1); | ||
2401 | fdata[1] = cpu_to_le32(d2 << 16 | d3); | ||
2402 | rval = qla2xxx_hw_event_store(ha, fdata); | ||
2403 | if (rval != QLA_SUCCESS) { | ||
2404 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
2405 | "HW event -- Failed error write=%x.!\n", | ||
2406 | rval)); | ||
2407 | } | ||
2408 | |||
2409 | return rval; | ||
2410 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index ea08a129fee9..f42f17acf2cf 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -1,15 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2005 QLogic Corporation | 3 | * Copyright (c) 2003-2008 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.02.00-k9" | 10 | #define QLA2XXX_VERSION "8.02.01-k1" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 2 | 13 | #define QLA_DRIVER_MINOR_VER 2 |
14 | #define QLA_DRIVER_PATCH_VER 0 | 14 | #define QLA_DRIVER_PATCH_VER 1 |
15 | #define QLA_DRIVER_BETA_VER 0 | 15 | #define QLA_DRIVER_BETA_VER 0 |
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index fe415ec85655..1b667a70cffa 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h | |||
@@ -216,6 +216,7 @@ union external_hw_config_reg { | |||
216 | #define MBOX_CMD_ABOUT_FW 0x0009 | 216 | #define MBOX_CMD_ABOUT_FW 0x0009 |
217 | #define MBOX_CMD_PING 0x000B | 217 | #define MBOX_CMD_PING 0x000B |
218 | #define MBOX_CMD_LUN_RESET 0x0016 | 218 | #define MBOX_CMD_LUN_RESET 0x0016 |
219 | #define MBOX_CMD_TARGET_WARM_RESET 0x0017 | ||
219 | #define MBOX_CMD_GET_MANAGEMENT_DATA 0x001E | 220 | #define MBOX_CMD_GET_MANAGEMENT_DATA 0x001E |
220 | #define MBOX_CMD_GET_FW_STATUS 0x001F | 221 | #define MBOX_CMD_GET_FW_STATUS 0x001F |
221 | #define MBOX_CMD_SET_ISNS_SERVICE 0x0021 | 222 | #define MBOX_CMD_SET_ISNS_SERVICE 0x0021 |
@@ -677,7 +678,8 @@ struct qla4_marker_entry { | |||
677 | uint32_t system_defined; /* 04-07 */ | 678 | uint32_t system_defined; /* 04-07 */ |
678 | uint16_t target; /* 08-09 */ | 679 | uint16_t target; /* 08-09 */ |
679 | uint16_t modifier; /* 0A-0B */ | 680 | uint16_t modifier; /* 0A-0B */ |
680 | #define MM_LUN_RESET 0 | 681 | #define MM_LUN_RESET 0 |
682 | #define MM_TGT_WARM_RESET 1 | ||
681 | 683 | ||
682 | uint16_t flags; /* 0C-0D */ | 684 | uint16_t flags; /* 0C-0D */ |
683 | uint16_t reserved1; /* 0E-0F */ | 685 | uint16_t reserved1; /* 0E-0F */ |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index a3608e028bf6..96ebfb021f6c 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -27,6 +27,8 @@ int qla4xxx_relogin_device(struct scsi_qla_host * ha, | |||
27 | struct ddb_entry * ddb_entry); | 27 | struct ddb_entry * ddb_entry); |
28 | int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, | 28 | int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, |
29 | int lun); | 29 | int lun); |
30 | int qla4xxx_reset_target(struct scsi_qla_host * ha, | ||
31 | struct ddb_entry * ddb_entry); | ||
30 | int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, | 32 | int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, |
31 | uint32_t offset, uint32_t len); | 33 | uint32_t offset, uint32_t len); |
32 | int qla4xxx_get_firmware_status(struct scsi_qla_host * ha); | 34 | int qla4xxx_get_firmware_status(struct scsi_qla_host * ha); |
@@ -68,6 +70,8 @@ int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha); | |||
68 | int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, | 70 | int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, |
69 | uint32_t fw_ddb_index, uint32_t state); | 71 | uint32_t fw_ddb_index, uint32_t state); |
70 | void qla4xxx_dump_buffer(void *b, uint32_t size); | 72 | void qla4xxx_dump_buffer(void *b, uint32_t size); |
73 | int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, | ||
74 | struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod); | ||
71 | 75 | ||
72 | extern int ql4xextended_error_logging; | 76 | extern int ql4xextended_error_logging; |
73 | extern int ql4xdiscoverywait; | 77 | extern int ql4xdiscoverywait; |
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c index e4461b5d767a..912a67494adf 100644 --- a/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/drivers/scsi/qla4xxx/ql4_iocb.c | |||
@@ -66,8 +66,8 @@ static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, | |||
66 | * | 66 | * |
67 | * This routine issues a marker IOCB. | 67 | * This routine issues a marker IOCB. |
68 | **/ | 68 | **/ |
69 | static int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, | 69 | int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, |
70 | struct ddb_entry *ddb_entry, int lun) | 70 | struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod) |
71 | { | 71 | { |
72 | struct qla4_marker_entry *marker_entry; | 72 | struct qla4_marker_entry *marker_entry; |
73 | unsigned long flags = 0; | 73 | unsigned long flags = 0; |
@@ -87,7 +87,7 @@ static int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, | |||
87 | marker_entry->hdr.entryType = ET_MARKER; | 87 | marker_entry->hdr.entryType = ET_MARKER; |
88 | marker_entry->hdr.entryCount = 1; | 88 | marker_entry->hdr.entryCount = 1; |
89 | marker_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); | 89 | marker_entry->target = cpu_to_le16(ddb_entry->fw_ddb_index); |
90 | marker_entry->modifier = cpu_to_le16(MM_LUN_RESET); | 90 | marker_entry->modifier = cpu_to_le16(mrkr_mod); |
91 | int_to_scsilun(lun, &marker_entry->lun); | 91 | int_to_scsilun(lun, &marker_entry->lun); |
92 | wmb(); | 92 | wmb(); |
93 | 93 | ||
@@ -210,14 +210,6 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |||
210 | /* Get real lun and adapter */ | 210 | /* Get real lun and adapter */ |
211 | ddb_entry = srb->ddb; | 211 | ddb_entry = srb->ddb; |
212 | 212 | ||
213 | /* Send marker(s) if needed. */ | ||
214 | if (ha->marker_needed == 1) { | ||
215 | if (qla4xxx_send_marker_iocb(ha, ddb_entry, | ||
216 | cmd->device->lun) != QLA_SUCCESS) | ||
217 | return QLA_ERROR; | ||
218 | |||
219 | ha->marker_needed = 0; | ||
220 | } | ||
221 | tot_dsds = 0; | 213 | tot_dsds = 0; |
222 | 214 | ||
223 | /* Acquire hardware specific lock */ | 215 | /* Acquire hardware specific lock */ |
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index fc84db4069f4..a91a57c57bff 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c | |||
@@ -11,28 +11,6 @@ | |||
11 | #include "ql4_inline.h" | 11 | #include "ql4_inline.h" |
12 | 12 | ||
13 | /** | 13 | /** |
14 | * qla2x00_process_completed_request() - Process a Fast Post response. | ||
15 | * @ha: SCSI driver HA context | ||
16 | * @index: SRB index | ||
17 | **/ | ||
18 | static void qla4xxx_process_completed_request(struct scsi_qla_host *ha, | ||
19 | uint32_t index) | ||
20 | { | ||
21 | struct srb *srb; | ||
22 | |||
23 | srb = qla4xxx_del_from_active_array(ha, index); | ||
24 | if (srb) { | ||
25 | /* Save ISP completion status */ | ||
26 | srb->cmd->result = DID_OK << 16; | ||
27 | qla4xxx_srb_compl(ha, srb); | ||
28 | } else { | ||
29 | DEBUG2(printk("scsi%ld: Invalid ISP SCSI completion handle = " | ||
30 | "%d\n", ha->host_no, index)); | ||
31 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | ||
32 | } | ||
33 | } | ||
34 | |||
35 | /** | ||
36 | * qla4xxx_status_entry - processes status IOCBs | 14 | * qla4xxx_status_entry - processes status IOCBs |
37 | * @ha: Pointer to host adapter structure. | 15 | * @ha: Pointer to host adapter structure. |
38 | * @sts_entry: Pointer to status entry structure. | 16 | * @sts_entry: Pointer to status entry structure. |
@@ -47,14 +25,6 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
47 | uint32_t residual; | 25 | uint32_t residual; |
48 | uint16_t sensebytecnt; | 26 | uint16_t sensebytecnt; |
49 | 27 | ||
50 | if (sts_entry->completionStatus == SCS_COMPLETE && | ||
51 | sts_entry->scsiStatus == 0) { | ||
52 | qla4xxx_process_completed_request(ha, | ||
53 | le32_to_cpu(sts_entry-> | ||
54 | handle)); | ||
55 | return; | ||
56 | } | ||
57 | |||
58 | srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle)); | 28 | srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle)); |
59 | if (!srb) { | 29 | if (!srb) { |
60 | /* FIXMEdg: Don't we need to reset ISP in this case??? */ | 30 | /* FIXMEdg: Don't we need to reset ISP in this case??? */ |
@@ -62,6 +32,9 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
62 | "handle 0x%x, sp=%p. This cmd may have already " | 32 | "handle 0x%x, sp=%p. This cmd may have already " |
63 | "been completed.\n", ha->host_no, __func__, | 33 | "been completed.\n", ha->host_no, __func__, |
64 | le32_to_cpu(sts_entry->handle), srb)); | 34 | le32_to_cpu(sts_entry->handle), srb)); |
35 | dev_warn(&ha->pdev->dev, "%s invalid status entry:" | ||
36 | " handle=0x%0x\n", __func__, sts_entry->handle); | ||
37 | set_bit(DPC_RESET_HA, &ha->dpc_flags); | ||
65 | return; | 38 | return; |
66 | } | 39 | } |
67 | 40 | ||
@@ -88,10 +61,6 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
88 | scsi_status = sts_entry->scsiStatus; | 61 | scsi_status = sts_entry->scsiStatus; |
89 | switch (sts_entry->completionStatus) { | 62 | switch (sts_entry->completionStatus) { |
90 | case SCS_COMPLETE: | 63 | case SCS_COMPLETE: |
91 | if (scsi_status == 0) { | ||
92 | cmd->result = DID_OK << 16; | ||
93 | break; | ||
94 | } | ||
95 | 64 | ||
96 | if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) { | 65 | if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) { |
97 | cmd->result = DID_ERROR << 16; | 66 | cmd->result = DID_ERROR << 16; |
@@ -100,7 +69,8 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha, | |||
100 | 69 | ||
101 | if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) { | 70 | if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) { |
102 | scsi_set_resid(cmd, residual); | 71 | scsi_set_resid(cmd, residual); |
103 | if ((scsi_bufflen(cmd) - residual) < cmd->underflow) { | 72 | if (!scsi_status && ((scsi_bufflen(cmd) - residual) < |
73 | cmd->underflow)) { | ||
104 | 74 | ||
105 | cmd->result = DID_ERROR << 16; | 75 | cmd->result = DID_ERROR << 16; |
106 | 76 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index 35cd73c72a68..c577d79bd7e8 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -713,6 +713,45 @@ int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry, | |||
713 | return status; | 713 | return status; |
714 | } | 714 | } |
715 | 715 | ||
716 | /** | ||
717 | * qla4xxx_reset_target - issues target Reset | ||
718 | * @ha: Pointer to host adapter structure. | ||
719 | * @db_entry: Pointer to device database entry | ||
720 | * @un_entry: Pointer to lun entry structure | ||
721 | * | ||
722 | * This routine performs a TARGET RESET on the specified target. | ||
723 | * The caller must ensure that the ddb_entry pointers | ||
724 | * are valid before calling this routine. | ||
725 | **/ | ||
726 | int qla4xxx_reset_target(struct scsi_qla_host *ha, | ||
727 | struct ddb_entry *ddb_entry) | ||
728 | { | ||
729 | uint32_t mbox_cmd[MBOX_REG_COUNT]; | ||
730 | uint32_t mbox_sts[MBOX_REG_COUNT]; | ||
731 | int status = QLA_SUCCESS; | ||
732 | |||
733 | DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no, | ||
734 | ddb_entry->os_target_id)); | ||
735 | |||
736 | /* | ||
737 | * Send target reset command to ISP, so that the ISP will return all | ||
738 | * outstanding requests with RESET status | ||
739 | */ | ||
740 | memset(&mbox_cmd, 0, sizeof(mbox_cmd)); | ||
741 | memset(&mbox_sts, 0, sizeof(mbox_sts)); | ||
742 | |||
743 | mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET; | ||
744 | mbox_cmd[1] = ddb_entry->fw_ddb_index; | ||
745 | mbox_cmd[5] = 0x01; /* Immediate Command Enable */ | ||
746 | |||
747 | qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], | ||
748 | &mbox_sts[0]); | ||
749 | if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE && | ||
750 | mbox_sts[0] != MBOX_STS_COMMAND_ERROR) | ||
751 | status = QLA_ERROR; | ||
752 | |||
753 | return status; | ||
754 | } | ||
716 | 755 | ||
717 | int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, | 756 | int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr, |
718 | uint32_t offset, uint32_t len) | 757 | uint32_t offset, uint32_t len) |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 8b92f348f02c..0c786944d2c2 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -71,6 +71,7 @@ static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session); | |||
71 | static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, | 71 | static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, |
72 | void (*done) (struct scsi_cmnd *)); | 72 | void (*done) (struct scsi_cmnd *)); |
73 | static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd); | 73 | static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd); |
74 | static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd); | ||
74 | static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); | 75 | static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd); |
75 | static int qla4xxx_slave_alloc(struct scsi_device *device); | 76 | static int qla4xxx_slave_alloc(struct scsi_device *device); |
76 | static int qla4xxx_slave_configure(struct scsi_device *device); | 77 | static int qla4xxx_slave_configure(struct scsi_device *device); |
@@ -84,6 +85,7 @@ static struct scsi_host_template qla4xxx_driver_template = { | |||
84 | .queuecommand = qla4xxx_queuecommand, | 85 | .queuecommand = qla4xxx_queuecommand, |
85 | 86 | ||
86 | .eh_device_reset_handler = qla4xxx_eh_device_reset, | 87 | .eh_device_reset_handler = qla4xxx_eh_device_reset, |
88 | .eh_target_reset_handler = qla4xxx_eh_target_reset, | ||
87 | .eh_host_reset_handler = qla4xxx_eh_host_reset, | 89 | .eh_host_reset_handler = qla4xxx_eh_host_reset, |
88 | 90 | ||
89 | .slave_configure = qla4xxx_slave_configure, | 91 | .slave_configure = qla4xxx_slave_configure, |
@@ -1482,7 +1484,7 @@ static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) | |||
1482 | } | 1484 | } |
1483 | 1485 | ||
1484 | /** | 1486 | /** |
1485 | * qla4xxx_eh_wait_for_active_target_commands - wait for active cmds to finish. | 1487 | * qla4xxx_eh_wait_for_commands - wait for active cmds to finish. |
1486 | * @ha: pointer to to HBA | 1488 | * @ha: pointer to to HBA |
1487 | * @t: target id | 1489 | * @t: target id |
1488 | * @l: lun id | 1490 | * @l: lun id |
@@ -1490,20 +1492,22 @@ static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha) | |||
1490 | * This function waits for all outstanding commands to a lun to complete. It | 1492 | * This function waits for all outstanding commands to a lun to complete. It |
1491 | * returns 0 if all pending commands are returned and 1 otherwise. | 1493 | * returns 0 if all pending commands are returned and 1 otherwise. |
1492 | **/ | 1494 | **/ |
1493 | static int qla4xxx_eh_wait_for_active_target_commands(struct scsi_qla_host *ha, | 1495 | static int qla4xxx_eh_wait_for_commands(struct scsi_qla_host *ha, |
1494 | int t, int l) | 1496 | struct scsi_target *stgt, |
1497 | struct scsi_device *sdev) | ||
1495 | { | 1498 | { |
1496 | int cnt; | 1499 | int cnt; |
1497 | int status = 0; | 1500 | int status = 0; |
1498 | struct scsi_cmnd *cmd; | 1501 | struct scsi_cmnd *cmd; |
1499 | 1502 | ||
1500 | /* | 1503 | /* |
1501 | * Waiting for all commands for the designated target in the active | 1504 | * Waiting for all commands for the designated target or dev |
1502 | * array | 1505 | * in the active array |
1503 | */ | 1506 | */ |
1504 | for (cnt = 0; cnt < ha->host->can_queue; cnt++) { | 1507 | for (cnt = 0; cnt < ha->host->can_queue; cnt++) { |
1505 | cmd = scsi_host_find_tag(ha->host, cnt); | 1508 | cmd = scsi_host_find_tag(ha->host, cnt); |
1506 | if (cmd && cmd->device->id == t && cmd->device->lun == l) { | 1509 | if (cmd && stgt == scsi_target(cmd->device) && |
1510 | (!sdev || sdev == cmd->device)) { | ||
1507 | if (!qla4xxx_eh_wait_on_command(ha, cmd)) { | 1511 | if (!qla4xxx_eh_wait_on_command(ha, cmd)) { |
1508 | status++; | 1512 | status++; |
1509 | break; | 1513 | break; |
@@ -1548,24 +1552,19 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd) | |||
1548 | goto eh_dev_reset_done; | 1552 | goto eh_dev_reset_done; |
1549 | } | 1553 | } |
1550 | 1554 | ||
1551 | /* Send marker. */ | 1555 | if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device), |
1552 | ha->marker_needed = 1; | 1556 | cmd->device)) { |
1553 | 1557 | dev_info(&ha->pdev->dev, | |
1554 | /* | 1558 | "DEVICE RESET FAILED - waiting for " |
1555 | * If we are coming down the EH path, wait for all commands to complete | 1559 | "commands.\n"); |
1556 | * for the device. | 1560 | goto eh_dev_reset_done; |
1557 | */ | ||
1558 | if (cmd->device->host->shost_state == SHOST_RECOVERY) { | ||
1559 | if (qla4xxx_eh_wait_for_active_target_commands(ha, | ||
1560 | cmd->device->id, | ||
1561 | cmd->device->lun)){ | ||
1562 | dev_info(&ha->pdev->dev, | ||
1563 | "DEVICE RESET FAILED - waiting for " | ||
1564 | "commands.\n"); | ||
1565 | goto eh_dev_reset_done; | ||
1566 | } | ||
1567 | } | 1561 | } |
1568 | 1562 | ||
1563 | /* Send marker. */ | ||
1564 | if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun, | ||
1565 | MM_LUN_RESET) != QLA_SUCCESS) | ||
1566 | goto eh_dev_reset_done; | ||
1567 | |||
1569 | dev_info(&ha->pdev->dev, | 1568 | dev_info(&ha->pdev->dev, |
1570 | "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n", | 1569 | "scsi(%ld:%d:%d:%d): DEVICE RESET SUCCEEDED.\n", |
1571 | ha->host_no, cmd->device->channel, cmd->device->id, | 1570 | ha->host_no, cmd->device->channel, cmd->device->id, |
@@ -1579,6 +1578,59 @@ eh_dev_reset_done: | |||
1579 | } | 1578 | } |
1580 | 1579 | ||
1581 | /** | 1580 | /** |
1581 | * qla4xxx_eh_target_reset - callback for target reset. | ||
1582 | * @cmd: Pointer to Linux's SCSI command structure | ||
1583 | * | ||
1584 | * This routine is called by the Linux OS to reset the target. | ||
1585 | **/ | ||
1586 | static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd) | ||
1587 | { | ||
1588 | struct scsi_qla_host *ha = to_qla_host(cmd->device->host); | ||
1589 | struct ddb_entry *ddb_entry = cmd->device->hostdata; | ||
1590 | int stat; | ||
1591 | |||
1592 | if (!ddb_entry) | ||
1593 | return FAILED; | ||
1594 | |||
1595 | starget_printk(KERN_INFO, scsi_target(cmd->device), | ||
1596 | "WARM TARGET RESET ISSUED.\n"); | ||
1597 | |||
1598 | DEBUG2(printk(KERN_INFO | ||
1599 | "scsi%ld: TARGET_DEVICE_RESET cmd=%p jiffies = 0x%lx, " | ||
1600 | "to=%x,dpc_flags=%lx, status=%x allowed=%d\n", | ||
1601 | ha->host_no, cmd, jiffies, cmd->timeout_per_command / HZ, | ||
1602 | ha->dpc_flags, cmd->result, cmd->allowed)); | ||
1603 | |||
1604 | stat = qla4xxx_reset_target(ha, ddb_entry); | ||
1605 | if (stat != QLA_SUCCESS) { | ||
1606 | starget_printk(KERN_INFO, scsi_target(cmd->device), | ||
1607 | "WARM TARGET RESET FAILED.\n"); | ||
1608 | return FAILED; | ||
1609 | } | ||
1610 | |||
1611 | if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device), | ||
1612 | NULL)) { | ||
1613 | starget_printk(KERN_INFO, scsi_target(cmd->device), | ||
1614 | "WARM TARGET DEVICE RESET FAILED - " | ||
1615 | "waiting for commands.\n"); | ||
1616 | return FAILED; | ||
1617 | } | ||
1618 | |||
1619 | /* Send marker. */ | ||
1620 | if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun, | ||
1621 | MM_TGT_WARM_RESET) != QLA_SUCCESS) { | ||
1622 | starget_printk(KERN_INFO, scsi_target(cmd->device), | ||
1623 | "WARM TARGET DEVICE RESET FAILED - " | ||
1624 | "marker iocb failed.\n"); | ||
1625 | return FAILED; | ||
1626 | } | ||
1627 | |||
1628 | starget_printk(KERN_INFO, scsi_target(cmd->device), | ||
1629 | "WARM TARGET RESET SUCCEEDED.\n"); | ||
1630 | return SUCCESS; | ||
1631 | } | ||
1632 | |||
1633 | /** | ||
1582 | * qla4xxx_eh_host_reset - kernel callback | 1634 | * qla4xxx_eh_host_reset - kernel callback |
1583 | * @cmd: Pointer to Linux's SCSI command structure | 1635 | * @cmd: Pointer to Linux's SCSI command structure |
1584 | * | 1636 | * |
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c index 86e13183c9ba..52182a744ba6 100644 --- a/drivers/scsi/raid_class.c +++ b/drivers/scsi/raid_class.c | |||
@@ -289,7 +289,7 @@ raid_class_release(struct raid_template *r) | |||
289 | { | 289 | { |
290 | struct raid_internal *i = to_raid_internal(r); | 290 | struct raid_internal *i = to_raid_internal(r); |
291 | 291 | ||
292 | attribute_container_unregister(&i->r.raid_attrs.ac); | 292 | BUG_ON(attribute_container_unregister(&i->r.raid_attrs.ac)); |
293 | 293 | ||
294 | kfree(i); | 294 | kfree(i); |
295 | } | 295 | } |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c78b836f59dd..f6980bd9d8f9 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -166,6 +166,51 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { | |||
166 | static DEFINE_MUTEX(host_cmd_pool_mutex); | 166 | static DEFINE_MUTEX(host_cmd_pool_mutex); |
167 | 167 | ||
168 | /** | 168 | /** |
169 | * scsi_pool_alloc_command - internal function to get a fully allocated command | ||
170 | * @pool: slab pool to allocate the command from | ||
171 | * @gfp_mask: mask for the allocation | ||
172 | * | ||
173 | * Returns a fully allocated command (with the allied sense buffer) or | ||
174 | * NULL on failure | ||
175 | */ | ||
176 | static struct scsi_cmnd * | ||
177 | scsi_pool_alloc_command(struct scsi_host_cmd_pool *pool, gfp_t gfp_mask) | ||
178 | { | ||
179 | struct scsi_cmnd *cmd; | ||
180 | |||
181 | cmd = kmem_cache_alloc(pool->cmd_slab, gfp_mask | pool->gfp_mask); | ||
182 | if (!cmd) | ||
183 | return NULL; | ||
184 | |||
185 | memset(cmd, 0, sizeof(*cmd)); | ||
186 | |||
187 | cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab, | ||
188 | gfp_mask | pool->gfp_mask); | ||
189 | if (!cmd->sense_buffer) { | ||
190 | kmem_cache_free(pool->cmd_slab, cmd); | ||
191 | return NULL; | ||
192 | } | ||
193 | |||
194 | return cmd; | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * scsi_pool_free_command - internal function to release a command | ||
199 | * @pool: slab pool to allocate the command from | ||
200 | * @cmd: command to release | ||
201 | * | ||
202 | * the command must previously have been allocated by | ||
203 | * scsi_pool_alloc_command. | ||
204 | */ | ||
205 | static void | ||
206 | scsi_pool_free_command(struct scsi_host_cmd_pool *pool, | ||
207 | struct scsi_cmnd *cmd) | ||
208 | { | ||
209 | kmem_cache_free(pool->sense_slab, cmd->sense_buffer); | ||
210 | kmem_cache_free(pool->cmd_slab, cmd); | ||
211 | } | ||
212 | |||
213 | /** | ||
169 | * __scsi_get_command - Allocate a struct scsi_cmnd | 214 | * __scsi_get_command - Allocate a struct scsi_cmnd |
170 | * @shost: host to transmit command | 215 | * @shost: host to transmit command |
171 | * @gfp_mask: allocation mask | 216 | * @gfp_mask: allocation mask |
@@ -178,20 +223,7 @@ struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) | |||
178 | struct scsi_cmnd *cmd; | 223 | struct scsi_cmnd *cmd; |
179 | unsigned char *buf; | 224 | unsigned char *buf; |
180 | 225 | ||
181 | cmd = kmem_cache_alloc(shost->cmd_pool->cmd_slab, | 226 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); |
182 | gfp_mask | shost->cmd_pool->gfp_mask); | ||
183 | |||
184 | if (likely(cmd)) { | ||
185 | buf = kmem_cache_alloc(shost->cmd_pool->sense_slab, | ||
186 | gfp_mask | shost->cmd_pool->gfp_mask); | ||
187 | if (likely(buf)) { | ||
188 | memset(cmd, 0, sizeof(*cmd)); | ||
189 | cmd->sense_buffer = buf; | ||
190 | } else { | ||
191 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
192 | cmd = NULL; | ||
193 | } | ||
194 | } | ||
195 | 227 | ||
196 | if (unlikely(!cmd)) { | 228 | if (unlikely(!cmd)) { |
197 | unsigned long flags; | 229 | unsigned long flags; |
@@ -268,11 +300,8 @@ void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd, | |||
268 | } | 300 | } |
269 | spin_unlock_irqrestore(&shost->free_list_lock, flags); | 301 | spin_unlock_irqrestore(&shost->free_list_lock, flags); |
270 | 302 | ||
271 | if (likely(cmd != NULL)) { | 303 | if (likely(cmd != NULL)) |
272 | kmem_cache_free(shost->cmd_pool->sense_slab, | 304 | scsi_pool_free_command(shost->cmd_pool, cmd); |
273 | cmd->sense_buffer); | ||
274 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
275 | } | ||
276 | 305 | ||
277 | put_device(dev); | 306 | put_device(dev); |
278 | } | 307 | } |
@@ -301,30 +330,16 @@ void scsi_put_command(struct scsi_cmnd *cmd) | |||
301 | } | 330 | } |
302 | EXPORT_SYMBOL(scsi_put_command); | 331 | EXPORT_SYMBOL(scsi_put_command); |
303 | 332 | ||
304 | /** | 333 | static struct scsi_host_cmd_pool *scsi_get_host_cmd_pool(gfp_t gfp_mask) |
305 | * scsi_setup_command_freelist - Setup the command freelist for a scsi host. | ||
306 | * @shost: host to allocate the freelist for. | ||
307 | * | ||
308 | * Description: The command freelist protects against system-wide out of memory | ||
309 | * deadlock by preallocating one SCSI command structure for each host, so the | ||
310 | * system can always write to a swap file on a device associated with that host. | ||
311 | * | ||
312 | * Returns: Nothing. | ||
313 | */ | ||
314 | int scsi_setup_command_freelist(struct Scsi_Host *shost) | ||
315 | { | 334 | { |
316 | struct scsi_host_cmd_pool *pool; | 335 | struct scsi_host_cmd_pool *retval = NULL, *pool; |
317 | struct scsi_cmnd *cmd; | ||
318 | |||
319 | spin_lock_init(&shost->free_list_lock); | ||
320 | INIT_LIST_HEAD(&shost->free_list); | ||
321 | |||
322 | /* | 336 | /* |
323 | * Select a command slab for this host and create it if not | 337 | * Select a command slab for this host and create it if not |
324 | * yet existent. | 338 | * yet existent. |
325 | */ | 339 | */ |
326 | mutex_lock(&host_cmd_pool_mutex); | 340 | mutex_lock(&host_cmd_pool_mutex); |
327 | pool = (shost->unchecked_isa_dma ? &scsi_cmd_dma_pool : &scsi_cmd_pool); | 341 | pool = (gfp_mask & __GFP_DMA) ? &scsi_cmd_dma_pool : |
342 | &scsi_cmd_pool; | ||
328 | if (!pool->users) { | 343 | if (!pool->users) { |
329 | pool->cmd_slab = kmem_cache_create(pool->cmd_name, | 344 | pool->cmd_slab = kmem_cache_create(pool->cmd_name, |
330 | sizeof(struct scsi_cmnd), 0, | 345 | sizeof(struct scsi_cmnd), 0, |
@@ -342,37 +357,122 @@ int scsi_setup_command_freelist(struct Scsi_Host *shost) | |||
342 | } | 357 | } |
343 | 358 | ||
344 | pool->users++; | 359 | pool->users++; |
345 | shost->cmd_pool = pool; | 360 | retval = pool; |
361 | fail: | ||
346 | mutex_unlock(&host_cmd_pool_mutex); | 362 | mutex_unlock(&host_cmd_pool_mutex); |
363 | return retval; | ||
364 | } | ||
365 | |||
366 | static void scsi_put_host_cmd_pool(gfp_t gfp_mask) | ||
367 | { | ||
368 | struct scsi_host_cmd_pool *pool; | ||
347 | 369 | ||
370 | mutex_lock(&host_cmd_pool_mutex); | ||
371 | pool = (gfp_mask & __GFP_DMA) ? &scsi_cmd_dma_pool : | ||
372 | &scsi_cmd_pool; | ||
348 | /* | 373 | /* |
349 | * Get one backup command for this host. | 374 | * This may happen if a driver has a mismatched get and put |
375 | * of the command pool; the driver should be implicated in | ||
376 | * the stack trace | ||
350 | */ | 377 | */ |
351 | cmd = kmem_cache_alloc(shost->cmd_pool->cmd_slab, | 378 | BUG_ON(pool->users == 0); |
352 | GFP_KERNEL | shost->cmd_pool->gfp_mask); | ||
353 | if (!cmd) | ||
354 | goto fail2; | ||
355 | 379 | ||
356 | cmd->sense_buffer = kmem_cache_alloc(shost->cmd_pool->sense_slab, | ||
357 | GFP_KERNEL | | ||
358 | shost->cmd_pool->gfp_mask); | ||
359 | if (!cmd->sense_buffer) | ||
360 | goto fail2; | ||
361 | |||
362 | list_add(&cmd->list, &shost->free_list); | ||
363 | return 0; | ||
364 | |||
365 | fail2: | ||
366 | if (cmd) | ||
367 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
368 | mutex_lock(&host_cmd_pool_mutex); | ||
369 | if (!--pool->users) { | 380 | if (!--pool->users) { |
370 | kmem_cache_destroy(pool->cmd_slab); | 381 | kmem_cache_destroy(pool->cmd_slab); |
371 | kmem_cache_destroy(pool->sense_slab); | 382 | kmem_cache_destroy(pool->sense_slab); |
372 | } | 383 | } |
373 | fail: | ||
374 | mutex_unlock(&host_cmd_pool_mutex); | 384 | mutex_unlock(&host_cmd_pool_mutex); |
375 | return -ENOMEM; | 385 | } |
386 | |||
387 | /** | ||
388 | * scsi_allocate_command - get a fully allocated SCSI command | ||
389 | * @gfp_mask: allocation mask | ||
390 | * | ||
391 | * This function is for use outside of the normal host based pools. | ||
392 | * It allocates the relevant command and takes an additional reference | ||
393 | * on the pool it used. This function *must* be paired with | ||
394 | * scsi_free_command which also has the identical mask, otherwise the | ||
395 | * free pool counts will eventually go wrong and you'll trigger a bug. | ||
396 | * | ||
397 | * This function should *only* be used by drivers that need a static | ||
398 | * command allocation at start of day for internal functions. | ||
399 | */ | ||
400 | struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask) | ||
401 | { | ||
402 | struct scsi_host_cmd_pool *pool = scsi_get_host_cmd_pool(gfp_mask); | ||
403 | |||
404 | if (!pool) | ||
405 | return NULL; | ||
406 | |||
407 | return scsi_pool_alloc_command(pool, gfp_mask); | ||
408 | } | ||
409 | EXPORT_SYMBOL(scsi_allocate_command); | ||
410 | |||
411 | /** | ||
412 | * scsi_free_command - free a command allocated by scsi_allocate_command | ||
413 | * @gfp_mask: mask used in the original allocation | ||
414 | * @cmd: command to free | ||
415 | * | ||
416 | * Note: using the original allocation mask is vital because that's | ||
417 | * what determines which command pool we use to free the command. Any | ||
418 | * mismatch will cause the system to BUG eventually. | ||
419 | */ | ||
420 | void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd) | ||
421 | { | ||
422 | struct scsi_host_cmd_pool *pool = scsi_get_host_cmd_pool(gfp_mask); | ||
423 | |||
424 | /* | ||
425 | * this could trigger if the mask to scsi_allocate_command | ||
426 | * doesn't match this mask. Otherwise we're guaranteed that this | ||
427 | * succeeds because scsi_allocate_command must have taken a reference | ||
428 | * on the pool | ||
429 | */ | ||
430 | BUG_ON(!pool); | ||
431 | |||
432 | scsi_pool_free_command(pool, cmd); | ||
433 | /* | ||
434 | * scsi_put_host_cmd_pool is called twice; once to release the | ||
435 | * reference we took above, and once to release the reference | ||
436 | * originally taken by scsi_allocate_command | ||
437 | */ | ||
438 | scsi_put_host_cmd_pool(gfp_mask); | ||
439 | scsi_put_host_cmd_pool(gfp_mask); | ||
440 | } | ||
441 | EXPORT_SYMBOL(scsi_free_command); | ||
442 | |||
443 | /** | ||
444 | * scsi_setup_command_freelist - Setup the command freelist for a scsi host. | ||
445 | * @shost: host to allocate the freelist for. | ||
446 | * | ||
447 | * Description: The command freelist protects against system-wide out of memory | ||
448 | * deadlock by preallocating one SCSI command structure for each host, so the | ||
449 | * system can always write to a swap file on a device associated with that host. | ||
450 | * | ||
451 | * Returns: Nothing. | ||
452 | */ | ||
453 | int scsi_setup_command_freelist(struct Scsi_Host *shost) | ||
454 | { | ||
455 | struct scsi_cmnd *cmd; | ||
456 | const gfp_t gfp_mask = shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL; | ||
457 | |||
458 | spin_lock_init(&shost->free_list_lock); | ||
459 | INIT_LIST_HEAD(&shost->free_list); | ||
460 | |||
461 | shost->cmd_pool = scsi_get_host_cmd_pool(gfp_mask); | ||
462 | |||
463 | if (!shost->cmd_pool) | ||
464 | return -ENOMEM; | ||
465 | |||
466 | /* | ||
467 | * Get one backup command for this host. | ||
468 | */ | ||
469 | cmd = scsi_pool_alloc_command(shost->cmd_pool, gfp_mask); | ||
470 | if (!cmd) { | ||
471 | scsi_put_host_cmd_pool(gfp_mask); | ||
472 | return -ENOMEM; | ||
473 | } | ||
474 | list_add(&cmd->list, &shost->free_list); | ||
475 | return 0; | ||
376 | } | 476 | } |
377 | 477 | ||
378 | /** | 478 | /** |
@@ -386,17 +486,10 @@ void scsi_destroy_command_freelist(struct Scsi_Host *shost) | |||
386 | 486 | ||
387 | cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list); | 487 | cmd = list_entry(shost->free_list.next, struct scsi_cmnd, list); |
388 | list_del_init(&cmd->list); | 488 | list_del_init(&cmd->list); |
389 | kmem_cache_free(shost->cmd_pool->sense_slab, | 489 | scsi_pool_free_command(shost->cmd_pool, cmd); |
390 | cmd->sense_buffer); | ||
391 | kmem_cache_free(shost->cmd_pool->cmd_slab, cmd); | ||
392 | } | 490 | } |
393 | 491 | shost->cmd_pool = NULL; | |
394 | mutex_lock(&host_cmd_pool_mutex); | 492 | scsi_put_host_cmd_pool(shost->unchecked_isa_dma ? GFP_DMA : GFP_KERNEL); |
395 | if (!--shost->cmd_pool->users) { | ||
396 | kmem_cache_destroy(shost->cmd_pool->cmd_slab); | ||
397 | kmem_cache_destroy(shost->cmd_pool->sense_slab); | ||
398 | } | ||
399 | mutex_unlock(&host_cmd_pool_mutex); | ||
400 | } | 493 | } |
401 | 494 | ||
402 | #ifdef CONFIG_SCSI_LOGGING | 495 | #ifdef CONFIG_SCSI_LOGGING |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d1777a9a9625..07103c399fe0 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -39,16 +39,18 @@ | |||
39 | #include <linux/vmalloc.h> | 39 | #include <linux/vmalloc.h> |
40 | #include <linux/moduleparam.h> | 40 | #include <linux/moduleparam.h> |
41 | #include <linux/scatterlist.h> | 41 | #include <linux/scatterlist.h> |
42 | |||
43 | #include <linux/blkdev.h> | 42 | #include <linux/blkdev.h> |
44 | #include "scsi.h" | 43 | |
44 | #include <scsi/scsi.h> | ||
45 | #include <scsi/scsi_cmnd.h> | ||
46 | #include <scsi/scsi_device.h> | ||
45 | #include <scsi/scsi_host.h> | 47 | #include <scsi/scsi_host.h> |
46 | #include <scsi/scsicam.h> | 48 | #include <scsi/scsicam.h> |
49 | #include <scsi/scsi_eh.h> | ||
47 | 50 | ||
48 | #include <linux/stat.h> | 51 | #include <linux/stat.h> |
49 | 52 | ||
50 | #include "scsi_logging.h" | 53 | #include "scsi_logging.h" |
51 | #include "scsi_debug.h" | ||
52 | 54 | ||
53 | #define SCSI_DEBUG_VERSION "1.81" | 55 | #define SCSI_DEBUG_VERSION "1.81" |
54 | static const char * scsi_debug_version_date = "20070104"; | 56 | static const char * scsi_debug_version_date = "20070104"; |
@@ -146,7 +148,6 @@ static int scsi_debug_cmnd_count = 0; | |||
146 | #define DEV_READONLY(TGT) (0) | 148 | #define DEV_READONLY(TGT) (0) |
147 | #define DEV_REMOVEABLE(TGT) (0) | 149 | #define DEV_REMOVEABLE(TGT) (0) |
148 | 150 | ||
149 | static unsigned int sdebug_store_size; /* in bytes */ | ||
150 | static unsigned int sdebug_store_sectors; | 151 | static unsigned int sdebug_store_sectors; |
151 | static sector_t sdebug_capacity; /* in sectors */ | 152 | static sector_t sdebug_capacity; /* in sectors */ |
152 | 153 | ||
@@ -165,6 +166,9 @@ static int sdebug_sectors_per; /* sectors per cylinder */ | |||
165 | 166 | ||
166 | #define SDEBUG_SENSE_LEN 32 | 167 | #define SDEBUG_SENSE_LEN 32 |
167 | 168 | ||
169 | #define SCSI_DEBUG_CANQUEUE 255 | ||
170 | #define SCSI_DEBUG_MAX_CMD_LEN 16 | ||
171 | |||
168 | struct sdebug_dev_info { | 172 | struct sdebug_dev_info { |
169 | struct list_head dev_list; | 173 | struct list_head dev_list; |
170 | unsigned char sense_buff[SDEBUG_SENSE_LEN]; /* weak nexus */ | 174 | unsigned char sense_buff[SDEBUG_SENSE_LEN]; /* weak nexus */ |
@@ -202,30 +206,6 @@ struct sdebug_queued_cmd { | |||
202 | }; | 206 | }; |
203 | static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; | 207 | static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; |
204 | 208 | ||
205 | static struct scsi_host_template sdebug_driver_template = { | ||
206 | .proc_info = scsi_debug_proc_info, | ||
207 | .name = "SCSI DEBUG", | ||
208 | .info = scsi_debug_info, | ||
209 | .slave_alloc = scsi_debug_slave_alloc, | ||
210 | .slave_configure = scsi_debug_slave_configure, | ||
211 | .slave_destroy = scsi_debug_slave_destroy, | ||
212 | .ioctl = scsi_debug_ioctl, | ||
213 | .queuecommand = scsi_debug_queuecommand, | ||
214 | .eh_abort_handler = scsi_debug_abort, | ||
215 | .eh_bus_reset_handler = scsi_debug_bus_reset, | ||
216 | .eh_device_reset_handler = scsi_debug_device_reset, | ||
217 | .eh_host_reset_handler = scsi_debug_host_reset, | ||
218 | .bios_param = scsi_debug_biosparam, | ||
219 | .can_queue = SCSI_DEBUG_CANQUEUE, | ||
220 | .this_id = 7, | ||
221 | .sg_tablesize = 256, | ||
222 | .cmd_per_lun = 16, | ||
223 | .max_sectors = 0xffff, | ||
224 | .unchecked_isa_dma = 0, | ||
225 | .use_clustering = DISABLE_CLUSTERING, | ||
226 | .module = THIS_MODULE, | ||
227 | }; | ||
228 | |||
229 | static unsigned char * fake_storep; /* ramdisk storage */ | 209 | static unsigned char * fake_storep; /* ramdisk storage */ |
230 | 210 | ||
231 | static int num_aborts = 0; | 211 | static int num_aborts = 0; |
@@ -238,8 +218,6 @@ static DEFINE_RWLOCK(atomic_rw); | |||
238 | 218 | ||
239 | static char sdebug_proc_name[] = "scsi_debug"; | 219 | static char sdebug_proc_name[] = "scsi_debug"; |
240 | 220 | ||
241 | static int sdebug_driver_probe(struct device *); | ||
242 | static int sdebug_driver_remove(struct device *); | ||
243 | static struct bus_type pseudo_lld_bus; | 221 | static struct bus_type pseudo_lld_bus; |
244 | 222 | ||
245 | static struct device_driver sdebug_driverfs_driver = { | 223 | static struct device_driver sdebug_driverfs_driver = { |
@@ -255,94 +233,77 @@ static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | |||
255 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | 233 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, |
256 | 0, 0, 0x0, 0x0}; | 234 | 0, 0, 0x0, 0x0}; |
257 | 235 | ||
258 | /* function declarations */ | ||
259 | static int resp_inquiry(struct scsi_cmnd * SCpnt, int target, | ||
260 | struct sdebug_dev_info * devip); | ||
261 | static int resp_requests(struct scsi_cmnd * SCpnt, | ||
262 | struct sdebug_dev_info * devip); | ||
263 | static int resp_start_stop(struct scsi_cmnd * scp, | ||
264 | struct sdebug_dev_info * devip); | ||
265 | static int resp_report_tgtpgs(struct scsi_cmnd * scp, | ||
266 | struct sdebug_dev_info * devip); | ||
267 | static int resp_readcap(struct scsi_cmnd * SCpnt, | ||
268 | struct sdebug_dev_info * devip); | ||
269 | static int resp_readcap16(struct scsi_cmnd * SCpnt, | ||
270 | struct sdebug_dev_info * devip); | ||
271 | static int resp_mode_sense(struct scsi_cmnd * scp, int target, | ||
272 | struct sdebug_dev_info * devip); | ||
273 | static int resp_mode_select(struct scsi_cmnd * scp, int mselect6, | ||
274 | struct sdebug_dev_info * devip); | ||
275 | static int resp_log_sense(struct scsi_cmnd * scp, | ||
276 | struct sdebug_dev_info * devip); | ||
277 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
278 | unsigned int num, struct sdebug_dev_info * devip); | ||
279 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, | ||
280 | unsigned int num, struct sdebug_dev_info * devip); | ||
281 | static int resp_report_luns(struct scsi_cmnd * SCpnt, | ||
282 | struct sdebug_dev_info * devip); | ||
283 | static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, | ||
284 | unsigned int num, struct sdebug_dev_info *devip); | ||
285 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | ||
286 | int arr_len); | ||
287 | static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | ||
288 | int max_arr_len); | ||
289 | static void timer_intr_handler(unsigned long); | ||
290 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); | ||
291 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, | ||
292 | int asc, int asq); | ||
293 | static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, | ||
294 | struct sdebug_dev_info * devip); | ||
295 | static int schedule_resp(struct scsi_cmnd * cmnd, | ||
296 | struct sdebug_dev_info * devip, | ||
297 | done_funct_t done, int scsi_result, int delta_jiff); | ||
298 | static void __init sdebug_build_parts(unsigned char * ramp); | ||
299 | static void __init init_all_queued(void); | ||
300 | static void stop_all_queued(void); | ||
301 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd); | ||
302 | static int inquiry_evpd_83(unsigned char * arr, int port_group_id, | ||
303 | int target_dev_id, int dev_id_num, | ||
304 | const char * dev_id_str, int dev_id_str_len); | ||
305 | static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); | ||
306 | static int do_create_driverfs_files(void); | ||
307 | static void do_remove_driverfs_files(void); | ||
308 | |||
309 | static int sdebug_add_adapter(void); | 236 | static int sdebug_add_adapter(void); |
310 | static void sdebug_remove_adapter(void); | 237 | static void sdebug_remove_adapter(void); |
311 | static void sdebug_max_tgts_luns(void); | ||
312 | 238 | ||
313 | static struct device pseudo_primary; | 239 | static void sdebug_max_tgts_luns(void) |
314 | static struct bus_type pseudo_lld_bus; | 240 | { |
241 | struct sdebug_host_info *sdbg_host; | ||
242 | struct Scsi_Host *hpnt; | ||
243 | |||
244 | spin_lock(&sdebug_host_list_lock); | ||
245 | list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { | ||
246 | hpnt = sdbg_host->shost; | ||
247 | if ((hpnt->this_id >= 0) && | ||
248 | (scsi_debug_num_tgts > hpnt->this_id)) | ||
249 | hpnt->max_id = scsi_debug_num_tgts + 1; | ||
250 | else | ||
251 | hpnt->max_id = scsi_debug_num_tgts; | ||
252 | /* scsi_debug_max_luns; */ | ||
253 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; | ||
254 | } | ||
255 | spin_unlock(&sdebug_host_list_lock); | ||
256 | } | ||
257 | |||
258 | static void mk_sense_buffer(struct sdebug_dev_info *devip, int key, | ||
259 | int asc, int asq) | ||
260 | { | ||
261 | unsigned char *sbuff; | ||
262 | |||
263 | sbuff = devip->sense_buff; | ||
264 | memset(sbuff, 0, SDEBUG_SENSE_LEN); | ||
265 | |||
266 | scsi_build_sense_buffer(scsi_debug_dsense, sbuff, key, asc, asq); | ||
267 | |||
268 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
269 | printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: " | ||
270 | "[0x%x,0x%x,0x%x]\n", key, asc, asq); | ||
271 | } | ||
315 | 272 | ||
316 | static void get_data_transfer_info(unsigned char *cmd, | 273 | static void get_data_transfer_info(unsigned char *cmd, |
317 | unsigned long long *lba, unsigned int *num) | 274 | unsigned long long *lba, unsigned int *num) |
318 | { | 275 | { |
319 | int i; | ||
320 | |||
321 | switch (*cmd) { | 276 | switch (*cmd) { |
322 | case WRITE_16: | 277 | case WRITE_16: |
323 | case READ_16: | 278 | case READ_16: |
324 | for (*lba = 0, i = 0; i < 8; ++i) { | 279 | *lba = (u64)cmd[9] | (u64)cmd[8] << 8 | |
325 | if (i > 0) | 280 | (u64)cmd[7] << 16 | (u64)cmd[6] << 24 | |
326 | *lba <<= 8; | 281 | (u64)cmd[5] << 32 | (u64)cmd[4] << 40 | |
327 | *lba += cmd[2 + i]; | 282 | (u64)cmd[3] << 48 | (u64)cmd[2] << 56; |
328 | } | 283 | |
329 | *num = cmd[13] + (cmd[12] << 8) + | 284 | *num = (u32)cmd[13] | (u32)cmd[12] << 8 | (u32)cmd[11] << 16 | |
330 | (cmd[11] << 16) + (cmd[10] << 24); | 285 | (u32)cmd[10] << 24; |
331 | break; | 286 | break; |
332 | case WRITE_12: | 287 | case WRITE_12: |
333 | case READ_12: | 288 | case READ_12: |
334 | *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); | 289 | *lba = (u32)cmd[5] | (u32)cmd[4] << 8 | (u32)cmd[3] << 16 | |
335 | *num = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); | 290 | (u32)cmd[2] << 24; |
291 | |||
292 | *num = (u32)cmd[9] | (u32)cmd[8] << 8 | (u32)cmd[7] << 16 | | ||
293 | (u32)cmd[6] << 24; | ||
336 | break; | 294 | break; |
337 | case WRITE_10: | 295 | case WRITE_10: |
338 | case READ_10: | 296 | case READ_10: |
339 | case XDWRITEREAD_10: | 297 | case XDWRITEREAD_10: |
340 | *lba = cmd[5] + (cmd[4] << 8) + (cmd[3] << 16) + (cmd[2] << 24); | 298 | *lba = (u32)cmd[5] | (u32)cmd[4] << 8 | (u32)cmd[3] << 16 | |
341 | *num = cmd[8] + (cmd[7] << 8); | 299 | (u32)cmd[2] << 24; |
300 | |||
301 | *num = (u32)cmd[8] | (u32)cmd[7] << 8; | ||
342 | break; | 302 | break; |
343 | case WRITE_6: | 303 | case WRITE_6: |
344 | case READ_6: | 304 | case READ_6: |
345 | *lba = cmd[3] + (cmd[2] << 8) + ((cmd[1] & 0x1f) << 16); | 305 | *lba = (u32)cmd[3] | (u32)cmd[2] << 8 | |
306 | (u32)(cmd[1] & 0x1f) << 16; | ||
346 | *num = (0 == cmd[4]) ? 256 : cmd[4]; | 307 | *num = (0 == cmd[4]) ? 256 : cmd[4]; |
347 | break; | 308 | break; |
348 | default: | 309 | default: |
@@ -350,237 +311,6 @@ static void get_data_transfer_info(unsigned char *cmd, | |||
350 | } | 311 | } |
351 | } | 312 | } |
352 | 313 | ||
353 | static | ||
354 | int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done) | ||
355 | { | ||
356 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; | ||
357 | int len, k; | ||
358 | unsigned int num; | ||
359 | unsigned long long lba; | ||
360 | int errsts = 0; | ||
361 | int target = SCpnt->device->id; | ||
362 | struct sdebug_dev_info * devip = NULL; | ||
363 | int inj_recovered = 0; | ||
364 | int inj_transport = 0; | ||
365 | int delay_override = 0; | ||
366 | |||
367 | if (done == NULL) | ||
368 | return 0; /* assume mid level reprocessing command */ | ||
369 | |||
370 | scsi_set_resid(SCpnt, 0); | ||
371 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { | ||
372 | printk(KERN_INFO "scsi_debug: cmd "); | ||
373 | for (k = 0, len = SCpnt->cmd_len; k < len; ++k) | ||
374 | printk("%02x ", (int)cmd[k]); | ||
375 | printk("\n"); | ||
376 | } | ||
377 | if(target == sdebug_driver_template.this_id) { | ||
378 | printk(KERN_INFO "scsi_debug: initiator's id used as " | ||
379 | "target!\n"); | ||
380 | return schedule_resp(SCpnt, NULL, done, | ||
381 | DID_NO_CONNECT << 16, 0); | ||
382 | } | ||
383 | |||
384 | if ((SCpnt->device->lun >= scsi_debug_max_luns) && | ||
385 | (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) | ||
386 | return schedule_resp(SCpnt, NULL, done, | ||
387 | DID_NO_CONNECT << 16, 0); | ||
388 | devip = devInfoReg(SCpnt->device); | ||
389 | if (NULL == devip) | ||
390 | return schedule_resp(SCpnt, NULL, done, | ||
391 | DID_NO_CONNECT << 16, 0); | ||
392 | |||
393 | if ((scsi_debug_every_nth != 0) && | ||
394 | (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) { | ||
395 | scsi_debug_cmnd_count = 0; | ||
396 | if (scsi_debug_every_nth < -1) | ||
397 | scsi_debug_every_nth = -1; | ||
398 | if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts) | ||
399 | return 0; /* ignore command causing timeout */ | ||
400 | else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts) | ||
401 | inj_recovered = 1; /* to reads and writes below */ | ||
402 | else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts) | ||
403 | inj_transport = 1; /* to reads and writes below */ | ||
404 | } | ||
405 | |||
406 | if (devip->wlun) { | ||
407 | switch (*cmd) { | ||
408 | case INQUIRY: | ||
409 | case REQUEST_SENSE: | ||
410 | case TEST_UNIT_READY: | ||
411 | case REPORT_LUNS: | ||
412 | break; /* only allowable wlun commands */ | ||
413 | default: | ||
414 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
415 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x " | ||
416 | "not supported for wlun\n", *cmd); | ||
417 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
418 | INVALID_OPCODE, 0); | ||
419 | errsts = check_condition_result; | ||
420 | return schedule_resp(SCpnt, devip, done, errsts, | ||
421 | 0); | ||
422 | } | ||
423 | } | ||
424 | |||
425 | switch (*cmd) { | ||
426 | case INQUIRY: /* mandatory, ignore unit attention */ | ||
427 | delay_override = 1; | ||
428 | errsts = resp_inquiry(SCpnt, target, devip); | ||
429 | break; | ||
430 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ | ||
431 | delay_override = 1; | ||
432 | errsts = resp_requests(SCpnt, devip); | ||
433 | break; | ||
434 | case REZERO_UNIT: /* actually this is REWIND for SSC */ | ||
435 | case START_STOP: | ||
436 | errsts = resp_start_stop(SCpnt, devip); | ||
437 | break; | ||
438 | case ALLOW_MEDIUM_REMOVAL: | ||
439 | if ((errsts = check_readiness(SCpnt, 1, devip))) | ||
440 | break; | ||
441 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
442 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", | ||
443 | cmd[4] ? "inhibited" : "enabled"); | ||
444 | break; | ||
445 | case SEND_DIAGNOSTIC: /* mandatory */ | ||
446 | errsts = check_readiness(SCpnt, 1, devip); | ||
447 | break; | ||
448 | case TEST_UNIT_READY: /* mandatory */ | ||
449 | delay_override = 1; | ||
450 | errsts = check_readiness(SCpnt, 0, devip); | ||
451 | break; | ||
452 | case RESERVE: | ||
453 | errsts = check_readiness(SCpnt, 1, devip); | ||
454 | break; | ||
455 | case RESERVE_10: | ||
456 | errsts = check_readiness(SCpnt, 1, devip); | ||
457 | break; | ||
458 | case RELEASE: | ||
459 | errsts = check_readiness(SCpnt, 1, devip); | ||
460 | break; | ||
461 | case RELEASE_10: | ||
462 | errsts = check_readiness(SCpnt, 1, devip); | ||
463 | break; | ||
464 | case READ_CAPACITY: | ||
465 | errsts = resp_readcap(SCpnt, devip); | ||
466 | break; | ||
467 | case SERVICE_ACTION_IN: | ||
468 | if (SAI_READ_CAPACITY_16 != cmd[1]) { | ||
469 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
470 | INVALID_OPCODE, 0); | ||
471 | errsts = check_condition_result; | ||
472 | break; | ||
473 | } | ||
474 | errsts = resp_readcap16(SCpnt, devip); | ||
475 | break; | ||
476 | case MAINTENANCE_IN: | ||
477 | if (MI_REPORT_TARGET_PGS != cmd[1]) { | ||
478 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
479 | INVALID_OPCODE, 0); | ||
480 | errsts = check_condition_result; | ||
481 | break; | ||
482 | } | ||
483 | errsts = resp_report_tgtpgs(SCpnt, devip); | ||
484 | break; | ||
485 | case READ_16: | ||
486 | case READ_12: | ||
487 | case READ_10: | ||
488 | case READ_6: | ||
489 | if ((errsts = check_readiness(SCpnt, 0, devip))) | ||
490 | break; | ||
491 | if (scsi_debug_fake_rw) | ||
492 | break; | ||
493 | get_data_transfer_info(cmd, &lba, &num); | ||
494 | errsts = resp_read(SCpnt, lba, num, devip); | ||
495 | if (inj_recovered && (0 == errsts)) { | ||
496 | mk_sense_buffer(devip, RECOVERED_ERROR, | ||
497 | THRESHOLD_EXCEEDED, 0); | ||
498 | errsts = check_condition_result; | ||
499 | } else if (inj_transport && (0 == errsts)) { | ||
500 | mk_sense_buffer(devip, ABORTED_COMMAND, | ||
501 | TRANSPORT_PROBLEM, ACK_NAK_TO); | ||
502 | errsts = check_condition_result; | ||
503 | } | ||
504 | break; | ||
505 | case REPORT_LUNS: /* mandatory, ignore unit attention */ | ||
506 | delay_override = 1; | ||
507 | errsts = resp_report_luns(SCpnt, devip); | ||
508 | break; | ||
509 | case VERIFY: /* 10 byte SBC-2 command */ | ||
510 | errsts = check_readiness(SCpnt, 0, devip); | ||
511 | break; | ||
512 | case WRITE_16: | ||
513 | case WRITE_12: | ||
514 | case WRITE_10: | ||
515 | case WRITE_6: | ||
516 | if ((errsts = check_readiness(SCpnt, 0, devip))) | ||
517 | break; | ||
518 | if (scsi_debug_fake_rw) | ||
519 | break; | ||
520 | get_data_transfer_info(cmd, &lba, &num); | ||
521 | errsts = resp_write(SCpnt, lba, num, devip); | ||
522 | if (inj_recovered && (0 == errsts)) { | ||
523 | mk_sense_buffer(devip, RECOVERED_ERROR, | ||
524 | THRESHOLD_EXCEEDED, 0); | ||
525 | errsts = check_condition_result; | ||
526 | } | ||
527 | break; | ||
528 | case MODE_SENSE: | ||
529 | case MODE_SENSE_10: | ||
530 | errsts = resp_mode_sense(SCpnt, target, devip); | ||
531 | break; | ||
532 | case MODE_SELECT: | ||
533 | errsts = resp_mode_select(SCpnt, 1, devip); | ||
534 | break; | ||
535 | case MODE_SELECT_10: | ||
536 | errsts = resp_mode_select(SCpnt, 0, devip); | ||
537 | break; | ||
538 | case LOG_SENSE: | ||
539 | errsts = resp_log_sense(SCpnt, devip); | ||
540 | break; | ||
541 | case SYNCHRONIZE_CACHE: | ||
542 | delay_override = 1; | ||
543 | errsts = check_readiness(SCpnt, 0, devip); | ||
544 | break; | ||
545 | case WRITE_BUFFER: | ||
546 | errsts = check_readiness(SCpnt, 1, devip); | ||
547 | break; | ||
548 | case XDWRITEREAD_10: | ||
549 | if (!scsi_bidi_cmnd(SCpnt)) { | ||
550 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
551 | INVALID_FIELD_IN_CDB, 0); | ||
552 | errsts = check_condition_result; | ||
553 | break; | ||
554 | } | ||
555 | |||
556 | errsts = check_readiness(SCpnt, 0, devip); | ||
557 | if (errsts) | ||
558 | break; | ||
559 | if (scsi_debug_fake_rw) | ||
560 | break; | ||
561 | get_data_transfer_info(cmd, &lba, &num); | ||
562 | errsts = resp_read(SCpnt, lba, num, devip); | ||
563 | if (errsts) | ||
564 | break; | ||
565 | errsts = resp_write(SCpnt, lba, num, devip); | ||
566 | if (errsts) | ||
567 | break; | ||
568 | errsts = resp_xdwriteread(SCpnt, lba, num, devip); | ||
569 | break; | ||
570 | default: | ||
571 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
572 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | ||
573 | "supported\n", *cmd); | ||
574 | if ((errsts = check_readiness(SCpnt, 1, devip))) | ||
575 | break; /* Unit attention takes precedence */ | ||
576 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); | ||
577 | errsts = check_condition_result; | ||
578 | break; | ||
579 | } | ||
580 | return schedule_resp(SCpnt, devip, done, errsts, | ||
581 | (delay_override ? 0 : scsi_debug_delay)); | ||
582 | } | ||
583 | |||
584 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) | 314 | static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) |
585 | { | 315 | { |
586 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { | 316 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { |
@@ -613,81 +343,37 @@ static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only, | |||
613 | } | 343 | } |
614 | 344 | ||
615 | /* Returns 0 if ok else (DID_ERROR << 16). Sets scp->resid . */ | 345 | /* Returns 0 if ok else (DID_ERROR << 16). Sets scp->resid . */ |
616 | static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | 346 | static int fill_from_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr, |
617 | int arr_len) | 347 | int arr_len) |
618 | { | 348 | { |
619 | int k, req_len, act_len, len, active; | 349 | int act_len; |
620 | void * kaddr; | ||
621 | void * kaddr_off; | ||
622 | struct scatterlist *sg; | ||
623 | struct scsi_data_buffer *sdb = scsi_in(scp); | 350 | struct scsi_data_buffer *sdb = scsi_in(scp); |
624 | 351 | ||
625 | if (!sdb->length) | 352 | if (!sdb->length) |
626 | return 0; | 353 | return 0; |
627 | if (!sdb->table.sgl) | ||
628 | return (DID_ERROR << 16); | ||
629 | if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE)) | 354 | if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE)) |
630 | return (DID_ERROR << 16); | 355 | return (DID_ERROR << 16); |
631 | active = 1; | 356 | |
632 | req_len = act_len = 0; | 357 | act_len = sg_copy_from_buffer(sdb->table.sgl, sdb->table.nents, |
633 | for_each_sg(sdb->table.sgl, sg, sdb->table.nents, k) { | 358 | arr, arr_len); |
634 | if (active) { | ||
635 | kaddr = (unsigned char *) | ||
636 | kmap_atomic(sg_page(sg), KM_USER0); | ||
637 | if (NULL == kaddr) | ||
638 | return (DID_ERROR << 16); | ||
639 | kaddr_off = (unsigned char *)kaddr + sg->offset; | ||
640 | len = sg->length; | ||
641 | if ((req_len + len) > arr_len) { | ||
642 | active = 0; | ||
643 | len = arr_len - req_len; | ||
644 | } | ||
645 | memcpy(kaddr_off, arr + req_len, len); | ||
646 | kunmap_atomic(kaddr, KM_USER0); | ||
647 | act_len += len; | ||
648 | } | ||
649 | req_len += sg->length; | ||
650 | } | ||
651 | if (sdb->resid) | 359 | if (sdb->resid) |
652 | sdb->resid -= act_len; | 360 | sdb->resid -= act_len; |
653 | else | 361 | else |
654 | sdb->resid = req_len - act_len; | 362 | sdb->resid = scsi_bufflen(scp) - act_len; |
363 | |||
655 | return 0; | 364 | return 0; |
656 | } | 365 | } |
657 | 366 | ||
658 | /* Returns number of bytes fetched into 'arr' or -1 if error. */ | 367 | /* Returns number of bytes fetched into 'arr' or -1 if error. */ |
659 | static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr, | 368 | static int fetch_to_dev_buffer(struct scsi_cmnd *scp, unsigned char *arr, |
660 | int max_arr_len) | 369 | int arr_len) |
661 | { | 370 | { |
662 | int k, req_len, len, fin; | 371 | if (!scsi_bufflen(scp)) |
663 | void * kaddr; | ||
664 | void * kaddr_off; | ||
665 | struct scatterlist * sg; | ||
666 | |||
667 | if (0 == scsi_bufflen(scp)) | ||
668 | return 0; | 372 | return 0; |
669 | if (NULL == scsi_sglist(scp)) | ||
670 | return -1; | ||
671 | if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE)) | 373 | if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE)) |
672 | return -1; | 374 | return -1; |
673 | req_len = fin = 0; | 375 | |
674 | scsi_for_each_sg(scp, sg, scsi_sg_count(scp), k) { | 376 | return scsi_sg_copy_to_buffer(scp, arr, arr_len); |
675 | kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0); | ||
676 | if (NULL == kaddr) | ||
677 | return -1; | ||
678 | kaddr_off = (unsigned char *)kaddr + sg->offset; | ||
679 | len = sg->length; | ||
680 | if ((req_len + len) > max_arr_len) { | ||
681 | len = max_arr_len - req_len; | ||
682 | fin = 1; | ||
683 | } | ||
684 | memcpy(arr + req_len, kaddr_off, len); | ||
685 | kunmap_atomic(kaddr, KM_USER0); | ||
686 | if (fin) | ||
687 | return req_len + len; | ||
688 | req_len += sg->length; | ||
689 | } | ||
690 | return req_len; | ||
691 | } | 377 | } |
692 | 378 | ||
693 | 379 | ||
@@ -1159,6 +845,14 @@ static int resp_start_stop(struct scsi_cmnd * scp, | |||
1159 | return 0; | 845 | return 0; |
1160 | } | 846 | } |
1161 | 847 | ||
848 | static sector_t get_sdebug_capacity(void) | ||
849 | { | ||
850 | if (scsi_debug_virtual_gb > 0) | ||
851 | return 2048 * 1024 * scsi_debug_virtual_gb; | ||
852 | else | ||
853 | return sdebug_store_sectors; | ||
854 | } | ||
855 | |||
1162 | #define SDEBUG_READCAP_ARR_SZ 8 | 856 | #define SDEBUG_READCAP_ARR_SZ 8 |
1163 | static int resp_readcap(struct scsi_cmnd * scp, | 857 | static int resp_readcap(struct scsi_cmnd * scp, |
1164 | struct sdebug_dev_info * devip) | 858 | struct sdebug_dev_info * devip) |
@@ -1170,11 +864,7 @@ static int resp_readcap(struct scsi_cmnd * scp, | |||
1170 | if ((errsts = check_readiness(scp, 1, devip))) | 864 | if ((errsts = check_readiness(scp, 1, devip))) |
1171 | return errsts; | 865 | return errsts; |
1172 | /* following just in case virtual_gb changed */ | 866 | /* following just in case virtual_gb changed */ |
1173 | if (scsi_debug_virtual_gb > 0) { | 867 | sdebug_capacity = get_sdebug_capacity(); |
1174 | sdebug_capacity = 2048 * 1024; | ||
1175 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1176 | } else | ||
1177 | sdebug_capacity = sdebug_store_sectors; | ||
1178 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); | 868 | memset(arr, 0, SDEBUG_READCAP_ARR_SZ); |
1179 | if (sdebug_capacity < 0xffffffff) { | 869 | if (sdebug_capacity < 0xffffffff) { |
1180 | capac = (unsigned int)sdebug_capacity - 1; | 870 | capac = (unsigned int)sdebug_capacity - 1; |
@@ -1207,11 +897,7 @@ static int resp_readcap16(struct scsi_cmnd * scp, | |||
1207 | alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) | 897 | alloc_len = ((cmd[10] << 24) + (cmd[11] << 16) + (cmd[12] << 8) |
1208 | + cmd[13]); | 898 | + cmd[13]); |
1209 | /* following just in case virtual_gb changed */ | 899 | /* following just in case virtual_gb changed */ |
1210 | if (scsi_debug_virtual_gb > 0) { | 900 | sdebug_capacity = get_sdebug_capacity(); |
1211 | sdebug_capacity = 2048 * 1024; | ||
1212 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1213 | } else | ||
1214 | sdebug_capacity = sdebug_store_sectors; | ||
1215 | memset(arr, 0, SDEBUG_READCAP16_ARR_SZ); | 901 | memset(arr, 0, SDEBUG_READCAP16_ARR_SZ); |
1216 | capac = sdebug_capacity - 1; | 902 | capac = sdebug_capacity - 1; |
1217 | for (k = 0; k < 8; ++k, capac >>= 8) | 903 | for (k = 0; k < 8; ++k, capac >>= 8) |
@@ -1505,13 +1191,9 @@ static int resp_mode_sense(struct scsi_cmnd * scp, int target, | |||
1505 | offset = 8; | 1191 | offset = 8; |
1506 | } | 1192 | } |
1507 | ap = arr + offset; | 1193 | ap = arr + offset; |
1508 | if ((bd_len > 0) && (0 == sdebug_capacity)) { | 1194 | if ((bd_len > 0) && (!sdebug_capacity)) |
1509 | if (scsi_debug_virtual_gb > 0) { | 1195 | sdebug_capacity = get_sdebug_capacity(); |
1510 | sdebug_capacity = 2048 * 1024; | 1196 | |
1511 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
1512 | } else | ||
1513 | sdebug_capacity = sdebug_store_sectors; | ||
1514 | } | ||
1515 | if (8 == bd_len) { | 1197 | if (8 == bd_len) { |
1516 | if (sdebug_capacity > 0xfffffffe) { | 1198 | if (sdebug_capacity > 0xfffffffe) { |
1517 | ap[0] = 0xff; | 1199 | ap[0] = 0xff; |
@@ -1808,25 +1490,53 @@ static int resp_log_sense(struct scsi_cmnd * scp, | |||
1808 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); | 1490 | min(len, SDEBUG_MAX_INQ_ARR_SZ)); |
1809 | } | 1491 | } |
1810 | 1492 | ||
1811 | static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | 1493 | static int check_device_access_params(struct sdebug_dev_info *devi, |
1812 | unsigned int num, struct sdebug_dev_info * devip) | 1494 | unsigned long long lba, unsigned int num) |
1813 | { | 1495 | { |
1814 | unsigned long iflags; | ||
1815 | unsigned int block, from_bottom; | ||
1816 | unsigned long long u; | ||
1817 | int ret; | ||
1818 | |||
1819 | if (lba + num > sdebug_capacity) { | 1496 | if (lba + num > sdebug_capacity) { |
1820 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1497 | mk_sense_buffer(devi, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, 0); |
1821 | 0); | ||
1822 | return check_condition_result; | 1498 | return check_condition_result; |
1823 | } | 1499 | } |
1824 | /* transfer length excessive (tie in to block limits VPD page) */ | 1500 | /* transfer length excessive (tie in to block limits VPD page) */ |
1825 | if (num > sdebug_store_sectors) { | 1501 | if (num > sdebug_store_sectors) { |
1826 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | 1502 | mk_sense_buffer(devi, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); |
1827 | 0); | ||
1828 | return check_condition_result; | 1503 | return check_condition_result; |
1829 | } | 1504 | } |
1505 | return 0; | ||
1506 | } | ||
1507 | |||
1508 | static int do_device_access(struct scsi_cmnd *scmd, | ||
1509 | struct sdebug_dev_info *devi, | ||
1510 | unsigned long long lba, unsigned int num, int write) | ||
1511 | { | ||
1512 | int ret; | ||
1513 | unsigned int block, rest = 0; | ||
1514 | int (*func)(struct scsi_cmnd *, unsigned char *, int); | ||
1515 | |||
1516 | func = write ? fetch_to_dev_buffer : fill_from_dev_buffer; | ||
1517 | |||
1518 | block = do_div(lba, sdebug_store_sectors); | ||
1519 | if (block + num > sdebug_store_sectors) | ||
1520 | rest = block + num - sdebug_store_sectors; | ||
1521 | |||
1522 | ret = func(scmd, fake_storep + (block * SECT_SIZE), | ||
1523 | (num - rest) * SECT_SIZE); | ||
1524 | if (!ret && rest) | ||
1525 | ret = func(scmd, fake_storep, rest * SECT_SIZE); | ||
1526 | |||
1527 | return ret; | ||
1528 | } | ||
1529 | |||
1530 | static int resp_read(struct scsi_cmnd *SCpnt, unsigned long long lba, | ||
1531 | unsigned int num, struct sdebug_dev_info *devip) | ||
1532 | { | ||
1533 | unsigned long iflags; | ||
1534 | int ret; | ||
1535 | |||
1536 | ret = check_device_access_params(devip, lba, num); | ||
1537 | if (ret) | ||
1538 | return ret; | ||
1539 | |||
1830 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && | 1540 | if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && |
1831 | (lba <= OPT_MEDIUM_ERR_ADDR) && | 1541 | (lba <= OPT_MEDIUM_ERR_ADDR) && |
1832 | ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { | 1542 | ((lba + num) > OPT_MEDIUM_ERR_ADDR)) { |
@@ -1845,74 +1555,30 @@ static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba, | |||
1845 | return check_condition_result; | 1555 | return check_condition_result; |
1846 | } | 1556 | } |
1847 | read_lock_irqsave(&atomic_rw, iflags); | 1557 | read_lock_irqsave(&atomic_rw, iflags); |
1848 | if ((lba + num) <= sdebug_store_sectors) | 1558 | ret = do_device_access(SCpnt, devip, lba, num, 0); |
1849 | ret = fill_from_dev_buffer(SCpnt, | ||
1850 | fake_storep + (lba * SECT_SIZE), | ||
1851 | num * SECT_SIZE); | ||
1852 | else { | ||
1853 | /* modulo when one arg is 64 bits needs do_div() */ | ||
1854 | u = lba; | ||
1855 | block = do_div(u, sdebug_store_sectors); | ||
1856 | from_bottom = 0; | ||
1857 | if ((block + num) > sdebug_store_sectors) | ||
1858 | from_bottom = (block + num) - sdebug_store_sectors; | ||
1859 | ret = fill_from_dev_buffer(SCpnt, | ||
1860 | fake_storep + (block * SECT_SIZE), | ||
1861 | (num - from_bottom) * SECT_SIZE); | ||
1862 | if ((0 == ret) && (from_bottom > 0)) | ||
1863 | ret = fill_from_dev_buffer(SCpnt, fake_storep, | ||
1864 | from_bottom * SECT_SIZE); | ||
1865 | } | ||
1866 | read_unlock_irqrestore(&atomic_rw, iflags); | 1559 | read_unlock_irqrestore(&atomic_rw, iflags); |
1867 | return ret; | 1560 | return ret; |
1868 | } | 1561 | } |
1869 | 1562 | ||
1870 | static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba, | 1563 | static int resp_write(struct scsi_cmnd *SCpnt, unsigned long long lba, |
1871 | unsigned int num, struct sdebug_dev_info * devip) | 1564 | unsigned int num, struct sdebug_dev_info *devip) |
1872 | { | 1565 | { |
1873 | unsigned long iflags; | 1566 | unsigned long iflags; |
1874 | unsigned int block, to_bottom; | 1567 | int ret; |
1875 | unsigned long long u; | ||
1876 | int res; | ||
1877 | 1568 | ||
1878 | if (lba + num > sdebug_capacity) { | 1569 | ret = check_device_access_params(devip, lba, num); |
1879 | mk_sense_buffer(devip, ILLEGAL_REQUEST, ADDR_OUT_OF_RANGE, | 1570 | if (ret) |
1880 | 0); | 1571 | return ret; |
1881 | return check_condition_result; | ||
1882 | } | ||
1883 | /* transfer length excessive (tie in to block limits VPD page) */ | ||
1884 | if (num > sdebug_store_sectors) { | ||
1885 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, | ||
1886 | 0); | ||
1887 | return check_condition_result; | ||
1888 | } | ||
1889 | 1572 | ||
1890 | write_lock_irqsave(&atomic_rw, iflags); | 1573 | write_lock_irqsave(&atomic_rw, iflags); |
1891 | if ((lba + num) <= sdebug_store_sectors) | 1574 | ret = do_device_access(SCpnt, devip, lba, num, 1); |
1892 | res = fetch_to_dev_buffer(SCpnt, | ||
1893 | fake_storep + (lba * SECT_SIZE), | ||
1894 | num * SECT_SIZE); | ||
1895 | else { | ||
1896 | /* modulo when one arg is 64 bits needs do_div() */ | ||
1897 | u = lba; | ||
1898 | block = do_div(u, sdebug_store_sectors); | ||
1899 | to_bottom = 0; | ||
1900 | if ((block + num) > sdebug_store_sectors) | ||
1901 | to_bottom = (block + num) - sdebug_store_sectors; | ||
1902 | res = fetch_to_dev_buffer(SCpnt, | ||
1903 | fake_storep + (block * SECT_SIZE), | ||
1904 | (num - to_bottom) * SECT_SIZE); | ||
1905 | if ((0 == res) && (to_bottom > 0)) | ||
1906 | res = fetch_to_dev_buffer(SCpnt, fake_storep, | ||
1907 | to_bottom * SECT_SIZE); | ||
1908 | } | ||
1909 | write_unlock_irqrestore(&atomic_rw, iflags); | 1575 | write_unlock_irqrestore(&atomic_rw, iflags); |
1910 | if (-1 == res) | 1576 | if (-1 == ret) |
1911 | return (DID_ERROR << 16); | 1577 | return (DID_ERROR << 16); |
1912 | else if ((res < (num * SECT_SIZE)) && | 1578 | else if ((ret < (num * SECT_SIZE)) && |
1913 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 1579 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
1914 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, " | 1580 | printk(KERN_INFO "scsi_debug: write: cdb indicated=%u, " |
1915 | " IO sent=%d bytes\n", num * SECT_SIZE, res); | 1581 | " IO sent=%d bytes\n", num * SECT_SIZE, ret); |
1916 | return 0; | 1582 | return 0; |
1917 | } | 1583 | } |
1918 | 1584 | ||
@@ -1987,16 +1653,7 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba, | |||
1987 | if (!buf) | 1653 | if (!buf) |
1988 | return ret; | 1654 | return ret; |
1989 | 1655 | ||
1990 | offset = 0; | 1656 | scsi_sg_copy_to_buffer(scp, buf, scsi_bufflen(scp)); |
1991 | scsi_for_each_sg(scp, sg, scsi_sg_count(scp), i) { | ||
1992 | kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0); | ||
1993 | if (!kaddr) | ||
1994 | goto out; | ||
1995 | |||
1996 | memcpy(buf + offset, kaddr + sg->offset, sg->length); | ||
1997 | offset += sg->length; | ||
1998 | kunmap_atomic(kaddr, KM_USER0); | ||
1999 | } | ||
2000 | 1657 | ||
2001 | offset = 0; | 1658 | offset = 0; |
2002 | for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { | 1659 | for_each_sg(sdb->table.sgl, sg, sdb->table.nents, i) { |
@@ -2045,7 +1702,73 @@ static void timer_intr_handler(unsigned long indx) | |||
2045 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 1702 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2046 | } | 1703 | } |
2047 | 1704 | ||
2048 | static int scsi_debug_slave_alloc(struct scsi_device * sdp) | 1705 | |
1706 | static struct sdebug_dev_info * | ||
1707 | sdebug_device_create(struct sdebug_host_info *sdbg_host, gfp_t flags) | ||
1708 | { | ||
1709 | struct sdebug_dev_info *devip; | ||
1710 | |||
1711 | devip = kzalloc(sizeof(*devip), flags); | ||
1712 | if (devip) { | ||
1713 | devip->sdbg_host = sdbg_host; | ||
1714 | list_add_tail(&devip->dev_list, &sdbg_host->dev_info_list); | ||
1715 | } | ||
1716 | return devip; | ||
1717 | } | ||
1718 | |||
1719 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | ||
1720 | { | ||
1721 | struct sdebug_host_info * sdbg_host; | ||
1722 | struct sdebug_dev_info * open_devip = NULL; | ||
1723 | struct sdebug_dev_info * devip = | ||
1724 | (struct sdebug_dev_info *)sdev->hostdata; | ||
1725 | |||
1726 | if (devip) | ||
1727 | return devip; | ||
1728 | sdbg_host = *(struct sdebug_host_info **)shost_priv(sdev->host); | ||
1729 | if (!sdbg_host) { | ||
1730 | printk(KERN_ERR "Host info NULL\n"); | ||
1731 | return NULL; | ||
1732 | } | ||
1733 | list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { | ||
1734 | if ((devip->used) && (devip->channel == sdev->channel) && | ||
1735 | (devip->target == sdev->id) && | ||
1736 | (devip->lun == sdev->lun)) | ||
1737 | return devip; | ||
1738 | else { | ||
1739 | if ((!devip->used) && (!open_devip)) | ||
1740 | open_devip = devip; | ||
1741 | } | ||
1742 | } | ||
1743 | if (!open_devip) { /* try and make a new one */ | ||
1744 | open_devip = sdebug_device_create(sdbg_host, GFP_ATOMIC); | ||
1745 | if (!open_devip) { | ||
1746 | printk(KERN_ERR "%s: out of memory at line %d\n", | ||
1747 | __FUNCTION__, __LINE__); | ||
1748 | return NULL; | ||
1749 | } | ||
1750 | } | ||
1751 | |||
1752 | open_devip->channel = sdev->channel; | ||
1753 | open_devip->target = sdev->id; | ||
1754 | open_devip->lun = sdev->lun; | ||
1755 | open_devip->sdbg_host = sdbg_host; | ||
1756 | open_devip->reset = 1; | ||
1757 | open_devip->used = 1; | ||
1758 | memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN); | ||
1759 | if (scsi_debug_dsense) | ||
1760 | open_devip->sense_buff[0] = 0x72; | ||
1761 | else { | ||
1762 | open_devip->sense_buff[0] = 0x70; | ||
1763 | open_devip->sense_buff[7] = 0xa; | ||
1764 | } | ||
1765 | if (sdev->lun == SAM2_WLUN_REPORT_LUNS) | ||
1766 | open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
1767 | |||
1768 | return open_devip; | ||
1769 | } | ||
1770 | |||
1771 | static int scsi_debug_slave_alloc(struct scsi_device *sdp) | ||
2049 | { | 1772 | { |
2050 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1773 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
2051 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", | 1774 | printk(KERN_INFO "scsi_debug: slave_alloc <%u %u %u %u>\n", |
@@ -2054,9 +1777,9 @@ static int scsi_debug_slave_alloc(struct scsi_device * sdp) | |||
2054 | return 0; | 1777 | return 0; |
2055 | } | 1778 | } |
2056 | 1779 | ||
2057 | static int scsi_debug_slave_configure(struct scsi_device * sdp) | 1780 | static int scsi_debug_slave_configure(struct scsi_device *sdp) |
2058 | { | 1781 | { |
2059 | struct sdebug_dev_info * devip; | 1782 | struct sdebug_dev_info *devip; |
2060 | 1783 | ||
2061 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1784 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
2062 | printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n", | 1785 | printk(KERN_INFO "scsi_debug: slave_configure <%u %u %u %u>\n", |
@@ -2074,10 +1797,10 @@ static int scsi_debug_slave_configure(struct scsi_device * sdp) | |||
2074 | return 0; | 1797 | return 0; |
2075 | } | 1798 | } |
2076 | 1799 | ||
2077 | static void scsi_debug_slave_destroy(struct scsi_device * sdp) | 1800 | static void scsi_debug_slave_destroy(struct scsi_device *sdp) |
2078 | { | 1801 | { |
2079 | struct sdebug_dev_info * devip = | 1802 | struct sdebug_dev_info *devip = |
2080 | (struct sdebug_dev_info *)sdp->hostdata; | 1803 | (struct sdebug_dev_info *)sdp->hostdata; |
2081 | 1804 | ||
2082 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1805 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) |
2083 | printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", | 1806 | printk(KERN_INFO "scsi_debug: slave_destroy <%u %u %u %u>\n", |
@@ -2089,84 +1812,44 @@ static void scsi_debug_slave_destroy(struct scsi_device * sdp) | |||
2089 | } | 1812 | } |
2090 | } | 1813 | } |
2091 | 1814 | ||
2092 | static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev) | 1815 | /* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */ |
1816 | static int stop_queued_cmnd(struct scsi_cmnd *cmnd) | ||
2093 | { | 1817 | { |
2094 | struct sdebug_host_info * sdbg_host; | 1818 | unsigned long iflags; |
2095 | struct sdebug_dev_info * open_devip = NULL; | 1819 | int k; |
2096 | struct sdebug_dev_info * devip = | 1820 | struct sdebug_queued_cmd *sqcp; |
2097 | (struct sdebug_dev_info *)sdev->hostdata; | ||
2098 | 1821 | ||
2099 | if (devip) | 1822 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2100 | return devip; | 1823 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { |
2101 | sdbg_host = *(struct sdebug_host_info **) sdev->host->hostdata; | 1824 | sqcp = &queued_arr[k]; |
2102 | if(! sdbg_host) { | 1825 | if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) { |
2103 | printk(KERN_ERR "Host info NULL\n"); | 1826 | del_timer_sync(&sqcp->cmnd_timer); |
2104 | return NULL; | 1827 | sqcp->in_use = 0; |
2105 | } | 1828 | sqcp->a_cmnd = NULL; |
2106 | list_for_each_entry(devip, &sdbg_host->dev_info_list, dev_list) { | 1829 | break; |
2107 | if ((devip->used) && (devip->channel == sdev->channel) && | ||
2108 | (devip->target == sdev->id) && | ||
2109 | (devip->lun == sdev->lun)) | ||
2110 | return devip; | ||
2111 | else { | ||
2112 | if ((!devip->used) && (!open_devip)) | ||
2113 | open_devip = devip; | ||
2114 | } | 1830 | } |
2115 | } | 1831 | } |
2116 | if (NULL == open_devip) { /* try and make a new one */ | 1832 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2117 | open_devip = kzalloc(sizeof(*open_devip),GFP_ATOMIC); | 1833 | return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0; |
2118 | if (NULL == open_devip) { | ||
2119 | printk(KERN_ERR "%s: out of memory at line %d\n", | ||
2120 | __FUNCTION__, __LINE__); | ||
2121 | return NULL; | ||
2122 | } | ||
2123 | open_devip->sdbg_host = sdbg_host; | ||
2124 | list_add_tail(&open_devip->dev_list, | ||
2125 | &sdbg_host->dev_info_list); | ||
2126 | } | ||
2127 | if (open_devip) { | ||
2128 | open_devip->channel = sdev->channel; | ||
2129 | open_devip->target = sdev->id; | ||
2130 | open_devip->lun = sdev->lun; | ||
2131 | open_devip->sdbg_host = sdbg_host; | ||
2132 | open_devip->reset = 1; | ||
2133 | open_devip->used = 1; | ||
2134 | memset(open_devip->sense_buff, 0, SDEBUG_SENSE_LEN); | ||
2135 | if (scsi_debug_dsense) | ||
2136 | open_devip->sense_buff[0] = 0x72; | ||
2137 | else { | ||
2138 | open_devip->sense_buff[0] = 0x70; | ||
2139 | open_devip->sense_buff[7] = 0xa; | ||
2140 | } | ||
2141 | if (sdev->lun == SAM2_WLUN_REPORT_LUNS) | ||
2142 | open_devip->wlun = SAM2_WLUN_REPORT_LUNS & 0xff; | ||
2143 | return open_devip; | ||
2144 | } | ||
2145 | return NULL; | ||
2146 | } | 1834 | } |
2147 | 1835 | ||
2148 | static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, | 1836 | /* Deletes (stops) timers of all queued commands */ |
2149 | int asc, int asq) | 1837 | static void stop_all_queued(void) |
2150 | { | 1838 | { |
2151 | unsigned char * sbuff; | 1839 | unsigned long iflags; |
1840 | int k; | ||
1841 | struct sdebug_queued_cmd *sqcp; | ||
2152 | 1842 | ||
2153 | sbuff = devip->sense_buff; | 1843 | spin_lock_irqsave(&queued_arr_lock, iflags); |
2154 | memset(sbuff, 0, SDEBUG_SENSE_LEN); | 1844 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { |
2155 | if (scsi_debug_dsense) { | 1845 | sqcp = &queued_arr[k]; |
2156 | sbuff[0] = 0x72; /* descriptor, current */ | 1846 | if (sqcp->in_use && sqcp->a_cmnd) { |
2157 | sbuff[1] = key; | 1847 | del_timer_sync(&sqcp->cmnd_timer); |
2158 | sbuff[2] = asc; | 1848 | sqcp->in_use = 0; |
2159 | sbuff[3] = asq; | 1849 | sqcp->a_cmnd = NULL; |
2160 | } else { | 1850 | } |
2161 | sbuff[0] = 0x70; /* fixed, current */ | ||
2162 | sbuff[2] = key; | ||
2163 | sbuff[7] = 0xa; /* implies 18 byte sense buffer */ | ||
2164 | sbuff[12] = asc; | ||
2165 | sbuff[13] = asq; | ||
2166 | } | 1851 | } |
2167 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | 1852 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2168 | printk(KERN_INFO "scsi_debug: [sense_key,asc,ascq]: " | ||
2169 | "[0x%x,0x%x,0x%x]\n", key, asc, asq); | ||
2170 | } | 1853 | } |
2171 | 1854 | ||
2172 | static int scsi_debug_abort(struct scsi_cmnd * SCpnt) | 1855 | static int scsi_debug_abort(struct scsi_cmnd * SCpnt) |
@@ -2226,7 +1909,7 @@ static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt) | |||
2226 | printk(KERN_INFO "scsi_debug: bus_reset\n"); | 1909 | printk(KERN_INFO "scsi_debug: bus_reset\n"); |
2227 | ++num_bus_resets; | 1910 | ++num_bus_resets; |
2228 | if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) { | 1911 | if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) { |
2229 | sdbg_host = *(struct sdebug_host_info **) hp->hostdata; | 1912 | sdbg_host = *(struct sdebug_host_info **)shost_priv(hp); |
2230 | if (sdbg_host) { | 1913 | if (sdbg_host) { |
2231 | list_for_each_entry(dev_info, | 1914 | list_for_each_entry(dev_info, |
2232 | &sdbg_host->dev_info_list, | 1915 | &sdbg_host->dev_info_list, |
@@ -2256,46 +1939,6 @@ static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt) | |||
2256 | return SUCCESS; | 1939 | return SUCCESS; |
2257 | } | 1940 | } |
2258 | 1941 | ||
2259 | /* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */ | ||
2260 | static int stop_queued_cmnd(struct scsi_cmnd * cmnd) | ||
2261 | { | ||
2262 | unsigned long iflags; | ||
2263 | int k; | ||
2264 | struct sdebug_queued_cmd * sqcp; | ||
2265 | |||
2266 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
2267 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { | ||
2268 | sqcp = &queued_arr[k]; | ||
2269 | if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) { | ||
2270 | del_timer_sync(&sqcp->cmnd_timer); | ||
2271 | sqcp->in_use = 0; | ||
2272 | sqcp->a_cmnd = NULL; | ||
2273 | break; | ||
2274 | } | ||
2275 | } | ||
2276 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2277 | return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0; | ||
2278 | } | ||
2279 | |||
2280 | /* Deletes (stops) timers of all queued commands */ | ||
2281 | static void stop_all_queued(void) | ||
2282 | { | ||
2283 | unsigned long iflags; | ||
2284 | int k; | ||
2285 | struct sdebug_queued_cmd * sqcp; | ||
2286 | |||
2287 | spin_lock_irqsave(&queued_arr_lock, iflags); | ||
2288 | for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { | ||
2289 | sqcp = &queued_arr[k]; | ||
2290 | if (sqcp->in_use && sqcp->a_cmnd) { | ||
2291 | del_timer_sync(&sqcp->cmnd_timer); | ||
2292 | sqcp->in_use = 0; | ||
2293 | sqcp->a_cmnd = NULL; | ||
2294 | } | ||
2295 | } | ||
2296 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | ||
2297 | } | ||
2298 | |||
2299 | /* Initializes timers in queued array */ | 1942 | /* Initializes timers in queued array */ |
2300 | static void __init init_all_queued(void) | 1943 | static void __init init_all_queued(void) |
2301 | { | 1944 | { |
@@ -2313,7 +1956,8 @@ static void __init init_all_queued(void) | |||
2313 | spin_unlock_irqrestore(&queued_arr_lock, iflags); | 1956 | spin_unlock_irqrestore(&queued_arr_lock, iflags); |
2314 | } | 1957 | } |
2315 | 1958 | ||
2316 | static void __init sdebug_build_parts(unsigned char * ramp) | 1959 | static void __init sdebug_build_parts(unsigned char *ramp, |
1960 | unsigned long store_size) | ||
2317 | { | 1961 | { |
2318 | struct partition * pp; | 1962 | struct partition * pp; |
2319 | int starts[SDEBUG_MAX_PARTS + 2]; | 1963 | int starts[SDEBUG_MAX_PARTS + 2]; |
@@ -2321,7 +1965,7 @@ static void __init sdebug_build_parts(unsigned char * ramp) | |||
2321 | int heads_by_sects, start_sec, end_sec; | 1965 | int heads_by_sects, start_sec, end_sec; |
2322 | 1966 | ||
2323 | /* assume partition table already zeroed */ | 1967 | /* assume partition table already zeroed */ |
2324 | if ((scsi_debug_num_parts < 1) || (sdebug_store_size < 1048576)) | 1968 | if ((scsi_debug_num_parts < 1) || (store_size < 1048576)) |
2325 | return; | 1969 | return; |
2326 | if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) { | 1970 | if (scsi_debug_num_parts > SDEBUG_MAX_PARTS) { |
2327 | scsi_debug_num_parts = SDEBUG_MAX_PARTS; | 1971 | scsi_debug_num_parts = SDEBUG_MAX_PARTS; |
@@ -2419,7 +2063,6 @@ static int schedule_resp(struct scsi_cmnd * cmnd, | |||
2419 | return 0; | 2063 | return 0; |
2420 | } | 2064 | } |
2421 | } | 2065 | } |
2422 | |||
2423 | /* Note: The following macros create attribute files in the | 2066 | /* Note: The following macros create attribute files in the |
2424 | /sys/module/scsi_debug/parameters directory. Unfortunately this | 2067 | /sys/module/scsi_debug/parameters directory. Unfortunately this |
2425 | driver is unaware of a change and cannot trigger auxiliary actions | 2068 | driver is unaware of a change and cannot trigger auxiliary actions |
@@ -2736,11 +2379,9 @@ static ssize_t sdebug_virtual_gb_store(struct device_driver * ddp, | |||
2736 | 2379 | ||
2737 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { | 2380 | if ((count > 0) && (1 == sscanf(buf, "%d", &n)) && (n >= 0)) { |
2738 | scsi_debug_virtual_gb = n; | 2381 | scsi_debug_virtual_gb = n; |
2739 | if (scsi_debug_virtual_gb > 0) { | 2382 | |
2740 | sdebug_capacity = 2048 * 1024; | 2383 | sdebug_capacity = get_sdebug_capacity(); |
2741 | sdebug_capacity *= scsi_debug_virtual_gb; | 2384 | |
2742 | } else | ||
2743 | sdebug_capacity = sdebug_store_sectors; | ||
2744 | return count; | 2385 | return count; |
2745 | } | 2386 | } |
2746 | return -EINVAL; | 2387 | return -EINVAL; |
@@ -2756,21 +2397,10 @@ static ssize_t sdebug_add_host_show(struct device_driver * ddp, char * buf) | |||
2756 | static ssize_t sdebug_add_host_store(struct device_driver * ddp, | 2397 | static ssize_t sdebug_add_host_store(struct device_driver * ddp, |
2757 | const char * buf, size_t count) | 2398 | const char * buf, size_t count) |
2758 | { | 2399 | { |
2759 | int delta_hosts; | 2400 | int delta_hosts; |
2760 | char work[20]; | ||
2761 | 2401 | ||
2762 | if (1 != sscanf(buf, "%10s", work)) | 2402 | if (sscanf(buf, "%d", &delta_hosts) != 1) |
2763 | return -EINVAL; | 2403 | return -EINVAL; |
2764 | { /* temporary hack around sscanf() problem with -ve nums */ | ||
2765 | int neg = 0; | ||
2766 | |||
2767 | if ('-' == *work) | ||
2768 | neg = 1; | ||
2769 | if (1 != sscanf(work + neg, "%d", &delta_hosts)) | ||
2770 | return -EINVAL; | ||
2771 | if (neg) | ||
2772 | delta_hosts = -delta_hosts; | ||
2773 | } | ||
2774 | if (delta_hosts > 0) { | 2404 | if (delta_hosts > 0) { |
2775 | do { | 2405 | do { |
2776 | sdebug_add_adapter(); | 2406 | sdebug_add_adapter(); |
@@ -2782,7 +2412,7 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp, | |||
2782 | } | 2412 | } |
2783 | return count; | 2413 | return count; |
2784 | } | 2414 | } |
2785 | DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, | 2415 | DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, |
2786 | sdebug_add_host_store); | 2416 | sdebug_add_host_store); |
2787 | 2417 | ||
2788 | static ssize_t sdebug_vpd_use_hostno_show(struct device_driver * ddp, | 2418 | static ssize_t sdebug_vpd_use_hostno_show(struct device_driver * ddp, |
@@ -2851,22 +2481,29 @@ static void do_remove_driverfs_files(void) | |||
2851 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host); | 2481 | driver_remove_file(&sdebug_driverfs_driver, &driver_attr_add_host); |
2852 | } | 2482 | } |
2853 | 2483 | ||
2484 | static void pseudo_0_release(struct device *dev) | ||
2485 | { | ||
2486 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2487 | printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n"); | ||
2488 | } | ||
2489 | |||
2490 | static struct device pseudo_primary = { | ||
2491 | .bus_id = "pseudo_0", | ||
2492 | .release = pseudo_0_release, | ||
2493 | }; | ||
2494 | |||
2854 | static int __init scsi_debug_init(void) | 2495 | static int __init scsi_debug_init(void) |
2855 | { | 2496 | { |
2856 | unsigned int sz; | 2497 | unsigned long sz; |
2857 | int host_to_add; | 2498 | int host_to_add; |
2858 | int k; | 2499 | int k; |
2859 | int ret; | 2500 | int ret; |
2860 | 2501 | ||
2861 | if (scsi_debug_dev_size_mb < 1) | 2502 | if (scsi_debug_dev_size_mb < 1) |
2862 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ | 2503 | scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ |
2863 | sdebug_store_size = (unsigned int)scsi_debug_dev_size_mb * 1048576; | 2504 | sz = (unsigned long)scsi_debug_dev_size_mb * 1048576; |
2864 | sdebug_store_sectors = sdebug_store_size / SECT_SIZE; | 2505 | sdebug_store_sectors = sz / SECT_SIZE; |
2865 | if (scsi_debug_virtual_gb > 0) { | 2506 | sdebug_capacity = get_sdebug_capacity(); |
2866 | sdebug_capacity = 2048 * 1024; | ||
2867 | sdebug_capacity *= scsi_debug_virtual_gb; | ||
2868 | } else | ||
2869 | sdebug_capacity = sdebug_store_sectors; | ||
2870 | 2507 | ||
2871 | /* play around with geometry, don't waste too much on track 0 */ | 2508 | /* play around with geometry, don't waste too much on track 0 */ |
2872 | sdebug_heads = 8; | 2509 | sdebug_heads = 8; |
@@ -2885,7 +2522,6 @@ static int __init scsi_debug_init(void) | |||
2885 | (sdebug_sectors_per * sdebug_heads); | 2522 | (sdebug_sectors_per * sdebug_heads); |
2886 | } | 2523 | } |
2887 | 2524 | ||
2888 | sz = sdebug_store_size; | ||
2889 | fake_storep = vmalloc(sz); | 2525 | fake_storep = vmalloc(sz); |
2890 | if (NULL == fake_storep) { | 2526 | if (NULL == fake_storep) { |
2891 | printk(KERN_ERR "scsi_debug_init: out of memory, 1\n"); | 2527 | printk(KERN_ERR "scsi_debug_init: out of memory, 1\n"); |
@@ -2893,7 +2529,7 @@ static int __init scsi_debug_init(void) | |||
2893 | } | 2529 | } |
2894 | memset(fake_storep, 0, sz); | 2530 | memset(fake_storep, 0, sz); |
2895 | if (scsi_debug_num_parts > 0) | 2531 | if (scsi_debug_num_parts > 0) |
2896 | sdebug_build_parts(fake_storep); | 2532 | sdebug_build_parts(fake_storep, sz); |
2897 | 2533 | ||
2898 | ret = device_register(&pseudo_primary); | 2534 | ret = device_register(&pseudo_primary); |
2899 | if (ret < 0) { | 2535 | if (ret < 0) { |
@@ -2922,8 +2558,6 @@ static int __init scsi_debug_init(void) | |||
2922 | 2558 | ||
2923 | init_all_queued(); | 2559 | init_all_queued(); |
2924 | 2560 | ||
2925 | sdebug_driver_template.proc_name = sdebug_proc_name; | ||
2926 | |||
2927 | host_to_add = scsi_debug_add_host; | 2561 | host_to_add = scsi_debug_add_host; |
2928 | scsi_debug_add_host = 0; | 2562 | scsi_debug_add_host = 0; |
2929 | 2563 | ||
@@ -2972,30 +2606,6 @@ static void __exit scsi_debug_exit(void) | |||
2972 | device_initcall(scsi_debug_init); | 2606 | device_initcall(scsi_debug_init); |
2973 | module_exit(scsi_debug_exit); | 2607 | module_exit(scsi_debug_exit); |
2974 | 2608 | ||
2975 | static void pseudo_0_release(struct device * dev) | ||
2976 | { | ||
2977 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2978 | printk(KERN_INFO "scsi_debug: pseudo_0_release() called\n"); | ||
2979 | } | ||
2980 | |||
2981 | static struct device pseudo_primary = { | ||
2982 | .bus_id = "pseudo_0", | ||
2983 | .release = pseudo_0_release, | ||
2984 | }; | ||
2985 | |||
2986 | static int pseudo_lld_bus_match(struct device *dev, | ||
2987 | struct device_driver *dev_driver) | ||
2988 | { | ||
2989 | return 1; | ||
2990 | } | ||
2991 | |||
2992 | static struct bus_type pseudo_lld_bus = { | ||
2993 | .name = "pseudo", | ||
2994 | .match = pseudo_lld_bus_match, | ||
2995 | .probe = sdebug_driver_probe, | ||
2996 | .remove = sdebug_driver_remove, | ||
2997 | }; | ||
2998 | |||
2999 | static void sdebug_release_adapter(struct device * dev) | 2609 | static void sdebug_release_adapter(struct device * dev) |
3000 | { | 2610 | { |
3001 | struct sdebug_host_info *sdbg_host; | 2611 | struct sdebug_host_info *sdbg_host; |
@@ -3009,8 +2619,7 @@ static int sdebug_add_adapter(void) | |||
3009 | int k, devs_per_host; | 2619 | int k, devs_per_host; |
3010 | int error = 0; | 2620 | int error = 0; |
3011 | struct sdebug_host_info *sdbg_host; | 2621 | struct sdebug_host_info *sdbg_host; |
3012 | struct sdebug_dev_info *sdbg_devinfo; | 2622 | struct sdebug_dev_info *sdbg_devinfo, *tmp; |
3013 | struct list_head *lh, *lh_sf; | ||
3014 | 2623 | ||
3015 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); | 2624 | sdbg_host = kzalloc(sizeof(*sdbg_host),GFP_KERNEL); |
3016 | if (NULL == sdbg_host) { | 2625 | if (NULL == sdbg_host) { |
@@ -3023,16 +2632,13 @@ static int sdebug_add_adapter(void) | |||
3023 | 2632 | ||
3024 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; | 2633 | devs_per_host = scsi_debug_num_tgts * scsi_debug_max_luns; |
3025 | for (k = 0; k < devs_per_host; k++) { | 2634 | for (k = 0; k < devs_per_host; k++) { |
3026 | sdbg_devinfo = kzalloc(sizeof(*sdbg_devinfo),GFP_KERNEL); | 2635 | sdbg_devinfo = sdebug_device_create(sdbg_host, GFP_KERNEL); |
3027 | if (NULL == sdbg_devinfo) { | 2636 | if (!sdbg_devinfo) { |
3028 | printk(KERN_ERR "%s: out of memory at line %d\n", | 2637 | printk(KERN_ERR "%s: out of memory at line %d\n", |
3029 | __FUNCTION__, __LINE__); | 2638 | __FUNCTION__, __LINE__); |
3030 | error = -ENOMEM; | 2639 | error = -ENOMEM; |
3031 | goto clean; | 2640 | goto clean; |
3032 | } | 2641 | } |
3033 | sdbg_devinfo->sdbg_host = sdbg_host; | ||
3034 | list_add_tail(&sdbg_devinfo->dev_list, | ||
3035 | &sdbg_host->dev_info_list); | ||
3036 | } | 2642 | } |
3037 | 2643 | ||
3038 | spin_lock(&sdebug_host_list_lock); | 2644 | spin_lock(&sdebug_host_list_lock); |
@@ -3053,9 +2659,8 @@ static int sdebug_add_adapter(void) | |||
3053 | return error; | 2659 | return error; |
3054 | 2660 | ||
3055 | clean: | 2661 | clean: |
3056 | list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) { | 2662 | list_for_each_entry_safe(sdbg_devinfo, tmp, &sdbg_host->dev_info_list, |
3057 | sdbg_devinfo = list_entry(lh, struct sdebug_dev_info, | 2663 | dev_list) { |
3058 | dev_list); | ||
3059 | list_del(&sdbg_devinfo->dev_list); | 2664 | list_del(&sdbg_devinfo->dev_list); |
3060 | kfree(sdbg_devinfo); | 2665 | kfree(sdbg_devinfo); |
3061 | } | 2666 | } |
@@ -3083,6 +2688,263 @@ static void sdebug_remove_adapter(void) | |||
3083 | --scsi_debug_add_host; | 2688 | --scsi_debug_add_host; |
3084 | } | 2689 | } |
3085 | 2690 | ||
2691 | static | ||
2692 | int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done) | ||
2693 | { | ||
2694 | unsigned char *cmd = (unsigned char *) SCpnt->cmnd; | ||
2695 | int len, k; | ||
2696 | unsigned int num; | ||
2697 | unsigned long long lba; | ||
2698 | int errsts = 0; | ||
2699 | int target = SCpnt->device->id; | ||
2700 | struct sdebug_dev_info *devip = NULL; | ||
2701 | int inj_recovered = 0; | ||
2702 | int inj_transport = 0; | ||
2703 | int delay_override = 0; | ||
2704 | |||
2705 | scsi_set_resid(SCpnt, 0); | ||
2706 | if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) { | ||
2707 | printk(KERN_INFO "scsi_debug: cmd "); | ||
2708 | for (k = 0, len = SCpnt->cmd_len; k < len; ++k) | ||
2709 | printk("%02x ", (int)cmd[k]); | ||
2710 | printk("\n"); | ||
2711 | } | ||
2712 | |||
2713 | if (target == SCpnt->device->host->hostt->this_id) { | ||
2714 | printk(KERN_INFO "scsi_debug: initiator's id used as " | ||
2715 | "target!\n"); | ||
2716 | return schedule_resp(SCpnt, NULL, done, | ||
2717 | DID_NO_CONNECT << 16, 0); | ||
2718 | } | ||
2719 | |||
2720 | if ((SCpnt->device->lun >= scsi_debug_max_luns) && | ||
2721 | (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS)) | ||
2722 | return schedule_resp(SCpnt, NULL, done, | ||
2723 | DID_NO_CONNECT << 16, 0); | ||
2724 | devip = devInfoReg(SCpnt->device); | ||
2725 | if (NULL == devip) | ||
2726 | return schedule_resp(SCpnt, NULL, done, | ||
2727 | DID_NO_CONNECT << 16, 0); | ||
2728 | |||
2729 | if ((scsi_debug_every_nth != 0) && | ||
2730 | (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) { | ||
2731 | scsi_debug_cmnd_count = 0; | ||
2732 | if (scsi_debug_every_nth < -1) | ||
2733 | scsi_debug_every_nth = -1; | ||
2734 | if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts) | ||
2735 | return 0; /* ignore command causing timeout */ | ||
2736 | else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts) | ||
2737 | inj_recovered = 1; /* to reads and writes below */ | ||
2738 | else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts) | ||
2739 | inj_transport = 1; /* to reads and writes below */ | ||
2740 | } | ||
2741 | |||
2742 | if (devip->wlun) { | ||
2743 | switch (*cmd) { | ||
2744 | case INQUIRY: | ||
2745 | case REQUEST_SENSE: | ||
2746 | case TEST_UNIT_READY: | ||
2747 | case REPORT_LUNS: | ||
2748 | break; /* only allowable wlun commands */ | ||
2749 | default: | ||
2750 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2751 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x " | ||
2752 | "not supported for wlun\n", *cmd); | ||
2753 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
2754 | INVALID_OPCODE, 0); | ||
2755 | errsts = check_condition_result; | ||
2756 | return schedule_resp(SCpnt, devip, done, errsts, | ||
2757 | 0); | ||
2758 | } | ||
2759 | } | ||
2760 | |||
2761 | switch (*cmd) { | ||
2762 | case INQUIRY: /* mandatory, ignore unit attention */ | ||
2763 | delay_override = 1; | ||
2764 | errsts = resp_inquiry(SCpnt, target, devip); | ||
2765 | break; | ||
2766 | case REQUEST_SENSE: /* mandatory, ignore unit attention */ | ||
2767 | delay_override = 1; | ||
2768 | errsts = resp_requests(SCpnt, devip); | ||
2769 | break; | ||
2770 | case REZERO_UNIT: /* actually this is REWIND for SSC */ | ||
2771 | case START_STOP: | ||
2772 | errsts = resp_start_stop(SCpnt, devip); | ||
2773 | break; | ||
2774 | case ALLOW_MEDIUM_REMOVAL: | ||
2775 | errsts = check_readiness(SCpnt, 1, devip); | ||
2776 | if (errsts) | ||
2777 | break; | ||
2778 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2779 | printk(KERN_INFO "scsi_debug: Medium removal %s\n", | ||
2780 | cmd[4] ? "inhibited" : "enabled"); | ||
2781 | break; | ||
2782 | case SEND_DIAGNOSTIC: /* mandatory */ | ||
2783 | errsts = check_readiness(SCpnt, 1, devip); | ||
2784 | break; | ||
2785 | case TEST_UNIT_READY: /* mandatory */ | ||
2786 | delay_override = 1; | ||
2787 | errsts = check_readiness(SCpnt, 0, devip); | ||
2788 | break; | ||
2789 | case RESERVE: | ||
2790 | errsts = check_readiness(SCpnt, 1, devip); | ||
2791 | break; | ||
2792 | case RESERVE_10: | ||
2793 | errsts = check_readiness(SCpnt, 1, devip); | ||
2794 | break; | ||
2795 | case RELEASE: | ||
2796 | errsts = check_readiness(SCpnt, 1, devip); | ||
2797 | break; | ||
2798 | case RELEASE_10: | ||
2799 | errsts = check_readiness(SCpnt, 1, devip); | ||
2800 | break; | ||
2801 | case READ_CAPACITY: | ||
2802 | errsts = resp_readcap(SCpnt, devip); | ||
2803 | break; | ||
2804 | case SERVICE_ACTION_IN: | ||
2805 | if (SAI_READ_CAPACITY_16 != cmd[1]) { | ||
2806 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
2807 | INVALID_OPCODE, 0); | ||
2808 | errsts = check_condition_result; | ||
2809 | break; | ||
2810 | } | ||
2811 | errsts = resp_readcap16(SCpnt, devip); | ||
2812 | break; | ||
2813 | case MAINTENANCE_IN: | ||
2814 | if (MI_REPORT_TARGET_PGS != cmd[1]) { | ||
2815 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
2816 | INVALID_OPCODE, 0); | ||
2817 | errsts = check_condition_result; | ||
2818 | break; | ||
2819 | } | ||
2820 | errsts = resp_report_tgtpgs(SCpnt, devip); | ||
2821 | break; | ||
2822 | case READ_16: | ||
2823 | case READ_12: | ||
2824 | case READ_10: | ||
2825 | case READ_6: | ||
2826 | errsts = check_readiness(SCpnt, 0, devip); | ||
2827 | if (errsts) | ||
2828 | break; | ||
2829 | if (scsi_debug_fake_rw) | ||
2830 | break; | ||
2831 | get_data_transfer_info(cmd, &lba, &num); | ||
2832 | errsts = resp_read(SCpnt, lba, num, devip); | ||
2833 | if (inj_recovered && (0 == errsts)) { | ||
2834 | mk_sense_buffer(devip, RECOVERED_ERROR, | ||
2835 | THRESHOLD_EXCEEDED, 0); | ||
2836 | errsts = check_condition_result; | ||
2837 | } else if (inj_transport && (0 == errsts)) { | ||
2838 | mk_sense_buffer(devip, ABORTED_COMMAND, | ||
2839 | TRANSPORT_PROBLEM, ACK_NAK_TO); | ||
2840 | errsts = check_condition_result; | ||
2841 | } | ||
2842 | break; | ||
2843 | case REPORT_LUNS: /* mandatory, ignore unit attention */ | ||
2844 | delay_override = 1; | ||
2845 | errsts = resp_report_luns(SCpnt, devip); | ||
2846 | break; | ||
2847 | case VERIFY: /* 10 byte SBC-2 command */ | ||
2848 | errsts = check_readiness(SCpnt, 0, devip); | ||
2849 | break; | ||
2850 | case WRITE_16: | ||
2851 | case WRITE_12: | ||
2852 | case WRITE_10: | ||
2853 | case WRITE_6: | ||
2854 | errsts = check_readiness(SCpnt, 0, devip); | ||
2855 | if (errsts) | ||
2856 | break; | ||
2857 | if (scsi_debug_fake_rw) | ||
2858 | break; | ||
2859 | get_data_transfer_info(cmd, &lba, &num); | ||
2860 | errsts = resp_write(SCpnt, lba, num, devip); | ||
2861 | if (inj_recovered && (0 == errsts)) { | ||
2862 | mk_sense_buffer(devip, RECOVERED_ERROR, | ||
2863 | THRESHOLD_EXCEEDED, 0); | ||
2864 | errsts = check_condition_result; | ||
2865 | } | ||
2866 | break; | ||
2867 | case MODE_SENSE: | ||
2868 | case MODE_SENSE_10: | ||
2869 | errsts = resp_mode_sense(SCpnt, target, devip); | ||
2870 | break; | ||
2871 | case MODE_SELECT: | ||
2872 | errsts = resp_mode_select(SCpnt, 1, devip); | ||
2873 | break; | ||
2874 | case MODE_SELECT_10: | ||
2875 | errsts = resp_mode_select(SCpnt, 0, devip); | ||
2876 | break; | ||
2877 | case LOG_SENSE: | ||
2878 | errsts = resp_log_sense(SCpnt, devip); | ||
2879 | break; | ||
2880 | case SYNCHRONIZE_CACHE: | ||
2881 | delay_override = 1; | ||
2882 | errsts = check_readiness(SCpnt, 0, devip); | ||
2883 | break; | ||
2884 | case WRITE_BUFFER: | ||
2885 | errsts = check_readiness(SCpnt, 1, devip); | ||
2886 | break; | ||
2887 | case XDWRITEREAD_10: | ||
2888 | if (!scsi_bidi_cmnd(SCpnt)) { | ||
2889 | mk_sense_buffer(devip, ILLEGAL_REQUEST, | ||
2890 | INVALID_FIELD_IN_CDB, 0); | ||
2891 | errsts = check_condition_result; | ||
2892 | break; | ||
2893 | } | ||
2894 | |||
2895 | errsts = check_readiness(SCpnt, 0, devip); | ||
2896 | if (errsts) | ||
2897 | break; | ||
2898 | if (scsi_debug_fake_rw) | ||
2899 | break; | ||
2900 | get_data_transfer_info(cmd, &lba, &num); | ||
2901 | errsts = resp_read(SCpnt, lba, num, devip); | ||
2902 | if (errsts) | ||
2903 | break; | ||
2904 | errsts = resp_write(SCpnt, lba, num, devip); | ||
2905 | if (errsts) | ||
2906 | break; | ||
2907 | errsts = resp_xdwriteread(SCpnt, lba, num, devip); | ||
2908 | break; | ||
2909 | default: | ||
2910 | if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) | ||
2911 | printk(KERN_INFO "scsi_debug: Opcode: 0x%x not " | ||
2912 | "supported\n", *cmd); | ||
2913 | errsts = check_readiness(SCpnt, 1, devip); | ||
2914 | if (errsts) | ||
2915 | break; /* Unit attention takes precedence */ | ||
2916 | mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0); | ||
2917 | errsts = check_condition_result; | ||
2918 | break; | ||
2919 | } | ||
2920 | return schedule_resp(SCpnt, devip, done, errsts, | ||
2921 | (delay_override ? 0 : scsi_debug_delay)); | ||
2922 | } | ||
2923 | |||
2924 | static struct scsi_host_template sdebug_driver_template = { | ||
2925 | .proc_info = scsi_debug_proc_info, | ||
2926 | .proc_name = sdebug_proc_name, | ||
2927 | .name = "SCSI DEBUG", | ||
2928 | .info = scsi_debug_info, | ||
2929 | .slave_alloc = scsi_debug_slave_alloc, | ||
2930 | .slave_configure = scsi_debug_slave_configure, | ||
2931 | .slave_destroy = scsi_debug_slave_destroy, | ||
2932 | .ioctl = scsi_debug_ioctl, | ||
2933 | .queuecommand = scsi_debug_queuecommand, | ||
2934 | .eh_abort_handler = scsi_debug_abort, | ||
2935 | .eh_bus_reset_handler = scsi_debug_bus_reset, | ||
2936 | .eh_device_reset_handler = scsi_debug_device_reset, | ||
2937 | .eh_host_reset_handler = scsi_debug_host_reset, | ||
2938 | .bios_param = scsi_debug_biosparam, | ||
2939 | .can_queue = SCSI_DEBUG_CANQUEUE, | ||
2940 | .this_id = 7, | ||
2941 | .sg_tablesize = 256, | ||
2942 | .cmd_per_lun = 16, | ||
2943 | .max_sectors = 0xffff, | ||
2944 | .use_clustering = DISABLE_CLUSTERING, | ||
2945 | .module = THIS_MODULE, | ||
2946 | }; | ||
2947 | |||
3086 | static int sdebug_driver_probe(struct device * dev) | 2948 | static int sdebug_driver_probe(struct device * dev) |
3087 | { | 2949 | { |
3088 | int error = 0; | 2950 | int error = 0; |
@@ -3120,9 +2982,8 @@ static int sdebug_driver_probe(struct device * dev) | |||
3120 | 2982 | ||
3121 | static int sdebug_driver_remove(struct device * dev) | 2983 | static int sdebug_driver_remove(struct device * dev) |
3122 | { | 2984 | { |
3123 | struct list_head *lh, *lh_sf; | ||
3124 | struct sdebug_host_info *sdbg_host; | 2985 | struct sdebug_host_info *sdbg_host; |
3125 | struct sdebug_dev_info *sdbg_devinfo; | 2986 | struct sdebug_dev_info *sdbg_devinfo, *tmp; |
3126 | 2987 | ||
3127 | sdbg_host = to_sdebug_host(dev); | 2988 | sdbg_host = to_sdebug_host(dev); |
3128 | 2989 | ||
@@ -3134,9 +2995,8 @@ static int sdebug_driver_remove(struct device * dev) | |||
3134 | 2995 | ||
3135 | scsi_remove_host(sdbg_host->shost); | 2996 | scsi_remove_host(sdbg_host->shost); |
3136 | 2997 | ||
3137 | list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) { | 2998 | list_for_each_entry_safe(sdbg_devinfo, tmp, &sdbg_host->dev_info_list, |
3138 | sdbg_devinfo = list_entry(lh, struct sdebug_dev_info, | 2999 | dev_list) { |
3139 | dev_list); | ||
3140 | list_del(&sdbg_devinfo->dev_list); | 3000 | list_del(&sdbg_devinfo->dev_list); |
3141 | kfree(sdbg_devinfo); | 3001 | kfree(sdbg_devinfo); |
3142 | } | 3002 | } |
@@ -3145,20 +3005,15 @@ static int sdebug_driver_remove(struct device * dev) | |||
3145 | return 0; | 3005 | return 0; |
3146 | } | 3006 | } |
3147 | 3007 | ||
3148 | static void sdebug_max_tgts_luns(void) | 3008 | static int pseudo_lld_bus_match(struct device *dev, |
3009 | struct device_driver *dev_driver) | ||
3149 | { | 3010 | { |
3150 | struct sdebug_host_info * sdbg_host; | 3011 | return 1; |
3151 | struct Scsi_Host *hpnt; | ||
3152 | |||
3153 | spin_lock(&sdebug_host_list_lock); | ||
3154 | list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) { | ||
3155 | hpnt = sdbg_host->shost; | ||
3156 | if ((hpnt->this_id >= 0) && | ||
3157 | (scsi_debug_num_tgts > hpnt->this_id)) | ||
3158 | hpnt->max_id = scsi_debug_num_tgts + 1; | ||
3159 | else | ||
3160 | hpnt->max_id = scsi_debug_num_tgts; | ||
3161 | hpnt->max_lun = SAM2_WLUN_REPORT_LUNS; /* scsi_debug_max_luns; */ | ||
3162 | } | ||
3163 | spin_unlock(&sdebug_host_list_lock); | ||
3164 | } | 3012 | } |
3013 | |||
3014 | static struct bus_type pseudo_lld_bus = { | ||
3015 | .name = "pseudo", | ||
3016 | .match = pseudo_lld_bus_match, | ||
3017 | .probe = sdebug_driver_probe, | ||
3018 | .remove = sdebug_driver_remove, | ||
3019 | }; | ||
diff --git a/drivers/scsi/scsi_debug.h b/drivers/scsi/scsi_debug.h deleted file mode 100644 index 965dd5e760c1..000000000000 --- a/drivers/scsi/scsi_debug.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | #ifndef _SCSI_DEBUG_H | ||
2 | |||
3 | #include <linux/types.h> | ||
4 | |||
5 | static int scsi_debug_slave_alloc(struct scsi_device *); | ||
6 | static int scsi_debug_slave_configure(struct scsi_device *); | ||
7 | static void scsi_debug_slave_destroy(struct scsi_device *); | ||
8 | static int scsi_debug_queuecommand(struct scsi_cmnd *, | ||
9 | void (*done) (struct scsi_cmnd *)); | ||
10 | static int scsi_debug_ioctl(struct scsi_device *, int, void __user *); | ||
11 | static int scsi_debug_biosparam(struct scsi_device *, struct block_device *, | ||
12 | sector_t, int[]); | ||
13 | static int scsi_debug_abort(struct scsi_cmnd *); | ||
14 | static int scsi_debug_bus_reset(struct scsi_cmnd *); | ||
15 | static int scsi_debug_device_reset(struct scsi_cmnd *); | ||
16 | static int scsi_debug_host_reset(struct scsi_cmnd *); | ||
17 | static int scsi_debug_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); | ||
18 | static const char * scsi_debug_info(struct Scsi_Host *); | ||
19 | |||
20 | #define SCSI_DEBUG_CANQUEUE 255 /* needs to be >= 1 */ | ||
21 | |||
22 | #define SCSI_DEBUG_MAX_CMD_LEN 16 | ||
23 | |||
24 | #endif | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 045a0868fc7b..221f31e36d26 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -524,6 +524,41 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd) | |||
524 | return rtn; | 524 | return rtn; |
525 | } | 525 | } |
526 | 526 | ||
527 | static void __scsi_report_device_reset(struct scsi_device *sdev, void *data) | ||
528 | { | ||
529 | sdev->was_reset = 1; | ||
530 | sdev->expecting_cc_ua = 1; | ||
531 | } | ||
532 | |||
533 | /** | ||
534 | * scsi_try_target_reset - Ask host to perform a target reset | ||
535 | * @scmd: SCSI cmd used to send a target reset | ||
536 | * | ||
537 | * Notes: | ||
538 | * There is no timeout for this operation. if this operation is | ||
539 | * unreliable for a given host, then the host itself needs to put a | ||
540 | * timer on it, and set the host back to a consistent state prior to | ||
541 | * returning. | ||
542 | */ | ||
543 | static int scsi_try_target_reset(struct scsi_cmnd *scmd) | ||
544 | { | ||
545 | unsigned long flags; | ||
546 | int rtn; | ||
547 | |||
548 | if (!scmd->device->host->hostt->eh_target_reset_handler) | ||
549 | return FAILED; | ||
550 | |||
551 | rtn = scmd->device->host->hostt->eh_target_reset_handler(scmd); | ||
552 | if (rtn == SUCCESS) { | ||
553 | spin_lock_irqsave(scmd->device->host->host_lock, flags); | ||
554 | __starget_for_each_device(scsi_target(scmd->device), NULL, | ||
555 | __scsi_report_device_reset); | ||
556 | spin_unlock_irqrestore(scmd->device->host->host_lock, flags); | ||
557 | } | ||
558 | |||
559 | return rtn; | ||
560 | } | ||
561 | |||
527 | /** | 562 | /** |
528 | * scsi_try_bus_device_reset - Ask host to perform a BDR on a dev | 563 | * scsi_try_bus_device_reset - Ask host to perform a BDR on a dev |
529 | * @scmd: SCSI cmd used to send BDR | 564 | * @scmd: SCSI cmd used to send BDR |
@@ -542,11 +577,8 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) | |||
542 | return FAILED; | 577 | return FAILED; |
543 | 578 | ||
544 | rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd); | 579 | rtn = scmd->device->host->hostt->eh_device_reset_handler(scmd); |
545 | if (rtn == SUCCESS) { | 580 | if (rtn == SUCCESS) |
546 | scmd->device->was_reset = 1; | 581 | __scsi_report_device_reset(scmd->device, NULL); |
547 | scmd->device->expecting_cc_ua = 1; | ||
548 | } | ||
549 | |||
550 | return rtn; | 582 | return rtn; |
551 | } | 583 | } |
552 | 584 | ||
@@ -584,8 +616,9 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) | |||
584 | { | 616 | { |
585 | if (__scsi_try_to_abort_cmd(scmd) != SUCCESS) | 617 | if (__scsi_try_to_abort_cmd(scmd) != SUCCESS) |
586 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) | 618 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) |
587 | if (scsi_try_bus_reset(scmd) != SUCCESS) | 619 | if (scsi_try_target_reset(scmd) != SUCCESS) |
588 | scsi_try_host_reset(scmd); | 620 | if (scsi_try_bus_reset(scmd) != SUCCESS) |
621 | scsi_try_host_reset(scmd); | ||
589 | } | 622 | } |
590 | 623 | ||
591 | /** | 624 | /** |
@@ -1060,6 +1093,56 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost, | |||
1060 | } | 1093 | } |
1061 | 1094 | ||
1062 | /** | 1095 | /** |
1096 | * scsi_eh_target_reset - send target reset if needed | ||
1097 | * @shost: scsi host being recovered. | ||
1098 | * @work_q: &list_head for pending commands. | ||
1099 | * @done_q: &list_head for processed commands. | ||
1100 | * | ||
1101 | * Notes: | ||
1102 | * Try a target reset. | ||
1103 | */ | ||
1104 | static int scsi_eh_target_reset(struct Scsi_Host *shost, | ||
1105 | struct list_head *work_q, | ||
1106 | struct list_head *done_q) | ||
1107 | { | ||
1108 | struct scsi_cmnd *scmd, *tgtr_scmd, *next; | ||
1109 | unsigned int id; | ||
1110 | int rtn; | ||
1111 | |||
1112 | for (id = 0; id <= shost->max_id; id++) { | ||
1113 | tgtr_scmd = NULL; | ||
1114 | list_for_each_entry(scmd, work_q, eh_entry) { | ||
1115 | if (id == scmd_id(scmd)) { | ||
1116 | tgtr_scmd = scmd; | ||
1117 | break; | ||
1118 | } | ||
1119 | } | ||
1120 | if (!tgtr_scmd) | ||
1121 | continue; | ||
1122 | |||
1123 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset " | ||
1124 | "to target %d\n", | ||
1125 | current->comm, id)); | ||
1126 | rtn = scsi_try_target_reset(tgtr_scmd); | ||
1127 | if (rtn == SUCCESS) { | ||
1128 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { | ||
1129 | if (id == scmd_id(scmd)) | ||
1130 | if (!scsi_device_online(scmd->device) || | ||
1131 | !scsi_eh_tur(tgtr_scmd)) | ||
1132 | scsi_eh_finish_cmd(scmd, | ||
1133 | done_q); | ||
1134 | } | ||
1135 | } else | ||
1136 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Target reset" | ||
1137 | " failed target: " | ||
1138 | "%d\n", | ||
1139 | current->comm, id)); | ||
1140 | } | ||
1141 | |||
1142 | return list_empty(work_q); | ||
1143 | } | ||
1144 | |||
1145 | /** | ||
1063 | * scsi_eh_bus_reset - send a bus reset | 1146 | * scsi_eh_bus_reset - send a bus reset |
1064 | * @shost: &scsi host being recovered. | 1147 | * @shost: &scsi host being recovered. |
1065 | * @work_q: &list_head for pending commands. | 1148 | * @work_q: &list_head for pending commands. |
@@ -1447,9 +1530,11 @@ void scsi_eh_ready_devs(struct Scsi_Host *shost, | |||
1447 | { | 1530 | { |
1448 | if (!scsi_eh_stu(shost, work_q, done_q)) | 1531 | if (!scsi_eh_stu(shost, work_q, done_q)) |
1449 | if (!scsi_eh_bus_device_reset(shost, work_q, done_q)) | 1532 | if (!scsi_eh_bus_device_reset(shost, work_q, done_q)) |
1450 | if (!scsi_eh_bus_reset(shost, work_q, done_q)) | 1533 | if (!scsi_eh_target_reset(shost, work_q, done_q)) |
1451 | if (!scsi_eh_host_reset(work_q, done_q)) | 1534 | if (!scsi_eh_bus_reset(shost, work_q, done_q)) |
1452 | scsi_eh_offline_sdevs(work_q, done_q); | 1535 | if (!scsi_eh_host_reset(work_q, done_q)) |
1536 | scsi_eh_offline_sdevs(work_q, | ||
1537 | done_q); | ||
1453 | } | 1538 | } |
1454 | EXPORT_SYMBOL_GPL(scsi_eh_ready_devs); | 1539 | EXPORT_SYMBOL_GPL(scsi_eh_ready_devs); |
1455 | 1540 | ||
@@ -1619,10 +1704,8 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel) | |||
1619 | struct scsi_device *sdev; | 1704 | struct scsi_device *sdev; |
1620 | 1705 | ||
1621 | __shost_for_each_device(sdev, shost) { | 1706 | __shost_for_each_device(sdev, shost) { |
1622 | if (channel == sdev_channel(sdev)) { | 1707 | if (channel == sdev_channel(sdev)) |
1623 | sdev->was_reset = 1; | 1708 | __scsi_report_device_reset(sdev, NULL); |
1624 | sdev->expecting_cc_ua = 1; | ||
1625 | } | ||
1626 | } | 1709 | } |
1627 | } | 1710 | } |
1628 | EXPORT_SYMBOL(scsi_report_bus_reset); | 1711 | EXPORT_SYMBOL(scsi_report_bus_reset); |
@@ -1655,10 +1738,8 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target) | |||
1655 | 1738 | ||
1656 | __shost_for_each_device(sdev, shost) { | 1739 | __shost_for_each_device(sdev, shost) { |
1657 | if (channel == sdev_channel(sdev) && | 1740 | if (channel == sdev_channel(sdev) && |
1658 | target == sdev_id(sdev)) { | 1741 | target == sdev_id(sdev)) |
1659 | sdev->was_reset = 1; | 1742 | __scsi_report_device_reset(sdev, NULL); |
1660 | sdev->expecting_cc_ua = 1; | ||
1661 | } | ||
1662 | } | 1743 | } |
1663 | } | 1744 | } |
1664 | EXPORT_SYMBOL(scsi_report_device_reset); | 1745 | EXPORT_SYMBOL(scsi_report_device_reset); |
@@ -1714,6 +1795,11 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1714 | if (rtn == SUCCESS) | 1795 | if (rtn == SUCCESS) |
1715 | break; | 1796 | break; |
1716 | /* FALLTHROUGH */ | 1797 | /* FALLTHROUGH */ |
1798 | case SCSI_TRY_RESET_TARGET: | ||
1799 | rtn = scsi_try_target_reset(scmd); | ||
1800 | if (rtn == SUCCESS) | ||
1801 | break; | ||
1802 | /* FALLTHROUGH */ | ||
1717 | case SCSI_TRY_RESET_BUS: | 1803 | case SCSI_TRY_RESET_BUS: |
1718 | rtn = scsi_try_bus_reset(scmd); | 1804 | rtn = scsi_try_bus_reset(scmd); |
1719 | if (rtn == SUCCESS) | 1805 | if (rtn == SUCCESS) |
@@ -1907,3 +1993,31 @@ int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, | |||
1907 | } | 1993 | } |
1908 | } | 1994 | } |
1909 | EXPORT_SYMBOL(scsi_get_sense_info_fld); | 1995 | EXPORT_SYMBOL(scsi_get_sense_info_fld); |
1996 | |||
1997 | /** | ||
1998 | * scsi_build_sense_buffer - build sense data in a buffer | ||
1999 | * @desc: Sense format (non zero == descriptor format, | ||
2000 | * 0 == fixed format) | ||
2001 | * @buf: Where to build sense data | ||
2002 | * @key: Sense key | ||
2003 | * @asc: Additional sense code | ||
2004 | * @ascq: Additional sense code qualifier | ||
2005 | * | ||
2006 | **/ | ||
2007 | void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq) | ||
2008 | { | ||
2009 | if (desc) { | ||
2010 | buf[0] = 0x72; /* descriptor, current */ | ||
2011 | buf[1] = key; | ||
2012 | buf[2] = asc; | ||
2013 | buf[3] = ascq; | ||
2014 | buf[7] = 0; | ||
2015 | } else { | ||
2016 | buf[0] = 0x70; /* fixed, current */ | ||
2017 | buf[2] = key; | ||
2018 | buf[7] = 0xa; | ||
2019 | buf[12] = asc; | ||
2020 | buf[13] = ascq; | ||
2021 | } | ||
2022 | } | ||
2023 | EXPORT_SYMBOL(scsi_build_sense_buffer); | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index f40898dc2d14..67f412bb4974 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -784,7 +784,7 @@ EXPORT_SYMBOL(scsi_release_buffers); | |||
784 | * in req->data_len and req->next_rq->data_len. The upper-layer driver can | 784 | * in req->data_len and req->next_rq->data_len. The upper-layer driver can |
785 | * decide what to do with this information. | 785 | * decide what to do with this information. |
786 | */ | 786 | */ |
787 | void scsi_end_bidi_request(struct scsi_cmnd *cmd) | 787 | static void scsi_end_bidi_request(struct scsi_cmnd *cmd) |
788 | { | 788 | { |
789 | struct request *req = cmd->request; | 789 | struct request *req = cmd->request; |
790 | unsigned int dlen = req->data_len; | 790 | unsigned int dlen = req->data_len; |
@@ -839,7 +839,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
839 | int this_count = scsi_bufflen(cmd); | 839 | int this_count = scsi_bufflen(cmd); |
840 | struct request_queue *q = cmd->device->request_queue; | 840 | struct request_queue *q = cmd->device->request_queue; |
841 | struct request *req = cmd->request; | 841 | struct request *req = cmd->request; |
842 | int clear_errors = 1; | 842 | int error = 0; |
843 | struct scsi_sense_hdr sshdr; | 843 | struct scsi_sense_hdr sshdr; |
844 | int sense_valid = 0; | 844 | int sense_valid = 0; |
845 | int sense_deferred = 0; | 845 | int sense_deferred = 0; |
@@ -853,7 +853,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
853 | if (blk_pc_request(req)) { /* SG_IO ioctl from block level */ | 853 | if (blk_pc_request(req)) { /* SG_IO ioctl from block level */ |
854 | req->errors = result; | 854 | req->errors = result; |
855 | if (result) { | 855 | if (result) { |
856 | clear_errors = 0; | ||
857 | if (sense_valid && req->sense) { | 856 | if (sense_valid && req->sense) { |
858 | /* | 857 | /* |
859 | * SG_IO wants current and deferred errors | 858 | * SG_IO wants current and deferred errors |
@@ -865,6 +864,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
865 | memcpy(req->sense, cmd->sense_buffer, len); | 864 | memcpy(req->sense, cmd->sense_buffer, len); |
866 | req->sense_len = len; | 865 | req->sense_len = len; |
867 | } | 866 | } |
867 | if (!sense_deferred) | ||
868 | error = -EIO; | ||
868 | } | 869 | } |
869 | if (scsi_bidi_cmnd(cmd)) { | 870 | if (scsi_bidi_cmnd(cmd)) { |
870 | /* will also release_buffers */ | 871 | /* will also release_buffers */ |
@@ -885,14 +886,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
885 | "%d bytes done.\n", | 886 | "%d bytes done.\n", |
886 | req->nr_sectors, good_bytes)); | 887 | req->nr_sectors, good_bytes)); |
887 | 888 | ||
888 | if (clear_errors) | ||
889 | req->errors = 0; | ||
890 | |||
891 | /* A number of bytes were successfully read. If there | 889 | /* A number of bytes were successfully read. If there |
892 | * are leftovers and there is some kind of error | 890 | * are leftovers and there is some kind of error |
893 | * (result != 0), retry the rest. | 891 | * (result != 0), retry the rest. |
894 | */ | 892 | */ |
895 | if (scsi_end_request(cmd, 0, good_bytes, result == 0) == NULL) | 893 | if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL) |
896 | return; | 894 | return; |
897 | 895 | ||
898 | /* good_bytes = 0, or (inclusive) there were leftovers and | 896 | /* good_bytes = 0, or (inclusive) there were leftovers and |
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index a0f308bd145b..ee8496aa0336 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c | |||
@@ -621,9 +621,7 @@ static int __init scsi_tgt_init(void) | |||
621 | { | 621 | { |
622 | int err; | 622 | int err; |
623 | 623 | ||
624 | scsi_tgt_cmd_cache = kmem_cache_create("scsi_tgt_cmd", | 624 | scsi_tgt_cmd_cache = KMEM_CACHE(scsi_tgt_cmd, 0); |
625 | sizeof(struct scsi_tgt_cmd), | ||
626 | 0, 0, NULL); | ||
627 | if (!scsi_tgt_cmd_cache) | 625 | if (!scsi_tgt_cmd_cache) |
628 | return -ENOMEM; | 626 | return -ENOMEM; |
629 | 627 | ||
diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index 26cfc56c7091..03e359670506 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c | |||
@@ -263,10 +263,11 @@ static int __init sgiwd93_probe(struct platform_device *pdev) | |||
263 | regs.SASR = wdregs + 3; | 263 | regs.SASR = wdregs + 3; |
264 | regs.SCMD = wdregs + 7; | 264 | regs.SCMD = wdregs + 7; |
265 | 265 | ||
266 | wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_MHZ(20)); | 266 | hdata->wh.no_sync = 0; |
267 | hdata->wh.fast = 1; | ||
268 | hdata->wh.dma_mode = CTRL_BURST; | ||
267 | 269 | ||
268 | if (hdata->wh.no_sync == 0xff) | 270 | wd33c93_init(host, regs, dma_setup, dma_stop, WD33C93_FS_MHZ(20)); |
269 | hdata->wh.no_sync = 0; | ||
270 | 271 | ||
271 | err = request_irq(irq, sgiwd93_intr, 0, "SGI WD93", host); | 272 | err = request_irq(irq, sgiwd93_intr, 0, "SGI WD93", host); |
272 | if (err) { | 273 | if (err) { |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 0a52d9d2da2c..df83bea2c620 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -17,7 +17,7 @@ | |||
17 | Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support | 17 | Last modified: 18-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support |
18 | */ | 18 | */ |
19 | 19 | ||
20 | static const char *verstr = "20080221"; | 20 | static const char *verstr = "20080224"; |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
@@ -183,6 +183,7 @@ static int modes_defined; | |||
183 | 183 | ||
184 | static struct st_buffer *new_tape_buffer(int, int, int); | 184 | static struct st_buffer *new_tape_buffer(int, int, int); |
185 | static int enlarge_buffer(struct st_buffer *, int, int); | 185 | static int enlarge_buffer(struct st_buffer *, int, int); |
186 | static void clear_buffer(struct st_buffer *); | ||
186 | static void normalize_buffer(struct st_buffer *); | 187 | static void normalize_buffer(struct st_buffer *); |
187 | static int append_to_buffer(const char __user *, struct st_buffer *, int); | 188 | static int append_to_buffer(const char __user *, struct st_buffer *, int); |
188 | static int from_buffer(struct st_buffer *, char __user *, int); | 189 | static int from_buffer(struct st_buffer *, char __user *, int); |
@@ -442,6 +443,7 @@ static void st_sleep_done(void *data, char *sense, int result, int resid) | |||
442 | 443 | ||
443 | memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE); | 444 | memcpy(SRpnt->sense, sense, SCSI_SENSE_BUFFERSIZE); |
444 | (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result; | 445 | (STp->buffer)->cmdstat.midlevel_result = SRpnt->result = result; |
446 | (STp->buffer)->cmdstat.residual = resid; | ||
445 | DEB( STp->write_pending = 0; ) | 447 | DEB( STp->write_pending = 0; ) |
446 | 448 | ||
447 | if (SRpnt->waiting) | 449 | if (SRpnt->waiting) |
@@ -626,7 +628,7 @@ static int cross_eof(struct scsi_tape * STp, int forward) | |||
626 | 628 | ||
627 | 629 | ||
628 | /* Flush the write buffer (never need to write if variable blocksize). */ | 630 | /* Flush the write buffer (never need to write if variable blocksize). */ |
629 | static int flush_write_buffer(struct scsi_tape * STp) | 631 | static int st_flush_write_buffer(struct scsi_tape * STp) |
630 | { | 632 | { |
631 | int offset, transfer, blks; | 633 | int offset, transfer, blks; |
632 | int result; | 634 | int result; |
@@ -717,7 +719,7 @@ static int flush_buffer(struct scsi_tape *STp, int seek_next) | |||
717 | return 0; | 719 | return 0; |
718 | STps = &(STp->ps[STp->partition]); | 720 | STps = &(STp->ps[STp->partition]); |
719 | if (STps->rw == ST_WRITING) /* Writing */ | 721 | if (STps->rw == ST_WRITING) /* Writing */ |
720 | return flush_write_buffer(STp); | 722 | return st_flush_write_buffer(STp); |
721 | 723 | ||
722 | if (STp->block_size == 0) | 724 | if (STp->block_size == 0) |
723 | return 0; | 725 | return 0; |
@@ -1159,6 +1161,7 @@ static int st_open(struct inode *inode, struct file *filp) | |||
1159 | goto err_out; | 1161 | goto err_out; |
1160 | } | 1162 | } |
1161 | 1163 | ||
1164 | (STp->buffer)->cleared = 0; | ||
1162 | (STp->buffer)->writing = 0; | 1165 | (STp->buffer)->writing = 0; |
1163 | (STp->buffer)->syscall_result = 0; | 1166 | (STp->buffer)->syscall_result = 0; |
1164 | 1167 | ||
@@ -1211,7 +1214,7 @@ static int st_flush(struct file *filp, fl_owner_t id) | |||
1211 | return 0; | 1214 | return 0; |
1212 | 1215 | ||
1213 | if (STps->rw == ST_WRITING && !STp->pos_unknown) { | 1216 | if (STps->rw == ST_WRITING && !STp->pos_unknown) { |
1214 | result = flush_write_buffer(STp); | 1217 | result = st_flush_write_buffer(STp); |
1215 | if (result != 0 && result != (-ENOSPC)) | 1218 | if (result != 0 && result != (-ENOSPC)) |
1216 | goto out; | 1219 | goto out; |
1217 | } | 1220 | } |
@@ -1432,8 +1435,14 @@ static int setup_buffering(struct scsi_tape *STp, const char __user *buf, | |||
1432 | if (STp->block_size) | 1435 | if (STp->block_size) |
1433 | bufsize = STp->block_size > st_fixed_buffer_size ? | 1436 | bufsize = STp->block_size > st_fixed_buffer_size ? |
1434 | STp->block_size : st_fixed_buffer_size; | 1437 | STp->block_size : st_fixed_buffer_size; |
1435 | else | 1438 | else { |
1436 | bufsize = count; | 1439 | bufsize = count; |
1440 | /* Make sure that data from previous user is not leaked even if | ||
1441 | HBA does not return correct residual */ | ||
1442 | if (is_read && STp->sili && !STbp->cleared) | ||
1443 | clear_buffer(STbp); | ||
1444 | } | ||
1445 | |||
1437 | if (bufsize > STbp->buffer_size && | 1446 | if (bufsize > STbp->buffer_size && |
1438 | !enlarge_buffer(STbp, bufsize, STp->restr_dma)) { | 1447 | !enlarge_buffer(STbp, bufsize, STp->restr_dma)) { |
1439 | printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n", | 1448 | printk(KERN_WARNING "%s: Can't allocate %d byte tape buffer.\n", |
@@ -1783,6 +1792,8 @@ static long read_tape(struct scsi_tape *STp, long count, | |||
1783 | memset(cmd, 0, MAX_COMMAND_SIZE); | 1792 | memset(cmd, 0, MAX_COMMAND_SIZE); |
1784 | cmd[0] = READ_6; | 1793 | cmd[0] = READ_6; |
1785 | cmd[1] = (STp->block_size != 0); | 1794 | cmd[1] = (STp->block_size != 0); |
1795 | if (!cmd[1] && STp->sili) | ||
1796 | cmd[1] |= 2; | ||
1786 | cmd[2] = blks >> 16; | 1797 | cmd[2] = blks >> 16; |
1787 | cmd[3] = blks >> 8; | 1798 | cmd[3] = blks >> 8; |
1788 | cmd[4] = blks; | 1799 | cmd[4] = blks; |
@@ -1911,8 +1922,11 @@ static long read_tape(struct scsi_tape *STp, long count, | |||
1911 | 1922 | ||
1912 | } | 1923 | } |
1913 | /* End of error handling */ | 1924 | /* End of error handling */ |
1914 | else /* Read successful */ | 1925 | else { /* Read successful */ |
1915 | STbp->buffer_bytes = bytes; | 1926 | STbp->buffer_bytes = bytes; |
1927 | if (STp->sili) /* In fixed block mode residual is always zero here */ | ||
1928 | STbp->buffer_bytes -= STp->buffer->cmdstat.residual; | ||
1929 | } | ||
1916 | 1930 | ||
1917 | if (STps->drv_block >= 0) { | 1931 | if (STps->drv_block >= 0) { |
1918 | if (STp->block_size == 0) | 1932 | if (STp->block_size == 0) |
@@ -2090,7 +2104,8 @@ static void st_log_options(struct scsi_tape * STp, struct st_modedef * STm, char | |||
2090 | name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions, | 2104 | name, STm->defaults_for_writes, STp->omit_blklims, STp->can_partitions, |
2091 | STp->scsi2_logical); | 2105 | STp->scsi2_logical); |
2092 | printk(KERN_INFO | 2106 | printk(KERN_INFO |
2093 | "%s: sysv: %d nowait: %d\n", name, STm->sysv, STp->immediate); | 2107 | "%s: sysv: %d nowait: %d sili: %d\n", name, STm->sysv, STp->immediate, |
2108 | STp->sili); | ||
2094 | printk(KERN_INFO "%s: debugging: %d\n", | 2109 | printk(KERN_INFO "%s: debugging: %d\n", |
2095 | name, debugging); | 2110 | name, debugging); |
2096 | } | 2111 | } |
@@ -2133,6 +2148,7 @@ static int st_set_options(struct scsi_tape *STp, long options) | |||
2133 | STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0; | 2148 | STp->scsi2_logical = (options & MT_ST_SCSI2LOGICAL) != 0; |
2134 | STp->immediate = (options & MT_ST_NOWAIT) != 0; | 2149 | STp->immediate = (options & MT_ST_NOWAIT) != 0; |
2135 | STm->sysv = (options & MT_ST_SYSV) != 0; | 2150 | STm->sysv = (options & MT_ST_SYSV) != 0; |
2151 | STp->sili = (options & MT_ST_SILI) != 0; | ||
2136 | DEB( debugging = (options & MT_ST_DEBUGGING) != 0; | 2152 | DEB( debugging = (options & MT_ST_DEBUGGING) != 0; |
2137 | st_log_options(STp, STm, name); ) | 2153 | st_log_options(STp, STm, name); ) |
2138 | } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) { | 2154 | } else if (code == MT_ST_SETBOOLEANS || code == MT_ST_CLEARBOOLEANS) { |
@@ -2164,6 +2180,8 @@ static int st_set_options(struct scsi_tape *STp, long options) | |||
2164 | STp->immediate = value; | 2180 | STp->immediate = value; |
2165 | if ((options & MT_ST_SYSV) != 0) | 2181 | if ((options & MT_ST_SYSV) != 0) |
2166 | STm->sysv = value; | 2182 | STm->sysv = value; |
2183 | if ((options & MT_ST_SILI) != 0) | ||
2184 | STp->sili = value; | ||
2167 | DEB( | 2185 | DEB( |
2168 | if ((options & MT_ST_DEBUGGING) != 0) | 2186 | if ((options & MT_ST_DEBUGGING) != 0) |
2169 | debugging = value; | 2187 | debugging = value; |
@@ -3655,6 +3673,8 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm | |||
3655 | STbuffer->frp_segs += 1; | 3673 | STbuffer->frp_segs += 1; |
3656 | got += b_size; | 3674 | got += b_size; |
3657 | STbuffer->buffer_size = got; | 3675 | STbuffer->buffer_size = got; |
3676 | if (STbuffer->cleared) | ||
3677 | memset(page_address(STbuffer->frp[segs].page), 0, b_size); | ||
3658 | segs++; | 3678 | segs++; |
3659 | } | 3679 | } |
3660 | STbuffer->b_data = page_address(STbuffer->frp[0].page); | 3680 | STbuffer->b_data = page_address(STbuffer->frp[0].page); |
@@ -3663,6 +3683,17 @@ static int enlarge_buffer(struct st_buffer * STbuffer, int new_size, int need_dm | |||
3663 | } | 3683 | } |
3664 | 3684 | ||
3665 | 3685 | ||
3686 | /* Make sure that no data from previous user is in the internal buffer */ | ||
3687 | static void clear_buffer(struct st_buffer * st_bp) | ||
3688 | { | ||
3689 | int i; | ||
3690 | |||
3691 | for (i=0; i < st_bp->frp_segs; i++) | ||
3692 | memset(page_address(st_bp->frp[i].page), 0, st_bp->frp[i].length); | ||
3693 | st_bp->cleared = 1; | ||
3694 | } | ||
3695 | |||
3696 | |||
3666 | /* Release the extra buffer */ | 3697 | /* Release the extra buffer */ |
3667 | static void normalize_buffer(struct st_buffer * STbuffer) | 3698 | static void normalize_buffer(struct st_buffer * STbuffer) |
3668 | { | 3699 | { |
@@ -3987,6 +4018,7 @@ static int st_probe(struct device *dev) | |||
3987 | tpnt->two_fm = ST_TWO_FM; | 4018 | tpnt->two_fm = ST_TWO_FM; |
3988 | tpnt->fast_mteom = ST_FAST_MTEOM; | 4019 | tpnt->fast_mteom = ST_FAST_MTEOM; |
3989 | tpnt->scsi2_logical = ST_SCSI2LOGICAL; | 4020 | tpnt->scsi2_logical = ST_SCSI2LOGICAL; |
4021 | tpnt->sili = ST_SILI; | ||
3990 | tpnt->immediate = ST_NOWAIT; | 4022 | tpnt->immediate = ST_NOWAIT; |
3991 | tpnt->default_drvbuffer = 0xff; /* No forced buffering */ | 4023 | tpnt->default_drvbuffer = 0xff; /* No forced buffering */ |
3992 | tpnt->partition = 0; | 4024 | tpnt->partition = 0; |
@@ -4333,6 +4365,46 @@ static ssize_t st_defcompression_show(struct class_device *class_dev, char *buf) | |||
4333 | 4365 | ||
4334 | CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL); | 4366 | CLASS_DEVICE_ATTR(default_compression, S_IRUGO, st_defcompression_show, NULL); |
4335 | 4367 | ||
4368 | static ssize_t st_options_show(struct class_device *class_dev, char *buf) | ||
4369 | { | ||
4370 | struct st_modedef *STm = (struct st_modedef *)class_get_devdata(class_dev); | ||
4371 | struct scsi_tape *STp; | ||
4372 | int i, j, options; | ||
4373 | ssize_t l = 0; | ||
4374 | |||
4375 | for (i=0; i < st_dev_max; i++) { | ||
4376 | for (j=0; j < ST_NBR_MODES; j++) | ||
4377 | if (&scsi_tapes[i]->modes[j] == STm) | ||
4378 | break; | ||
4379 | if (j < ST_NBR_MODES) | ||
4380 | break; | ||
4381 | } | ||
4382 | if (i == st_dev_max) | ||
4383 | return 0; /* should never happen */ | ||
4384 | |||
4385 | STp = scsi_tapes[i]; | ||
4386 | |||
4387 | options = STm->do_buffer_writes ? MT_ST_BUFFER_WRITES : 0; | ||
4388 | options |= STm->do_async_writes ? MT_ST_ASYNC_WRITES : 0; | ||
4389 | options |= STm->do_read_ahead ? MT_ST_READ_AHEAD : 0; | ||
4390 | DEB( options |= debugging ? MT_ST_DEBUGGING : 0 ); | ||
4391 | options |= STp->two_fm ? MT_ST_TWO_FM : 0; | ||
4392 | options |= STp->fast_mteom ? MT_ST_FAST_MTEOM : 0; | ||
4393 | options |= STm->defaults_for_writes ? MT_ST_DEF_WRITES : 0; | ||
4394 | options |= STp->can_bsr ? MT_ST_CAN_BSR : 0; | ||
4395 | options |= STp->omit_blklims ? MT_ST_NO_BLKLIMS : 0; | ||
4396 | options |= STp->can_partitions ? MT_ST_CAN_PARTITIONS : 0; | ||
4397 | options |= STp->scsi2_logical ? MT_ST_SCSI2LOGICAL : 0; | ||
4398 | options |= STm->sysv ? MT_ST_SYSV : 0; | ||
4399 | options |= STp->immediate ? MT_ST_NOWAIT : 0; | ||
4400 | options |= STp->sili ? MT_ST_SILI : 0; | ||
4401 | |||
4402 | l = snprintf(buf, PAGE_SIZE, "0x%08x\n", options); | ||
4403 | return l; | ||
4404 | } | ||
4405 | |||
4406 | CLASS_DEVICE_ATTR(options, S_IRUGO, st_options_show, NULL); | ||
4407 | |||
4336 | static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) | 4408 | static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) |
4337 | { | 4409 | { |
4338 | int i, rew, error; | 4410 | int i, rew, error; |
@@ -4370,6 +4442,9 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode) | |||
4370 | error = class_device_create_file(st_class_member, | 4442 | error = class_device_create_file(st_class_member, |
4371 | &class_device_attr_default_compression); | 4443 | &class_device_attr_default_compression); |
4372 | if (error) goto out; | 4444 | if (error) goto out; |
4445 | error = class_device_create_file(st_class_member, | ||
4446 | &class_device_attr_options); | ||
4447 | if (error) goto out; | ||
4373 | 4448 | ||
4374 | if (mode == 0 && rew == 0) { | 4449 | if (mode == 0 && rew == 0) { |
4375 | error = sysfs_create_link(&STp->device->sdev_gendev.kobj, | 4450 | error = sysfs_create_link(&STp->device->sdev_gendev.kobj, |
diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 5931726fcf93..b92712f95931 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h | |||
@@ -12,6 +12,7 @@ struct st_cmdstatus { | |||
12 | int midlevel_result; | 12 | int midlevel_result; |
13 | struct scsi_sense_hdr sense_hdr; | 13 | struct scsi_sense_hdr sense_hdr; |
14 | int have_sense; | 14 | int have_sense; |
15 | int residual; | ||
15 | u64 uremainder64; | 16 | u64 uremainder64; |
16 | u8 flags; | 17 | u8 flags; |
17 | u8 remainder_valid; | 18 | u8 remainder_valid; |
@@ -34,6 +35,7 @@ struct st_request { | |||
34 | struct st_buffer { | 35 | struct st_buffer { |
35 | unsigned char dma; /* DMA-able buffer */ | 36 | unsigned char dma; /* DMA-able buffer */ |
36 | unsigned char do_dio; /* direct i/o set up? */ | 37 | unsigned char do_dio; /* direct i/o set up? */ |
38 | unsigned char cleared; /* internal buffer cleared after open? */ | ||
37 | int buffer_size; | 39 | int buffer_size; |
38 | int buffer_blocks; | 40 | int buffer_blocks; |
39 | int buffer_bytes; | 41 | int buffer_bytes; |
@@ -122,6 +124,7 @@ struct scsi_tape { | |||
122 | unsigned char try_dio_now; /* try direct i/o before next close? */ | 124 | unsigned char try_dio_now; /* try direct i/o before next close? */ |
123 | unsigned char c_algo; /* compression algorithm */ | 125 | unsigned char c_algo; /* compression algorithm */ |
124 | unsigned char pos_unknown; /* after reset position unknown */ | 126 | unsigned char pos_unknown; /* after reset position unknown */ |
127 | unsigned char sili; /* use SILI when reading in variable b mode */ | ||
125 | int tape_type; | 128 | int tape_type; |
126 | int long_timeout; /* timeout for commands known to take long time */ | 129 | int long_timeout; /* timeout for commands known to take long time */ |
127 | 130 | ||
diff --git a/drivers/scsi/st_options.h b/drivers/scsi/st_options.h index b6b5c9c37677..d2f947935554 100644 --- a/drivers/scsi/st_options.h +++ b/drivers/scsi/st_options.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | Copyright 1995-2003 Kai Makisara. | 4 | Copyright 1995-2003 Kai Makisara. |
5 | 5 | ||
6 | Last modified: Mon Apr 7 22:49:18 2003 by makisara | 6 | Last modified: Thu Feb 21 21:47:07 2008 by kai.makisara |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #ifndef _ST_OPTIONS_H | 9 | #ifndef _ST_OPTIONS_H |
@@ -94,6 +94,10 @@ | |||
94 | The default is BSD semantics. */ | 94 | The default is BSD semantics. */ |
95 | #define ST_SYSV 0 | 95 | #define ST_SYSV 0 |
96 | 96 | ||
97 | /* If ST_SILI is non-zero, the SILI bit is set when reading in variable block | ||
98 | mode and the block size is determined using the residual returned by the HBA. */ | ||
99 | #define ST_SILI 0 | ||
100 | |||
97 | /* Time to wait for the drive to become ready if blocking open */ | 101 | /* Time to wait for the drive to become ready if blocking open */ |
98 | #define ST_BLOCK_SECONDS 120 | 102 | #define ST_BLOCK_SECONDS 120 |
99 | 103 | ||
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 654430edf74d..f308a0308829 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <scsi/scsi_host.h> | 33 | #include <scsi/scsi_host.h> |
34 | #include <scsi/scsi_tcq.h> | 34 | #include <scsi/scsi_tcq.h> |
35 | #include <scsi/scsi_dbg.h> | 35 | #include <scsi/scsi_dbg.h> |
36 | #include <scsi/scsi_eh.h> | ||
36 | 37 | ||
37 | #define DRV_NAME "stex" | 38 | #define DRV_NAME "stex" |
38 | #define ST_DRIVER_VERSION "3.6.0000.1" | 39 | #define ST_DRIVER_VERSION "3.6.0000.1" |
@@ -362,22 +363,14 @@ static struct status_msg *stex_get_status(struct st_hba *hba) | |||
362 | return status; | 363 | return status; |
363 | } | 364 | } |
364 | 365 | ||
365 | static void stex_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) | ||
366 | { | ||
367 | cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | ||
368 | |||
369 | cmd->sense_buffer[0] = 0x70; /* fixed format, current */ | ||
370 | cmd->sense_buffer[2] = sk; | ||
371 | cmd->sense_buffer[7] = 18 - 8; /* additional sense length */ | ||
372 | cmd->sense_buffer[12] = asc; | ||
373 | cmd->sense_buffer[13] = ascq; | ||
374 | } | ||
375 | |||
376 | static void stex_invalid_field(struct scsi_cmnd *cmd, | 366 | static void stex_invalid_field(struct scsi_cmnd *cmd, |
377 | void (*done)(struct scsi_cmnd *)) | 367 | void (*done)(struct scsi_cmnd *)) |
378 | { | 368 | { |
369 | cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | ||
370 | |||
379 | /* "Invalid field in cbd" */ | 371 | /* "Invalid field in cbd" */ |
380 | stex_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0); | 372 | scsi_build_sense_buffer(0, cmd->sense_buffer, ILLEGAL_REQUEST, 0x24, |
373 | 0x0); | ||
381 | done(cmd); | 374 | done(cmd); |
382 | } | 375 | } |
383 | 376 | ||
@@ -426,49 +419,13 @@ static int stex_map_sg(struct st_hba *hba, | |||
426 | return 0; | 419 | return 0; |
427 | } | 420 | } |
428 | 421 | ||
429 | static void stex_internal_copy(struct scsi_cmnd *cmd, | ||
430 | const void *src, size_t *count, int sg_count, int direction) | ||
431 | { | ||
432 | size_t lcount; | ||
433 | size_t len; | ||
434 | void *s, *d, *base = NULL; | ||
435 | size_t offset; | ||
436 | |||
437 | if (*count > scsi_bufflen(cmd)) | ||
438 | *count = scsi_bufflen(cmd); | ||
439 | lcount = *count; | ||
440 | while (lcount) { | ||
441 | len = lcount; | ||
442 | s = (void *)src; | ||
443 | |||
444 | offset = *count - lcount; | ||
445 | s += offset; | ||
446 | base = scsi_kmap_atomic_sg(scsi_sglist(cmd), | ||
447 | sg_count, &offset, &len); | ||
448 | if (!base) { | ||
449 | *count -= lcount; | ||
450 | return; | ||
451 | } | ||
452 | d = base + offset; | ||
453 | |||
454 | if (direction == ST_TO_CMD) | ||
455 | memcpy(d, s, len); | ||
456 | else | ||
457 | memcpy(s, d, len); | ||
458 | |||
459 | lcount -= len; | ||
460 | scsi_kunmap_atomic_sg(base); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | 422 | static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) |
465 | { | 423 | { |
466 | struct st_frame *p; | 424 | struct st_frame *p; |
467 | size_t count = sizeof(struct st_frame); | 425 | size_t count = sizeof(struct st_frame); |
468 | 426 | ||
469 | p = hba->copy_buffer; | 427 | p = hba->copy_buffer; |
470 | stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd), | 428 | count = scsi_sg_copy_to_buffer(ccb->cmd, p, count); |
471 | ST_FROM_CMD); | ||
472 | memset(p->base, 0, sizeof(u32)*6); | 429 | memset(p->base, 0, sizeof(u32)*6); |
473 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); | 430 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); |
474 | p->rom_addr = 0; | 431 | p->rom_addr = 0; |
@@ -486,8 +443,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | |||
486 | p->subid = | 443 | p->subid = |
487 | hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; | 444 | hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device; |
488 | 445 | ||
489 | stex_internal_copy(ccb->cmd, p, &count, scsi_sg_count(ccb->cmd), | 446 | count = scsi_sg_copy_from_buffer(ccb->cmd, p, count); |
490 | ST_TO_CMD); | ||
491 | } | 447 | } |
492 | 448 | ||
493 | static void | 449 | static void |
@@ -554,10 +510,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
554 | unsigned char page; | 510 | unsigned char page; |
555 | page = cmd->cmnd[2] & 0x3f; | 511 | page = cmd->cmnd[2] & 0x3f; |
556 | if (page == 0x8 || page == 0x3f) { | 512 | if (page == 0x8 || page == 0x3f) { |
557 | size_t cp_len = sizeof(ms10_caching_page); | 513 | scsi_sg_copy_from_buffer(cmd, ms10_caching_page, |
558 | stex_internal_copy(cmd, ms10_caching_page, | 514 | sizeof(ms10_caching_page)); |
559 | &cp_len, scsi_sg_count(cmd), | ||
560 | ST_TO_CMD); | ||
561 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | 515 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; |
562 | done(cmd); | 516 | done(cmd); |
563 | } else | 517 | } else |
@@ -586,10 +540,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
586 | if (id != host->max_id - 1) | 540 | if (id != host->max_id - 1) |
587 | break; | 541 | break; |
588 | if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { | 542 | if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) { |
589 | size_t cp_len = sizeof(console_inq_page); | 543 | scsi_sg_copy_from_buffer(cmd, (void *)console_inq_page, |
590 | stex_internal_copy(cmd, console_inq_page, | 544 | sizeof(console_inq_page)); |
591 | &cp_len, scsi_sg_count(cmd), | ||
592 | ST_TO_CMD); | ||
593 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; | 545 | cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8; |
594 | done(cmd); | 546 | done(cmd); |
595 | } else | 547 | } else |
@@ -606,8 +558,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) | |||
606 | ver.signature[0] = PASSTHRU_SIGNATURE; | 558 | ver.signature[0] = PASSTHRU_SIGNATURE; |
607 | ver.console_id = host->max_id - 1; | 559 | ver.console_id = host->max_id - 1; |
608 | ver.host_no = hba->host->host_no; | 560 | ver.host_no = hba->host->host_no; |
609 | stex_internal_copy(cmd, &ver, &cp_len, | 561 | cp_len = scsi_sg_copy_from_buffer(cmd, &ver, cp_len); |
610 | scsi_sg_count(cmd), ST_TO_CMD); | ||
611 | cmd->result = sizeof(ver) == cp_len ? | 562 | cmd->result = sizeof(ver) == cp_len ? |
612 | DID_OK << 16 | COMMAND_COMPLETE << 8 : | 563 | DID_OK << 16 | COMMAND_COMPLETE << 8 : |
613 | DID_ERROR << 16 | COMMAND_COMPLETE << 8; | 564 | DID_ERROR << 16 | COMMAND_COMPLETE << 8; |
@@ -700,15 +651,12 @@ static void stex_copy_data(struct st_ccb *ccb, | |||
700 | 651 | ||
701 | if (ccb->cmd == NULL) | 652 | if (ccb->cmd == NULL) |
702 | return; | 653 | return; |
703 | stex_internal_copy(ccb->cmd, | 654 | count = scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, count); |
704 | resp->variable, &count, scsi_sg_count(ccb->cmd), ST_TO_CMD); | ||
705 | } | 655 | } |
706 | 656 | ||
707 | static void stex_ys_commands(struct st_hba *hba, | 657 | static void stex_ys_commands(struct st_hba *hba, |
708 | struct st_ccb *ccb, struct status_msg *resp) | 658 | struct st_ccb *ccb, struct status_msg *resp) |
709 | { | 659 | { |
710 | size_t count; | ||
711 | |||
712 | if (ccb->cmd->cmnd[0] == MGT_CMD && | 660 | if (ccb->cmd->cmnd[0] == MGT_CMD && |
713 | resp->scsi_status != SAM_STAT_CHECK_CONDITION) { | 661 | resp->scsi_status != SAM_STAT_CHECK_CONDITION) { |
714 | scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - | 662 | scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) - |
@@ -724,9 +672,8 @@ static void stex_ys_commands(struct st_hba *hba, | |||
724 | resp->scsi_status == SAM_STAT_GOOD) { | 672 | resp->scsi_status == SAM_STAT_GOOD) { |
725 | ST_INQ *inq_data; | 673 | ST_INQ *inq_data; |
726 | 674 | ||
727 | count = STEX_EXTRA_SIZE; | 675 | scsi_sg_copy_to_buffer(ccb->cmd, hba->copy_buffer, |
728 | stex_internal_copy(ccb->cmd, hba->copy_buffer, | 676 | STEX_EXTRA_SIZE); |
729 | &count, scsi_sg_count(ccb->cmd), ST_FROM_CMD); | ||
730 | inq_data = (ST_INQ *)hba->copy_buffer; | 677 | inq_data = (ST_INQ *)hba->copy_buffer; |
731 | if (inq_data->DeviceTypeQualifier != 0) | 678 | if (inq_data->DeviceTypeQualifier != 0) |
732 | ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; | 679 | ccb->srb_status = SRB_STATUS_SELECTION_TIMEOUT; |
diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c index 02d9727f017a..aaa4fd0dd1b9 100644 --- a/drivers/scsi/sun3_scsi_vme.c +++ b/drivers/scsi/sun3_scsi_vme.c | |||
@@ -582,3 +582,4 @@ static struct scsi_host_template driver_template = { | |||
582 | 582 | ||
583 | #include "scsi_module.c" | 583 | #include "scsi_module.c" |
584 | 584 | ||
585 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index f286c37da7e0..5fda881c2470 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c | |||
@@ -1973,10 +1973,7 @@ wd33c93_init(struct Scsi_Host *instance, const wd33c93_regs regs, | |||
1973 | hostdata->incoming_ptr = 0; | 1973 | hostdata->incoming_ptr = 0; |
1974 | hostdata->outgoing_len = 0; | 1974 | hostdata->outgoing_len = 0; |
1975 | hostdata->default_sx_per = DEFAULT_SX_PER; | 1975 | hostdata->default_sx_per = DEFAULT_SX_PER; |
1976 | hostdata->no_sync = 0xff; /* sync defaults to off */ | ||
1977 | hostdata->no_dma = 0; /* default is DMA enabled */ | 1976 | hostdata->no_dma = 0; /* default is DMA enabled */ |
1978 | hostdata->fast = 0; /* default is Fast SCSI transfers disabled */ | ||
1979 | hostdata->dma_mode = CTRL_DMA; /* default is Single Byte DMA */ | ||
1980 | 1977 | ||
1981 | #ifdef PROC_INTERFACE | 1978 | #ifdef PROC_INTERFACE |
1982 | hostdata->proc = PR_VERSION | PR_INFO | PR_STATISTICS | | 1979 | hostdata->proc = PR_VERSION | PR_INFO | PR_STATISTICS | |
diff --git a/include/linux/attribute_container.h b/include/linux/attribute_container.h index f5582332af04..574b201b99d8 100644 --- a/include/linux/attribute_container.h +++ b/include/linux/attribute_container.h | |||
@@ -37,7 +37,7 @@ attribute_container_set_no_classdevs(struct attribute_container *atc) | |||
37 | } | 37 | } |
38 | 38 | ||
39 | int attribute_container_register(struct attribute_container *cont); | 39 | int attribute_container_register(struct attribute_container *cont); |
40 | int attribute_container_unregister(struct attribute_container *cont); | 40 | int __must_check attribute_container_unregister(struct attribute_container *cont); |
41 | void attribute_container_create_device(struct device *dev, | 41 | void attribute_container_create_device(struct device *dev, |
42 | int (*fn)(struct attribute_container *, | 42 | int (*fn)(struct attribute_container *, |
43 | struct device *, | 43 | struct device *, |
diff --git a/include/linux/mtio.h b/include/linux/mtio.h index 6f8d2d45a8fb..ef01d6aa5934 100644 --- a/include/linux/mtio.h +++ b/include/linux/mtio.h | |||
@@ -192,6 +192,7 @@ struct mtpos { | |||
192 | #define MT_ST_SCSI2LOGICAL 0x800 | 192 | #define MT_ST_SCSI2LOGICAL 0x800 |
193 | #define MT_ST_SYSV 0x1000 | 193 | #define MT_ST_SYSV 0x1000 |
194 | #define MT_ST_NOWAIT 0x2000 | 194 | #define MT_ST_NOWAIT 0x2000 |
195 | #define MT_ST_SILI 0x4000 | ||
195 | 196 | ||
196 | /* The mode parameters to be controlled. Parameter chosen with bits 20-28 */ | 197 | /* The mode parameters to be controlled. Parameter chosen with bits 20-28 */ |
197 | #define MT_ST_CLEAR_DEFAULT 0xfffff | 198 | #define MT_ST_CLEAR_DEFAULT 0xfffff |
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index a3d567a974e8..71fc81360048 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h | |||
@@ -213,6 +213,11 @@ int __sg_alloc_table(struct sg_table *, unsigned int, unsigned int, gfp_t, | |||
213 | sg_alloc_fn *); | 213 | sg_alloc_fn *); |
214 | int sg_alloc_table(struct sg_table *, unsigned int, gfp_t); | 214 | int sg_alloc_table(struct sg_table *, unsigned int, gfp_t); |
215 | 215 | ||
216 | size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents, | ||
217 | void *buf, size_t buflen); | ||
218 | size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents, | ||
219 | void *buf, size_t buflen); | ||
220 | |||
216 | /* | 221 | /* |
217 | * Maximum number of entries that will be allocated in one piece, if | 222 | * Maximum number of entries that will be allocated in one piece, if |
218 | * a list larger than this is required then chaining will be utilized. | 223 | * a list larger than this is required then chaining will be utilized. |
diff --git a/include/linux/transport_class.h b/include/linux/transport_class.h index 1d6cc22e5f42..6696cf79c4f7 100644 --- a/include/linux/transport_class.h +++ b/include/linux/transport_class.h | |||
@@ -86,9 +86,10 @@ static inline int transport_container_register(struct transport_container *tc) | |||
86 | return attribute_container_register(&tc->ac); | 86 | return attribute_container_register(&tc->ac); |
87 | } | 87 | } |
88 | 88 | ||
89 | static inline int transport_container_unregister(struct transport_container *tc) | 89 | static inline void transport_container_unregister(struct transport_container *tc) |
90 | { | 90 | { |
91 | return attribute_container_unregister(&tc->ac); | 91 | if (unlikely(attribute_container_unregister(&tc->ac))) |
92 | BUG(); | ||
92 | } | 93 | } |
93 | 94 | ||
94 | int transport_class_register(struct transport_class *); | 95 | int transport_class_register(struct transport_class *); |
diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h index 5ffec8ad6964..e0593bfae622 100644 --- a/include/scsi/iscsi_proto.h +++ b/include/scsi/iscsi_proto.h | |||
@@ -112,6 +112,7 @@ struct iscsi_ahs_hdr { | |||
112 | 112 | ||
113 | #define ISCSI_AHSTYPE_CDB 1 | 113 | #define ISCSI_AHSTYPE_CDB 1 |
114 | #define ISCSI_AHSTYPE_RLENGTH 2 | 114 | #define ISCSI_AHSTYPE_RLENGTH 2 |
115 | #define ISCSI_CDB_SIZE 16 | ||
115 | 116 | ||
116 | /* iSCSI PDU Header */ | 117 | /* iSCSI PDU Header */ |
117 | struct iscsi_cmd { | 118 | struct iscsi_cmd { |
@@ -125,7 +126,7 @@ struct iscsi_cmd { | |||
125 | __be32 data_length; | 126 | __be32 data_length; |
126 | __be32 cmdsn; | 127 | __be32 cmdsn; |
127 | __be32 exp_statsn; | 128 | __be32 exp_statsn; |
128 | uint8_t cdb[16]; /* SCSI Command Block */ | 129 | uint8_t cdb[ISCSI_CDB_SIZE]; /* SCSI Command Block */ |
129 | /* Additional Data (Command Dependent) */ | 130 | /* Additional Data (Command Dependent) */ |
130 | }; | 131 | }; |
131 | 132 | ||
@@ -154,7 +155,8 @@ struct iscsi_ecdb_ahdr { | |||
154 | __be16 ahslength; /* CDB length - 15, including reserved byte */ | 155 | __be16 ahslength; /* CDB length - 15, including reserved byte */ |
155 | uint8_t ahstype; | 156 | uint8_t ahstype; |
156 | uint8_t reserved; | 157 | uint8_t reserved; |
157 | uint8_t ecdb[260 - 16]; /* 4-byte aligned extended CDB spillover */ | 158 | /* 4-byte aligned extended CDB spillover */ |
159 | uint8_t ecdb[260 - ISCSI_CDB_SIZE]; | ||
158 | }; | 160 | }; |
159 | 161 | ||
160 | /* SCSI Response Header */ | 162 | /* SCSI Response Header */ |
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 39e1cac24bb7..98724ba65a79 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h | |||
@@ -677,4 +677,6 @@ extern void sas_ssp_task_response(struct device *dev, struct sas_task *task, | |||
677 | struct ssp_response_iu *iu); | 677 | struct ssp_response_iu *iu); |
678 | struct sas_phy *sas_find_local_phy(struct domain_device *dev); | 678 | struct sas_phy *sas_find_local_phy(struct domain_device *dev); |
679 | 679 | ||
680 | int sas_request_addr(struct Scsi_Host *shost, u8 *addr); | ||
681 | |||
680 | #endif /* _SASLIB_H_ */ | 682 | #endif /* _SASLIB_H_ */ |
diff --git a/include/scsi/sas_ata.h b/include/scsi/sas_ata.h index dd5edc915417..c583193ae929 100644 --- a/include/scsi/sas_ata.h +++ b/include/scsi/sas_ata.h | |||
@@ -47,12 +47,12 @@ static inline int dev_is_sata(struct domain_device *dev) | |||
47 | { | 47 | { |
48 | return 0; | 48 | return 0; |
49 | } | 49 | } |
50 | int sas_ata_init_host_and_port(struct domain_device *found_dev, | 50 | static inline int sas_ata_init_host_and_port(struct domain_device *found_dev, |
51 | struct scsi_target *starget) | 51 | struct scsi_target *starget) |
52 | { | 52 | { |
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | void sas_ata_task_abort(struct sas_task *task) | 55 | static inline void sas_ata_task_abort(struct sas_task *task) |
56 | { | 56 | { |
57 | } | 57 | } |
58 | #endif | 58 | #endif |
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index de28aab820b0..8d20e60a94b7 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h | |||
@@ -130,6 +130,9 @@ extern void scsi_release_buffers(struct scsi_cmnd *cmd); | |||
130 | extern int scsi_dma_map(struct scsi_cmnd *cmd); | 130 | extern int scsi_dma_map(struct scsi_cmnd *cmd); |
131 | extern void scsi_dma_unmap(struct scsi_cmnd *cmd); | 131 | extern void scsi_dma_unmap(struct scsi_cmnd *cmd); |
132 | 132 | ||
133 | struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask); | ||
134 | void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd); | ||
135 | |||
133 | static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd) | 136 | static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd) |
134 | { | 137 | { |
135 | return cmd->sdb.table.nents; | 138 | return cmd->sdb.table.nents; |
@@ -175,4 +178,18 @@ static inline struct scsi_data_buffer *scsi_out(struct scsi_cmnd *cmd) | |||
175 | return &cmd->sdb; | 178 | return &cmd->sdb; |
176 | } | 179 | } |
177 | 180 | ||
181 | static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd, | ||
182 | void *buf, int buflen) | ||
183 | { | ||
184 | return sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), | ||
185 | buf, buflen); | ||
186 | } | ||
187 | |||
188 | static inline int scsi_sg_copy_to_buffer(struct scsi_cmnd *cmd, | ||
189 | void *buf, int buflen) | ||
190 | { | ||
191 | return sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), | ||
192 | buf, buflen); | ||
193 | } | ||
194 | |||
178 | #endif /* _SCSI_SCSI_CMND_H */ | 195 | #endif /* _SCSI_SCSI_CMND_H */ |
diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h index 25071d5d9bf8..d3a133b4a072 100644 --- a/include/scsi/scsi_eh.h +++ b/include/scsi/scsi_eh.h | |||
@@ -57,13 +57,16 @@ extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, | |||
57 | 57 | ||
58 | extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, | 58 | extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, |
59 | u64 * info_out); | 59 | u64 * info_out); |
60 | 60 | ||
61 | extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq); | ||
62 | |||
61 | /* | 63 | /* |
62 | * Reset request from external source | 64 | * Reset request from external source |
63 | */ | 65 | */ |
64 | #define SCSI_TRY_RESET_DEVICE 1 | 66 | #define SCSI_TRY_RESET_DEVICE 1 |
65 | #define SCSI_TRY_RESET_BUS 2 | 67 | #define SCSI_TRY_RESET_BUS 2 |
66 | #define SCSI_TRY_RESET_HOST 3 | 68 | #define SCSI_TRY_RESET_HOST 3 |
69 | #define SCSI_TRY_RESET_TARGET 4 | ||
67 | 70 | ||
68 | extern int scsi_reset_provider(struct scsi_device *, int); | 71 | extern int scsi_reset_provider(struct scsi_device *, int); |
69 | 72 | ||
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 530ff4c553f8..49132862bfaa 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
@@ -172,6 +172,7 @@ struct scsi_host_template { | |||
172 | */ | 172 | */ |
173 | int (* eh_abort_handler)(struct scsi_cmnd *); | 173 | int (* eh_abort_handler)(struct scsi_cmnd *); |
174 | int (* eh_device_reset_handler)(struct scsi_cmnd *); | 174 | int (* eh_device_reset_handler)(struct scsi_cmnd *); |
175 | int (* eh_target_reset_handler)(struct scsi_cmnd *); | ||
175 | int (* eh_bus_reset_handler)(struct scsi_cmnd *); | 176 | int (* eh_bus_reset_handler)(struct scsi_cmnd *); |
176 | int (* eh_host_reset_handler)(struct scsi_cmnd *); | 177 | int (* eh_host_reset_handler)(struct scsi_cmnd *); |
177 | 178 | ||
diff --git a/lib/scatterlist.c b/lib/scatterlist.c index acca4901046c..b80c21100d78 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c | |||
@@ -8,6 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/scatterlist.h> | 10 | #include <linux/scatterlist.h> |
11 | #include <linux/highmem.h> | ||
11 | 12 | ||
12 | /** | 13 | /** |
13 | * sg_next - return the next scatterlist entry in a list | 14 | * sg_next - return the next scatterlist entry in a list |
@@ -292,3 +293,104 @@ int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask) | |||
292 | return ret; | 293 | return ret; |
293 | } | 294 | } |
294 | EXPORT_SYMBOL(sg_alloc_table); | 295 | EXPORT_SYMBOL(sg_alloc_table); |
296 | |||
297 | /** | ||
298 | * sg_copy_buffer - Copy data between a linear buffer and an SG list | ||
299 | * @sgl: The SG list | ||
300 | * @nents: Number of SG entries | ||
301 | * @buf: Where to copy from | ||
302 | * @buflen: The number of bytes to copy | ||
303 | * @to_buffer: transfer direction (non zero == from an sg list to a | ||
304 | * buffer, 0 == from a buffer to an sg list | ||
305 | * | ||
306 | * Returns the number of copied bytes. | ||
307 | * | ||
308 | **/ | ||
309 | static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, | ||
310 | void *buf, size_t buflen, int to_buffer) | ||
311 | { | ||
312 | struct scatterlist *sg; | ||
313 | size_t buf_off = 0; | ||
314 | int i; | ||
315 | |||
316 | WARN_ON(!irqs_disabled()); | ||
317 | |||
318 | for_each_sg(sgl, sg, nents, i) { | ||
319 | struct page *page; | ||
320 | int n = 0; | ||
321 | unsigned int sg_off = sg->offset; | ||
322 | unsigned int sg_copy = sg->length; | ||
323 | |||
324 | if (sg_copy > buflen) | ||
325 | sg_copy = buflen; | ||
326 | buflen -= sg_copy; | ||
327 | |||
328 | while (sg_copy > 0) { | ||
329 | unsigned int page_copy; | ||
330 | void *p; | ||
331 | |||
332 | page_copy = PAGE_SIZE - sg_off; | ||
333 | if (page_copy > sg_copy) | ||
334 | page_copy = sg_copy; | ||
335 | |||
336 | page = nth_page(sg_page(sg), n); | ||
337 | p = kmap_atomic(page, KM_BIO_SRC_IRQ); | ||
338 | |||
339 | if (to_buffer) | ||
340 | memcpy(buf + buf_off, p + sg_off, page_copy); | ||
341 | else { | ||
342 | memcpy(p + sg_off, buf + buf_off, page_copy); | ||
343 | flush_kernel_dcache_page(page); | ||
344 | } | ||
345 | |||
346 | kunmap_atomic(p, KM_BIO_SRC_IRQ); | ||
347 | |||
348 | buf_off += page_copy; | ||
349 | sg_off += page_copy; | ||
350 | if (sg_off == PAGE_SIZE) { | ||
351 | sg_off = 0; | ||
352 | n++; | ||
353 | } | ||
354 | sg_copy -= page_copy; | ||
355 | } | ||
356 | |||
357 | if (!buflen) | ||
358 | break; | ||
359 | } | ||
360 | |||
361 | return buf_off; | ||
362 | } | ||
363 | |||
364 | /** | ||
365 | * sg_copy_from_buffer - Copy from a linear buffer to an SG list | ||
366 | * @sgl: The SG list | ||
367 | * @nents: Number of SG entries | ||
368 | * @buf: Where to copy from | ||
369 | * @buflen: The number of bytes to copy | ||
370 | * | ||
371 | * Returns the number of copied bytes. | ||
372 | * | ||
373 | **/ | ||
374 | size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents, | ||
375 | void *buf, size_t buflen) | ||
376 | { | ||
377 | return sg_copy_buffer(sgl, nents, buf, buflen, 0); | ||
378 | } | ||
379 | EXPORT_SYMBOL(sg_copy_from_buffer); | ||
380 | |||
381 | /** | ||
382 | * sg_copy_to_buffer - Copy from an SG list to a linear buffer | ||
383 | * @sgl: The SG list | ||
384 | * @nents: Number of SG entries | ||
385 | * @buf: Where to copy to | ||
386 | * @buflen: The number of bytes to copy | ||
387 | * | ||
388 | * Returns the number of copied bytes. | ||
389 | * | ||
390 | **/ | ||
391 | size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents, | ||
392 | void *buf, size_t buflen) | ||
393 | { | ||
394 | return sg_copy_buffer(sgl, nents, buf, buflen, 1); | ||
395 | } | ||
396 | EXPORT_SYMBOL(sg_copy_to_buffer); | ||