diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-12-07 04:57:19 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-07 04:57:19 -0500 |
commit | 8d1413b28033c49c7f1a4d320e815d7a5531acee (patch) | |
tree | b37281abef014cd60803b81c100388d7a475d49e /drivers | |
parent | ed25ffa16434724f5ed825aa48734c7f3aefa203 (diff) | |
parent | 620034c84d1d939717bdfbe02c51a3fee43541c3 (diff) |
Merge branch 'master' into upstream
Conflicts:
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_main.c
Diffstat (limited to 'drivers')
391 files changed, 8035 insertions, 3464 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 4ac14dab3079..67711770b1d9 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -77,3 +77,4 @@ obj-$(CONFIG_CRYPTO) += crypto/ | |||
77 | obj-$(CONFIG_SUPERH) += sh/ | 77 | obj-$(CONFIG_SUPERH) += sh/ |
78 | obj-$(CONFIG_GENERIC_TIME) += clocksource/ | 78 | obj-$(CONFIG_GENERIC_TIME) += clocksource/ |
79 | obj-$(CONFIG_DMA_ENGINE) += dma/ | 79 | obj-$(CONFIG_DMA_ENGINE) += dma/ |
80 | obj-$(CONFIG_PPC_PS3) += ps3/ | ||
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 068fe4f100b0..02b30ae6a68e 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -50,6 +50,7 @@ ACPI_MODULE_NAME("osl") | |||
50 | struct acpi_os_dpc { | 50 | struct acpi_os_dpc { |
51 | acpi_osd_exec_callback function; | 51 | acpi_osd_exec_callback function; |
52 | void *context; | 52 | void *context; |
53 | struct work_struct work; | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | #ifdef CONFIG_ACPI_CUSTOM_DSDT | 56 | #ifdef CONFIG_ACPI_CUSTOM_DSDT |
@@ -564,12 +565,9 @@ void acpi_os_derive_pci_id(acpi_handle rhandle, /* upper bound */ | |||
564 | acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number); | 565 | acpi_os_derive_pci_id_2(rhandle, chandle, id, &is_bridge, &bus_number); |
565 | } | 566 | } |
566 | 567 | ||
567 | static void acpi_os_execute_deferred(void *context) | 568 | static void acpi_os_execute_deferred(struct work_struct *work) |
568 | { | 569 | { |
569 | struct acpi_os_dpc *dpc = NULL; | 570 | struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work); |
570 | |||
571 | |||
572 | dpc = (struct acpi_os_dpc *)context; | ||
573 | if (!dpc) { | 571 | if (!dpc) { |
574 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); | 572 | printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); |
575 | return; | 573 | return; |
@@ -602,7 +600,6 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
602 | { | 600 | { |
603 | acpi_status status = AE_OK; | 601 | acpi_status status = AE_OK; |
604 | struct acpi_os_dpc *dpc; | 602 | struct acpi_os_dpc *dpc; |
605 | struct work_struct *task; | ||
606 | 603 | ||
607 | ACPI_FUNCTION_TRACE("os_queue_for_execution"); | 604 | ACPI_FUNCTION_TRACE("os_queue_for_execution"); |
608 | 605 | ||
@@ -615,28 +612,22 @@ acpi_status acpi_os_execute(acpi_execute_type type, | |||
615 | 612 | ||
616 | /* | 613 | /* |
617 | * Allocate/initialize DPC structure. Note that this memory will be | 614 | * Allocate/initialize DPC structure. Note that this memory will be |
618 | * freed by the callee. The kernel handles the tq_struct list in a | 615 | * freed by the callee. The kernel handles the work_struct list in a |
619 | * way that allows us to also free its memory inside the callee. | 616 | * way that allows us to also free its memory inside the callee. |
620 | * Because we may want to schedule several tasks with different | 617 | * Because we may want to schedule several tasks with different |
621 | * parameters we can't use the approach some kernel code uses of | 618 | * parameters we can't use the approach some kernel code uses of |
622 | * having a static tq_struct. | 619 | * having a static work_struct. |
623 | * We can save time and code by allocating the DPC and tq_structs | ||
624 | * from the same memory. | ||
625 | */ | 620 | */ |
626 | 621 | ||
627 | dpc = | 622 | dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC); |
628 | kmalloc(sizeof(struct acpi_os_dpc) + sizeof(struct work_struct), | ||
629 | GFP_ATOMIC); | ||
630 | if (!dpc) | 623 | if (!dpc) |
631 | return_ACPI_STATUS(AE_NO_MEMORY); | 624 | return_ACPI_STATUS(AE_NO_MEMORY); |
632 | 625 | ||
633 | dpc->function = function; | 626 | dpc->function = function; |
634 | dpc->context = context; | 627 | dpc->context = context; |
635 | 628 | ||
636 | task = (void *)(dpc + 1); | 629 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
637 | INIT_WORK(task, acpi_os_execute_deferred, (void *)dpc); | 630 | if (!queue_work(kacpid_wq, &dpc->work)) { |
638 | |||
639 | if (!queue_work(kacpid_wq, task)) { | ||
640 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 631 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
641 | "Call to queue_work() failed.\n")); | 632 | "Call to queue_work() failed.\n")); |
642 | kfree(dpc); | 633 | kfree(dpc); |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f8ec3896b793..8816e30fb7a4 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1081,7 +1081,7 @@ static unsigned int ata_id_xfermask(const u16 *id) | |||
1081 | * ata_port_queue_task - Queue port_task | 1081 | * ata_port_queue_task - Queue port_task |
1082 | * @ap: The ata_port to queue port_task for | 1082 | * @ap: The ata_port to queue port_task for |
1083 | * @fn: workqueue function to be scheduled | 1083 | * @fn: workqueue function to be scheduled |
1084 | * @data: data value to pass to workqueue function | 1084 | * @data: data for @fn to use |
1085 | * @delay: delay time for workqueue function | 1085 | * @delay: delay time for workqueue function |
1086 | * | 1086 | * |
1087 | * Schedule @fn(@data) for execution after @delay jiffies using | 1087 | * Schedule @fn(@data) for execution after @delay jiffies using |
@@ -1096,7 +1096,7 @@ static unsigned int ata_id_xfermask(const u16 *id) | |||
1096 | * LOCKING: | 1096 | * LOCKING: |
1097 | * Inherited from caller. | 1097 | * Inherited from caller. |
1098 | */ | 1098 | */ |
1099 | void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data, | 1099 | void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data, |
1100 | unsigned long delay) | 1100 | unsigned long delay) |
1101 | { | 1101 | { |
1102 | int rc; | 1102 | int rc; |
@@ -1104,12 +1104,10 @@ void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data, | |||
1104 | if (ap->pflags & ATA_PFLAG_FLUSH_PORT_TASK) | 1104 | if (ap->pflags & ATA_PFLAG_FLUSH_PORT_TASK) |
1105 | return; | 1105 | return; |
1106 | 1106 | ||
1107 | PREPARE_WORK(&ap->port_task, fn, data); | 1107 | PREPARE_DELAYED_WORK(&ap->port_task, fn); |
1108 | ap->port_task_data = data; | ||
1108 | 1109 | ||
1109 | if (!delay) | 1110 | rc = queue_delayed_work(ata_wq, &ap->port_task, delay); |
1110 | rc = queue_work(ata_wq, &ap->port_task); | ||
1111 | else | ||
1112 | rc = queue_delayed_work(ata_wq, &ap->port_task, delay); | ||
1113 | 1111 | ||
1114 | /* rc == 0 means that another user is using port task */ | 1112 | /* rc == 0 means that another user is using port task */ |
1115 | WARN_ON(rc == 0); | 1113 | WARN_ON(rc == 0); |
@@ -4588,10 +4586,11 @@ fsm_start: | |||
4588 | return poll_next; | 4586 | return poll_next; |
4589 | } | 4587 | } |
4590 | 4588 | ||
4591 | static void ata_pio_task(void *_data) | 4589 | static void ata_pio_task(struct work_struct *work) |
4592 | { | 4590 | { |
4593 | struct ata_queued_cmd *qc = _data; | 4591 | struct ata_port *ap = |
4594 | struct ata_port *ap = qc->ap; | 4592 | container_of(work, struct ata_port, port_task.work); |
4593 | struct ata_queued_cmd *qc = ap->port_task_data; | ||
4595 | u8 status; | 4594 | u8 status; |
4596 | int poll_next; | 4595 | int poll_next; |
4597 | 4596 | ||
@@ -5635,9 +5634,9 @@ void ata_port_init(struct ata_port *ap, struct ata_host *host, | |||
5635 | ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; | 5634 | ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; |
5636 | #endif | 5635 | #endif |
5637 | 5636 | ||
5638 | INIT_WORK(&ap->port_task, NULL, NULL); | 5637 | INIT_DELAYED_WORK(&ap->port_task, NULL); |
5639 | INIT_WORK(&ap->hotplug_task, ata_scsi_hotplug, ap); | 5638 | INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); |
5640 | INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan, ap); | 5639 | INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); |
5641 | INIT_LIST_HEAD(&ap->eh_done_q); | 5640 | INIT_LIST_HEAD(&ap->eh_done_q); |
5642 | init_waitqueue_head(&ap->eh_wait_q); | 5641 | init_waitqueue_head(&ap->eh_wait_q); |
5643 | 5642 | ||
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 76a85dfb7307..08ad44b3e48f 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -332,7 +332,7 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
332 | if (ap->pflags & ATA_PFLAG_LOADING) | 332 | if (ap->pflags & ATA_PFLAG_LOADING) |
333 | ap->pflags &= ~ATA_PFLAG_LOADING; | 333 | ap->pflags &= ~ATA_PFLAG_LOADING; |
334 | else if (ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) | 334 | else if (ap->pflags & ATA_PFLAG_SCSI_HOTPLUG) |
335 | queue_work(ata_aux_wq, &ap->hotplug_task); | 335 | queue_delayed_work(ata_aux_wq, &ap->hotplug_task, 0); |
336 | 336 | ||
337 | if (ap->pflags & ATA_PFLAG_RECOVERED) | 337 | if (ap->pflags & ATA_PFLAG_RECOVERED) |
338 | ata_port_printk(ap, KERN_INFO, "EH complete\n"); | 338 | ata_port_printk(ap, KERN_INFO, "EH complete\n"); |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 8eaace94d963..664e1377b54c 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -2963,7 +2963,7 @@ static void ata_scsi_remove_dev(struct ata_device *dev) | |||
2963 | 2963 | ||
2964 | /** | 2964 | /** |
2965 | * ata_scsi_hotplug - SCSI part of hotplug | 2965 | * ata_scsi_hotplug - SCSI part of hotplug |
2966 | * @data: Pointer to ATA port to perform SCSI hotplug on | 2966 | * @work: Pointer to ATA port to perform SCSI hotplug on |
2967 | * | 2967 | * |
2968 | * Perform SCSI part of hotplug. It's executed from a separate | 2968 | * Perform SCSI part of hotplug. It's executed from a separate |
2969 | * workqueue after EH completes. This is necessary because SCSI | 2969 | * workqueue after EH completes. This is necessary because SCSI |
@@ -2973,9 +2973,10 @@ static void ata_scsi_remove_dev(struct ata_device *dev) | |||
2973 | * LOCKING: | 2973 | * LOCKING: |
2974 | * Kernel thread context (may sleep). | 2974 | * Kernel thread context (may sleep). |
2975 | */ | 2975 | */ |
2976 | void ata_scsi_hotplug(void *data) | 2976 | void ata_scsi_hotplug(struct work_struct *work) |
2977 | { | 2977 | { |
2978 | struct ata_port *ap = data; | 2978 | struct ata_port *ap = |
2979 | container_of(work, struct ata_port, hotplug_task.work); | ||
2979 | int i; | 2980 | int i; |
2980 | 2981 | ||
2981 | if (ap->pflags & ATA_PFLAG_UNLOADING) { | 2982 | if (ap->pflags & ATA_PFLAG_UNLOADING) { |
@@ -3076,7 +3077,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, | |||
3076 | 3077 | ||
3077 | /** | 3078 | /** |
3078 | * ata_scsi_dev_rescan - initiate scsi_rescan_device() | 3079 | * ata_scsi_dev_rescan - initiate scsi_rescan_device() |
3079 | * @data: Pointer to ATA port to perform scsi_rescan_device() | 3080 | * @work: Pointer to ATA port to perform scsi_rescan_device() |
3080 | * | 3081 | * |
3081 | * After ATA pass thru (SAT) commands are executed successfully, | 3082 | * After ATA pass thru (SAT) commands are executed successfully, |
3082 | * libata need to propagate the changes to SCSI layer. This | 3083 | * libata need to propagate the changes to SCSI layer. This |
@@ -3086,9 +3087,10 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, | |||
3086 | * LOCKING: | 3087 | * LOCKING: |
3087 | * Kernel thread context (may sleep). | 3088 | * Kernel thread context (may sleep). |
3088 | */ | 3089 | */ |
3089 | void ata_scsi_dev_rescan(void *data) | 3090 | void ata_scsi_dev_rescan(struct work_struct *work) |
3090 | { | 3091 | { |
3091 | struct ata_port *ap = data; | 3092 | struct ata_port *ap = |
3093 | container_of(work, struct ata_port, scsi_rescan_task); | ||
3092 | unsigned long flags; | 3094 | unsigned long flags; |
3093 | unsigned int i; | 3095 | unsigned int i; |
3094 | 3096 | ||
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 107b2b565229..81ae41d5f23f 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -94,7 +94,7 @@ extern struct scsi_transport_template ata_scsi_transport_template; | |||
94 | 94 | ||
95 | extern void ata_scsi_scan_host(struct ata_port *ap); | 95 | extern void ata_scsi_scan_host(struct ata_port *ap); |
96 | extern int ata_scsi_offline_dev(struct ata_device *dev); | 96 | extern int ata_scsi_offline_dev(struct ata_device *dev); |
97 | extern void ata_scsi_hotplug(void *data); | 97 | extern void ata_scsi_hotplug(struct work_struct *work); |
98 | extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, | 98 | extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, |
99 | unsigned int buflen); | 99 | unsigned int buflen); |
100 | 100 | ||
@@ -124,7 +124,7 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args, | |||
124 | unsigned int (*actor) (struct ata_scsi_args *args, | 124 | unsigned int (*actor) (struct ata_scsi_args *args, |
125 | u8 *rbuf, unsigned int buflen)); | 125 | u8 *rbuf, unsigned int buflen)); |
126 | extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); | 126 | extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); |
127 | extern void ata_scsi_dev_rescan(void *data); | 127 | extern void ata_scsi_dev_rescan(struct work_struct *work); |
128 | extern int ata_bus_probe(struct ata_port *ap); | 128 | extern int ata_bus_probe(struct ata_port *ap); |
129 | 129 | ||
130 | /* libata-eh.c */ | 130 | /* libata-eh.c */ |
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c index 4ca6fa5dcb42..9ed7f58424a3 100644 --- a/drivers/ata/pata_pcmcia.c +++ b/drivers/ata/pata_pcmcia.c | |||
@@ -154,19 +154,12 @@ static int pcmcia_init_one(struct pcmcia_device *pdev) | |||
154 | tuple.TupleOffset = 0; | 154 | tuple.TupleOffset = 0; |
155 | tuple.TupleDataMax = 255; | 155 | tuple.TupleDataMax = 255; |
156 | tuple.Attributes = 0; | 156 | tuple.Attributes = 0; |
157 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
158 | |||
159 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple)); | ||
160 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(pdev, &tuple)); | ||
161 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(pdev, &tuple, &stk->parse)); | ||
162 | pdev->conf.ConfigBase = stk->parse.config.base; | ||
163 | pdev->conf.Present = stk->parse.config.rmask[0]; | ||
164 | 157 | ||
165 | /* See if we have a manufacturer identifier. Use it to set is_kme for | 158 | /* See if we have a manufacturer identifier. Use it to set is_kme for |
166 | vendor quirks */ | 159 | vendor quirks */ |
167 | tuple.DesiredTuple = CISTPL_MANFID; | 160 | is_kme = ((pdev->manf_id == MANFID_KME) && |
168 | if (!pcmcia_get_first_tuple(pdev, &tuple) && !pcmcia_get_tuple_data(pdev, &tuple) && !pcmcia_parse_tuple(pdev, &tuple, &stk->parse)) | 161 | ((pdev->card_id == PRODID_KME_KXLC005_A) || |
169 | is_kme = ((stk->parse.manfid.manf == MANFID_KME) && ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || (stk->parse.manfid.card == PRODID_KME_KXLC005_B))); | 162 | (pdev->card_id == PRODID_KME_KXLC005_B))); |
170 | 163 | ||
171 | /* Not sure if this is right... look up the current Vcc */ | 164 | /* Not sure if this is right... look up the current Vcc */ |
172 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf)); | 165 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(pdev, &stk->conf)); |
@@ -356,8 +349,10 @@ static struct pcmcia_device_id pcmcia_devices[] = { | |||
356 | PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), | 349 | PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), |
357 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), | 350 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), |
358 | PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), | 351 | PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), |
352 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1), | ||
359 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), | 353 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), |
360 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), | 354 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), |
355 | PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918), | ||
361 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), | 356 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), |
362 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), | 357 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), |
363 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), | 358 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), |
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 87b17c33b3f9..f40786121948 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c | |||
@@ -135,7 +135,7 @@ static int idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, | |||
135 | int flags); | 135 | int flags); |
136 | static int idt77252_proc_read(struct atm_dev *dev, loff_t * pos, | 136 | static int idt77252_proc_read(struct atm_dev *dev, loff_t * pos, |
137 | char *page); | 137 | char *page); |
138 | static void idt77252_softint(void *dev_id); | 138 | static void idt77252_softint(struct work_struct *work); |
139 | 139 | ||
140 | 140 | ||
141 | static struct atmdev_ops idt77252_ops = | 141 | static struct atmdev_ops idt77252_ops = |
@@ -2866,9 +2866,10 @@ out: | |||
2866 | } | 2866 | } |
2867 | 2867 | ||
2868 | static void | 2868 | static void |
2869 | idt77252_softint(void *dev_id) | 2869 | idt77252_softint(struct work_struct *work) |
2870 | { | 2870 | { |
2871 | struct idt77252_dev *card = dev_id; | 2871 | struct idt77252_dev *card = |
2872 | container_of(work, struct idt77252_dev, tqueue); | ||
2872 | u32 stat; | 2873 | u32 stat; |
2873 | int done; | 2874 | int done; |
2874 | 2875 | ||
@@ -3697,7 +3698,7 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) | |||
3697 | card->pcidev = pcidev; | 3698 | card->pcidev = pcidev; |
3698 | sprintf(card->name, "idt77252-%d", card->index); | 3699 | sprintf(card->name, "idt77252-%d", card->index); |
3699 | 3700 | ||
3700 | INIT_WORK(&card->tqueue, idt77252_softint, (void *)card); | 3701 | INIT_WORK(&card->tqueue, idt77252_softint); |
3701 | 3702 | ||
3702 | membase = pci_resource_start(pcidev, 1); | 3703 | membase = pci_resource_start(pcidev, 1); |
3703 | srambase = pci_resource_start(pcidev, 2); | 3704 | srambase = pci_resource_start(pcidev, 2); |
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 6d111228cfac..2308e83e5f33 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h | |||
@@ -159,7 +159,7 @@ void aoecmd_work(struct aoedev *d); | |||
159 | void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor); | 159 | void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor); |
160 | void aoecmd_ata_rsp(struct sk_buff *); | 160 | void aoecmd_ata_rsp(struct sk_buff *); |
161 | void aoecmd_cfg_rsp(struct sk_buff *); | 161 | void aoecmd_cfg_rsp(struct sk_buff *); |
162 | void aoecmd_sleepwork(void *vp); | 162 | void aoecmd_sleepwork(struct work_struct *); |
163 | struct sk_buff *new_skb(ulong); | 163 | struct sk_buff *new_skb(ulong); |
164 | 164 | ||
165 | int aoedev_init(void); | 165 | int aoedev_init(void); |
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 8a13b1af8bab..97f7f535f412 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -408,9 +408,9 @@ rexmit_timer(ulong vp) | |||
408 | /* this function performs work that has been deferred until sleeping is OK | 408 | /* this function performs work that has been deferred until sleeping is OK |
409 | */ | 409 | */ |
410 | void | 410 | void |
411 | aoecmd_sleepwork(void *vp) | 411 | aoecmd_sleepwork(struct work_struct *work) |
412 | { | 412 | { |
413 | struct aoedev *d = (struct aoedev *) vp; | 413 | struct aoedev *d = container_of(work, struct aoedev, work); |
414 | 414 | ||
415 | if (d->flags & DEVFL_GDALLOC) | 415 | if (d->flags & DEVFL_GDALLOC) |
416 | aoeblk_gdalloc(d); | 416 | aoeblk_gdalloc(d); |
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index 6125921bbec4..05a97197c918 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c | |||
@@ -88,7 +88,7 @@ aoedev_newdev(ulong nframes) | |||
88 | kfree(d); | 88 | kfree(d); |
89 | return NULL; | 89 | return NULL; |
90 | } | 90 | } |
91 | INIT_WORK(&d->work, aoecmd_sleepwork, d); | 91 | INIT_WORK(&d->work, aoecmd_sleepwork); |
92 | spin_lock_init(&d->lock); | 92 | spin_lock_init(&d->lock); |
93 | init_timer(&d->timer); | 93 | init_timer(&d->timer); |
94 | d->timer.data = (ulong) d; | 94 | d->timer.data = (ulong) d; |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 9e6d3a87cbe3..3f1b38276e96 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -992,11 +992,11 @@ static void empty(void) | |||
992 | { | 992 | { |
993 | } | 993 | } |
994 | 994 | ||
995 | static DECLARE_WORK(floppy_work, NULL, NULL); | 995 | static DECLARE_WORK(floppy_work, NULL); |
996 | 996 | ||
997 | static void schedule_bh(void (*handler) (void)) | 997 | static void schedule_bh(void (*handler) (void)) |
998 | { | 998 | { |
999 | PREPARE_WORK(&floppy_work, (void (*)(void *))handler, NULL); | 999 | PREPARE_WORK(&floppy_work, (work_func_t)handler); |
1000 | schedule_work(&floppy_work); | 1000 | schedule_work(&floppy_work); |
1001 | } | 1001 | } |
1002 | 1002 | ||
@@ -1008,7 +1008,7 @@ static void cancel_activity(void) | |||
1008 | 1008 | ||
1009 | spin_lock_irqsave(&floppy_lock, flags); | 1009 | spin_lock_irqsave(&floppy_lock, flags); |
1010 | do_floppy = NULL; | 1010 | do_floppy = NULL; |
1011 | PREPARE_WORK(&floppy_work, (void *)empty, NULL); | 1011 | PREPARE_WORK(&floppy_work, (work_func_t)empty); |
1012 | del_timer(&fd_timer); | 1012 | del_timer(&fd_timer); |
1013 | spin_unlock_irqrestore(&floppy_lock, flags); | 1013 | spin_unlock_irqrestore(&floppy_lock, flags); |
1014 | } | 1014 | } |
@@ -1868,7 +1868,7 @@ static void show_floppy(void) | |||
1868 | printk("fdc_busy=%lu\n", fdc_busy); | 1868 | printk("fdc_busy=%lu\n", fdc_busy); |
1869 | if (do_floppy) | 1869 | if (do_floppy) |
1870 | printk("do_floppy=%p\n", do_floppy); | 1870 | printk("do_floppy=%p\n", do_floppy); |
1871 | if (floppy_work.pending) | 1871 | if (work_pending(&floppy_work)) |
1872 | printk("floppy_work.func=%p\n", floppy_work.func); | 1872 | printk("floppy_work.func=%p\n", floppy_work.func); |
1873 | if (timer_pending(&fd_timer)) | 1873 | if (timer_pending(&fd_timer)) |
1874 | printk("fd_timer.function=%p\n", fd_timer.function); | 1874 | printk("fd_timer.function=%p\n", fd_timer.function); |
@@ -4498,7 +4498,7 @@ static void floppy_release_irq_and_dma(void) | |||
4498 | printk("floppy timer still active:%s\n", timeout_message); | 4498 | printk("floppy timer still active:%s\n", timeout_message); |
4499 | if (timer_pending(&fd_timer)) | 4499 | if (timer_pending(&fd_timer)) |
4500 | printk("auxiliary floppy timer still active\n"); | 4500 | printk("auxiliary floppy timer still active\n"); |
4501 | if (floppy_work.pending) | 4501 | if (work_pending(&floppy_work)) |
4502 | printk("work still pending\n"); | 4502 | printk("work still pending\n"); |
4503 | #endif | 4503 | #endif |
4504 | old_fdc = fdc; | 4504 | old_fdc = fdc; |
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 40a11e567970..9d9bff23f426 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c | |||
@@ -352,19 +352,19 @@ static enum action (*phase)(void); | |||
352 | 352 | ||
353 | static void run_fsm(void); | 353 | static void run_fsm(void); |
354 | 354 | ||
355 | static void ps_tq_int( void *data); | 355 | static void ps_tq_int(struct work_struct *work); |
356 | 356 | ||
357 | static DECLARE_WORK(fsm_tq, ps_tq_int, NULL); | 357 | static DECLARE_DELAYED_WORK(fsm_tq, ps_tq_int); |
358 | 358 | ||
359 | static void schedule_fsm(void) | 359 | static void schedule_fsm(void) |
360 | { | 360 | { |
361 | if (!nice) | 361 | if (!nice) |
362 | schedule_work(&fsm_tq); | 362 | schedule_delayed_work(&fsm_tq, 0); |
363 | else | 363 | else |
364 | schedule_delayed_work(&fsm_tq, nice-1); | 364 | schedule_delayed_work(&fsm_tq, nice-1); |
365 | } | 365 | } |
366 | 366 | ||
367 | static void ps_tq_int(void *data) | 367 | static void ps_tq_int(struct work_struct *work) |
368 | { | 368 | { |
369 | run_fsm(); | 369 | run_fsm(); |
370 | } | 370 | } |
diff --git a/drivers/block/paride/pseudo.h b/drivers/block/paride/pseudo.h index 932342d7a8eb..bc3703294143 100644 --- a/drivers/block/paride/pseudo.h +++ b/drivers/block/paride/pseudo.h | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/workqueue.h> | 36 | #include <linux/workqueue.h> |
37 | 37 | ||
38 | static void ps_tq_int( void *data); | 38 | static void ps_tq_int(struct work_struct *work); |
39 | 39 | ||
40 | static void (* ps_continuation)(void); | 40 | static void (* ps_continuation)(void); |
41 | static int (* ps_ready)(void); | 41 | static int (* ps_ready)(void); |
@@ -45,7 +45,7 @@ static int ps_nice = 0; | |||
45 | 45 | ||
46 | static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused))); | 46 | static DEFINE_SPINLOCK(ps_spinlock __attribute__((unused))); |
47 | 47 | ||
48 | static DECLARE_WORK(ps_tq, ps_tq_int, NULL); | 48 | static DECLARE_DELAYED_WORK(ps_tq, ps_tq_int); |
49 | 49 | ||
50 | static void ps_set_intr(void (*continuation)(void), | 50 | static void ps_set_intr(void (*continuation)(void), |
51 | int (*ready)(void), | 51 | int (*ready)(void), |
@@ -63,14 +63,14 @@ static void ps_set_intr(void (*continuation)(void), | |||
63 | if (!ps_tq_active) { | 63 | if (!ps_tq_active) { |
64 | ps_tq_active = 1; | 64 | ps_tq_active = 1; |
65 | if (!ps_nice) | 65 | if (!ps_nice) |
66 | schedule_work(&ps_tq); | 66 | schedule_delayed_work(&ps_tq, 0); |
67 | else | 67 | else |
68 | schedule_delayed_work(&ps_tq, ps_nice-1); | 68 | schedule_delayed_work(&ps_tq, ps_nice-1); |
69 | } | 69 | } |
70 | spin_unlock_irqrestore(&ps_spinlock,flags); | 70 | spin_unlock_irqrestore(&ps_spinlock,flags); |
71 | } | 71 | } |
72 | 72 | ||
73 | static void ps_tq_int(void *data) | 73 | static void ps_tq_int(struct work_struct *work) |
74 | { | 74 | { |
75 | void (*con)(void); | 75 | void (*con)(void); |
76 | unsigned long flags; | 76 | unsigned long flags; |
@@ -92,7 +92,7 @@ static void ps_tq_int(void *data) | |||
92 | } | 92 | } |
93 | ps_tq_active = 1; | 93 | ps_tq_active = 1; |
94 | if (!ps_nice) | 94 | if (!ps_nice) |
95 | schedule_work(&ps_tq); | 95 | schedule_delayed_work(&ps_tq, 0); |
96 | else | 96 | else |
97 | schedule_delayed_work(&ps_tq, ps_nice-1); | 97 | schedule_delayed_work(&ps_tq, ps_nice-1); |
98 | spin_unlock_irqrestore(&ps_spinlock,flags); | 98 | spin_unlock_irqrestore(&ps_spinlock,flags); |
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index 47d6975268ff..54509eb3391b 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c | |||
@@ -1244,9 +1244,10 @@ out: | |||
1244 | return IRQ_RETVAL(handled); | 1244 | return IRQ_RETVAL(handled); |
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | static void carm_fsm_task (void *_data) | 1247 | static void carm_fsm_task (struct work_struct *work) |
1248 | { | 1248 | { |
1249 | struct carm_host *host = _data; | 1249 | struct carm_host *host = |
1250 | container_of(work, struct carm_host, fsm_task); | ||
1250 | unsigned long flags; | 1251 | unsigned long flags; |
1251 | unsigned int state; | 1252 | unsigned int state; |
1252 | int rc, i, next_dev; | 1253 | int rc, i, next_dev; |
@@ -1619,7 +1620,7 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1619 | host->pdev = pdev; | 1620 | host->pdev = pdev; |
1620 | host->flags = pci_dac ? FL_DAC : 0; | 1621 | host->flags = pci_dac ? FL_DAC : 0; |
1621 | spin_lock_init(&host->lock); | 1622 | spin_lock_init(&host->lock); |
1622 | INIT_WORK(&host->fsm_task, carm_fsm_task, host); | 1623 | INIT_WORK(&host->fsm_task, carm_fsm_task); |
1623 | init_completion(&host->probe_comp); | 1624 | init_completion(&host->probe_comp); |
1624 | 1625 | ||
1625 | for (i = 0; i < ARRAY_SIZE(host->req); i++) | 1626 | for (i = 0; i < ARRAY_SIZE(host->req); i++) |
diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 0d5c73f07265..2098eff91e14 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c | |||
@@ -376,7 +376,7 @@ static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, | |||
376 | int stalled_pipe); | 376 | int stalled_pipe); |
377 | static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); | 377 | static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); |
378 | static void ub_reset_enter(struct ub_dev *sc, int try); | 378 | static void ub_reset_enter(struct ub_dev *sc, int try); |
379 | static void ub_reset_task(void *arg); | 379 | static void ub_reset_task(struct work_struct *work); |
380 | static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); | 380 | static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); |
381 | static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, | 381 | static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, |
382 | struct ub_capacity *ret); | 382 | struct ub_capacity *ret); |
@@ -1558,9 +1558,9 @@ static void ub_reset_enter(struct ub_dev *sc, int try) | |||
1558 | schedule_work(&sc->reset_work); | 1558 | schedule_work(&sc->reset_work); |
1559 | } | 1559 | } |
1560 | 1560 | ||
1561 | static void ub_reset_task(void *arg) | 1561 | static void ub_reset_task(struct work_struct *work) |
1562 | { | 1562 | { |
1563 | struct ub_dev *sc = arg; | 1563 | struct ub_dev *sc = container_of(work, struct ub_dev, reset_work); |
1564 | unsigned long flags; | 1564 | unsigned long flags; |
1565 | struct list_head *p; | 1565 | struct list_head *p; |
1566 | struct ub_lun *lun; | 1566 | struct ub_lun *lun; |
@@ -2179,7 +2179,7 @@ static int ub_probe(struct usb_interface *intf, | |||
2179 | usb_init_urb(&sc->work_urb); | 2179 | usb_init_urb(&sc->work_urb); |
2180 | tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); | 2180 | tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); |
2181 | atomic_set(&sc->poison, 0); | 2181 | atomic_set(&sc->poison, 0); |
2182 | INIT_WORK(&sc->reset_work, ub_reset_task, sc); | 2182 | INIT_WORK(&sc->reset_work, ub_reset_task); |
2183 | init_waitqueue_head(&sc->reset_wait); | 2183 | init_waitqueue_head(&sc->reset_wait); |
2184 | 2184 | ||
2185 | init_timer(&sc->work_timer); | 2185 | init_timer(&sc->work_timer); |
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index ec5a1b90a0a2..e19ba4ebcd4e 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c | |||
@@ -759,6 +759,8 @@ static struct vio_driver viodasd_driver = { | |||
759 | } | 759 | } |
760 | }; | 760 | }; |
761 | 761 | ||
762 | static int need_delete_probe; | ||
763 | |||
762 | /* | 764 | /* |
763 | * Initialize the whole device driver. Handle module and non-module | 765 | * Initialize the whole device driver. Handle module and non-module |
764 | * versions | 766 | * versions |
@@ -773,46 +775,67 @@ static int __init viodasd_init(void) | |||
773 | 775 | ||
774 | if (viopath_hostLp == HvLpIndexInvalid) { | 776 | if (viopath_hostLp == HvLpIndexInvalid) { |
775 | printk(VIOD_KERN_WARNING "invalid hosting partition\n"); | 777 | printk(VIOD_KERN_WARNING "invalid hosting partition\n"); |
776 | return -EIO; | 778 | rc = -EIO; |
779 | goto early_fail; | ||
777 | } | 780 | } |
778 | 781 | ||
779 | printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n", | 782 | printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n", |
780 | viopath_hostLp); | 783 | viopath_hostLp); |
781 | 784 | ||
782 | /* register the block device */ | 785 | /* register the block device */ |
783 | if (register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME)) { | 786 | rc = register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); |
787 | if (rc) { | ||
784 | printk(VIOD_KERN_WARNING | 788 | printk(VIOD_KERN_WARNING |
785 | "Unable to get major number %d for %s\n", | 789 | "Unable to get major number %d for %s\n", |
786 | VIODASD_MAJOR, VIOD_GENHD_NAME); | 790 | VIODASD_MAJOR, VIOD_GENHD_NAME); |
787 | return -EIO; | 791 | goto early_fail; |
788 | } | 792 | } |
789 | /* Actually open the path to the hosting partition */ | 793 | /* Actually open the path to the hosting partition */ |
790 | if (viopath_open(viopath_hostLp, viomajorsubtype_blockio, | 794 | rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio, |
791 | VIOMAXREQ + 2)) { | 795 | VIOMAXREQ + 2); |
796 | if (rc) { | ||
792 | printk(VIOD_KERN_WARNING | 797 | printk(VIOD_KERN_WARNING |
793 | "error opening path to host partition %d\n", | 798 | "error opening path to host partition %d\n", |
794 | viopath_hostLp); | 799 | viopath_hostLp); |
795 | unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); | 800 | goto unregister_blk; |
796 | return -EIO; | ||
797 | } | 801 | } |
798 | 802 | ||
799 | /* Initialize our request handler */ | 803 | /* Initialize our request handler */ |
800 | vio_setHandler(viomajorsubtype_blockio, handle_block_event); | 804 | vio_setHandler(viomajorsubtype_blockio, handle_block_event); |
801 | 805 | ||
802 | rc = vio_register_driver(&viodasd_driver); | 806 | rc = vio_register_driver(&viodasd_driver); |
803 | if (rc == 0) | 807 | if (rc) { |
804 | driver_create_file(&viodasd_driver.driver, &driver_attr_probe); | 808 | printk(VIOD_KERN_WARNING "vio_register_driver failed\n"); |
809 | goto unset_handler; | ||
810 | } | ||
811 | |||
812 | /* | ||
813 | * If this call fails, it just means that we cannot dynamically | ||
814 | * add virtual disks, but the driver will still work fine for | ||
815 | * all existing disk, so ignore the failure. | ||
816 | */ | ||
817 | if (!driver_create_file(&viodasd_driver.driver, &driver_attr_probe)) | ||
818 | need_delete_probe = 1; | ||
819 | |||
820 | return 0; | ||
821 | |||
822 | unset_handler: | ||
823 | vio_clearHandler(viomajorsubtype_blockio); | ||
824 | viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2); | ||
825 | unregister_blk: | ||
826 | unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); | ||
827 | early_fail: | ||
805 | return rc; | 828 | return rc; |
806 | } | 829 | } |
807 | module_init(viodasd_init); | 830 | module_init(viodasd_init); |
808 | 831 | ||
809 | void viodasd_exit(void) | 832 | void __exit viodasd_exit(void) |
810 | { | 833 | { |
811 | driver_remove_file(&viodasd_driver.driver, &driver_attr_probe); | 834 | if (need_delete_probe) |
835 | driver_remove_file(&viodasd_driver.driver, &driver_attr_probe); | ||
812 | vio_unregister_driver(&viodasd_driver); | 836 | vio_unregister_driver(&viodasd_driver); |
813 | vio_clearHandler(viomajorsubtype_blockio); | 837 | vio_clearHandler(viomajorsubtype_blockio); |
814 | unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); | ||
815 | viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2); | 838 | viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2); |
839 | unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); | ||
816 | } | 840 | } |
817 | |||
818 | module_exit(viodasd_exit); | 841 | module_exit(viodasd_exit); |
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c index 516751754aa9..9256985cbe36 100644 --- a/drivers/bluetooth/bcm203x.c +++ b/drivers/bluetooth/bcm203x.c | |||
@@ -157,9 +157,10 @@ static void bcm203x_complete(struct urb *urb) | |||
157 | } | 157 | } |
158 | } | 158 | } |
159 | 159 | ||
160 | static void bcm203x_work(void *user_data) | 160 | static void bcm203x_work(struct work_struct *work) |
161 | { | 161 | { |
162 | struct bcm203x_data *data = user_data; | 162 | struct bcm203x_data *data = |
163 | container_of(work, struct bcm203x_data, work); | ||
163 | 164 | ||
164 | if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) | 165 | if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0) |
165 | BT_ERR("Can't submit URB"); | 166 | BT_ERR("Can't submit URB"); |
@@ -246,7 +247,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id | |||
246 | 247 | ||
247 | release_firmware(firmware); | 248 | release_firmware(firmware); |
248 | 249 | ||
249 | INIT_WORK(&data->work, bcm203x_work, (void *) data); | 250 | INIT_WORK(&data->work, bcm203x_work); |
250 | 251 | ||
251 | usb_set_intfdata(intf, data); | 252 | usb_set_intfdata(intf, data); |
252 | 253 | ||
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index cbc07250b898..acfb6a430dcc 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -892,43 +892,10 @@ static void bluecard_detach(struct pcmcia_device *link) | |||
892 | } | 892 | } |
893 | 893 | ||
894 | 894 | ||
895 | static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse) | ||
896 | { | ||
897 | int i; | ||
898 | |||
899 | i = pcmcia_get_first_tuple(handle, tuple); | ||
900 | if (i != CS_SUCCESS) | ||
901 | return CS_NO_MORE_ITEMS; | ||
902 | |||
903 | i = pcmcia_get_tuple_data(handle, tuple); | ||
904 | if (i != CS_SUCCESS) | ||
905 | return i; | ||
906 | |||
907 | return pcmcia_parse_tuple(handle, tuple, parse); | ||
908 | } | ||
909 | |||
910 | static int bluecard_config(struct pcmcia_device *link) | 895 | static int bluecard_config(struct pcmcia_device *link) |
911 | { | 896 | { |
912 | bluecard_info_t *info = link->priv; | 897 | bluecard_info_t *info = link->priv; |
913 | tuple_t tuple; | 898 | int i, n; |
914 | u_short buf[256]; | ||
915 | cisparse_t parse; | ||
916 | int i, n, last_ret, last_fn; | ||
917 | |||
918 | tuple.TupleData = (cisdata_t *)buf; | ||
919 | tuple.TupleOffset = 0; | ||
920 | tuple.TupleDataMax = 255; | ||
921 | tuple.Attributes = 0; | ||
922 | |||
923 | /* Get configuration register information */ | ||
924 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
925 | last_ret = first_tuple(link, &tuple, &parse); | ||
926 | if (last_ret != CS_SUCCESS) { | ||
927 | last_fn = ParseTuple; | ||
928 | goto cs_failed; | ||
929 | } | ||
930 | link->conf.ConfigBase = parse.config.base; | ||
931 | link->conf.Present = parse.config.rmask[0]; | ||
932 | 899 | ||
933 | link->conf.ConfigIndex = 0x20; | 900 | link->conf.ConfigIndex = 0x20; |
934 | link->io.NumPorts1 = 64; | 901 | link->io.NumPorts1 = 64; |
@@ -966,9 +933,6 @@ static int bluecard_config(struct pcmcia_device *link) | |||
966 | 933 | ||
967 | return 0; | 934 | return 0; |
968 | 935 | ||
969 | cs_failed: | ||
970 | cs_error(link, last_fn, last_ret); | ||
971 | |||
972 | failed: | 936 | failed: |
973 | bluecard_release(link); | 937 | bluecard_release(link); |
974 | return -ENODEV; | 938 | return -ENODEV; |
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 3a96a0babc6a..aae3abace586 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -713,22 +713,7 @@ static int bt3c_config(struct pcmcia_device *link) | |||
713 | u_short buf[256]; | 713 | u_short buf[256]; |
714 | cisparse_t parse; | 714 | cisparse_t parse; |
715 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 715 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; |
716 | int i, j, try, last_ret, last_fn; | 716 | int i, j, try; |
717 | |||
718 | tuple.TupleData = (cisdata_t *)buf; | ||
719 | tuple.TupleOffset = 0; | ||
720 | tuple.TupleDataMax = 255; | ||
721 | tuple.Attributes = 0; | ||
722 | |||
723 | /* Get configuration register information */ | ||
724 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
725 | last_ret = first_tuple(link, &tuple, &parse); | ||
726 | if (last_ret != CS_SUCCESS) { | ||
727 | last_fn = ParseTuple; | ||
728 | goto cs_failed; | ||
729 | } | ||
730 | link->conf.ConfigBase = parse.config.base; | ||
731 | link->conf.Present = parse.config.rmask[0]; | ||
732 | 717 | ||
733 | /* First pass: look for a config entry that looks normal. */ | 718 | /* First pass: look for a config entry that looks normal. */ |
734 | tuple.TupleData = (cisdata_t *)buf; | 719 | tuple.TupleData = (cisdata_t *)buf; |
@@ -802,9 +787,6 @@ found_port: | |||
802 | 787 | ||
803 | return 0; | 788 | return 0; |
804 | 789 | ||
805 | cs_failed: | ||
806 | cs_error(link, last_fn, last_ret); | ||
807 | |||
808 | failed: | 790 | failed: |
809 | bt3c_release(link); | 791 | bt3c_release(link); |
810 | return -ENODEV; | 792 | return -ENODEV; |
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 3b29086b7c3f..92648ef2f5d0 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -644,22 +644,7 @@ static int btuart_config(struct pcmcia_device *link) | |||
644 | u_short buf[256]; | 644 | u_short buf[256]; |
645 | cisparse_t parse; | 645 | cisparse_t parse; |
646 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 646 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; |
647 | int i, j, try, last_ret, last_fn; | 647 | int i, j, try; |
648 | |||
649 | tuple.TupleData = (cisdata_t *)buf; | ||
650 | tuple.TupleOffset = 0; | ||
651 | tuple.TupleDataMax = 255; | ||
652 | tuple.Attributes = 0; | ||
653 | |||
654 | /* Get configuration register information */ | ||
655 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
656 | last_ret = first_tuple(link, &tuple, &parse); | ||
657 | if (last_ret != CS_SUCCESS) { | ||
658 | last_fn = ParseTuple; | ||
659 | goto cs_failed; | ||
660 | } | ||
661 | link->conf.ConfigBase = parse.config.base; | ||
662 | link->conf.Present = parse.config.rmask[0]; | ||
663 | 648 | ||
664 | /* First pass: look for a config entry that looks normal. */ | 649 | /* First pass: look for a config entry that looks normal. */ |
665 | tuple.TupleData = (cisdata_t *) buf; | 650 | tuple.TupleData = (cisdata_t *) buf; |
@@ -734,9 +719,6 @@ found_port: | |||
734 | 719 | ||
735 | return 0; | 720 | return 0; |
736 | 721 | ||
737 | cs_failed: | ||
738 | cs_error(link, last_fn, last_ret); | ||
739 | |||
740 | failed: | 722 | failed: |
741 | btuart_release(link); | 723 | btuart_release(link); |
742 | return -ENODEV; | 724 | return -ENODEV; |
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 07eafbc5dc3a..77b99eecbc49 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -626,22 +626,7 @@ static int dtl1_config(struct pcmcia_device *link) | |||
626 | u_short buf[256]; | 626 | u_short buf[256]; |
627 | cisparse_t parse; | 627 | cisparse_t parse; |
628 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; | 628 | cistpl_cftable_entry_t *cf = &parse.cftable_entry; |
629 | int i, last_ret, last_fn; | 629 | int i; |
630 | |||
631 | tuple.TupleData = (cisdata_t *)buf; | ||
632 | tuple.TupleOffset = 0; | ||
633 | tuple.TupleDataMax = 255; | ||
634 | tuple.Attributes = 0; | ||
635 | |||
636 | /* Get configuration register information */ | ||
637 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
638 | last_ret = first_tuple(link, &tuple, &parse); | ||
639 | if (last_ret != CS_SUCCESS) { | ||
640 | last_fn = ParseTuple; | ||
641 | goto cs_failed; | ||
642 | } | ||
643 | link->conf.ConfigBase = parse.config.base; | ||
644 | link->conf.Present = parse.config.rmask[0]; | ||
645 | 630 | ||
646 | tuple.TupleData = (cisdata_t *)buf; | 631 | tuple.TupleData = (cisdata_t *)buf; |
647 | tuple.TupleOffset = 0; | 632 | tuple.TupleOffset = 0; |
@@ -690,9 +675,6 @@ static int dtl1_config(struct pcmcia_device *link) | |||
690 | 675 | ||
691 | return 0; | 676 | return 0; |
692 | 677 | ||
693 | cs_failed: | ||
694 | cs_error(link, last_fn, last_ret); | ||
695 | |||
696 | failed: | 678 | failed: |
697 | dtl1_release(link); | 679 | dtl1_release(link); |
698 | return -ENODEV; | 680 | return -ENODEV; |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index e608dadece2f..acb2de5e3a98 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -926,9 +926,10 @@ cy_sched_event(struct cyclades_port *info, int event) | |||
926 | * had to poll every port to see if that port needed servicing. | 926 | * had to poll every port to see if that port needed servicing. |
927 | */ | 927 | */ |
928 | static void | 928 | static void |
929 | do_softint(void *private_) | 929 | do_softint(struct work_struct *work) |
930 | { | 930 | { |
931 | struct cyclades_port *info = (struct cyclades_port *) private_; | 931 | struct cyclades_port *info = |
932 | container_of(work, struct cyclades_port, tqueue); | ||
932 | struct tty_struct *tty; | 933 | struct tty_struct *tty; |
933 | 934 | ||
934 | tty = info->tty; | 935 | tty = info->tty; |
@@ -5328,7 +5329,7 @@ cy_init(void) | |||
5328 | info->blocked_open = 0; | 5329 | info->blocked_open = 0; |
5329 | info->default_threshold = 0; | 5330 | info->default_threshold = 0; |
5330 | info->default_timeout = 0; | 5331 | info->default_timeout = 0; |
5331 | INIT_WORK(&info->tqueue, do_softint, info); | 5332 | INIT_WORK(&info->tqueue, do_softint); |
5332 | init_waitqueue_head(&info->open_wait); | 5333 | init_waitqueue_head(&info->open_wait); |
5333 | init_waitqueue_head(&info->close_wait); | 5334 | init_waitqueue_head(&info->close_wait); |
5334 | init_waitqueue_head(&info->shutdown_wait); | 5335 | init_waitqueue_head(&info->shutdown_wait); |
@@ -5403,7 +5404,7 @@ cy_init(void) | |||
5403 | info->blocked_open = 0; | 5404 | info->blocked_open = 0; |
5404 | info->default_threshold = 0; | 5405 | info->default_threshold = 0; |
5405 | info->default_timeout = 0; | 5406 | info->default_timeout = 0; |
5406 | INIT_WORK(&info->tqueue, do_softint, info); | 5407 | INIT_WORK(&info->tqueue, do_softint); |
5407 | init_waitqueue_head(&info->open_wait); | 5408 | init_waitqueue_head(&info->open_wait); |
5408 | init_waitqueue_head(&info->close_wait); | 5409 | init_waitqueue_head(&info->close_wait); |
5409 | init_waitqueue_head(&info->shutdown_wait); | 5410 | init_waitqueue_head(&info->shutdown_wait); |
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c index 60c1695db300..806f9ce5f47b 100644 --- a/drivers/char/drm/via_dmablit.c +++ b/drivers/char/drm/via_dmablit.c | |||
@@ -500,9 +500,9 @@ via_dmablit_timer(unsigned long data) | |||
500 | 500 | ||
501 | 501 | ||
502 | static void | 502 | static void |
503 | via_dmablit_workqueue(void *data) | 503 | via_dmablit_workqueue(struct work_struct *work) |
504 | { | 504 | { |
505 | drm_via_blitq_t *blitq = (drm_via_blitq_t *) data; | 505 | drm_via_blitq_t *blitq = container_of(work, drm_via_blitq_t, wq); |
506 | drm_device_t *dev = blitq->dev; | 506 | drm_device_t *dev = blitq->dev; |
507 | unsigned long irqsave; | 507 | unsigned long irqsave; |
508 | drm_via_sg_info_t *cur_sg; | 508 | drm_via_sg_info_t *cur_sg; |
@@ -571,7 +571,7 @@ via_init_dmablit(drm_device_t *dev) | |||
571 | DRM_INIT_WAITQUEUE(blitq->blit_queue + j); | 571 | DRM_INIT_WAITQUEUE(blitq->blit_queue + j); |
572 | } | 572 | } |
573 | DRM_INIT_WAITQUEUE(&blitq->busy_queue); | 573 | DRM_INIT_WAITQUEUE(&blitq->busy_queue); |
574 | INIT_WORK(&blitq->wq, via_dmablit_workqueue, blitq); | 574 | INIT_WORK(&blitq->wq, via_dmablit_workqueue); |
575 | init_timer(&blitq->poll_timer); | 575 | init_timer(&blitq->poll_timer); |
576 | blitq->poll_timer.function = &via_dmablit_timer; | 576 | blitq->poll_timer.function = &via_dmablit_timer; |
577 | blitq->poll_timer.data = (unsigned long) blitq; | 577 | blitq->poll_timer.data = (unsigned long) blitq; |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 706733c0b36a..7c71eb779802 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -200,7 +200,7 @@ static int pc_ioctl(struct tty_struct *, struct file *, | |||
200 | static int info_ioctl(struct tty_struct *, struct file *, | 200 | static int info_ioctl(struct tty_struct *, struct file *, |
201 | unsigned int, unsigned long); | 201 | unsigned int, unsigned long); |
202 | static void pc_set_termios(struct tty_struct *, struct termios *); | 202 | static void pc_set_termios(struct tty_struct *, struct termios *); |
203 | static void do_softint(void *); | 203 | static void do_softint(struct work_struct *work); |
204 | static void pc_stop(struct tty_struct *); | 204 | static void pc_stop(struct tty_struct *); |
205 | static void pc_start(struct tty_struct *); | 205 | static void pc_start(struct tty_struct *); |
206 | static void pc_throttle(struct tty_struct * tty); | 206 | static void pc_throttle(struct tty_struct * tty); |
@@ -1505,7 +1505,7 @@ static void post_fep_init(unsigned int crd) | |||
1505 | 1505 | ||
1506 | ch->brdchan = bc; | 1506 | ch->brdchan = bc; |
1507 | ch->mailbox = gd; | 1507 | ch->mailbox = gd; |
1508 | INIT_WORK(&ch->tqueue, do_softint, ch); | 1508 | INIT_WORK(&ch->tqueue, do_softint); |
1509 | ch->board = &boards[crd]; | 1509 | ch->board = &boards[crd]; |
1510 | 1510 | ||
1511 | spin_lock_irqsave(&epca_lock, flags); | 1511 | spin_lock_irqsave(&epca_lock, flags); |
@@ -2566,9 +2566,9 @@ static void pc_set_termios(struct tty_struct *tty, struct termios *old_termios) | |||
2566 | 2566 | ||
2567 | /* --------------------- Begin do_softint ----------------------- */ | 2567 | /* --------------------- Begin do_softint ----------------------- */ |
2568 | 2568 | ||
2569 | static void do_softint(void *private_) | 2569 | static void do_softint(struct work_struct *work) |
2570 | { /* Begin do_softint */ | 2570 | { /* Begin do_softint */ |
2571 | struct channel *ch = (struct channel *) private_; | 2571 | struct channel *ch = container_of(work, struct channel, tqueue); |
2572 | /* Called in response to a modem change event */ | 2572 | /* Called in response to a modem change event */ |
2573 | if (ch && ch->magic == EPCA_MAGIC) { /* Begin EPCA_MAGIC */ | 2573 | if (ch && ch->magic == EPCA_MAGIC) { /* Begin EPCA_MAGIC */ |
2574 | struct tty_struct *tty = ch->tty; | 2574 | struct tty_struct *tty = ch->tty; |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 15a4ea896328..93b551962513 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
@@ -723,9 +723,10 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id) | |||
723 | * ------------------------------------------------------------------- | 723 | * ------------------------------------------------------------------- |
724 | */ | 724 | */ |
725 | 725 | ||
726 | static void do_softint(void *private_) | 726 | static void do_softint(struct work_struct *work) |
727 | { | 727 | { |
728 | struct esp_struct *info = (struct esp_struct *) private_; | 728 | struct esp_struct *info = |
729 | container_of(work, struct esp_struct, tqueue); | ||
729 | struct tty_struct *tty; | 730 | struct tty_struct *tty; |
730 | 731 | ||
731 | tty = info->tty; | 732 | tty = info->tty; |
@@ -746,9 +747,10 @@ static void do_softint(void *private_) | |||
746 | * do_serial_hangup() -> tty->hangup() -> esp_hangup() | 747 | * do_serial_hangup() -> tty->hangup() -> esp_hangup() |
747 | * | 748 | * |
748 | */ | 749 | */ |
749 | static void do_serial_hangup(void *private_) | 750 | static void do_serial_hangup(struct work_struct *work) |
750 | { | 751 | { |
751 | struct esp_struct *info = (struct esp_struct *) private_; | 752 | struct esp_struct *info = |
753 | container_of(work, struct esp_struct, tqueue_hangup); | ||
752 | struct tty_struct *tty; | 754 | struct tty_struct *tty; |
753 | 755 | ||
754 | tty = info->tty; | 756 | tty = info->tty; |
@@ -2501,8 +2503,8 @@ static int __init espserial_init(void) | |||
2501 | info->magic = ESP_MAGIC; | 2503 | info->magic = ESP_MAGIC; |
2502 | info->close_delay = 5*HZ/10; | 2504 | info->close_delay = 5*HZ/10; |
2503 | info->closing_wait = 30*HZ; | 2505 | info->closing_wait = 30*HZ; |
2504 | INIT_WORK(&info->tqueue, do_softint, info); | 2506 | INIT_WORK(&info->tqueue, do_softint); |
2505 | INIT_WORK(&info->tqueue_hangup, do_serial_hangup, info); | 2507 | INIT_WORK(&info->tqueue_hangup, do_serial_hangup); |
2506 | info->config.rx_timeout = rx_timeout; | 2508 | info->config.rx_timeout = rx_timeout; |
2507 | info->config.flow_on = flow_on; | 2509 | info->config.flow_on = flow_on; |
2508 | info->config.flow_off = flow_off; | 2510 | info->config.flow_off = flow_off; |
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c index 817dc409ac20..23b25ada65ea 100644 --- a/drivers/char/genrtc.c +++ b/drivers/char/genrtc.c | |||
@@ -102,7 +102,7 @@ static void gen_rtc_interrupt(unsigned long arg); | |||
102 | * Routine to poll RTC seconds field for change as often as possible, | 102 | * Routine to poll RTC seconds field for change as often as possible, |
103 | * after first RTC_UIE use timer to reduce polling | 103 | * after first RTC_UIE use timer to reduce polling |
104 | */ | 104 | */ |
105 | static void genrtc_troutine(void *data) | 105 | static void genrtc_troutine(struct work_struct *work) |
106 | { | 106 | { |
107 | unsigned int tmp = get_rtc_ss(); | 107 | unsigned int tmp = get_rtc_ss(); |
108 | 108 | ||
@@ -255,7 +255,7 @@ static inline int gen_set_rtc_irq_bit(unsigned char bit) | |||
255 | irq_active = 1; | 255 | irq_active = 1; |
256 | stop_rtc_timers = 0; | 256 | stop_rtc_timers = 0; |
257 | lostint = 0; | 257 | lostint = 0; |
258 | INIT_WORK(&genrtc_task, genrtc_troutine, NULL); | 258 | INIT_WORK(&genrtc_task, genrtc_troutine); |
259 | oldsecs = get_rtc_ss(); | 259 | oldsecs = get_rtc_ss(); |
260 | init_timer(&timer_task); | 260 | init_timer(&timer_task); |
261 | 261 | ||
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 2cf63e7305a3..82a41d5b4ed0 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -69,7 +69,7 @@ | |||
69 | #define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) | 69 | #define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) |
70 | 70 | ||
71 | struct hvsi_struct { | 71 | struct hvsi_struct { |
72 | struct work_struct writer; | 72 | struct delayed_work writer; |
73 | struct work_struct handshaker; | 73 | struct work_struct handshaker; |
74 | wait_queue_head_t emptyq; /* woken when outbuf is emptied */ | 74 | wait_queue_head_t emptyq; /* woken when outbuf is emptied */ |
75 | wait_queue_head_t stateq; /* woken when HVSI state changes */ | 75 | wait_queue_head_t stateq; /* woken when HVSI state changes */ |
@@ -744,9 +744,10 @@ static int hvsi_handshake(struct hvsi_struct *hp) | |||
744 | return 0; | 744 | return 0; |
745 | } | 745 | } |
746 | 746 | ||
747 | static void hvsi_handshaker(void *arg) | 747 | static void hvsi_handshaker(struct work_struct *work) |
748 | { | 748 | { |
749 | struct hvsi_struct *hp = (struct hvsi_struct *)arg; | 749 | struct hvsi_struct *hp = |
750 | container_of(work, struct hvsi_struct, handshaker); | ||
750 | 751 | ||
751 | if (hvsi_handshake(hp) >= 0) | 752 | if (hvsi_handshake(hp) >= 0) |
752 | return; | 753 | return; |
@@ -951,9 +952,10 @@ static void hvsi_push(struct hvsi_struct *hp) | |||
951 | } | 952 | } |
952 | 953 | ||
953 | /* hvsi_write_worker will keep rescheduling itself until outbuf is empty */ | 954 | /* hvsi_write_worker will keep rescheduling itself until outbuf is empty */ |
954 | static void hvsi_write_worker(void *arg) | 955 | static void hvsi_write_worker(struct work_struct *work) |
955 | { | 956 | { |
956 | struct hvsi_struct *hp = (struct hvsi_struct *)arg; | 957 | struct hvsi_struct *hp = |
958 | container_of(work, struct hvsi_struct, writer.work); | ||
957 | unsigned long flags; | 959 | unsigned long flags; |
958 | #ifdef DEBUG | 960 | #ifdef DEBUG |
959 | static long start_j = 0; | 961 | static long start_j = 0; |
@@ -1287,8 +1289,8 @@ static int __init hvsi_console_init(void) | |||
1287 | } | 1289 | } |
1288 | 1290 | ||
1289 | hp = &hvsi_ports[hvsi_count]; | 1291 | hp = &hvsi_ports[hvsi_count]; |
1290 | INIT_WORK(&hp->writer, hvsi_write_worker, hp); | 1292 | INIT_DELAYED_WORK(&hp->writer, hvsi_write_worker); |
1291 | INIT_WORK(&hp->handshaker, hvsi_handshaker, hp); | 1293 | INIT_WORK(&hp->handshaker, hvsi_handshaker); |
1292 | init_waitqueue_head(&hp->emptyq); | 1294 | init_waitqueue_head(&hp->emptyq); |
1293 | init_waitqueue_head(&hp->stateq); | 1295 | init_waitqueue_head(&hp->stateq); |
1294 | spin_lock_init(&hp->lock); | 1296 | spin_lock_init(&hp->lock); |
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c index 54d93f0345e8..c213fdbdb2b0 100644 --- a/drivers/char/ip2/i2lib.c +++ b/drivers/char/ip2/i2lib.c | |||
@@ -84,8 +84,8 @@ static void iiSendPendingMail(i2eBordStrPtr); | |||
84 | static void serviceOutgoingFifo(i2eBordStrPtr); | 84 | static void serviceOutgoingFifo(i2eBordStrPtr); |
85 | 85 | ||
86 | // Functions defined in ip2.c as part of interrupt handling | 86 | // Functions defined in ip2.c as part of interrupt handling |
87 | static void do_input(void *); | 87 | static void do_input(struct work_struct *); |
88 | static void do_status(void *); | 88 | static void do_status(struct work_struct *); |
89 | 89 | ||
90 | //*************** | 90 | //*************** |
91 | //* Debug Data * | 91 | //* Debug Data * |
@@ -331,8 +331,8 @@ i2InitChannels ( i2eBordStrPtr pB, int nChannels, i2ChanStrPtr pCh) | |||
331 | pCh->ClosingWaitTime = 30*HZ; | 331 | pCh->ClosingWaitTime = 30*HZ; |
332 | 332 | ||
333 | // Initialize task queue objects | 333 | // Initialize task queue objects |
334 | INIT_WORK(&pCh->tqueue_input, do_input, pCh); | 334 | INIT_WORK(&pCh->tqueue_input, do_input); |
335 | INIT_WORK(&pCh->tqueue_status, do_status, pCh); | 335 | INIT_WORK(&pCh->tqueue_status, do_status); |
336 | 336 | ||
337 | #ifdef IP2DEBUG_TRACE | 337 | #ifdef IP2DEBUG_TRACE |
338 | pCh->trace = ip2trace; | 338 | pCh->trace = ip2trace; |
@@ -1573,7 +1573,7 @@ i2StripFifo(i2eBordStrPtr pB) | |||
1573 | #ifdef USE_IQ | 1573 | #ifdef USE_IQ |
1574 | schedule_work(&pCh->tqueue_input); | 1574 | schedule_work(&pCh->tqueue_input); |
1575 | #else | 1575 | #else |
1576 | do_input(pCh); | 1576 | do_input(&pCh->tqueue_input); |
1577 | #endif | 1577 | #endif |
1578 | 1578 | ||
1579 | // Note we do not need to maintain any flow-control credits at this | 1579 | // Note we do not need to maintain any flow-control credits at this |
@@ -1810,7 +1810,7 @@ i2StripFifo(i2eBordStrPtr pB) | |||
1810 | #ifdef USE_IQ | 1810 | #ifdef USE_IQ |
1811 | schedule_work(&pCh->tqueue_status); | 1811 | schedule_work(&pCh->tqueue_status); |
1812 | #else | 1812 | #else |
1813 | do_status(pCh); | 1813 | do_status(&pCh->tqueue_status); |
1814 | #endif | 1814 | #endif |
1815 | } | 1815 | } |
1816 | } | 1816 | } |
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index a3f32d46d2f8..cda2459c1d60 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -189,12 +189,12 @@ static int ip2_tiocmset(struct tty_struct *tty, struct file *file, | |||
189 | unsigned int set, unsigned int clear); | 189 | unsigned int set, unsigned int clear); |
190 | 190 | ||
191 | static void set_irq(int, int); | 191 | static void set_irq(int, int); |
192 | static void ip2_interrupt_bh(i2eBordStrPtr pB); | 192 | static void ip2_interrupt_bh(struct work_struct *work); |
193 | static irqreturn_t ip2_interrupt(int irq, void *dev_id); | 193 | static irqreturn_t ip2_interrupt(int irq, void *dev_id); |
194 | static void ip2_poll(unsigned long arg); | 194 | static void ip2_poll(unsigned long arg); |
195 | static inline void service_all_boards(void); | 195 | static inline void service_all_boards(void); |
196 | static void do_input(void *p); | 196 | static void do_input(struct work_struct *); |
197 | static void do_status(void *p); | 197 | static void do_status(struct work_struct *); |
198 | 198 | ||
199 | static void ip2_wait_until_sent(PTTY,int); | 199 | static void ip2_wait_until_sent(PTTY,int); |
200 | 200 | ||
@@ -918,7 +918,7 @@ ip2_init_board( int boardnum ) | |||
918 | pCh++; | 918 | pCh++; |
919 | } | 919 | } |
920 | ex_exit: | 920 | ex_exit: |
921 | INIT_WORK(&pB->tqueue_interrupt, (void(*)(void*)) ip2_interrupt_bh, pB); | 921 | INIT_WORK(&pB->tqueue_interrupt, ip2_interrupt_bh); |
922 | return; | 922 | return; |
923 | 923 | ||
924 | err_release_region: | 924 | err_release_region: |
@@ -1125,8 +1125,8 @@ service_all_boards(void) | |||
1125 | 1125 | ||
1126 | 1126 | ||
1127 | /******************************************************************************/ | 1127 | /******************************************************************************/ |
1128 | /* Function: ip2_interrupt_bh(pB) */ | 1128 | /* Function: ip2_interrupt_bh(work) */ |
1129 | /* Parameters: pB - pointer to the board structure */ | 1129 | /* Parameters: work - pointer to the board structure */ |
1130 | /* Returns: Nothing */ | 1130 | /* Returns: Nothing */ |
1131 | /* */ | 1131 | /* */ |
1132 | /* Description: */ | 1132 | /* Description: */ |
@@ -1135,8 +1135,9 @@ service_all_boards(void) | |||
1135 | /* */ | 1135 | /* */ |
1136 | /******************************************************************************/ | 1136 | /******************************************************************************/ |
1137 | static void | 1137 | static void |
1138 | ip2_interrupt_bh(i2eBordStrPtr pB) | 1138 | ip2_interrupt_bh(struct work_struct *work) |
1139 | { | 1139 | { |
1140 | i2eBordStrPtr pB = container_of(work, i2eBordStr, tqueue_interrupt); | ||
1140 | // pB better well be set or we have a problem! We can only get | 1141 | // pB better well be set or we have a problem! We can only get |
1141 | // here from the IMMEDIATE queue. Here, we process the boards. | 1142 | // here from the IMMEDIATE queue. Here, we process the boards. |
1142 | // Checking pB doesn't cost much and it saves us from the sanity checkers. | 1143 | // Checking pB doesn't cost much and it saves us from the sanity checkers. |
@@ -1245,9 +1246,9 @@ ip2_poll(unsigned long arg) | |||
1245 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); | 1246 | ip2trace (ITRC_NO_PORT, ITRC_INTR, ITRC_RETURN, 0 ); |
1246 | } | 1247 | } |
1247 | 1248 | ||
1248 | static void do_input(void *p) | 1249 | static void do_input(struct work_struct *work) |
1249 | { | 1250 | { |
1250 | i2ChanStrPtr pCh = p; | 1251 | i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_input); |
1251 | unsigned long flags; | 1252 | unsigned long flags; |
1252 | 1253 | ||
1253 | ip2trace(CHANN, ITRC_INPUT, 21, 0 ); | 1254 | ip2trace(CHANN, ITRC_INPUT, 21, 0 ); |
@@ -1279,9 +1280,9 @@ static inline void isig(int sig, struct tty_struct *tty, int flush) | |||
1279 | } | 1280 | } |
1280 | } | 1281 | } |
1281 | 1282 | ||
1282 | static void do_status(void *p) | 1283 | static void do_status(struct work_struct *work) |
1283 | { | 1284 | { |
1284 | i2ChanStrPtr pCh = p; | 1285 | i2ChanStrPtr pCh = container_of(work, i2ChanStr, tqueue_status); |
1285 | int status; | 1286 | int status; |
1286 | 1287 | ||
1287 | status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) ); | 1288 | status = i2GetStatus( pCh, (I2_BRK|I2_PAR|I2_FRA|I2_OVR) ); |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 58c955e390b3..1637c1d9a4ba 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -530,9 +530,9 @@ sched_again: | |||
530 | /* Interrupt handlers */ | 530 | /* Interrupt handlers */ |
531 | 531 | ||
532 | 532 | ||
533 | static void isicom_bottomhalf(void *data) | 533 | static void isicom_bottomhalf(struct work_struct *work) |
534 | { | 534 | { |
535 | struct isi_port *port = (struct isi_port *) data; | 535 | struct isi_port *port = container_of(work, struct isi_port, bh_tqueue); |
536 | struct tty_struct *tty = port->tty; | 536 | struct tty_struct *tty = port->tty; |
537 | 537 | ||
538 | if (!tty) | 538 | if (!tty) |
@@ -1474,9 +1474,9 @@ static void isicom_start(struct tty_struct *tty) | |||
1474 | } | 1474 | } |
1475 | 1475 | ||
1476 | /* hangup et all */ | 1476 | /* hangup et all */ |
1477 | static void do_isicom_hangup(void *data) | 1477 | static void do_isicom_hangup(struct work_struct *work) |
1478 | { | 1478 | { |
1479 | struct isi_port *port = data; | 1479 | struct isi_port *port = container_of(work, struct isi_port, hangup_tq); |
1480 | struct tty_struct *tty; | 1480 | struct tty_struct *tty; |
1481 | 1481 | ||
1482 | tty = port->tty; | 1482 | tty = port->tty; |
@@ -1966,8 +1966,8 @@ static int __devinit isicom_setup(void) | |||
1966 | port->channel = channel; | 1966 | port->channel = channel; |
1967 | port->close_delay = 50 * HZ/100; | 1967 | port->close_delay = 50 * HZ/100; |
1968 | port->closing_wait = 3000 * HZ/100; | 1968 | port->closing_wait = 3000 * HZ/100; |
1969 | INIT_WORK(&port->hangup_tq, do_isicom_hangup, port); | 1969 | INIT_WORK(&port->hangup_tq, do_isicom_hangup); |
1970 | INIT_WORK(&port->bh_tqueue, isicom_bottomhalf, port); | 1970 | INIT_WORK(&port->bh_tqueue, isicom_bottomhalf); |
1971 | port->status = 0; | 1971 | port->status = 0; |
1972 | init_waitqueue_head(&port->open_wait); | 1972 | init_waitqueue_head(&port->open_wait); |
1973 | init_waitqueue_head(&port->close_wait); | 1973 | init_waitqueue_head(&port->close_wait); |
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index ffdf9df1a67a..bd9195e17956 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -663,7 +663,7 @@ static int stli_initopen(stlibrd_t *brdp, stliport_t *portp); | |||
663 | static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait); | 663 | static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait); |
664 | static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait); | 664 | static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait); |
665 | static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp); | 665 | static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp); |
666 | static void stli_dohangup(void *arg); | 666 | static void stli_dohangup(struct work_struct *); |
667 | static int stli_setport(stliport_t *portp); | 667 | static int stli_setport(stliport_t *portp); |
668 | static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); | 668 | static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); |
669 | static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); | 669 | static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); |
@@ -1990,9 +1990,9 @@ static void stli_start(struct tty_struct *tty) | |||
1990 | * aren't that time critical). | 1990 | * aren't that time critical). |
1991 | */ | 1991 | */ |
1992 | 1992 | ||
1993 | static void stli_dohangup(void *arg) | 1993 | static void stli_dohangup(struct work_struct *ugly_api) |
1994 | { | 1994 | { |
1995 | stliport_t *portp = (stliport_t *) arg; | 1995 | stliport_t *portp = container_of(ugly_api, stliport_t, tqhangup); |
1996 | if (portp->tty != NULL) { | 1996 | if (portp->tty != NULL) { |
1997 | tty_hangup(portp->tty); | 1997 | tty_hangup(portp->tty); |
1998 | } | 1998 | } |
@@ -2898,7 +2898,7 @@ static int stli_initports(stlibrd_t *brdp) | |||
2898 | portp->baud_base = STL_BAUDBASE; | 2898 | portp->baud_base = STL_BAUDBASE; |
2899 | portp->close_delay = STL_CLOSEDELAY; | 2899 | portp->close_delay = STL_CLOSEDELAY; |
2900 | portp->closing_wait = 30 * HZ; | 2900 | portp->closing_wait = 30 * HZ; |
2901 | INIT_WORK(&portp->tqhangup, stli_dohangup, portp); | 2901 | INIT_WORK(&portp->tqhangup, stli_dohangup); |
2902 | init_waitqueue_head(&portp->open_wait); | 2902 | init_waitqueue_head(&portp->open_wait); |
2903 | init_waitqueue_head(&portp->close_wait); | 2903 | init_waitqueue_head(&portp->close_wait); |
2904 | init_waitqueue_head(&portp->raw_wait); | 2904 | init_waitqueue_head(&portp->raw_wait); |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 96cb1f07332b..2d025a9fd14d 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -222,7 +222,7 @@ static struct semaphore moxaBuffSem; | |||
222 | /* | 222 | /* |
223 | * static functions: | 223 | * static functions: |
224 | */ | 224 | */ |
225 | static void do_moxa_softint(void *); | 225 | static void do_moxa_softint(struct work_struct *); |
226 | static int moxa_open(struct tty_struct *, struct file *); | 226 | static int moxa_open(struct tty_struct *, struct file *); |
227 | static void moxa_close(struct tty_struct *, struct file *); | 227 | static void moxa_close(struct tty_struct *, struct file *); |
228 | static int moxa_write(struct tty_struct *, const unsigned char *, int); | 228 | static int moxa_write(struct tty_struct *, const unsigned char *, int); |
@@ -363,7 +363,7 @@ static int __init moxa_init(void) | |||
363 | for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) { | 363 | for (i = 0, ch = moxaChannels; i < MAX_PORTS; i++, ch++) { |
364 | ch->type = PORT_16550A; | 364 | ch->type = PORT_16550A; |
365 | ch->port = i; | 365 | ch->port = i; |
366 | INIT_WORK(&ch->tqueue, do_moxa_softint, ch); | 366 | INIT_WORK(&ch->tqueue, do_moxa_softint); |
367 | ch->tty = NULL; | 367 | ch->tty = NULL; |
368 | ch->close_delay = 5 * HZ / 10; | 368 | ch->close_delay = 5 * HZ / 10; |
369 | ch->closing_wait = 30 * HZ; | 369 | ch->closing_wait = 30 * HZ; |
@@ -509,9 +509,9 @@ static void __exit moxa_exit(void) | |||
509 | module_init(moxa_init); | 509 | module_init(moxa_init); |
510 | module_exit(moxa_exit); | 510 | module_exit(moxa_exit); |
511 | 511 | ||
512 | static void do_moxa_softint(void *private_) | 512 | static void do_moxa_softint(struct work_struct *work) |
513 | { | 513 | { |
514 | struct moxa_str *ch = (struct moxa_str *) private_; | 514 | struct moxa_str *ch = container_of(work, struct moxa_str, tqueue); |
515 | struct tty_struct *tty; | 515 | struct tty_struct *tty; |
516 | 516 | ||
517 | if (ch && (tty = ch->tty)) { | 517 | if (ch && (tty = ch->tty)) { |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 048d91142c17..5ed2486b7581 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -389,7 +389,7 @@ static int mxser_init(void); | |||
389 | /* static void mxser_poll(unsigned long); */ | 389 | /* static void mxser_poll(unsigned long); */ |
390 | static int mxser_get_ISA_conf(int, struct mxser_hwconf *); | 390 | static int mxser_get_ISA_conf(int, struct mxser_hwconf *); |
391 | static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *); | 391 | static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *); |
392 | static void mxser_do_softint(void *); | 392 | static void mxser_do_softint(struct work_struct *); |
393 | static int mxser_open(struct tty_struct *, struct file *); | 393 | static int mxser_open(struct tty_struct *, struct file *); |
394 | static void mxser_close(struct tty_struct *, struct file *); | 394 | static void mxser_close(struct tty_struct *, struct file *); |
395 | static int mxser_write(struct tty_struct *, const unsigned char *, int); | 395 | static int mxser_write(struct tty_struct *, const unsigned char *, int); |
@@ -590,7 +590,7 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf) | |||
590 | info->custom_divisor = hwconf->baud_base[i] * 16; | 590 | info->custom_divisor = hwconf->baud_base[i] * 16; |
591 | info->close_delay = 5 * HZ / 10; | 591 | info->close_delay = 5 * HZ / 10; |
592 | info->closing_wait = 30 * HZ; | 592 | info->closing_wait = 30 * HZ; |
593 | INIT_WORK(&info->tqueue, mxser_do_softint, info); | 593 | INIT_WORK(&info->tqueue, mxser_do_softint); |
594 | info->normal_termios = mxvar_sdriver->init_termios; | 594 | info->normal_termios = mxvar_sdriver->init_termios; |
595 | init_waitqueue_head(&info->open_wait); | 595 | init_waitqueue_head(&info->open_wait); |
596 | init_waitqueue_head(&info->close_wait); | 596 | init_waitqueue_head(&info->close_wait); |
@@ -917,9 +917,10 @@ static int mxser_init(void) | |||
917 | return 0; | 917 | return 0; |
918 | } | 918 | } |
919 | 919 | ||
920 | static void mxser_do_softint(void *private_) | 920 | static void mxser_do_softint(struct work_struct *work) |
921 | { | 921 | { |
922 | struct mxser_struct *info = private_; | 922 | struct mxser_struct *info = |
923 | container_of(work, struct mxser_struct, tqueue); | ||
923 | struct tty_struct *tty; | 924 | struct tty_struct *tty; |
924 | 925 | ||
925 | tty = info->tty; | 926 | tty = info->tty; |
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 50d20aafeb18..211c93fda6fc 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c | |||
@@ -1764,29 +1764,11 @@ static int cm4000_config(struct pcmcia_device * link, int devno) | |||
1764 | int rc; | 1764 | int rc; |
1765 | 1765 | ||
1766 | /* read the config-tuples */ | 1766 | /* read the config-tuples */ |
1767 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
1768 | tuple.Attributes = 0; | 1767 | tuple.Attributes = 0; |
1769 | tuple.TupleData = buf; | 1768 | tuple.TupleData = buf; |
1770 | tuple.TupleDataMax = sizeof(buf); | 1769 | tuple.TupleDataMax = sizeof(buf); |
1771 | tuple.TupleOffset = 0; | 1770 | tuple.TupleOffset = 0; |
1772 | 1771 | ||
1773 | if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) { | ||
1774 | fail_fn = GetFirstTuple; | ||
1775 | goto cs_failed; | ||
1776 | } | ||
1777 | if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) { | ||
1778 | fail_fn = GetTupleData; | ||
1779 | goto cs_failed; | ||
1780 | } | ||
1781 | if ((fail_rc = | ||
1782 | pcmcia_parse_tuple(link, &tuple, &parse)) != CS_SUCCESS) { | ||
1783 | fail_fn = ParseTuple; | ||
1784 | goto cs_failed; | ||
1785 | } | ||
1786 | |||
1787 | link->conf.ConfigBase = parse.config.base; | ||
1788 | link->conf.Present = parse.config.rmask[0]; | ||
1789 | |||
1790 | link->io.BasePort2 = 0; | 1772 | link->io.BasePort2 = 0; |
1791 | link->io.NumPorts2 = 0; | 1773 | link->io.NumPorts2 = 0; |
1792 | link->io.Attributes2 = 0; | 1774 | link->io.Attributes2 = 0; |
@@ -1841,8 +1823,6 @@ static int cm4000_config(struct pcmcia_device * link, int devno) | |||
1841 | 1823 | ||
1842 | return 0; | 1824 | return 0; |
1843 | 1825 | ||
1844 | cs_failed: | ||
1845 | cs_error(link, fail_fn, fail_rc); | ||
1846 | cs_release: | 1826 | cs_release: |
1847 | cm4000_release(link); | 1827 | cm4000_release(link); |
1848 | return -ENODEV; | 1828 | return -ENODEV; |
@@ -1973,14 +1953,14 @@ static int __init cmm_init(void) | |||
1973 | printk(KERN_INFO "%s\n", version); | 1953 | printk(KERN_INFO "%s\n", version); |
1974 | 1954 | ||
1975 | cmm_class = class_create(THIS_MODULE, "cardman_4000"); | 1955 | cmm_class = class_create(THIS_MODULE, "cardman_4000"); |
1976 | if (!cmm_class) | 1956 | if (IS_ERR(cmm_class)) |
1977 | return -1; | 1957 | return PTR_ERR(cmm_class); |
1978 | 1958 | ||
1979 | major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); | 1959 | major = register_chrdev(0, DEVICE_NAME, &cm4000_fops); |
1980 | if (major < 0) { | 1960 | if (major < 0) { |
1981 | printk(KERN_WARNING MODULE_NAME | 1961 | printk(KERN_WARNING MODULE_NAME |
1982 | ": could not get major number\n"); | 1962 | ": could not get major number\n"); |
1983 | return -1; | 1963 | return major; |
1984 | } | 1964 | } |
1985 | 1965 | ||
1986 | rc = pcmcia_register_driver(&cm4000_driver); | 1966 | rc = pcmcia_register_driver(&cm4000_driver); |
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 55cf4be42976..9b1ff7e8f896 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c | |||
@@ -523,29 +523,11 @@ static int reader_config(struct pcmcia_device *link, int devno) | |||
523 | int fail_fn, fail_rc; | 523 | int fail_fn, fail_rc; |
524 | int rc; | 524 | int rc; |
525 | 525 | ||
526 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
527 | tuple.Attributes = 0; | 526 | tuple.Attributes = 0; |
528 | tuple.TupleData = buf; | 527 | tuple.TupleData = buf; |
529 | tuple.TupleDataMax = sizeof(buf); | 528 | tuple.TupleDataMax = sizeof(buf); |
530 | tuple.TupleOffset = 0; | 529 | tuple.TupleOffset = 0; |
531 | 530 | ||
532 | if ((fail_rc = pcmcia_get_first_tuple(link, &tuple)) != CS_SUCCESS) { | ||
533 | fail_fn = GetFirstTuple; | ||
534 | goto cs_failed; | ||
535 | } | ||
536 | if ((fail_rc = pcmcia_get_tuple_data(link, &tuple)) != CS_SUCCESS) { | ||
537 | fail_fn = GetTupleData; | ||
538 | goto cs_failed; | ||
539 | } | ||
540 | if ((fail_rc = pcmcia_parse_tuple(link, &tuple, &parse)) | ||
541 | != CS_SUCCESS) { | ||
542 | fail_fn = ParseTuple; | ||
543 | goto cs_failed; | ||
544 | } | ||
545 | |||
546 | link->conf.ConfigBase = parse.config.base; | ||
547 | link->conf.Present = parse.config.rmask[0]; | ||
548 | |||
549 | link->io.BasePort2 = 0; | 531 | link->io.BasePort2 = 0; |
550 | link->io.NumPorts2 = 0; | 532 | link->io.NumPorts2 = 0; |
551 | link->io.Attributes2 = 0; | 533 | link->io.Attributes2 = 0; |
@@ -609,8 +591,6 @@ static int reader_config(struct pcmcia_device *link, int devno) | |||
609 | 591 | ||
610 | return 0; | 592 | return 0; |
611 | 593 | ||
612 | cs_failed: | ||
613 | cs_error(link, fail_fn, fail_rc); | ||
614 | cs_release: | 594 | cs_release: |
615 | reader_release(link); | 595 | reader_release(link); |
616 | return -ENODEV; | 596 | return -ENODEV; |
@@ -721,14 +701,14 @@ static int __init cm4040_init(void) | |||
721 | 701 | ||
722 | printk(KERN_INFO "%s\n", version); | 702 | printk(KERN_INFO "%s\n", version); |
723 | cmx_class = class_create(THIS_MODULE, "cardman_4040"); | 703 | cmx_class = class_create(THIS_MODULE, "cardman_4040"); |
724 | if (!cmx_class) | 704 | if (IS_ERR(cmx_class)) |
725 | return -1; | 705 | return PTR_ERR(cmx_class); |
726 | 706 | ||
727 | major = register_chrdev(0, DEVICE_NAME, &reader_fops); | 707 | major = register_chrdev(0, DEVICE_NAME, &reader_fops); |
728 | if (major < 0) { | 708 | if (major < 0) { |
729 | printk(KERN_WARNING MODULE_NAME | 709 | printk(KERN_WARNING MODULE_NAME |
730 | ": could not get major number\n"); | 710 | ": could not get major number\n"); |
731 | return -1; | 711 | return major; |
732 | } | 712 | } |
733 | 713 | ||
734 | rc = pcmcia_register_driver(&reader_driver); | 714 | rc = pcmcia_register_driver(&reader_driver); |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 1a0bc30b79d1..1bd12296dca5 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -421,7 +421,7 @@ static irqreturn_t mgslpc_isr(int irq, void *dev_id); | |||
421 | /* | 421 | /* |
422 | * Bottom half interrupt handlers | 422 | * Bottom half interrupt handlers |
423 | */ | 423 | */ |
424 | static void bh_handler(void* Context); | 424 | static void bh_handler(struct work_struct *work); |
425 | static void bh_transmit(MGSLPC_INFO *info); | 425 | static void bh_transmit(MGSLPC_INFO *info); |
426 | static void bh_status(MGSLPC_INFO *info); | 426 | static void bh_status(MGSLPC_INFO *info); |
427 | 427 | ||
@@ -547,7 +547,7 @@ static int mgslpc_probe(struct pcmcia_device *link) | |||
547 | 547 | ||
548 | memset(info, 0, sizeof(MGSLPC_INFO)); | 548 | memset(info, 0, sizeof(MGSLPC_INFO)); |
549 | info->magic = MGSLPC_MAGIC; | 549 | info->magic = MGSLPC_MAGIC; |
550 | INIT_WORK(&info->task, bh_handler, info); | 550 | INIT_WORK(&info->task, bh_handler); |
551 | info->max_frame_size = 4096; | 551 | info->max_frame_size = 4096; |
552 | info->close_delay = 5*HZ/10; | 552 | info->close_delay = 5*HZ/10; |
553 | info->closing_wait = 30*HZ; | 553 | info->closing_wait = 30*HZ; |
@@ -604,17 +604,10 @@ static int mgslpc_config(struct pcmcia_device *link) | |||
604 | if (debug_level >= DEBUG_LEVEL_INFO) | 604 | if (debug_level >= DEBUG_LEVEL_INFO) |
605 | printk("mgslpc_config(0x%p)\n", link); | 605 | printk("mgslpc_config(0x%p)\n", link); |
606 | 606 | ||
607 | /* read CONFIG tuple to find its configuration registers */ | ||
608 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
609 | tuple.Attributes = 0; | 607 | tuple.Attributes = 0; |
610 | tuple.TupleData = buf; | 608 | tuple.TupleData = buf; |
611 | tuple.TupleDataMax = sizeof(buf); | 609 | tuple.TupleDataMax = sizeof(buf); |
612 | tuple.TupleOffset = 0; | 610 | tuple.TupleOffset = 0; |
613 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
614 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
615 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
616 | link->conf.ConfigBase = parse.config.base; | ||
617 | link->conf.Present = parse.config.rmask[0]; | ||
618 | 611 | ||
619 | /* get CIS configuration entry */ | 612 | /* get CIS configuration entry */ |
620 | 613 | ||
@@ -842,9 +835,9 @@ static int bh_action(MGSLPC_INFO *info) | |||
842 | return rc; | 835 | return rc; |
843 | } | 836 | } |
844 | 837 | ||
845 | static void bh_handler(void* Context) | 838 | static void bh_handler(struct work_struct *work) |
846 | { | 839 | { |
847 | MGSLPC_INFO *info = (MGSLPC_INFO*)Context; | 840 | MGSLPC_INFO *info = container_of(work, MGSLPC_INFO, task); |
848 | int action; | 841 | int action; |
849 | 842 | ||
850 | if (!info) | 843 | if (!info) |
diff --git a/drivers/char/random.c b/drivers/char/random.c index d40df30c2b10..4c6782a1ecdb 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1422,9 +1422,9 @@ static struct keydata { | |||
1422 | 1422 | ||
1423 | static unsigned int ip_cnt; | 1423 | static unsigned int ip_cnt; |
1424 | 1424 | ||
1425 | static void rekey_seq_generator(void *private_); | 1425 | static void rekey_seq_generator(struct work_struct *work); |
1426 | 1426 | ||
1427 | static DECLARE_WORK(rekey_work, rekey_seq_generator, NULL); | 1427 | static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator); |
1428 | 1428 | ||
1429 | /* | 1429 | /* |
1430 | * Lock avoidance: | 1430 | * Lock avoidance: |
@@ -1438,7 +1438,7 @@ static DECLARE_WORK(rekey_work, rekey_seq_generator, NULL); | |||
1438 | * happen, and even if that happens only a not perfectly compliant | 1438 | * happen, and even if that happens only a not perfectly compliant |
1439 | * ISN is generated, nothing fatal. | 1439 | * ISN is generated, nothing fatal. |
1440 | */ | 1440 | */ |
1441 | static void rekey_seq_generator(void *private_) | 1441 | static void rekey_seq_generator(struct work_struct *work) |
1442 | { | 1442 | { |
1443 | struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)]; | 1443 | struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)]; |
1444 | 1444 | ||
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 5ab32b38f45a..722dd3e74185 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -1516,9 +1516,9 @@ static void rc_start(struct tty_struct * tty) | |||
1516 | * do_rc_hangup() -> tty->hangup() -> rc_hangup() | 1516 | * do_rc_hangup() -> tty->hangup() -> rc_hangup() |
1517 | * | 1517 | * |
1518 | */ | 1518 | */ |
1519 | static void do_rc_hangup(void *private_) | 1519 | static void do_rc_hangup(struct work_struct *ugly_api) |
1520 | { | 1520 | { |
1521 | struct riscom_port *port = (struct riscom_port *) private_; | 1521 | struct riscom_port *port = container_of(ugly_api, struct riscom_port, tqueue_hangup); |
1522 | struct tty_struct *tty; | 1522 | struct tty_struct *tty; |
1523 | 1523 | ||
1524 | tty = port->tty; | 1524 | tty = port->tty; |
@@ -1567,9 +1567,9 @@ static void rc_set_termios(struct tty_struct * tty, struct termios * old_termios | |||
1567 | } | 1567 | } |
1568 | } | 1568 | } |
1569 | 1569 | ||
1570 | static void do_softint(void *private_) | 1570 | static void do_softint(struct work_struct *ugly_api) |
1571 | { | 1571 | { |
1572 | struct riscom_port *port = (struct riscom_port *) private_; | 1572 | struct riscom_port *port = container_of(ugly_api, struct riscom_port, tqueue); |
1573 | struct tty_struct *tty; | 1573 | struct tty_struct *tty; |
1574 | 1574 | ||
1575 | if(!(tty = port->tty)) | 1575 | if(!(tty = port->tty)) |
@@ -1632,8 +1632,8 @@ static inline int rc_init_drivers(void) | |||
1632 | memset(rc_port, 0, sizeof(rc_port)); | 1632 | memset(rc_port, 0, sizeof(rc_port)); |
1633 | for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { | 1633 | for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { |
1634 | rc_port[i].magic = RISCOM8_MAGIC; | 1634 | rc_port[i].magic = RISCOM8_MAGIC; |
1635 | INIT_WORK(&rc_port[i].tqueue, do_softint, &rc_port[i]); | 1635 | INIT_WORK(&rc_port[i].tqueue, do_softint); |
1636 | INIT_WORK(&rc_port[i].tqueue_hangup, do_rc_hangup, &rc_port[i]); | 1636 | INIT_WORK(&rc_port[i].tqueue_hangup, do_rc_hangup); |
1637 | rc_port[i].close_delay = 50 * HZ/100; | 1637 | rc_port[i].close_delay = 50 * HZ/100; |
1638 | rc_port[i].closing_wait = 3000 * HZ/100; | 1638 | rc_port[i].closing_wait = 3000 * HZ/100; |
1639 | init_waitqueue_head(&rc_port[i].open_wait); | 1639 | init_waitqueue_head(&rc_port[i].open_wait); |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 3af7f0958c5d..9ba13af234be 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -706,9 +706,9 @@ cd2401_rx_interrupt(int irq, void *dev_id) | |||
706 | * had to poll every port to see if that port needed servicing. | 706 | * had to poll every port to see if that port needed servicing. |
707 | */ | 707 | */ |
708 | static void | 708 | static void |
709 | do_softint(void *private_) | 709 | do_softint(struct work_struct *ugly_api) |
710 | { | 710 | { |
711 | struct cyclades_port *info = (struct cyclades_port *) private_; | 711 | struct cyclades_port *info = container_of(ugly_api, struct cyclades_port, tqueue); |
712 | struct tty_struct *tty; | 712 | struct tty_struct *tty; |
713 | 713 | ||
714 | tty = info->tty; | 714 | tty = info->tty; |
@@ -2273,7 +2273,7 @@ scrn[1] = '\0'; | |||
2273 | info->blocked_open = 0; | 2273 | info->blocked_open = 0; |
2274 | info->default_threshold = 0; | 2274 | info->default_threshold = 0; |
2275 | info->default_timeout = 0; | 2275 | info->default_timeout = 0; |
2276 | INIT_WORK(&info->tqueue, do_softint, info); | 2276 | INIT_WORK(&info->tqueue, do_softint); |
2277 | init_waitqueue_head(&info->open_wait); | 2277 | init_waitqueue_head(&info->open_wait); |
2278 | init_waitqueue_head(&info->close_wait); | 2278 | init_waitqueue_head(&info->close_wait); |
2279 | /* info->session */ | 2279 | /* info->session */ |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index c084149153de..fc87070f1866 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -765,7 +765,7 @@ static void sonypi_setbluetoothpower(u8 state) | |||
765 | sonypi_device.bluetooth_power = state; | 765 | sonypi_device.bluetooth_power = state; |
766 | } | 766 | } |
767 | 767 | ||
768 | static void input_keyrelease(void *data) | 768 | static void input_keyrelease(struct work_struct *work) |
769 | { | 769 | { |
770 | struct sonypi_keypress kp; | 770 | struct sonypi_keypress kp; |
771 | 771 | ||
@@ -1412,7 +1412,7 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
1412 | goto err_inpdev_unregister; | 1412 | goto err_inpdev_unregister; |
1413 | } | 1413 | } |
1414 | 1414 | ||
1415 | INIT_WORK(&sonypi_device.input_work, input_keyrelease, NULL); | 1415 | INIT_WORK(&sonypi_device.input_work, input_keyrelease); |
1416 | } | 1416 | } |
1417 | 1417 | ||
1418 | sonypi_enable(0); | 1418 | sonypi_enable(0); |
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 7e1bd9562c2a..99137ab66b62 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -2261,9 +2261,10 @@ static void sx_start(struct tty_struct * tty) | |||
2261 | * do_sx_hangup() -> tty->hangup() -> sx_hangup() | 2261 | * do_sx_hangup() -> tty->hangup() -> sx_hangup() |
2262 | * | 2262 | * |
2263 | */ | 2263 | */ |
2264 | static void do_sx_hangup(void *private_) | 2264 | static void do_sx_hangup(struct work_struct *work) |
2265 | { | 2265 | { |
2266 | struct specialix_port *port = (struct specialix_port *) private_; | 2266 | struct specialix_port *port = |
2267 | container_of(work, struct specialix_port, tqueue_hangup); | ||
2267 | struct tty_struct *tty; | 2268 | struct tty_struct *tty; |
2268 | 2269 | ||
2269 | func_enter(); | 2270 | func_enter(); |
@@ -2336,9 +2337,10 @@ static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios | |||
2336 | } | 2337 | } |
2337 | 2338 | ||
2338 | 2339 | ||
2339 | static void do_softint(void *private_) | 2340 | static void do_softint(struct work_struct *work) |
2340 | { | 2341 | { |
2341 | struct specialix_port *port = (struct specialix_port *) private_; | 2342 | struct specialix_port *port = |
2343 | container_of(work, struct specialix_port, tqueue); | ||
2342 | struct tty_struct *tty; | 2344 | struct tty_struct *tty; |
2343 | 2345 | ||
2344 | func_enter(); | 2346 | func_enter(); |
@@ -2411,8 +2413,8 @@ static int sx_init_drivers(void) | |||
2411 | memset(sx_port, 0, sizeof(sx_port)); | 2413 | memset(sx_port, 0, sizeof(sx_port)); |
2412 | for (i = 0; i < SX_NPORT * SX_NBOARD; i++) { | 2414 | for (i = 0; i < SX_NPORT * SX_NBOARD; i++) { |
2413 | sx_port[i].magic = SPECIALIX_MAGIC; | 2415 | sx_port[i].magic = SPECIALIX_MAGIC; |
2414 | INIT_WORK(&sx_port[i].tqueue, do_softint, &sx_port[i]); | 2416 | INIT_WORK(&sx_port[i].tqueue, do_softint); |
2415 | INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup, &sx_port[i]); | 2417 | INIT_WORK(&sx_port[i].tqueue_hangup, do_sx_hangup); |
2416 | sx_port[i].close_delay = 50 * HZ/100; | 2418 | sx_port[i].close_delay = 50 * HZ/100; |
2417 | sx_port[i].closing_wait = 3000 * HZ/100; | 2419 | sx_port[i].closing_wait = 3000 * HZ/100; |
2418 | init_waitqueue_head(&sx_port[i].open_wait); | 2420 | init_waitqueue_head(&sx_port[i].open_wait); |
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 522e88e395cc..5e2de62bce70 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
@@ -500,7 +500,7 @@ static int stl_echatintr(stlbrd_t *brdp); | |||
500 | static int stl_echmcaintr(stlbrd_t *brdp); | 500 | static int stl_echmcaintr(stlbrd_t *brdp); |
501 | static int stl_echpciintr(stlbrd_t *brdp); | 501 | static int stl_echpciintr(stlbrd_t *brdp); |
502 | static int stl_echpci64intr(stlbrd_t *brdp); | 502 | static int stl_echpci64intr(stlbrd_t *brdp); |
503 | static void stl_offintr(void *private); | 503 | static void stl_offintr(struct work_struct *); |
504 | static stlbrd_t *stl_allocbrd(void); | 504 | static stlbrd_t *stl_allocbrd(void); |
505 | static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); | 505 | static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); |
506 | 506 | ||
@@ -2081,14 +2081,12 @@ static int stl_echpci64intr(stlbrd_t *brdp) | |||
2081 | /* | 2081 | /* |
2082 | * Service an off-level request for some channel. | 2082 | * Service an off-level request for some channel. |
2083 | */ | 2083 | */ |
2084 | static void stl_offintr(void *private) | 2084 | static void stl_offintr(struct work_struct *work) |
2085 | { | 2085 | { |
2086 | stlport_t *portp; | 2086 | stlport_t *portp = container_of(work, stlport_t, tqueue); |
2087 | struct tty_struct *tty; | 2087 | struct tty_struct *tty; |
2088 | unsigned int oldsigs; | 2088 | unsigned int oldsigs; |
2089 | 2089 | ||
2090 | portp = private; | ||
2091 | |||
2092 | #ifdef DEBUG | 2090 | #ifdef DEBUG |
2093 | printk("stl_offintr(portp=%x)\n", (int) portp); | 2091 | printk("stl_offintr(portp=%x)\n", (int) portp); |
2094 | #endif | 2092 | #endif |
@@ -2156,7 +2154,7 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | |||
2156 | portp->baud_base = STL_BAUDBASE; | 2154 | portp->baud_base = STL_BAUDBASE; |
2157 | portp->close_delay = STL_CLOSEDELAY; | 2155 | portp->close_delay = STL_CLOSEDELAY; |
2158 | portp->closing_wait = 30 * HZ; | 2156 | portp->closing_wait = 30 * HZ; |
2159 | INIT_WORK(&portp->tqueue, stl_offintr, portp); | 2157 | INIT_WORK(&portp->tqueue, stl_offintr); |
2160 | init_waitqueue_head(&portp->open_wait); | 2158 | init_waitqueue_head(&portp->open_wait); |
2161 | init_waitqueue_head(&portp->close_wait); | 2159 | init_waitqueue_head(&portp->close_wait); |
2162 | portp->stats.brd = portp->brdnr; | 2160 | portp->stats.brd = portp->brdnr; |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 06784adcc35c..147c30da81ea 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -802,7 +802,7 @@ static int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, u | |||
802 | /* | 802 | /* |
803 | * Bottom half interrupt handlers | 803 | * Bottom half interrupt handlers |
804 | */ | 804 | */ |
805 | static void mgsl_bh_handler(void* Context); | 805 | static void mgsl_bh_handler(struct work_struct *work); |
806 | static void mgsl_bh_receive(struct mgsl_struct *info); | 806 | static void mgsl_bh_receive(struct mgsl_struct *info); |
807 | static void mgsl_bh_transmit(struct mgsl_struct *info); | 807 | static void mgsl_bh_transmit(struct mgsl_struct *info); |
808 | static void mgsl_bh_status(struct mgsl_struct *info); | 808 | static void mgsl_bh_status(struct mgsl_struct *info); |
@@ -1071,9 +1071,10 @@ static int mgsl_bh_action(struct mgsl_struct *info) | |||
1071 | /* | 1071 | /* |
1072 | * Perform bottom half processing of work items queued by ISR. | 1072 | * Perform bottom half processing of work items queued by ISR. |
1073 | */ | 1073 | */ |
1074 | static void mgsl_bh_handler(void* Context) | 1074 | static void mgsl_bh_handler(struct work_struct *work) |
1075 | { | 1075 | { |
1076 | struct mgsl_struct *info = (struct mgsl_struct*)Context; | 1076 | struct mgsl_struct *info = |
1077 | container_of(work, struct mgsl_struct, task); | ||
1077 | int action; | 1078 | int action; |
1078 | 1079 | ||
1079 | if (!info) | 1080 | if (!info) |
@@ -4337,7 +4338,7 @@ static struct mgsl_struct* mgsl_allocate_device(void) | |||
4337 | } else { | 4338 | } else { |
4338 | memset(info, 0, sizeof(struct mgsl_struct)); | 4339 | memset(info, 0, sizeof(struct mgsl_struct)); |
4339 | info->magic = MGSL_MAGIC; | 4340 | info->magic = MGSL_MAGIC; |
4340 | INIT_WORK(&info->task, mgsl_bh_handler, info); | 4341 | INIT_WORK(&info->task, mgsl_bh_handler); |
4341 | info->max_frame_size = 4096; | 4342 | info->max_frame_size = 4096; |
4342 | info->close_delay = 5*HZ/10; | 4343 | info->close_delay = 5*HZ/10; |
4343 | info->closing_wait = 30*HZ; | 4344 | info->closing_wait = 30*HZ; |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index d4334c79f8d4..07f34d43dc7f 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -485,7 +485,7 @@ static void enable_loopback(struct slgt_info *info); | |||
485 | static void set_rate(struct slgt_info *info, u32 data_rate); | 485 | static void set_rate(struct slgt_info *info, u32 data_rate); |
486 | 486 | ||
487 | static int bh_action(struct slgt_info *info); | 487 | static int bh_action(struct slgt_info *info); |
488 | static void bh_handler(void* context); | 488 | static void bh_handler(struct work_struct *work); |
489 | static void bh_transmit(struct slgt_info *info); | 489 | static void bh_transmit(struct slgt_info *info); |
490 | static void isr_serial(struct slgt_info *info); | 490 | static void isr_serial(struct slgt_info *info); |
491 | static void isr_rdma(struct slgt_info *info); | 491 | static void isr_rdma(struct slgt_info *info); |
@@ -1878,9 +1878,9 @@ static int bh_action(struct slgt_info *info) | |||
1878 | /* | 1878 | /* |
1879 | * perform bottom half processing | 1879 | * perform bottom half processing |
1880 | */ | 1880 | */ |
1881 | static void bh_handler(void* context) | 1881 | static void bh_handler(struct work_struct *work) |
1882 | { | 1882 | { |
1883 | struct slgt_info *info = context; | 1883 | struct slgt_info *info = container_of(work, struct slgt_info, task); |
1884 | int action; | 1884 | int action; |
1885 | 1885 | ||
1886 | if (!info) | 1886 | if (!info) |
@@ -3326,7 +3326,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev | |||
3326 | } else { | 3326 | } else { |
3327 | memset(info, 0, sizeof(struct slgt_info)); | 3327 | memset(info, 0, sizeof(struct slgt_info)); |
3328 | info->magic = MGSL_MAGIC; | 3328 | info->magic = MGSL_MAGIC; |
3329 | INIT_WORK(&info->task, bh_handler, info); | 3329 | INIT_WORK(&info->task, bh_handler); |
3330 | info->max_frame_size = 4096; | 3330 | info->max_frame_size = 4096; |
3331 | info->raw_rx_size = DMABUFSIZE; | 3331 | info->raw_rx_size = DMABUFSIZE; |
3332 | info->close_delay = 5*HZ/10; | 3332 | info->close_delay = 5*HZ/10; |
@@ -4799,6 +4799,6 @@ static void rx_timeout(unsigned long context) | |||
4799 | spin_lock_irqsave(&info->lock, flags); | 4799 | spin_lock_irqsave(&info->lock, flags); |
4800 | info->pending_bh |= BH_RECEIVE; | 4800 | info->pending_bh |= BH_RECEIVE; |
4801 | spin_unlock_irqrestore(&info->lock, flags); | 4801 | spin_unlock_irqrestore(&info->lock, flags); |
4802 | bh_handler(info); | 4802 | bh_handler(&info->task); |
4803 | } | 4803 | } |
4804 | 4804 | ||
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 3e932b681371..13a57245cf2e 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -602,7 +602,7 @@ static void enable_loopback(SLMP_INFO *info, int enable); | |||
602 | static void set_rate(SLMP_INFO *info, u32 data_rate); | 602 | static void set_rate(SLMP_INFO *info, u32 data_rate); |
603 | 603 | ||
604 | static int bh_action(SLMP_INFO *info); | 604 | static int bh_action(SLMP_INFO *info); |
605 | static void bh_handler(void* Context); | 605 | static void bh_handler(struct work_struct *work); |
606 | static void bh_receive(SLMP_INFO *info); | 606 | static void bh_receive(SLMP_INFO *info); |
607 | static void bh_transmit(SLMP_INFO *info); | 607 | static void bh_transmit(SLMP_INFO *info); |
608 | static void bh_status(SLMP_INFO *info); | 608 | static void bh_status(SLMP_INFO *info); |
@@ -2063,9 +2063,9 @@ int bh_action(SLMP_INFO *info) | |||
2063 | 2063 | ||
2064 | /* Perform bottom half processing of work items queued by ISR. | 2064 | /* Perform bottom half processing of work items queued by ISR. |
2065 | */ | 2065 | */ |
2066 | void bh_handler(void* Context) | 2066 | void bh_handler(struct work_struct *work) |
2067 | { | 2067 | { |
2068 | SLMP_INFO *info = (SLMP_INFO*)Context; | 2068 | SLMP_INFO *info = container_of(work, SLMP_INFO, task); |
2069 | int action; | 2069 | int action; |
2070 | 2070 | ||
2071 | if (!info) | 2071 | if (!info) |
@@ -3805,7 +3805,7 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev) | |||
3805 | } else { | 3805 | } else { |
3806 | memset(info, 0, sizeof(SLMP_INFO)); | 3806 | memset(info, 0, sizeof(SLMP_INFO)); |
3807 | info->magic = MGSL_MAGIC; | 3807 | info->magic = MGSL_MAGIC; |
3808 | INIT_WORK(&info->task, bh_handler, info); | 3808 | INIT_WORK(&info->task, bh_handler); |
3809 | info->max_frame_size = 4096; | 3809 | info->max_frame_size = 4096; |
3810 | info->close_delay = 5*HZ/10; | 3810 | info->close_delay = 5*HZ/10; |
3811 | info->closing_wait = 30*HZ; | 3811 | info->closing_wait = 30*HZ; |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 5f49280779fb..c64f5bcff947 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -219,13 +219,13 @@ static struct sysrq_key_op sysrq_term_op = { | |||
219 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 219 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
220 | }; | 220 | }; |
221 | 221 | ||
222 | static void moom_callback(void *ignored) | 222 | static void moom_callback(struct work_struct *ignored) |
223 | { | 223 | { |
224 | out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL], | 224 | out_of_memory(&NODE_DATA(0)->node_zonelists[ZONE_NORMAL], |
225 | GFP_KERNEL, 0); | 225 | GFP_KERNEL, 0); |
226 | } | 226 | } |
227 | 227 | ||
228 | static DECLARE_WORK(moom_work, moom_callback, NULL); | 228 | static DECLARE_WORK(moom_work, moom_callback); |
229 | 229 | ||
230 | static void sysrq_handle_moom(int key, struct tty_struct *tty) | 230 | static void sysrq_handle_moom(int key, struct tty_struct *tty) |
231 | { | 231 | { |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 6e1329d404d2..774fa861169a 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -325,9 +325,9 @@ static void user_reader_timeout(unsigned long ptr) | |||
325 | schedule_work(&chip->work); | 325 | schedule_work(&chip->work); |
326 | } | 326 | } |
327 | 327 | ||
328 | static void timeout_work(void *ptr) | 328 | static void timeout_work(struct work_struct *work) |
329 | { | 329 | { |
330 | struct tpm_chip *chip = ptr; | 330 | struct tpm_chip *chip = container_of(work, struct tpm_chip, work); |
331 | 331 | ||
332 | down(&chip->buffer_mutex); | 332 | down(&chip->buffer_mutex); |
333 | atomic_set(&chip->data_pending, 0); | 333 | atomic_set(&chip->data_pending, 0); |
@@ -1105,7 +1105,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1105 | init_MUTEX(&chip->tpm_mutex); | 1105 | init_MUTEX(&chip->tpm_mutex); |
1106 | INIT_LIST_HEAD(&chip->list); | 1106 | INIT_LIST_HEAD(&chip->list); |
1107 | 1107 | ||
1108 | INIT_WORK(&chip->work, timeout_work, chip); | 1108 | INIT_WORK(&chip->work, timeout_work); |
1109 | 1109 | ||
1110 | init_timer(&chip->user_read_timer); | 1110 | init_timer(&chip->user_read_timer); |
1111 | chip->user_read_timer.function = user_reader_timeout; | 1111 | chip->user_read_timer.function = user_reader_timeout; |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 50dc49205a23..b3cfc8bc613c 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -1254,7 +1254,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); | |||
1254 | 1254 | ||
1255 | /** | 1255 | /** |
1256 | * do_tty_hangup - actual handler for hangup events | 1256 | * do_tty_hangup - actual handler for hangup events |
1257 | * @data: tty device | 1257 | * @work: tty device |
1258 | * | 1258 | * |
1259 | * This can be called by the "eventd" kernel thread. That is process | 1259 | * This can be called by the "eventd" kernel thread. That is process |
1260 | * synchronous but doesn't hold any locks, so we need to make sure we | 1260 | * synchronous but doesn't hold any locks, so we need to make sure we |
@@ -1274,9 +1274,10 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); | |||
1274 | * tasklist_lock to walk task list for hangup event | 1274 | * tasklist_lock to walk task list for hangup event |
1275 | * | 1275 | * |
1276 | */ | 1276 | */ |
1277 | static void do_tty_hangup(void *data) | 1277 | static void do_tty_hangup(struct work_struct *work) |
1278 | { | 1278 | { |
1279 | struct tty_struct *tty = (struct tty_struct *) data; | 1279 | struct tty_struct *tty = |
1280 | container_of(work, struct tty_struct, hangup_work); | ||
1280 | struct file * cons_filp = NULL; | 1281 | struct file * cons_filp = NULL; |
1281 | struct file *filp, *f = NULL; | 1282 | struct file *filp, *f = NULL; |
1282 | struct task_struct *p; | 1283 | struct task_struct *p; |
@@ -1433,7 +1434,7 @@ void tty_vhangup(struct tty_struct * tty) | |||
1433 | 1434 | ||
1434 | printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); | 1435 | printk(KERN_DEBUG "%s vhangup...\n", tty_name(tty, buf)); |
1435 | #endif | 1436 | #endif |
1436 | do_tty_hangup((void *) tty); | 1437 | do_tty_hangup(&tty->hangup_work); |
1437 | } | 1438 | } |
1438 | EXPORT_SYMBOL(tty_vhangup); | 1439 | EXPORT_SYMBOL(tty_vhangup); |
1439 | 1440 | ||
@@ -3304,12 +3305,13 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
3304 | * Nasty bug: do_SAK is being called in interrupt context. This can | 3305 | * Nasty bug: do_SAK is being called in interrupt context. This can |
3305 | * deadlock. We punt it up to process context. AKPM - 16Mar2001 | 3306 | * deadlock. We punt it up to process context. AKPM - 16Mar2001 |
3306 | */ | 3307 | */ |
3307 | static void __do_SAK(void *arg) | 3308 | static void __do_SAK(struct work_struct *work) |
3308 | { | 3309 | { |
3310 | struct tty_struct *tty = | ||
3311 | container_of(work, struct tty_struct, SAK_work); | ||
3309 | #ifdef TTY_SOFT_SAK | 3312 | #ifdef TTY_SOFT_SAK |
3310 | tty_hangup(tty); | 3313 | tty_hangup(tty); |
3311 | #else | 3314 | #else |
3312 | struct tty_struct *tty = arg; | ||
3313 | struct task_struct *g, *p; | 3315 | struct task_struct *g, *p; |
3314 | int session; | 3316 | int session; |
3315 | int i; | 3317 | int i; |
@@ -3388,7 +3390,7 @@ void do_SAK(struct tty_struct *tty) | |||
3388 | { | 3390 | { |
3389 | if (!tty) | 3391 | if (!tty) |
3390 | return; | 3392 | return; |
3391 | PREPARE_WORK(&tty->SAK_work, __do_SAK, tty); | 3393 | PREPARE_WORK(&tty->SAK_work, __do_SAK); |
3392 | schedule_work(&tty->SAK_work); | 3394 | schedule_work(&tty->SAK_work); |
3393 | } | 3395 | } |
3394 | 3396 | ||
@@ -3396,7 +3398,7 @@ EXPORT_SYMBOL(do_SAK); | |||
3396 | 3398 | ||
3397 | /** | 3399 | /** |
3398 | * flush_to_ldisc | 3400 | * flush_to_ldisc |
3399 | * @private_: tty structure passed from work queue. | 3401 | * @work: tty structure passed from work queue. |
3400 | * | 3402 | * |
3401 | * This routine is called out of the software interrupt to flush data | 3403 | * This routine is called out of the software interrupt to flush data |
3402 | * from the buffer chain to the line discipline. | 3404 | * from the buffer chain to the line discipline. |
@@ -3406,9 +3408,10 @@ EXPORT_SYMBOL(do_SAK); | |||
3406 | * receive_buf method is single threaded for each tty instance. | 3408 | * receive_buf method is single threaded for each tty instance. |
3407 | */ | 3409 | */ |
3408 | 3410 | ||
3409 | static void flush_to_ldisc(void *private_) | 3411 | static void flush_to_ldisc(struct work_struct *work) |
3410 | { | 3412 | { |
3411 | struct tty_struct *tty = (struct tty_struct *) private_; | 3413 | struct tty_struct *tty = |
3414 | container_of(work, struct tty_struct, buf.work.work); | ||
3412 | unsigned long flags; | 3415 | unsigned long flags; |
3413 | struct tty_ldisc *disc; | 3416 | struct tty_ldisc *disc; |
3414 | struct tty_buffer *tbuf, *head; | 3417 | struct tty_buffer *tbuf, *head; |
@@ -3553,7 +3556,7 @@ void tty_flip_buffer_push(struct tty_struct *tty) | |||
3553 | spin_unlock_irqrestore(&tty->buf.lock, flags); | 3556 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
3554 | 3557 | ||
3555 | if (tty->low_latency) | 3558 | if (tty->low_latency) |
3556 | flush_to_ldisc((void *) tty); | 3559 | flush_to_ldisc(&tty->buf.work.work); |
3557 | else | 3560 | else |
3558 | schedule_delayed_work(&tty->buf.work, 1); | 3561 | schedule_delayed_work(&tty->buf.work, 1); |
3559 | } | 3562 | } |
@@ -3580,17 +3583,17 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
3580 | tty->overrun_time = jiffies; | 3583 | tty->overrun_time = jiffies; |
3581 | tty->buf.head = tty->buf.tail = NULL; | 3584 | tty->buf.head = tty->buf.tail = NULL; |
3582 | tty_buffer_init(tty); | 3585 | tty_buffer_init(tty); |
3583 | INIT_WORK(&tty->buf.work, flush_to_ldisc, tty); | 3586 | INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); |
3584 | init_MUTEX(&tty->buf.pty_sem); | 3587 | init_MUTEX(&tty->buf.pty_sem); |
3585 | mutex_init(&tty->termios_mutex); | 3588 | mutex_init(&tty->termios_mutex); |
3586 | init_waitqueue_head(&tty->write_wait); | 3589 | init_waitqueue_head(&tty->write_wait); |
3587 | init_waitqueue_head(&tty->read_wait); | 3590 | init_waitqueue_head(&tty->read_wait); |
3588 | INIT_WORK(&tty->hangup_work, do_tty_hangup, tty); | 3591 | INIT_WORK(&tty->hangup_work, do_tty_hangup); |
3589 | mutex_init(&tty->atomic_read_lock); | 3592 | mutex_init(&tty->atomic_read_lock); |
3590 | mutex_init(&tty->atomic_write_lock); | 3593 | mutex_init(&tty->atomic_write_lock); |
3591 | spin_lock_init(&tty->read_lock); | 3594 | spin_lock_init(&tty->read_lock); |
3592 | INIT_LIST_HEAD(&tty->tty_files); | 3595 | INIT_LIST_HEAD(&tty->tty_files); |
3593 | INIT_WORK(&tty->SAK_work, NULL, NULL); | 3596 | INIT_WORK(&tty->SAK_work, NULL); |
3594 | } | 3597 | } |
3595 | 3598 | ||
3596 | /* | 3599 | /* |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 87587b4385ab..75ff0286e1ad 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -155,7 +155,7 @@ static void con_flush_chars(struct tty_struct *tty); | |||
155 | static void set_vesa_blanking(char __user *p); | 155 | static void set_vesa_blanking(char __user *p); |
156 | static void set_cursor(struct vc_data *vc); | 156 | static void set_cursor(struct vc_data *vc); |
157 | static void hide_cursor(struct vc_data *vc); | 157 | static void hide_cursor(struct vc_data *vc); |
158 | static void console_callback(void *ignored); | 158 | static void console_callback(struct work_struct *ignored); |
159 | static void blank_screen_t(unsigned long dummy); | 159 | static void blank_screen_t(unsigned long dummy); |
160 | static void set_palette(struct vc_data *vc); | 160 | static void set_palette(struct vc_data *vc); |
161 | 161 | ||
@@ -174,7 +174,7 @@ static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */ | |||
174 | static int blankinterval = 10*60*HZ; | 174 | static int blankinterval = 10*60*HZ; |
175 | static int vesa_off_interval; | 175 | static int vesa_off_interval; |
176 | 176 | ||
177 | static DECLARE_WORK(console_work, console_callback, NULL); | 177 | static DECLARE_WORK(console_work, console_callback); |
178 | 178 | ||
179 | /* | 179 | /* |
180 | * fg_console is the current virtual console, | 180 | * fg_console is the current virtual console, |
@@ -2154,7 +2154,7 @@ out: | |||
2154 | * with other console code and prevention of re-entrancy is | 2154 | * with other console code and prevention of re-entrancy is |
2155 | * ensured with console_sem. | 2155 | * ensured with console_sem. |
2156 | */ | 2156 | */ |
2157 | static void console_callback(void *ignored) | 2157 | static void console_callback(struct work_struct *ignored) |
2158 | { | 2158 | { |
2159 | acquire_console_sem(); | 2159 | acquire_console_sem(); |
2160 | 2160 | ||
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index 05f8ce2cfb4a..b418b16e910e 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c | |||
@@ -31,9 +31,11 @@ | |||
31 | #include <linux/connector.h> | 31 | #include <linux/connector.h> |
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | 33 | ||
34 | void cn_queue_wrapper(void *data) | 34 | void cn_queue_wrapper(struct work_struct *work) |
35 | { | 35 | { |
36 | struct cn_callback_data *d = data; | 36 | struct cn_callback_entry *cbq = |
37 | container_of(work, struct cn_callback_entry, work.work); | ||
38 | struct cn_callback_data *d = &cbq->data; | ||
37 | 39 | ||
38 | d->callback(d->callback_priv); | 40 | d->callback(d->callback_priv); |
39 | 41 | ||
@@ -57,7 +59,7 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struc | |||
57 | memcpy(&cbq->id.id, id, sizeof(struct cb_id)); | 59 | memcpy(&cbq->id.id, id, sizeof(struct cb_id)); |
58 | cbq->data.callback = callback; | 60 | cbq->data.callback = callback; |
59 | 61 | ||
60 | INIT_WORK(&cbq->work, &cn_queue_wrapper, &cbq->data); | 62 | INIT_DELAYED_WORK(&cbq->work, &cn_queue_wrapper); |
61 | return cbq; | 63 | return cbq; |
62 | } | 64 | } |
63 | 65 | ||
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index b49bacfd8de8..5e7cd45d10ee 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
@@ -135,40 +135,39 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v | |||
135 | spin_lock_bh(&dev->cbdev->queue_lock); | 135 | spin_lock_bh(&dev->cbdev->queue_lock); |
136 | list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { | 136 | list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) { |
137 | if (cn_cb_equal(&__cbq->id.id, &msg->id)) { | 137 | if (cn_cb_equal(&__cbq->id.id, &msg->id)) { |
138 | if (likely(!test_bit(0, &__cbq->work.pending) && | 138 | if (likely(!test_bit(WORK_STRUCT_PENDING, |
139 | &__cbq->work.work.management) && | ||
139 | __cbq->data.ddata == NULL)) { | 140 | __cbq->data.ddata == NULL)) { |
140 | __cbq->data.callback_priv = msg; | 141 | __cbq->data.callback_priv = msg; |
141 | 142 | ||
142 | __cbq->data.ddata = data; | 143 | __cbq->data.ddata = data; |
143 | __cbq->data.destruct_data = destruct_data; | 144 | __cbq->data.destruct_data = destruct_data; |
144 | 145 | ||
145 | if (queue_work(dev->cbdev->cn_queue, | 146 | if (queue_delayed_work( |
146 | &__cbq->work)) | 147 | dev->cbdev->cn_queue, |
148 | &__cbq->work, 0)) | ||
147 | err = 0; | 149 | err = 0; |
148 | } else { | 150 | } else { |
149 | struct work_struct *w; | ||
150 | struct cn_callback_data *d; | 151 | struct cn_callback_data *d; |
151 | 152 | ||
152 | w = kzalloc(sizeof(*w) + sizeof(*d), GFP_ATOMIC); | 153 | __cbq = kzalloc(sizeof(*__cbq), GFP_ATOMIC); |
153 | if (w) { | 154 | if (__cbq) { |
154 | d = (struct cn_callback_data *)(w+1); | 155 | d = &__cbq->data; |
155 | |||
156 | d->callback_priv = msg; | 156 | d->callback_priv = msg; |
157 | d->callback = __cbq->data.callback; | 157 | d->callback = __cbq->data.callback; |
158 | d->ddata = data; | 158 | d->ddata = data; |
159 | d->destruct_data = destruct_data; | 159 | d->destruct_data = destruct_data; |
160 | d->free = w; | 160 | d->free = __cbq; |
161 | 161 | ||
162 | INIT_LIST_HEAD(&w->entry); | 162 | INIT_DELAYED_WORK(&__cbq->work, |
163 | w->pending = 0; | 163 | &cn_queue_wrapper); |
164 | w->func = &cn_queue_wrapper; | ||
165 | w->data = d; | ||
166 | init_timer(&w->timer); | ||
167 | 164 | ||
168 | if (queue_work(dev->cbdev->cn_queue, w)) | 165 | if (queue_delayed_work( |
166 | dev->cbdev->cn_queue, | ||
167 | &__cbq->work, 0)) | ||
169 | err = 0; | 168 | err = 0; |
170 | else { | 169 | else { |
171 | kfree(w); | 170 | kfree(__cbq); |
172 | err = -EINVAL; | 171 | err = -EINVAL; |
173 | } | 172 | } |
174 | } else | 173 | } else |
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index dd0c2623e27b..7a7c6e6dfe4f 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -42,7 +42,7 @@ static DEFINE_SPINLOCK(cpufreq_driver_lock); | |||
42 | 42 | ||
43 | /* internal prototypes */ | 43 | /* internal prototypes */ |
44 | static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); | 44 | static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event); |
45 | static void handle_update(void *data); | 45 | static void handle_update(struct work_struct *work); |
46 | 46 | ||
47 | /** | 47 | /** |
48 | * Two notifier lists: the "policy" list is involved in the | 48 | * Two notifier lists: the "policy" list is involved in the |
@@ -665,7 +665,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
665 | mutex_init(&policy->lock); | 665 | mutex_init(&policy->lock); |
666 | mutex_lock(&policy->lock); | 666 | mutex_lock(&policy->lock); |
667 | init_completion(&policy->kobj_unregister); | 667 | init_completion(&policy->kobj_unregister); |
668 | INIT_WORK(&policy->update, handle_update, (void *)(long)cpu); | 668 | INIT_WORK(&policy->update, handle_update); |
669 | 669 | ||
670 | /* call driver. From then on the cpufreq must be able | 670 | /* call driver. From then on the cpufreq must be able |
671 | * to accept all calls to ->verify and ->setpolicy for this CPU | 671 | * to accept all calls to ->verify and ->setpolicy for this CPU |
@@ -895,9 +895,11 @@ static int cpufreq_remove_dev (struct sys_device * sys_dev) | |||
895 | } | 895 | } |
896 | 896 | ||
897 | 897 | ||
898 | static void handle_update(void *data) | 898 | static void handle_update(struct work_struct *work) |
899 | { | 899 | { |
900 | unsigned int cpu = (unsigned int)(long)data; | 900 | struct cpufreq_policy *policy = |
901 | container_of(work, struct cpufreq_policy, update); | ||
902 | unsigned int cpu = policy->cpu; | ||
901 | dprintk("handle_update for cpu %u called\n", cpu); | 903 | dprintk("handle_update for cpu %u called\n", cpu); |
902 | cpufreq_update_policy(cpu); | 904 | cpufreq_update_policy(cpu); |
903 | } | 905 | } |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index c4c578defabf..5ef5ede5b884 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -59,7 +59,7 @@ static unsigned int def_sampling_rate; | |||
59 | #define MAX_SAMPLING_DOWN_FACTOR (10) | 59 | #define MAX_SAMPLING_DOWN_FACTOR (10) |
60 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) | 60 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) |
61 | 61 | ||
62 | static void do_dbs_timer(void *data); | 62 | static void do_dbs_timer(struct work_struct *work); |
63 | 63 | ||
64 | struct cpu_dbs_info_s { | 64 | struct cpu_dbs_info_s { |
65 | struct cpufreq_policy *cur_policy; | 65 | struct cpufreq_policy *cur_policy; |
@@ -82,7 +82,7 @@ static unsigned int dbs_enable; /* number of CPUs using this policy */ | |||
82 | * is recursive for the same process. -Venki | 82 | * is recursive for the same process. -Venki |
83 | */ | 83 | */ |
84 | static DEFINE_MUTEX (dbs_mutex); | 84 | static DEFINE_MUTEX (dbs_mutex); |
85 | static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); | 85 | static DECLARE_DELAYED_WORK(dbs_work, do_dbs_timer); |
86 | 86 | ||
87 | struct dbs_tuners { | 87 | struct dbs_tuners { |
88 | unsigned int sampling_rate; | 88 | unsigned int sampling_rate; |
@@ -420,7 +420,7 @@ static void dbs_check_cpu(int cpu) | |||
420 | } | 420 | } |
421 | } | 421 | } |
422 | 422 | ||
423 | static void do_dbs_timer(void *data) | 423 | static void do_dbs_timer(struct work_struct *work) |
424 | { | 424 | { |
425 | int i; | 425 | int i; |
426 | lock_cpu_hotplug(); | 426 | lock_cpu_hotplug(); |
@@ -435,7 +435,6 @@ static void do_dbs_timer(void *data) | |||
435 | 435 | ||
436 | static inline void dbs_timer_init(void) | 436 | static inline void dbs_timer_init(void) |
437 | { | 437 | { |
438 | INIT_WORK(&dbs_work, do_dbs_timer, NULL); | ||
439 | schedule_delayed_work(&dbs_work, | 438 | schedule_delayed_work(&dbs_work, |
440 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); | 439 | usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); |
441 | return; | 440 | return; |
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index bf8aa45d4f01..e1cc5113c2ae 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c | |||
@@ -47,13 +47,17 @@ static unsigned int def_sampling_rate; | |||
47 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) | 47 | #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) |
48 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) | 48 | #define TRANSITION_LATENCY_LIMIT (10 * 1000) |
49 | 49 | ||
50 | static void do_dbs_timer(void *data); | 50 | static void do_dbs_timer(struct work_struct *work); |
51 | |||
52 | /* Sampling types */ | ||
53 | enum dbs_sample {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE}; | ||
51 | 54 | ||
52 | struct cpu_dbs_info_s { | 55 | struct cpu_dbs_info_s { |
53 | cputime64_t prev_cpu_idle; | 56 | cputime64_t prev_cpu_idle; |
54 | cputime64_t prev_cpu_wall; | 57 | cputime64_t prev_cpu_wall; |
55 | struct cpufreq_policy *cur_policy; | 58 | struct cpufreq_policy *cur_policy; |
56 | struct work_struct work; | 59 | struct delayed_work work; |
60 | enum dbs_sample sample_type; | ||
57 | unsigned int enable; | 61 | unsigned int enable; |
58 | struct cpufreq_frequency_table *freq_table; | 62 | struct cpufreq_frequency_table *freq_table; |
59 | unsigned int freq_lo; | 63 | unsigned int freq_lo; |
@@ -407,30 +411,31 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info) | |||
407 | } | 411 | } |
408 | } | 412 | } |
409 | 413 | ||
410 | /* Sampling types */ | 414 | static void do_dbs_timer(struct work_struct *work) |
411 | enum {DBS_NORMAL_SAMPLE, DBS_SUB_SAMPLE}; | ||
412 | |||
413 | static void do_dbs_timer(void *data) | ||
414 | { | 415 | { |
415 | unsigned int cpu = smp_processor_id(); | 416 | unsigned int cpu = smp_processor_id(); |
416 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); | 417 | struct cpu_dbs_info_s *dbs_info = &per_cpu(cpu_dbs_info, cpu); |
418 | enum dbs_sample sample_type = dbs_info->sample_type; | ||
417 | /* We want all CPUs to do sampling nearly on same jiffy */ | 419 | /* We want all CPUs to do sampling nearly on same jiffy */ |
418 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); | 420 | int delay = usecs_to_jiffies(dbs_tuners_ins.sampling_rate); |
421 | |||
422 | /* Permit rescheduling of this work item */ | ||
423 | work_release(work); | ||
424 | |||
419 | delay -= jiffies % delay; | 425 | delay -= jiffies % delay; |
420 | 426 | ||
421 | if (!dbs_info->enable) | 427 | if (!dbs_info->enable) |
422 | return; | 428 | return; |
423 | /* Common NORMAL_SAMPLE setup */ | 429 | /* Common NORMAL_SAMPLE setup */ |
424 | INIT_WORK(&dbs_info->work, do_dbs_timer, (void *)DBS_NORMAL_SAMPLE); | 430 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; |
425 | if (!dbs_tuners_ins.powersave_bias || | 431 | if (!dbs_tuners_ins.powersave_bias || |
426 | (unsigned long) data == DBS_NORMAL_SAMPLE) { | 432 | sample_type == DBS_NORMAL_SAMPLE) { |
427 | lock_cpu_hotplug(); | 433 | lock_cpu_hotplug(); |
428 | dbs_check_cpu(dbs_info); | 434 | dbs_check_cpu(dbs_info); |
429 | unlock_cpu_hotplug(); | 435 | unlock_cpu_hotplug(); |
430 | if (dbs_info->freq_lo) { | 436 | if (dbs_info->freq_lo) { |
431 | /* Setup timer for SUB_SAMPLE */ | 437 | /* Setup timer for SUB_SAMPLE */ |
432 | INIT_WORK(&dbs_info->work, do_dbs_timer, | 438 | dbs_info->sample_type = DBS_SUB_SAMPLE; |
433 | (void *)DBS_SUB_SAMPLE); | ||
434 | delay = dbs_info->freq_hi_jiffies; | 439 | delay = dbs_info->freq_hi_jiffies; |
435 | } | 440 | } |
436 | } else { | 441 | } else { |
@@ -449,7 +454,8 @@ static inline void dbs_timer_init(unsigned int cpu) | |||
449 | delay -= jiffies % delay; | 454 | delay -= jiffies % delay; |
450 | 455 | ||
451 | ondemand_powersave_bias_init(); | 456 | ondemand_powersave_bias_init(); |
452 | INIT_WORK(&dbs_info->work, do_dbs_timer, NULL); | 457 | INIT_DELAYED_WORK_NAR(&dbs_info->work, do_dbs_timer); |
458 | dbs_info->sample_type = DBS_NORMAL_SAMPLE; | ||
453 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); | 459 | queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, delay); |
454 | } | 460 | } |
455 | 461 | ||
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c index 4630f1969a09..15edf40828b4 100644 --- a/drivers/i2c/chips/ds1374.c +++ b/drivers/i2c/chips/ds1374.c | |||
@@ -140,12 +140,14 @@ ulong ds1374_get_rtc_time(void) | |||
140 | return t1; | 140 | return t1; |
141 | } | 141 | } |
142 | 142 | ||
143 | static void ds1374_set_work(void *arg) | 143 | static ulong new_time; |
144 | |||
145 | static void ds1374_set_work(struct work_struct *work) | ||
144 | { | 146 | { |
145 | ulong t1, t2; | 147 | ulong t1, t2; |
146 | int limit = 10; /* arbitrary retry limit */ | 148 | int limit = 10; /* arbitrary retry limit */ |
147 | 149 | ||
148 | t1 = *(ulong *) arg; | 150 | t1 = new_time; |
149 | 151 | ||
150 | mutex_lock(&ds1374_mutex); | 152 | mutex_lock(&ds1374_mutex); |
151 | 153 | ||
@@ -167,11 +169,9 @@ static void ds1374_set_work(void *arg) | |||
167 | "can't confirm time set from rtc chip\n"); | 169 | "can't confirm time set from rtc chip\n"); |
168 | } | 170 | } |
169 | 171 | ||
170 | static ulong new_time; | ||
171 | |||
172 | static struct workqueue_struct *ds1374_workqueue; | 172 | static struct workqueue_struct *ds1374_workqueue; |
173 | 173 | ||
174 | static DECLARE_WORK(ds1374_work, ds1374_set_work, &new_time); | 174 | static DECLARE_WORK(ds1374_work, ds1374_set_work); |
175 | 175 | ||
176 | int ds1374_set_rtc_time(ulong nowtime) | 176 | int ds1374_set_rtc_time(ulong nowtime) |
177 | { | 177 | { |
@@ -180,7 +180,7 @@ int ds1374_set_rtc_time(ulong nowtime) | |||
180 | if (in_interrupt()) | 180 | if (in_interrupt()) |
181 | queue_work(ds1374_workqueue, &ds1374_work); | 181 | queue_work(ds1374_workqueue, &ds1374_work); |
182 | else | 182 | else |
183 | ds1374_set_work(&new_time); | 183 | ds1374_set_work(NULL); |
184 | 184 | ||
185 | return 0; | 185 | return 0; |
186 | } | 186 | } |
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index 2dd0a34d9472..420377c86422 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c | |||
@@ -215,8 +215,15 @@ m41t00_set(void *arg) | |||
215 | } | 215 | } |
216 | 216 | ||
217 | static ulong new_time; | 217 | static ulong new_time; |
218 | /* well, isn't this API just _lovely_? */ | ||
219 | static void | ||
220 | m41t00_barf(struct work_struct *unusable) | ||
221 | { | ||
222 | m41t00_set(&new_time); | ||
223 | } | ||
224 | |||
218 | static struct workqueue_struct *m41t00_wq; | 225 | static struct workqueue_struct *m41t00_wq; |
219 | static DECLARE_WORK(m41t00_work, m41t00_set, &new_time); | 226 | static DECLARE_WORK(m41t00_work, m41t00_barf); |
220 | 227 | ||
221 | int | 228 | int |
222 | m41t00_set_rtc_time(ulong nowtime) | 229 | m41t00_set_rtc_time(ulong nowtime) |
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index bef4759f70e5..7efd28ac21ed 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c | |||
@@ -192,20 +192,10 @@ static int ide_config(struct pcmcia_device *link) | |||
192 | tuple.TupleOffset = 0; | 192 | tuple.TupleOffset = 0; |
193 | tuple.TupleDataMax = 255; | 193 | tuple.TupleDataMax = 255; |
194 | tuple.Attributes = 0; | 194 | tuple.Attributes = 0; |
195 | tuple.DesiredTuple = CISTPL_CONFIG; | 195 | |
196 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 196 | is_kme = ((link->manf_id == MANFID_KME) && |
197 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | 197 | ((link->card_id == PRODID_KME_KXLC005_A) || |
198 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &stk->parse)); | 198 | (link->card_id == PRODID_KME_KXLC005_B))); |
199 | link->conf.ConfigBase = stk->parse.config.base; | ||
200 | link->conf.Present = stk->parse.config.rmask[0]; | ||
201 | |||
202 | tuple.DesiredTuple = CISTPL_MANFID; | ||
203 | if (!pcmcia_get_first_tuple(link, &tuple) && | ||
204 | !pcmcia_get_tuple_data(link, &tuple) && | ||
205 | !pcmcia_parse_tuple(link, &tuple, &stk->parse)) | ||
206 | is_kme = ((stk->parse.manfid.manf == MANFID_KME) && | ||
207 | ((stk->parse.manfid.card == PRODID_KME_KXLC005_A) || | ||
208 | (stk->parse.manfid.card == PRODID_KME_KXLC005_B))); | ||
209 | 199 | ||
210 | /* Not sure if this is right... look up the current Vcc */ | 200 | /* Not sure if this is right... look up the current Vcc */ |
211 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); | 201 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &stk->conf)); |
@@ -408,8 +398,10 @@ static struct pcmcia_device_id ide_ids[] = { | |||
408 | PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), | 398 | PCMCIA_DEVICE_PROD_ID12("SMI VENDOR", "SMI PRODUCT", 0x30896c92, 0x703cc5f6), |
409 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), | 399 | PCMCIA_DEVICE_PROD_ID12("TOSHIBA", "MK2001MPL", 0xb4585a1a, 0x3489e003), |
410 | PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), | 400 | PCMCIA_DEVICE_PROD_ID1("TRANSCEND 512M ", 0xd0909443), |
401 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS1GCF80", 0x709b1bf1, 0x2a54d4b1), | ||
411 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), | 402 | PCMCIA_DEVICE_PROD_ID12("TRANSCEND", "TS4GCF120", 0x709b1bf1, 0xf54a91c8), |
412 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), | 403 | PCMCIA_DEVICE_PROD_ID12("WIT", "IDE16", 0x244e5994, 0x3e232852), |
404 | PCMCIA_DEVICE_PROD_ID12("WEIDA", "TWTTI", 0xcc7cf69c, 0x212bb918), | ||
413 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), | 405 | PCMCIA_DEVICE_PROD_ID1("STI Flash", 0xe4a13209), |
414 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), | 406 | PCMCIA_DEVICE_PROD_ID12("STI", "Flash 5.0", 0xbf2df18d, 0x8cb57a0e), |
415 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), | 407 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "SanDisk", "ConnectPlus", 0x7a954bd9, 0x74be00c6), |
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 2af634d7acf4..eb7ab112c050 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/ide.h> | 35 | #include <linux/ide.h> |
36 | #include <asm/io.h> | 36 | #include <asm/io.h> |
37 | 37 | ||
38 | #ifdef CONFIG_PPC_MULTIPLATFORM | 38 | #ifdef CONFIG_PPC_CHRP |
39 | #include <asm/processor.h> | 39 | #include <asm/processor.h> |
40 | #endif | 40 | #endif |
41 | 41 | ||
@@ -442,7 +442,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) | |||
442 | hwif->speedproc = &via_set_drive; | 442 | hwif->speedproc = &via_set_drive; |
443 | 443 | ||
444 | 444 | ||
445 | #if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32) | 445 | #ifdef CONFIG_PPC_CHRP |
446 | if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) { | 446 | if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) { |
447 | hwif->irq = hwif->channel ? 15 : 14; | 447 | hwif->irq = hwif->channel ? 15 : 14; |
448 | } | 448 | } |
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index d90a3a1898c0..8f4378a1631c 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c | |||
@@ -31,9 +31,10 @@ | |||
31 | #include "config_roms.h" | 31 | #include "config_roms.h" |
32 | 32 | ||
33 | 33 | ||
34 | static void delayed_reset_bus(void * __reset_info) | 34 | static void delayed_reset_bus(struct work_struct *work) |
35 | { | 35 | { |
36 | struct hpsb_host *host = (struct hpsb_host*)__reset_info; | 36 | struct hpsb_host *host = |
37 | container_of(work, struct hpsb_host, delayed_reset.work); | ||
37 | int generation = host->csr.generation + 1; | 38 | int generation = host->csr.generation + 1; |
38 | 39 | ||
39 | /* The generation field rolls over to 2 rather than 0 per IEEE | 40 | /* The generation field rolls over to 2 rather than 0 per IEEE |
@@ -145,7 +146,7 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, | |||
145 | 146 | ||
146 | atomic_set(&h->generation, 0); | 147 | atomic_set(&h->generation, 0); |
147 | 148 | ||
148 | INIT_WORK(&h->delayed_reset, delayed_reset_bus, h); | 149 | INIT_DELAYED_WORK(&h->delayed_reset, delayed_reset_bus); |
149 | 150 | ||
150 | init_timer(&h->timeout); | 151 | init_timer(&h->timeout); |
151 | h->timeout.data = (unsigned long) h; | 152 | h->timeout.data = (unsigned long) h; |
@@ -234,7 +235,7 @@ int hpsb_update_config_rom_image(struct hpsb_host *host) | |||
234 | * Config ROM in the near future. */ | 235 | * Config ROM in the near future. */ |
235 | reset_delay = HZ; | 236 | reset_delay = HZ; |
236 | 237 | ||
237 | PREPARE_WORK(&host->delayed_reset, delayed_reset_bus, host); | 238 | PREPARE_DELAYED_WORK(&host->delayed_reset, delayed_reset_bus); |
238 | schedule_delayed_work(&host->delayed_reset, reset_delay); | 239 | schedule_delayed_work(&host->delayed_reset, reset_delay); |
239 | 240 | ||
240 | return 0; | 241 | return 0; |
diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h index bc6dbfadb891..d553e38c9543 100644 --- a/drivers/ieee1394/hosts.h +++ b/drivers/ieee1394/hosts.h | |||
@@ -62,7 +62,7 @@ struct hpsb_host { | |||
62 | struct class_device class_dev; | 62 | struct class_device class_dev; |
63 | 63 | ||
64 | int update_config_rom; | 64 | int update_config_rom; |
65 | struct work_struct delayed_reset; | 65 | struct delayed_work delayed_reset; |
66 | unsigned int config_roms; | 66 | unsigned int config_roms; |
67 | 67 | ||
68 | struct list_head addr_space; | 68 | struct list_head addr_space; |
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 6986ac188281..cd156d4e779e 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -493,20 +493,25 @@ static void sbp2util_notify_fetch_agent(struct scsi_id_instance_data *scsi_id, | |||
493 | scsi_unblock_requests(scsi_id->scsi_host); | 493 | scsi_unblock_requests(scsi_id->scsi_host); |
494 | } | 494 | } |
495 | 495 | ||
496 | static void sbp2util_write_orb_pointer(void *p) | 496 | static void sbp2util_write_orb_pointer(struct work_struct *work) |
497 | { | 497 | { |
498 | struct scsi_id_instance_data *scsi_id = | ||
499 | container_of(work, struct scsi_id_instance_data, | ||
500 | protocol_work.work); | ||
498 | quadlet_t data[2]; | 501 | quadlet_t data[2]; |
499 | 502 | ||
500 | data[0] = ORB_SET_NODE_ID( | 503 | data[0] = ORB_SET_NODE_ID(scsi_id->hi->host->node_id); |
501 | ((struct scsi_id_instance_data *)p)->hi->host->node_id); | 504 | data[1] = scsi_id->last_orb_dma; |
502 | data[1] = ((struct scsi_id_instance_data *)p)->last_orb_dma; | ||
503 | sbp2util_cpu_to_be32_buffer(data, 8); | 505 | sbp2util_cpu_to_be32_buffer(data, 8); |
504 | sbp2util_notify_fetch_agent(p, SBP2_ORB_POINTER_OFFSET, data, 8); | 506 | sbp2util_notify_fetch_agent(scsi_id, SBP2_ORB_POINTER_OFFSET, data, 8); |
505 | } | 507 | } |
506 | 508 | ||
507 | static void sbp2util_write_doorbell(void *p) | 509 | static void sbp2util_write_doorbell(struct work_struct *work) |
508 | { | 510 | { |
509 | sbp2util_notify_fetch_agent(p, SBP2_DOORBELL_OFFSET, NULL, 4); | 511 | struct scsi_id_instance_data *scsi_id = |
512 | container_of(work, struct scsi_id_instance_data, | ||
513 | protocol_work.work); | ||
514 | sbp2util_notify_fetch_agent(scsi_id, SBP2_DOORBELL_OFFSET, NULL, 4); | ||
510 | } | 515 | } |
511 | 516 | ||
512 | /* | 517 | /* |
@@ -843,7 +848,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud | |||
843 | INIT_LIST_HEAD(&scsi_id->scsi_list); | 848 | INIT_LIST_HEAD(&scsi_id->scsi_list); |
844 | spin_lock_init(&scsi_id->sbp2_command_orb_lock); | 849 | spin_lock_init(&scsi_id->sbp2_command_orb_lock); |
845 | atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING); | 850 | atomic_set(&scsi_id->state, SBP2LU_STATE_RUNNING); |
846 | INIT_WORK(&scsi_id->protocol_work, NULL, NULL); | 851 | INIT_DELAYED_WORK(&scsi_id->protocol_work, NULL); |
847 | 852 | ||
848 | ud->device.driver_data = scsi_id; | 853 | ud->device.driver_data = scsi_id; |
849 | 854 | ||
@@ -2047,11 +2052,10 @@ static void sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, | |||
2047 | * We do not accept new commands until the job is over. | 2052 | * We do not accept new commands until the job is over. |
2048 | */ | 2053 | */ |
2049 | scsi_block_requests(scsi_id->scsi_host); | 2054 | scsi_block_requests(scsi_id->scsi_host); |
2050 | PREPARE_WORK(&scsi_id->protocol_work, | 2055 | PREPARE_DELAYED_WORK(&scsi_id->protocol_work, |
2051 | last_orb ? sbp2util_write_doorbell: | 2056 | last_orb ? sbp2util_write_doorbell: |
2052 | sbp2util_write_orb_pointer, | 2057 | sbp2util_write_orb_pointer); |
2053 | scsi_id); | 2058 | schedule_delayed_work(&scsi_id->protocol_work, 0); |
2054 | schedule_work(&scsi_id->protocol_work); | ||
2055 | } | 2059 | } |
2056 | } | 2060 | } |
2057 | 2061 | ||
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index abbe48e646c3..1b16d6b9cf11 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h | |||
@@ -348,7 +348,7 @@ struct scsi_id_instance_data { | |||
348 | unsigned workarounds; | 348 | unsigned workarounds; |
349 | 349 | ||
350 | atomic_t state; | 350 | atomic_t state; |
351 | struct work_struct protocol_work; | 351 | struct delayed_work protocol_work; |
352 | }; | 352 | }; |
353 | 353 | ||
354 | /* For use in scsi_id_instance_data.state */ | 354 | /* For use in scsi_id_instance_data.state */ |
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 7767a11b6890..af939796750d 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c | |||
@@ -55,11 +55,11 @@ struct addr_req { | |||
55 | int status; | 55 | int status; |
56 | }; | 56 | }; |
57 | 57 | ||
58 | static void process_req(void *data); | 58 | static void process_req(struct work_struct *work); |
59 | 59 | ||
60 | static DEFINE_MUTEX(lock); | 60 | static DEFINE_MUTEX(lock); |
61 | static LIST_HEAD(req_list); | 61 | static LIST_HEAD(req_list); |
62 | static DECLARE_WORK(work, process_req, NULL); | 62 | static DECLARE_DELAYED_WORK(work, process_req); |
63 | static struct workqueue_struct *addr_wq; | 63 | static struct workqueue_struct *addr_wq; |
64 | 64 | ||
65 | void rdma_addr_register_client(struct rdma_addr_client *client) | 65 | void rdma_addr_register_client(struct rdma_addr_client *client) |
@@ -215,7 +215,7 @@ out: | |||
215 | return ret; | 215 | return ret; |
216 | } | 216 | } |
217 | 217 | ||
218 | static void process_req(void *data) | 218 | static void process_req(struct work_struct *work) |
219 | { | 219 | { |
220 | struct addr_req *req, *temp_req; | 220 | struct addr_req *req, *temp_req; |
221 | struct sockaddr_in *src_in, *dst_in; | 221 | struct sockaddr_in *src_in, *dst_in; |
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 20e9f64e67a6..98272fbbfb31 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c | |||
@@ -285,9 +285,10 @@ err: | |||
285 | kfree(tprops); | 285 | kfree(tprops); |
286 | } | 286 | } |
287 | 287 | ||
288 | static void ib_cache_task(void *work_ptr) | 288 | static void ib_cache_task(struct work_struct *_work) |
289 | { | 289 | { |
290 | struct ib_update_work *work = work_ptr; | 290 | struct ib_update_work *work = |
291 | container_of(_work, struct ib_update_work, work); | ||
291 | 292 | ||
292 | ib_cache_update(work->device, work->port_num); | 293 | ib_cache_update(work->device, work->port_num); |
293 | kfree(work); | 294 | kfree(work); |
@@ -306,7 +307,7 @@ static void ib_cache_event(struct ib_event_handler *handler, | |||
306 | event->event == IB_EVENT_CLIENT_REREGISTER) { | 307 | event->event == IB_EVENT_CLIENT_REREGISTER) { |
307 | work = kmalloc(sizeof *work, GFP_ATOMIC); | 308 | work = kmalloc(sizeof *work, GFP_ATOMIC); |
308 | if (work) { | 309 | if (work) { |
309 | INIT_WORK(&work->work, ib_cache_task, work); | 310 | INIT_WORK(&work->work, ib_cache_task); |
310 | work->device = event->device; | 311 | work->device = event->device; |
311 | work->port_num = event->element.port_num; | 312 | work->port_num = event->element.port_num; |
312 | schedule_work(&work->work); | 313 | schedule_work(&work->work); |
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index e5dc4530808a..79c937bf6962 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c | |||
@@ -101,7 +101,7 @@ struct cm_av { | |||
101 | }; | 101 | }; |
102 | 102 | ||
103 | struct cm_work { | 103 | struct cm_work { |
104 | struct work_struct work; | 104 | struct delayed_work work; |
105 | struct list_head list; | 105 | struct list_head list; |
106 | struct cm_port *port; | 106 | struct cm_port *port; |
107 | struct ib_mad_recv_wc *mad_recv_wc; /* Received MADs */ | 107 | struct ib_mad_recv_wc *mad_recv_wc; /* Received MADs */ |
@@ -161,7 +161,7 @@ struct cm_id_private { | |||
161 | atomic_t work_count; | 161 | atomic_t work_count; |
162 | }; | 162 | }; |
163 | 163 | ||
164 | static void cm_work_handler(void *data); | 164 | static void cm_work_handler(struct work_struct *work); |
165 | 165 | ||
166 | static inline void cm_deref_id(struct cm_id_private *cm_id_priv) | 166 | static inline void cm_deref_id(struct cm_id_private *cm_id_priv) |
167 | { | 167 | { |
@@ -668,8 +668,7 @@ static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id) | |||
668 | return ERR_PTR(-ENOMEM); | 668 | return ERR_PTR(-ENOMEM); |
669 | 669 | ||
670 | timewait_info->work.local_id = local_id; | 670 | timewait_info->work.local_id = local_id; |
671 | INIT_WORK(&timewait_info->work.work, cm_work_handler, | 671 | INIT_DELAYED_WORK(&timewait_info->work.work, cm_work_handler); |
672 | &timewait_info->work); | ||
673 | timewait_info->work.cm_event.event = IB_CM_TIMEWAIT_EXIT; | 672 | timewait_info->work.cm_event.event = IB_CM_TIMEWAIT_EXIT; |
674 | return timewait_info; | 673 | return timewait_info; |
675 | } | 674 | } |
@@ -2995,9 +2994,9 @@ static void cm_send_handler(struct ib_mad_agent *mad_agent, | |||
2995 | } | 2994 | } |
2996 | } | 2995 | } |
2997 | 2996 | ||
2998 | static void cm_work_handler(void *data) | 2997 | static void cm_work_handler(struct work_struct *_work) |
2999 | { | 2998 | { |
3000 | struct cm_work *work = data; | 2999 | struct cm_work *work = container_of(_work, struct cm_work, work.work); |
3001 | int ret; | 3000 | int ret; |
3002 | 3001 | ||
3003 | switch (work->cm_event.event) { | 3002 | switch (work->cm_event.event) { |
@@ -3087,12 +3086,12 @@ static int cm_establish(struct ib_cm_id *cm_id) | |||
3087 | * we need to find the cm_id once we're in the context of the | 3086 | * we need to find the cm_id once we're in the context of the |
3088 | * worker thread, rather than holding a reference on it. | 3087 | * worker thread, rather than holding a reference on it. |
3089 | */ | 3088 | */ |
3090 | INIT_WORK(&work->work, cm_work_handler, work); | 3089 | INIT_DELAYED_WORK(&work->work, cm_work_handler); |
3091 | work->local_id = cm_id->local_id; | 3090 | work->local_id = cm_id->local_id; |
3092 | work->remote_id = cm_id->remote_id; | 3091 | work->remote_id = cm_id->remote_id; |
3093 | work->mad_recv_wc = NULL; | 3092 | work->mad_recv_wc = NULL; |
3094 | work->cm_event.event = IB_CM_USER_ESTABLISHED; | 3093 | work->cm_event.event = IB_CM_USER_ESTABLISHED; |
3095 | queue_work(cm.wq, &work->work); | 3094 | queue_delayed_work(cm.wq, &work->work, 0); |
3096 | out: | 3095 | out: |
3097 | return ret; | 3096 | return ret; |
3098 | } | 3097 | } |
@@ -3191,11 +3190,11 @@ static void cm_recv_handler(struct ib_mad_agent *mad_agent, | |||
3191 | return; | 3190 | return; |
3192 | } | 3191 | } |
3193 | 3192 | ||
3194 | INIT_WORK(&work->work, cm_work_handler, work); | 3193 | INIT_DELAYED_WORK(&work->work, cm_work_handler); |
3195 | work->cm_event.event = event; | 3194 | work->cm_event.event = event; |
3196 | work->mad_recv_wc = mad_recv_wc; | 3195 | work->mad_recv_wc = mad_recv_wc; |
3197 | work->port = (struct cm_port *)mad_agent->context; | 3196 | work->port = (struct cm_port *)mad_agent->context; |
3198 | queue_work(cm.wq, &work->work); | 3197 | queue_delayed_work(cm.wq, &work->work, 0); |
3199 | } | 3198 | } |
3200 | 3199 | ||
3201 | static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv, | 3200 | static int cm_init_qp_init_attr(struct cm_id_private *cm_id_priv, |
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index cf48f2697434..985a6b564d8f 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c | |||
@@ -1340,9 +1340,9 @@ static int cma_query_ib_route(struct rdma_id_private *id_priv, int timeout_ms, | |||
1340 | return (id_priv->query_id < 0) ? id_priv->query_id : 0; | 1340 | return (id_priv->query_id < 0) ? id_priv->query_id : 0; |
1341 | } | 1341 | } |
1342 | 1342 | ||
1343 | static void cma_work_handler(void *data) | 1343 | static void cma_work_handler(struct work_struct *_work) |
1344 | { | 1344 | { |
1345 | struct cma_work *work = data; | 1345 | struct cma_work *work = container_of(_work, struct cma_work, work); |
1346 | struct rdma_id_private *id_priv = work->id; | 1346 | struct rdma_id_private *id_priv = work->id; |
1347 | int destroy = 0; | 1347 | int destroy = 0; |
1348 | 1348 | ||
@@ -1373,7 +1373,7 @@ static int cma_resolve_ib_route(struct rdma_id_private *id_priv, int timeout_ms) | |||
1373 | return -ENOMEM; | 1373 | return -ENOMEM; |
1374 | 1374 | ||
1375 | work->id = id_priv; | 1375 | work->id = id_priv; |
1376 | INIT_WORK(&work->work, cma_work_handler, work); | 1376 | INIT_WORK(&work->work, cma_work_handler); |
1377 | work->old_state = CMA_ROUTE_QUERY; | 1377 | work->old_state = CMA_ROUTE_QUERY; |
1378 | work->new_state = CMA_ROUTE_RESOLVED; | 1378 | work->new_state = CMA_ROUTE_RESOLVED; |
1379 | work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED; | 1379 | work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED; |
@@ -1430,7 +1430,7 @@ static int cma_resolve_iw_route(struct rdma_id_private *id_priv, int timeout_ms) | |||
1430 | return -ENOMEM; | 1430 | return -ENOMEM; |
1431 | 1431 | ||
1432 | work->id = id_priv; | 1432 | work->id = id_priv; |
1433 | INIT_WORK(&work->work, cma_work_handler, work); | 1433 | INIT_WORK(&work->work, cma_work_handler); |
1434 | work->old_state = CMA_ROUTE_QUERY; | 1434 | work->old_state = CMA_ROUTE_QUERY; |
1435 | work->new_state = CMA_ROUTE_RESOLVED; | 1435 | work->new_state = CMA_ROUTE_RESOLVED; |
1436 | work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED; | 1436 | work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED; |
@@ -1583,7 +1583,7 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv) | |||
1583 | } | 1583 | } |
1584 | 1584 | ||
1585 | work->id = id_priv; | 1585 | work->id = id_priv; |
1586 | INIT_WORK(&work->work, cma_work_handler, work); | 1586 | INIT_WORK(&work->work, cma_work_handler); |
1587 | work->old_state = CMA_ADDR_QUERY; | 1587 | work->old_state = CMA_ADDR_QUERY; |
1588 | work->new_state = CMA_ADDR_RESOLVED; | 1588 | work->new_state = CMA_ADDR_RESOLVED; |
1589 | work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED; | 1589 | work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED; |
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index cf797d7aea09..1039ad57d53b 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c | |||
@@ -828,9 +828,9 @@ static int process_event(struct iwcm_id_private *cm_id_priv, | |||
828 | * thread asleep on the destroy_comp list vs. an object destroyed | 828 | * thread asleep on the destroy_comp list vs. an object destroyed |
829 | * here synchronously when the last reference is removed. | 829 | * here synchronously when the last reference is removed. |
830 | */ | 830 | */ |
831 | static void cm_work_handler(void *arg) | 831 | static void cm_work_handler(struct work_struct *_work) |
832 | { | 832 | { |
833 | struct iwcm_work *work = arg; | 833 | struct iwcm_work *work = container_of(_work, struct iwcm_work, work); |
834 | struct iw_cm_event levent; | 834 | struct iw_cm_event levent; |
835 | struct iwcm_id_private *cm_id_priv = work->cm_id; | 835 | struct iwcm_id_private *cm_id_priv = work->cm_id; |
836 | unsigned long flags; | 836 | unsigned long flags; |
@@ -900,7 +900,7 @@ static int cm_event_handler(struct iw_cm_id *cm_id, | |||
900 | goto out; | 900 | goto out; |
901 | } | 901 | } |
902 | 902 | ||
903 | INIT_WORK(&work->work, cm_work_handler, work); | 903 | INIT_WORK(&work->work, cm_work_handler); |
904 | work->cm_id = cm_id_priv; | 904 | work->cm_id = cm_id_priv; |
905 | work->event = *iw_event; | 905 | work->event = *iw_event; |
906 | 906 | ||
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 3f9c16232c4d..15f38d94b3a8 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -65,8 +65,8 @@ static struct ib_mad_agent_private *find_mad_agent( | |||
65 | static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info, | 65 | static int ib_mad_post_receive_mads(struct ib_mad_qp_info *qp_info, |
66 | struct ib_mad_private *mad); | 66 | struct ib_mad_private *mad); |
67 | static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv); | 67 | static void cancel_mads(struct ib_mad_agent_private *mad_agent_priv); |
68 | static void timeout_sends(void *data); | 68 | static void timeout_sends(struct work_struct *work); |
69 | static void local_completions(void *data); | 69 | static void local_completions(struct work_struct *work); |
70 | static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req, | 70 | static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req, |
71 | struct ib_mad_agent_private *agent_priv, | 71 | struct ib_mad_agent_private *agent_priv, |
72 | u8 mgmt_class); | 72 | u8 mgmt_class); |
@@ -356,10 +356,9 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, | |||
356 | INIT_LIST_HEAD(&mad_agent_priv->wait_list); | 356 | INIT_LIST_HEAD(&mad_agent_priv->wait_list); |
357 | INIT_LIST_HEAD(&mad_agent_priv->done_list); | 357 | INIT_LIST_HEAD(&mad_agent_priv->done_list); |
358 | INIT_LIST_HEAD(&mad_agent_priv->rmpp_list); | 358 | INIT_LIST_HEAD(&mad_agent_priv->rmpp_list); |
359 | INIT_WORK(&mad_agent_priv->timed_work, timeout_sends, mad_agent_priv); | 359 | INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends); |
360 | INIT_LIST_HEAD(&mad_agent_priv->local_list); | 360 | INIT_LIST_HEAD(&mad_agent_priv->local_list); |
361 | INIT_WORK(&mad_agent_priv->local_work, local_completions, | 361 | INIT_WORK(&mad_agent_priv->local_work, local_completions); |
362 | mad_agent_priv); | ||
363 | atomic_set(&mad_agent_priv->refcount, 1); | 362 | atomic_set(&mad_agent_priv->refcount, 1); |
364 | init_completion(&mad_agent_priv->comp); | 363 | init_completion(&mad_agent_priv->comp); |
365 | 364 | ||
@@ -2198,12 +2197,12 @@ static void mad_error_handler(struct ib_mad_port_private *port_priv, | |||
2198 | /* | 2197 | /* |
2199 | * IB MAD completion callback | 2198 | * IB MAD completion callback |
2200 | */ | 2199 | */ |
2201 | static void ib_mad_completion_handler(void *data) | 2200 | static void ib_mad_completion_handler(struct work_struct *work) |
2202 | { | 2201 | { |
2203 | struct ib_mad_port_private *port_priv; | 2202 | struct ib_mad_port_private *port_priv; |
2204 | struct ib_wc wc; | 2203 | struct ib_wc wc; |
2205 | 2204 | ||
2206 | port_priv = (struct ib_mad_port_private *)data; | 2205 | port_priv = container_of(work, struct ib_mad_port_private, work); |
2207 | ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP); | 2206 | ib_req_notify_cq(port_priv->cq, IB_CQ_NEXT_COMP); |
2208 | 2207 | ||
2209 | while (ib_poll_cq(port_priv->cq, 1, &wc) == 1) { | 2208 | while (ib_poll_cq(port_priv->cq, 1, &wc) == 1) { |
@@ -2324,7 +2323,7 @@ void ib_cancel_mad(struct ib_mad_agent *mad_agent, | |||
2324 | } | 2323 | } |
2325 | EXPORT_SYMBOL(ib_cancel_mad); | 2324 | EXPORT_SYMBOL(ib_cancel_mad); |
2326 | 2325 | ||
2327 | static void local_completions(void *data) | 2326 | static void local_completions(struct work_struct *work) |
2328 | { | 2327 | { |
2329 | struct ib_mad_agent_private *mad_agent_priv; | 2328 | struct ib_mad_agent_private *mad_agent_priv; |
2330 | struct ib_mad_local_private *local; | 2329 | struct ib_mad_local_private *local; |
@@ -2334,7 +2333,8 @@ static void local_completions(void *data) | |||
2334 | struct ib_wc wc; | 2333 | struct ib_wc wc; |
2335 | struct ib_mad_send_wc mad_send_wc; | 2334 | struct ib_mad_send_wc mad_send_wc; |
2336 | 2335 | ||
2337 | mad_agent_priv = (struct ib_mad_agent_private *)data; | 2336 | mad_agent_priv = |
2337 | container_of(work, struct ib_mad_agent_private, local_work); | ||
2338 | 2338 | ||
2339 | spin_lock_irqsave(&mad_agent_priv->lock, flags); | 2339 | spin_lock_irqsave(&mad_agent_priv->lock, flags); |
2340 | while (!list_empty(&mad_agent_priv->local_list)) { | 2340 | while (!list_empty(&mad_agent_priv->local_list)) { |
@@ -2434,14 +2434,15 @@ static int retry_send(struct ib_mad_send_wr_private *mad_send_wr) | |||
2434 | return ret; | 2434 | return ret; |
2435 | } | 2435 | } |
2436 | 2436 | ||
2437 | static void timeout_sends(void *data) | 2437 | static void timeout_sends(struct work_struct *work) |
2438 | { | 2438 | { |
2439 | struct ib_mad_agent_private *mad_agent_priv; | 2439 | struct ib_mad_agent_private *mad_agent_priv; |
2440 | struct ib_mad_send_wr_private *mad_send_wr; | 2440 | struct ib_mad_send_wr_private *mad_send_wr; |
2441 | struct ib_mad_send_wc mad_send_wc; | 2441 | struct ib_mad_send_wc mad_send_wc; |
2442 | unsigned long flags, delay; | 2442 | unsigned long flags, delay; |
2443 | 2443 | ||
2444 | mad_agent_priv = (struct ib_mad_agent_private *)data; | 2444 | mad_agent_priv = container_of(work, struct ib_mad_agent_private, |
2445 | timed_work.work); | ||
2445 | mad_send_wc.vendor_err = 0; | 2446 | mad_send_wc.vendor_err = 0; |
2446 | 2447 | ||
2447 | spin_lock_irqsave(&mad_agent_priv->lock, flags); | 2448 | spin_lock_irqsave(&mad_agent_priv->lock, flags); |
@@ -2799,7 +2800,7 @@ static int ib_mad_port_open(struct ib_device *device, | |||
2799 | ret = -ENOMEM; | 2800 | ret = -ENOMEM; |
2800 | goto error8; | 2801 | goto error8; |
2801 | } | 2802 | } |
2802 | INIT_WORK(&port_priv->work, ib_mad_completion_handler, port_priv); | 2803 | INIT_WORK(&port_priv->work, ib_mad_completion_handler); |
2803 | 2804 | ||
2804 | spin_lock_irqsave(&ib_mad_port_list_lock, flags); | 2805 | spin_lock_irqsave(&ib_mad_port_list_lock, flags); |
2805 | list_add_tail(&port_priv->port_list, &ib_mad_port_list); | 2806 | list_add_tail(&port_priv->port_list, &ib_mad_port_list); |
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index d06b59083f6e..d5548e73e068 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h | |||
@@ -102,7 +102,7 @@ struct ib_mad_agent_private { | |||
102 | struct list_head send_list; | 102 | struct list_head send_list; |
103 | struct list_head wait_list; | 103 | struct list_head wait_list; |
104 | struct list_head done_list; | 104 | struct list_head done_list; |
105 | struct work_struct timed_work; | 105 | struct delayed_work timed_work; |
106 | unsigned long timeout; | 106 | unsigned long timeout; |
107 | struct list_head local_list; | 107 | struct list_head local_list; |
108 | struct work_struct local_work; | 108 | struct work_struct local_work; |
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index 1ef79d015a1e..3663fd7022be 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c | |||
@@ -45,8 +45,8 @@ enum rmpp_state { | |||
45 | struct mad_rmpp_recv { | 45 | struct mad_rmpp_recv { |
46 | struct ib_mad_agent_private *agent; | 46 | struct ib_mad_agent_private *agent; |
47 | struct list_head list; | 47 | struct list_head list; |
48 | struct work_struct timeout_work; | 48 | struct delayed_work timeout_work; |
49 | struct work_struct cleanup_work; | 49 | struct delayed_work cleanup_work; |
50 | struct completion comp; | 50 | struct completion comp; |
51 | enum rmpp_state state; | 51 | enum rmpp_state state; |
52 | spinlock_t lock; | 52 | spinlock_t lock; |
@@ -233,9 +233,10 @@ static void nack_recv(struct ib_mad_agent_private *agent, | |||
233 | } | 233 | } |
234 | } | 234 | } |
235 | 235 | ||
236 | static void recv_timeout_handler(void *data) | 236 | static void recv_timeout_handler(struct work_struct *work) |
237 | { | 237 | { |
238 | struct mad_rmpp_recv *rmpp_recv = data; | 238 | struct mad_rmpp_recv *rmpp_recv = |
239 | container_of(work, struct mad_rmpp_recv, timeout_work.work); | ||
239 | struct ib_mad_recv_wc *rmpp_wc; | 240 | struct ib_mad_recv_wc *rmpp_wc; |
240 | unsigned long flags; | 241 | unsigned long flags; |
241 | 242 | ||
@@ -254,9 +255,10 @@ static void recv_timeout_handler(void *data) | |||
254 | ib_free_recv_mad(rmpp_wc); | 255 | ib_free_recv_mad(rmpp_wc); |
255 | } | 256 | } |
256 | 257 | ||
257 | static void recv_cleanup_handler(void *data) | 258 | static void recv_cleanup_handler(struct work_struct *work) |
258 | { | 259 | { |
259 | struct mad_rmpp_recv *rmpp_recv = data; | 260 | struct mad_rmpp_recv *rmpp_recv = |
261 | container_of(work, struct mad_rmpp_recv, cleanup_work.work); | ||
260 | unsigned long flags; | 262 | unsigned long flags; |
261 | 263 | ||
262 | spin_lock_irqsave(&rmpp_recv->agent->lock, flags); | 264 | spin_lock_irqsave(&rmpp_recv->agent->lock, flags); |
@@ -285,8 +287,8 @@ create_rmpp_recv(struct ib_mad_agent_private *agent, | |||
285 | 287 | ||
286 | rmpp_recv->agent = agent; | 288 | rmpp_recv->agent = agent; |
287 | init_completion(&rmpp_recv->comp); | 289 | init_completion(&rmpp_recv->comp); |
288 | INIT_WORK(&rmpp_recv->timeout_work, recv_timeout_handler, rmpp_recv); | 290 | INIT_DELAYED_WORK(&rmpp_recv->timeout_work, recv_timeout_handler); |
289 | INIT_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler, rmpp_recv); | 291 | INIT_DELAYED_WORK(&rmpp_recv->cleanup_work, recv_cleanup_handler); |
290 | spin_lock_init(&rmpp_recv->lock); | 292 | spin_lock_init(&rmpp_recv->lock); |
291 | rmpp_recv->state = RMPP_STATE_ACTIVE; | 293 | rmpp_recv->state = RMPP_STATE_ACTIVE; |
292 | atomic_set(&rmpp_recv->refcount, 1); | 294 | atomic_set(&rmpp_recv->refcount, 1); |
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 1706d3c7e95e..e45afba75341 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -360,9 +360,10 @@ static void free_sm_ah(struct kref *kref) | |||
360 | kfree(sm_ah); | 360 | kfree(sm_ah); |
361 | } | 361 | } |
362 | 362 | ||
363 | static void update_sm_ah(void *port_ptr) | 363 | static void update_sm_ah(struct work_struct *work) |
364 | { | 364 | { |
365 | struct ib_sa_port *port = port_ptr; | 365 | struct ib_sa_port *port = |
366 | container_of(work, struct ib_sa_port, update_task); | ||
366 | struct ib_sa_sm_ah *new_ah, *old_ah; | 367 | struct ib_sa_sm_ah *new_ah, *old_ah; |
367 | struct ib_port_attr port_attr; | 368 | struct ib_port_attr port_attr; |
368 | struct ib_ah_attr ah_attr; | 369 | struct ib_ah_attr ah_attr; |
@@ -992,8 +993,7 @@ static void ib_sa_add_one(struct ib_device *device) | |||
992 | if (IS_ERR(sa_dev->port[i].agent)) | 993 | if (IS_ERR(sa_dev->port[i].agent)) |
993 | goto err; | 994 | goto err; |
994 | 995 | ||
995 | INIT_WORK(&sa_dev->port[i].update_task, | 996 | INIT_WORK(&sa_dev->port[i].update_task, update_sm_ah); |
996 | update_sm_ah, &sa_dev->port[i]); | ||
997 | } | 997 | } |
998 | 998 | ||
999 | ib_set_client_data(device, &sa_client, sa_dev); | 999 | ib_set_client_data(device, &sa_client, sa_dev); |
@@ -1010,7 +1010,7 @@ static void ib_sa_add_one(struct ib_device *device) | |||
1010 | goto err; | 1010 | goto err; |
1011 | 1011 | ||
1012 | for (i = 0; i <= e - s; ++i) | 1012 | for (i = 0; i <= e - s; ++i) |
1013 | update_sm_ah(&sa_dev->port[i]); | 1013 | update_sm_ah(&sa_dev->port[i].update_task); |
1014 | 1014 | ||
1015 | return; | 1015 | return; |
1016 | 1016 | ||
diff --git a/drivers/infiniband/core/uverbs_mem.c b/drivers/infiniband/core/uverbs_mem.c index efe147dbeb42..db12cc0841df 100644 --- a/drivers/infiniband/core/uverbs_mem.c +++ b/drivers/infiniband/core/uverbs_mem.c | |||
@@ -179,9 +179,10 @@ void ib_umem_release(struct ib_device *dev, struct ib_umem *umem) | |||
179 | up_write(¤t->mm->mmap_sem); | 179 | up_write(¤t->mm->mmap_sem); |
180 | } | 180 | } |
181 | 181 | ||
182 | static void ib_umem_account(void *work_ptr) | 182 | static void ib_umem_account(struct work_struct *_work) |
183 | { | 183 | { |
184 | struct ib_umem_account_work *work = work_ptr; | 184 | struct ib_umem_account_work *work = |
185 | container_of(_work, struct ib_umem_account_work, work); | ||
185 | 186 | ||
186 | down_write(&work->mm->mmap_sem); | 187 | down_write(&work->mm->mmap_sem); |
187 | work->mm->locked_vm -= work->diff; | 188 | work->mm->locked_vm -= work->diff; |
@@ -216,7 +217,7 @@ void ib_umem_release_on_close(struct ib_device *dev, struct ib_umem *umem) | |||
216 | return; | 217 | return; |
217 | } | 218 | } |
218 | 219 | ||
219 | INIT_WORK(&work->work, ib_umem_account, work); | 220 | INIT_WORK(&work->work, ib_umem_account); |
220 | work->mm = mm; | 221 | work->mm = mm; |
221 | work->diff = PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT; | 222 | work->diff = PAGE_ALIGN(umem->length + umem->offset) >> PAGE_SHIFT; |
222 | 223 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c index 413754b1d8a2..8536aeb96af8 100644 --- a/drivers/infiniband/hw/ipath/ipath_user_pages.c +++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c | |||
@@ -214,9 +214,10 @@ struct ipath_user_pages_work { | |||
214 | unsigned long num_pages; | 214 | unsigned long num_pages; |
215 | }; | 215 | }; |
216 | 216 | ||
217 | static void user_pages_account(void *ptr) | 217 | static void user_pages_account(struct work_struct *_work) |
218 | { | 218 | { |
219 | struct ipath_user_pages_work *work = ptr; | 219 | struct ipath_user_pages_work *work = |
220 | container_of(_work, struct ipath_user_pages_work, work); | ||
220 | 221 | ||
221 | down_write(&work->mm->mmap_sem); | 222 | down_write(&work->mm->mmap_sem); |
222 | work->mm->locked_vm -= work->num_pages; | 223 | work->mm->locked_vm -= work->num_pages; |
@@ -242,7 +243,7 @@ void ipath_release_user_pages_on_close(struct page **p, size_t num_pages) | |||
242 | 243 | ||
243 | goto bail; | 244 | goto bail; |
244 | 245 | ||
245 | INIT_WORK(&work->work, user_pages_account, work); | 246 | INIT_WORK(&work->work, user_pages_account); |
246 | work->mm = mm; | 247 | work->mm = mm; |
247 | work->num_pages = num_pages; | 248 | work->num_pages = num_pages; |
248 | 249 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c index cd044ea2dfa4..e948158a28d9 100644 --- a/drivers/infiniband/hw/mthca/mthca_catas.c +++ b/drivers/infiniband/hw/mthca/mthca_catas.c | |||
@@ -57,7 +57,7 @@ static int catas_reset_disable; | |||
57 | module_param_named(catas_reset_disable, catas_reset_disable, int, 0644); | 57 | module_param_named(catas_reset_disable, catas_reset_disable, int, 0644); |
58 | MODULE_PARM_DESC(catas_reset_disable, "disable reset on catastrophic event if nonzero"); | 58 | MODULE_PARM_DESC(catas_reset_disable, "disable reset on catastrophic event if nonzero"); |
59 | 59 | ||
60 | static void catas_reset(void *work_ptr) | 60 | static void catas_reset(struct work_struct *work) |
61 | { | 61 | { |
62 | struct mthca_dev *dev, *tmpdev; | 62 | struct mthca_dev *dev, *tmpdev; |
63 | LIST_HEAD(tlist); | 63 | LIST_HEAD(tlist); |
@@ -203,7 +203,7 @@ void mthca_stop_catas_poll(struct mthca_dev *dev) | |||
203 | 203 | ||
204 | int __init mthca_catas_init(void) | 204 | int __init mthca_catas_init(void) |
205 | { | 205 | { |
206 | INIT_WORK(&catas_work, catas_reset, NULL); | 206 | INIT_WORK(&catas_work, catas_reset); |
207 | 207 | ||
208 | catas_wq = create_singlethread_workqueue("mthca_catas"); | 208 | catas_wq = create_singlethread_workqueue("mthca_catas"); |
209 | if (!catas_wq) | 209 | if (!catas_wq) |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index f2b61851a49c..99547996aba2 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -136,11 +136,11 @@ struct ipoib_dev_priv { | |||
136 | struct list_head multicast_list; | 136 | struct list_head multicast_list; |
137 | struct rb_root multicast_tree; | 137 | struct rb_root multicast_tree; |
138 | 138 | ||
139 | struct work_struct pkey_task; | 139 | struct delayed_work pkey_task; |
140 | struct work_struct mcast_task; | 140 | struct delayed_work mcast_task; |
141 | struct work_struct flush_task; | 141 | struct work_struct flush_task; |
142 | struct work_struct restart_task; | 142 | struct work_struct restart_task; |
143 | struct work_struct ah_reap_task; | 143 | struct delayed_work ah_reap_task; |
144 | 144 | ||
145 | struct ib_device *ca; | 145 | struct ib_device *ca; |
146 | u8 port; | 146 | u8 port; |
@@ -254,13 +254,13 @@ int ipoib_add_pkey_attr(struct net_device *dev); | |||
254 | 254 | ||
255 | void ipoib_send(struct net_device *dev, struct sk_buff *skb, | 255 | void ipoib_send(struct net_device *dev, struct sk_buff *skb, |
256 | struct ipoib_ah *address, u32 qpn); | 256 | struct ipoib_ah *address, u32 qpn); |
257 | void ipoib_reap_ah(void *dev_ptr); | 257 | void ipoib_reap_ah(struct work_struct *work); |
258 | 258 | ||
259 | void ipoib_flush_paths(struct net_device *dev); | 259 | void ipoib_flush_paths(struct net_device *dev); |
260 | struct ipoib_dev_priv *ipoib_intf_alloc(const char *format); | 260 | struct ipoib_dev_priv *ipoib_intf_alloc(const char *format); |
261 | 261 | ||
262 | int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port); | 262 | int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port); |
263 | void ipoib_ib_dev_flush(void *dev); | 263 | void ipoib_ib_dev_flush(struct work_struct *work); |
264 | void ipoib_ib_dev_cleanup(struct net_device *dev); | 264 | void ipoib_ib_dev_cleanup(struct net_device *dev); |
265 | 265 | ||
266 | int ipoib_ib_dev_open(struct net_device *dev); | 266 | int ipoib_ib_dev_open(struct net_device *dev); |
@@ -271,10 +271,10 @@ int ipoib_ib_dev_stop(struct net_device *dev); | |||
271 | int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); | 271 | int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); |
272 | void ipoib_dev_cleanup(struct net_device *dev); | 272 | void ipoib_dev_cleanup(struct net_device *dev); |
273 | 273 | ||
274 | void ipoib_mcast_join_task(void *dev_ptr); | 274 | void ipoib_mcast_join_task(struct work_struct *work); |
275 | void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb); | 275 | void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb); |
276 | 276 | ||
277 | void ipoib_mcast_restart_task(void *dev_ptr); | 277 | void ipoib_mcast_restart_task(struct work_struct *work); |
278 | int ipoib_mcast_start_thread(struct net_device *dev); | 278 | int ipoib_mcast_start_thread(struct net_device *dev); |
279 | int ipoib_mcast_stop_thread(struct net_device *dev, int flush); | 279 | int ipoib_mcast_stop_thread(struct net_device *dev, int flush); |
280 | 280 | ||
@@ -312,7 +312,7 @@ void ipoib_event(struct ib_event_handler *handler, | |||
312 | int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey); | 312 | int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey); |
313 | int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey); | 313 | int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey); |
314 | 314 | ||
315 | void ipoib_pkey_poll(void *dev); | 315 | void ipoib_pkey_poll(struct work_struct *work); |
316 | int ipoib_pkey_dev_delay_open(struct net_device *dev); | 316 | int ipoib_pkey_dev_delay_open(struct net_device *dev); |
317 | 317 | ||
318 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG | 318 | #ifdef CONFIG_INFINIBAND_IPOIB_DEBUG |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 8bf5e9ec7c95..f10fba5d3265 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c | |||
@@ -400,10 +400,11 @@ static void __ipoib_reap_ah(struct net_device *dev) | |||
400 | spin_unlock_irq(&priv->tx_lock); | 400 | spin_unlock_irq(&priv->tx_lock); |
401 | } | 401 | } |
402 | 402 | ||
403 | void ipoib_reap_ah(void *dev_ptr) | 403 | void ipoib_reap_ah(struct work_struct *work) |
404 | { | 404 | { |
405 | struct net_device *dev = dev_ptr; | 405 | struct ipoib_dev_priv *priv = |
406 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 406 | container_of(work, struct ipoib_dev_priv, ah_reap_task.work); |
407 | struct net_device *dev = priv->dev; | ||
407 | 408 | ||
408 | __ipoib_reap_ah(dev); | 409 | __ipoib_reap_ah(dev); |
409 | 410 | ||
@@ -613,10 +614,11 @@ int ipoib_ib_dev_init(struct net_device *dev, struct ib_device *ca, int port) | |||
613 | return 0; | 614 | return 0; |
614 | } | 615 | } |
615 | 616 | ||
616 | void ipoib_ib_dev_flush(void *_dev) | 617 | void ipoib_ib_dev_flush(struct work_struct *work) |
617 | { | 618 | { |
618 | struct net_device *dev = (struct net_device *)_dev; | 619 | struct ipoib_dev_priv *cpriv, *priv = |
619 | struct ipoib_dev_priv *priv = netdev_priv(dev), *cpriv; | 620 | container_of(work, struct ipoib_dev_priv, flush_task); |
621 | struct net_device *dev = priv->dev; | ||
620 | 622 | ||
621 | if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags) ) { | 623 | if (!test_bit(IPOIB_FLAG_INITIALIZED, &priv->flags) ) { |
622 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); | 624 | ipoib_dbg(priv, "Not flushing - IPOIB_FLAG_INITIALIZED not set.\n"); |
@@ -638,14 +640,14 @@ void ipoib_ib_dev_flush(void *_dev) | |||
638 | */ | 640 | */ |
639 | if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { | 641 | if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) { |
640 | ipoib_ib_dev_up(dev); | 642 | ipoib_ib_dev_up(dev); |
641 | ipoib_mcast_restart_task(dev); | 643 | ipoib_mcast_restart_task(&priv->restart_task); |
642 | } | 644 | } |
643 | 645 | ||
644 | mutex_lock(&priv->vlan_mutex); | 646 | mutex_lock(&priv->vlan_mutex); |
645 | 647 | ||
646 | /* Flush any child interfaces too */ | 648 | /* Flush any child interfaces too */ |
647 | list_for_each_entry(cpriv, &priv->child_intfs, list) | 649 | list_for_each_entry(cpriv, &priv->child_intfs, list) |
648 | ipoib_ib_dev_flush(cpriv->dev); | 650 | ipoib_ib_dev_flush(&cpriv->flush_task); |
649 | 651 | ||
650 | mutex_unlock(&priv->vlan_mutex); | 652 | mutex_unlock(&priv->vlan_mutex); |
651 | } | 653 | } |
@@ -672,10 +674,11 @@ void ipoib_ib_dev_cleanup(struct net_device *dev) | |||
672 | * change async notification is available. | 674 | * change async notification is available. |
673 | */ | 675 | */ |
674 | 676 | ||
675 | void ipoib_pkey_poll(void *dev_ptr) | 677 | void ipoib_pkey_poll(struct work_struct *work) |
676 | { | 678 | { |
677 | struct net_device *dev = dev_ptr; | 679 | struct ipoib_dev_priv *priv = |
678 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 680 | container_of(work, struct ipoib_dev_priv, pkey_task.work); |
681 | struct net_device *dev = priv->dev; | ||
679 | 682 | ||
680 | ipoib_pkey_dev_check_presence(dev); | 683 | ipoib_pkey_dev_check_presence(dev); |
681 | 684 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 5ba3154320b4..c09280243726 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -940,11 +940,11 @@ static void ipoib_setup(struct net_device *dev) | |||
940 | INIT_LIST_HEAD(&priv->dead_ahs); | 940 | INIT_LIST_HEAD(&priv->dead_ahs); |
941 | INIT_LIST_HEAD(&priv->multicast_list); | 941 | INIT_LIST_HEAD(&priv->multicast_list); |
942 | 942 | ||
943 | INIT_WORK(&priv->pkey_task, ipoib_pkey_poll, priv->dev); | 943 | INIT_DELAYED_WORK(&priv->pkey_task, ipoib_pkey_poll); |
944 | INIT_WORK(&priv->mcast_task, ipoib_mcast_join_task, priv->dev); | 944 | INIT_DELAYED_WORK(&priv->mcast_task, ipoib_mcast_join_task); |
945 | INIT_WORK(&priv->flush_task, ipoib_ib_dev_flush, priv->dev); | 945 | INIT_WORK(&priv->flush_task, ipoib_ib_dev_flush); |
946 | INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task, priv->dev); | 946 | INIT_WORK(&priv->restart_task, ipoib_mcast_restart_task); |
947 | INIT_WORK(&priv->ah_reap_task, ipoib_reap_ah, priv->dev); | 947 | INIT_DELAYED_WORK(&priv->ah_reap_task, ipoib_reap_ah); |
948 | } | 948 | } |
949 | 949 | ||
950 | struct ipoib_dev_priv *ipoib_intf_alloc(const char *name) | 950 | struct ipoib_dev_priv *ipoib_intf_alloc(const char *name) |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index d282d65e3ee0..b04b72ca32ed 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -399,7 +399,8 @@ static void ipoib_mcast_join_complete(int status, | |||
399 | mcast->backoff = 1; | 399 | mcast->backoff = 1; |
400 | mutex_lock(&mcast_mutex); | 400 | mutex_lock(&mcast_mutex); |
401 | if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) | 401 | if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) |
402 | queue_work(ipoib_workqueue, &priv->mcast_task); | 402 | queue_delayed_work(ipoib_workqueue, |
403 | &priv->mcast_task, 0); | ||
403 | mutex_unlock(&mcast_mutex); | 404 | mutex_unlock(&mcast_mutex); |
404 | complete(&mcast->done); | 405 | complete(&mcast->done); |
405 | return; | 406 | return; |
@@ -435,7 +436,8 @@ static void ipoib_mcast_join_complete(int status, | |||
435 | 436 | ||
436 | if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) { | 437 | if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) { |
437 | if (status == -ETIMEDOUT) | 438 | if (status == -ETIMEDOUT) |
438 | queue_work(ipoib_workqueue, &priv->mcast_task); | 439 | queue_delayed_work(ipoib_workqueue, &priv->mcast_task, |
440 | 0); | ||
439 | else | 441 | else |
440 | queue_delayed_work(ipoib_workqueue, &priv->mcast_task, | 442 | queue_delayed_work(ipoib_workqueue, &priv->mcast_task, |
441 | mcast->backoff * HZ); | 443 | mcast->backoff * HZ); |
@@ -517,10 +519,11 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast, | |||
517 | mcast->query_id = ret; | 519 | mcast->query_id = ret; |
518 | } | 520 | } |
519 | 521 | ||
520 | void ipoib_mcast_join_task(void *dev_ptr) | 522 | void ipoib_mcast_join_task(struct work_struct *work) |
521 | { | 523 | { |
522 | struct net_device *dev = dev_ptr; | 524 | struct ipoib_dev_priv *priv = |
523 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 525 | container_of(work, struct ipoib_dev_priv, mcast_task.work); |
526 | struct net_device *dev = priv->dev; | ||
524 | 527 | ||
525 | if (!test_bit(IPOIB_MCAST_RUN, &priv->flags)) | 528 | if (!test_bit(IPOIB_MCAST_RUN, &priv->flags)) |
526 | return; | 529 | return; |
@@ -610,7 +613,7 @@ int ipoib_mcast_start_thread(struct net_device *dev) | |||
610 | 613 | ||
611 | mutex_lock(&mcast_mutex); | 614 | mutex_lock(&mcast_mutex); |
612 | if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags)) | 615 | if (!test_and_set_bit(IPOIB_MCAST_RUN, &priv->flags)) |
613 | queue_work(ipoib_workqueue, &priv->mcast_task); | 616 | queue_delayed_work(ipoib_workqueue, &priv->mcast_task, 0); |
614 | mutex_unlock(&mcast_mutex); | 617 | mutex_unlock(&mcast_mutex); |
615 | 618 | ||
616 | spin_lock_irq(&priv->lock); | 619 | spin_lock_irq(&priv->lock); |
@@ -818,10 +821,11 @@ void ipoib_mcast_dev_flush(struct net_device *dev) | |||
818 | } | 821 | } |
819 | } | 822 | } |
820 | 823 | ||
821 | void ipoib_mcast_restart_task(void *dev_ptr) | 824 | void ipoib_mcast_restart_task(struct work_struct *work) |
822 | { | 825 | { |
823 | struct net_device *dev = dev_ptr; | 826 | struct ipoib_dev_priv *priv = |
824 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 827 | container_of(work, struct ipoib_dev_priv, restart_task); |
828 | struct net_device *dev = priv->dev; | ||
825 | struct dev_mc_list *mclist; | 829 | struct dev_mc_list *mclist; |
826 | struct ipoib_mcast *mcast, *tmcast; | 830 | struct ipoib_mcast *mcast, *tmcast; |
827 | LIST_HEAD(remove_list); | 831 | LIST_HEAD(remove_list); |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 18a000034996..693b77002897 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | static void iser_cq_tasklet_fn(unsigned long data); | 49 | static void iser_cq_tasklet_fn(unsigned long data); |
50 | static void iser_cq_callback(struct ib_cq *cq, void *cq_context); | 50 | static void iser_cq_callback(struct ib_cq *cq, void *cq_context); |
51 | static void iser_comp_error_worker(void *data); | 51 | static void iser_comp_error_worker(struct work_struct *work); |
52 | 52 | ||
53 | static void iser_cq_event_callback(struct ib_event *cause, void *context) | 53 | static void iser_cq_event_callback(struct ib_event *cause, void *context) |
54 | { | 54 | { |
@@ -480,8 +480,7 @@ int iser_conn_init(struct iser_conn **ibconn) | |||
480 | init_waitqueue_head(&ib_conn->wait); | 480 | init_waitqueue_head(&ib_conn->wait); |
481 | atomic_set(&ib_conn->post_recv_buf_count, 0); | 481 | atomic_set(&ib_conn->post_recv_buf_count, 0); |
482 | atomic_set(&ib_conn->post_send_buf_count, 0); | 482 | atomic_set(&ib_conn->post_send_buf_count, 0); |
483 | INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker, | 483 | INIT_WORK(&ib_conn->comperror_work, iser_comp_error_worker); |
484 | ib_conn); | ||
485 | INIT_LIST_HEAD(&ib_conn->conn_list); | 484 | INIT_LIST_HEAD(&ib_conn->conn_list); |
486 | spin_lock_init(&ib_conn->lock); | 485 | spin_lock_init(&ib_conn->lock); |
487 | 486 | ||
@@ -754,9 +753,10 @@ int iser_post_send(struct iser_desc *tx_desc) | |||
754 | return ret_val; | 753 | return ret_val; |
755 | } | 754 | } |
756 | 755 | ||
757 | static void iser_comp_error_worker(void *data) | 756 | static void iser_comp_error_worker(struct work_struct *work) |
758 | { | 757 | { |
759 | struct iser_conn *ib_conn = data; | 758 | struct iser_conn *ib_conn = |
759 | container_of(work, struct iser_conn, comperror_work); | ||
760 | 760 | ||
761 | /* getting here when the state is UP means that the conn is being * | 761 | /* getting here when the state is UP means that the conn is being * |
762 | * terminated asynchronously from the iSCSI layer's perspective. */ | 762 | * terminated asynchronously from the iSCSI layer's perspective. */ |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 64ab5fc7cca3..a6289595557b 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -390,9 +390,10 @@ static void srp_disconnect_target(struct srp_target_port *target) | |||
390 | wait_for_completion(&target->done); | 390 | wait_for_completion(&target->done); |
391 | } | 391 | } |
392 | 392 | ||
393 | static void srp_remove_work(void *target_ptr) | 393 | static void srp_remove_work(struct work_struct *work) |
394 | { | 394 | { |
395 | struct srp_target_port *target = target_ptr; | 395 | struct srp_target_port *target = |
396 | container_of(work, struct srp_target_port, work); | ||
396 | 397 | ||
397 | spin_lock_irq(target->scsi_host->host_lock); | 398 | spin_lock_irq(target->scsi_host->host_lock); |
398 | if (target->state != SRP_TARGET_DEAD) { | 399 | if (target->state != SRP_TARGET_DEAD) { |
@@ -575,7 +576,7 @@ err: | |||
575 | spin_lock_irq(target->scsi_host->host_lock); | 576 | spin_lock_irq(target->scsi_host->host_lock); |
576 | if (target->state == SRP_TARGET_CONNECTING) { | 577 | if (target->state == SRP_TARGET_CONNECTING) { |
577 | target->state = SRP_TARGET_DEAD; | 578 | target->state = SRP_TARGET_DEAD; |
578 | INIT_WORK(&target->work, srp_remove_work, target); | 579 | INIT_WORK(&target->work, srp_remove_work); |
579 | schedule_work(&target->work); | 580 | schedule_work(&target->work); |
580 | } | 581 | } |
581 | spin_unlock_irq(target->scsi_host->host_lock); | 582 | spin_unlock_irq(target->scsi_host->host_lock); |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index cbb93669d1ce..8451b29a3db5 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -567,9 +567,9 @@ static int atkbd_set_leds(struct atkbd *atkbd) | |||
567 | * interrupt context. | 567 | * interrupt context. |
568 | */ | 568 | */ |
569 | 569 | ||
570 | static void atkbd_event_work(void *data) | 570 | static void atkbd_event_work(struct work_struct *work) |
571 | { | 571 | { |
572 | struct atkbd *atkbd = data; | 572 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work); |
573 | 573 | ||
574 | mutex_lock(&atkbd->event_mutex); | 574 | mutex_lock(&atkbd->event_mutex); |
575 | 575 | ||
@@ -943,7 +943,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
943 | 943 | ||
944 | atkbd->dev = dev; | 944 | atkbd->dev = dev; |
945 | ps2_init(&atkbd->ps2dev, serio); | 945 | ps2_init(&atkbd->ps2dev, serio); |
946 | INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd); | 946 | INIT_WORK(&atkbd->event_work, atkbd_event_work); |
947 | mutex_init(&atkbd->event_mutex); | 947 | mutex_init(&atkbd->event_mutex); |
948 | 948 | ||
949 | switch (serio->id.type) { | 949 | switch (serio->id.type) { |
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 979b93e33da7..b7f049b45b6b 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c | |||
@@ -572,9 +572,9 @@ lkkbd_event (struct input_dev *dev, unsigned int type, unsigned int code, | |||
572 | * were in. | 572 | * were in. |
573 | */ | 573 | */ |
574 | static void | 574 | static void |
575 | lkkbd_reinit (void *data) | 575 | lkkbd_reinit (struct work_struct *work) |
576 | { | 576 | { |
577 | struct lkkbd *lk = data; | 577 | struct lkkbd *lk = container_of(work, struct lkkbd, tq); |
578 | int division; | 578 | int division; |
579 | unsigned char leds_on = 0; | 579 | unsigned char leds_on = 0; |
580 | unsigned char leds_off = 0; | 580 | unsigned char leds_off = 0; |
@@ -651,7 +651,7 @@ lkkbd_connect (struct serio *serio, struct serio_driver *drv) | |||
651 | 651 | ||
652 | lk->serio = serio; | 652 | lk->serio = serio; |
653 | lk->dev = input_dev; | 653 | lk->dev = input_dev; |
654 | INIT_WORK (&lk->tq, lkkbd_reinit, lk); | 654 | INIT_WORK (&lk->tq, lkkbd_reinit); |
655 | lk->bell_volume = bell_volume; | 655 | lk->bell_volume = bell_volume; |
656 | lk->keyclick_volume = keyclick_volume; | 656 | lk->keyclick_volume = keyclick_volume; |
657 | lk->ctrlclick_volume = ctrlclick_volume; | 657 | lk->ctrlclick_volume = ctrlclick_volume; |
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index cac4781103c3..6cd887c5eb0a 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c | |||
@@ -208,9 +208,9 @@ static int sunkbd_initialize(struct sunkbd *sunkbd) | |||
208 | * were in. | 208 | * were in. |
209 | */ | 209 | */ |
210 | 210 | ||
211 | static void sunkbd_reinit(void *data) | 211 | static void sunkbd_reinit(struct work_struct *work) |
212 | { | 212 | { |
213 | struct sunkbd *sunkbd = data; | 213 | struct sunkbd *sunkbd = container_of(work, struct sunkbd, tq); |
214 | 214 | ||
215 | wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ); | 215 | wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ); |
216 | 216 | ||
@@ -248,7 +248,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
248 | sunkbd->serio = serio; | 248 | sunkbd->serio = serio; |
249 | sunkbd->dev = input_dev; | 249 | sunkbd->dev = input_dev; |
250 | init_waitqueue_head(&sunkbd->wait); | 250 | init_waitqueue_head(&sunkbd->wait); |
251 | INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd); | 251 | INIT_WORK(&sunkbd->tq, sunkbd_reinit); |
252 | snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys); | 252 | snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys); |
253 | 253 | ||
254 | serio_set_drvdata(serio, sunkbd); | 254 | serio_set_drvdata(serio, sunkbd); |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 6f9b2c7cc9c2..52bb2226ce2f 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -888,9 +888,10 @@ static int psmouse_poll(struct psmouse *psmouse) | |||
888 | * psmouse_resync() attempts to re-validate current protocol. | 888 | * psmouse_resync() attempts to re-validate current protocol. |
889 | */ | 889 | */ |
890 | 890 | ||
891 | static void psmouse_resync(void *p) | 891 | static void psmouse_resync(struct work_struct *work) |
892 | { | 892 | { |
893 | struct psmouse *psmouse = p, *parent = NULL; | 893 | struct psmouse *parent = NULL, *psmouse = |
894 | container_of(work, struct psmouse, resync_work); | ||
894 | struct serio *serio = psmouse->ps2dev.serio; | 895 | struct serio *serio = psmouse->ps2dev.serio; |
895 | psmouse_ret_t rc = PSMOUSE_GOOD_DATA; | 896 | psmouse_ret_t rc = PSMOUSE_GOOD_DATA; |
896 | int failed = 0, enabled = 0; | 897 | int failed = 0, enabled = 0; |
@@ -1121,7 +1122,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) | |||
1121 | goto out; | 1122 | goto out; |
1122 | 1123 | ||
1123 | ps2_init(&psmouse->ps2dev, serio); | 1124 | ps2_init(&psmouse->ps2dev, serio); |
1124 | INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse); | 1125 | INIT_WORK(&psmouse->resync_work, psmouse_resync); |
1125 | psmouse->dev = input_dev; | 1126 | psmouse->dev = input_dev; |
1126 | snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys); | 1127 | snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys); |
1127 | 1128 | ||
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c index e5b1b60757bb..b3e84d3bb7f7 100644 --- a/drivers/input/serio/libps2.c +++ b/drivers/input/serio/libps2.c | |||
@@ -251,9 +251,9 @@ EXPORT_SYMBOL(ps2_command); | |||
251 | * ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.) | 251 | * ps2_schedule_command(), to a PS/2 device (keyboard, mouse, etc.) |
252 | */ | 252 | */ |
253 | 253 | ||
254 | static void ps2_execute_scheduled_command(void *data) | 254 | static void ps2_execute_scheduled_command(struct work_struct *work) |
255 | { | 255 | { |
256 | struct ps2work *ps2work = data; | 256 | struct ps2work *ps2work = container_of(work, struct ps2work, work); |
257 | 257 | ||
258 | ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command); | 258 | ps2_command(ps2work->ps2dev, ps2work->param, ps2work->command); |
259 | kfree(ps2work); | 259 | kfree(ps2work); |
@@ -278,7 +278,7 @@ int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int comman | |||
278 | ps2work->ps2dev = ps2dev; | 278 | ps2work->ps2dev = ps2dev; |
279 | ps2work->command = command; | 279 | ps2work->command = command; |
280 | memcpy(ps2work->param, param, send); | 280 | memcpy(ps2work->param, param, send); |
281 | INIT_WORK(&ps2work->work, ps2_execute_scheduled_command, ps2work); | 281 | INIT_WORK(&ps2work->work, ps2_execute_scheduled_command); |
282 | 282 | ||
283 | if (!schedule_work(&ps2work->work)) { | 283 | if (!schedule_work(&ps2work->work)) { |
284 | kfree(ps2work); | 284 | kfree(ps2work); |
diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c index 6ae6eb322111..946c38cf6f8a 100644 --- a/drivers/isdn/act2000/capi.c +++ b/drivers/isdn/act2000/capi.c | |||
@@ -627,8 +627,10 @@ handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) { | |||
627 | } | 627 | } |
628 | 628 | ||
629 | void | 629 | void |
630 | actcapi_dispatch(act2000_card *card) | 630 | actcapi_dispatch(struct work_struct *work) |
631 | { | 631 | { |
632 | struct act2000_card *card = | ||
633 | container_of(work, struct act2000_card, rcv_tq); | ||
632 | struct sk_buff *skb; | 634 | struct sk_buff *skb; |
633 | actcapi_msg *msg; | 635 | actcapi_msg *msg; |
634 | __u16 ccmd; | 636 | __u16 ccmd; |
diff --git a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h index 49f453c53c64..e55f6a931f66 100644 --- a/drivers/isdn/act2000/capi.h +++ b/drivers/isdn/act2000/capi.h | |||
@@ -356,7 +356,7 @@ extern int actcapi_connect_req(act2000_card *, act2000_chan *, char *, char, int | |||
356 | extern void actcapi_select_b2_protocol_req(act2000_card *, act2000_chan *); | 356 | extern void actcapi_select_b2_protocol_req(act2000_card *, act2000_chan *); |
357 | extern void actcapi_disconnect_b3_req(act2000_card *, act2000_chan *); | 357 | extern void actcapi_disconnect_b3_req(act2000_card *, act2000_chan *); |
358 | extern void actcapi_connect_resp(act2000_card *, act2000_chan *, __u8); | 358 | extern void actcapi_connect_resp(act2000_card *, act2000_chan *, __u8); |
359 | extern void actcapi_dispatch(act2000_card *); | 359 | extern void actcapi_dispatch(struct work_struct *); |
360 | #ifdef DEBUG_MSG | 360 | #ifdef DEBUG_MSG |
361 | extern void actcapi_debug_msg(struct sk_buff *skb, int); | 361 | extern void actcapi_debug_msg(struct sk_buff *skb, int); |
362 | #else | 362 | #else |
diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c index d89dcde4eade..90593e2ef872 100644 --- a/drivers/isdn/act2000/module.c +++ b/drivers/isdn/act2000/module.c | |||
@@ -192,8 +192,11 @@ act2000_set_msn(act2000_card *card, char *eazmsn) | |||
192 | } | 192 | } |
193 | 193 | ||
194 | static void | 194 | static void |
195 | act2000_transmit(struct act2000_card *card) | 195 | act2000_transmit(struct work_struct *work) |
196 | { | 196 | { |
197 | struct act2000_card *card = | ||
198 | container_of(work, struct act2000_card, snd_tq); | ||
199 | |||
197 | switch (card->bus) { | 200 | switch (card->bus) { |
198 | case ACT2000_BUS_ISA: | 201 | case ACT2000_BUS_ISA: |
199 | act2000_isa_send(card); | 202 | act2000_isa_send(card); |
@@ -207,8 +210,11 @@ act2000_transmit(struct act2000_card *card) | |||
207 | } | 210 | } |
208 | 211 | ||
209 | static void | 212 | static void |
210 | act2000_receive(struct act2000_card *card) | 213 | act2000_receive(struct work_struct *work) |
211 | { | 214 | { |
215 | struct act2000_card *card = | ||
216 | container_of(work, struct act2000_card, poll_tq); | ||
217 | |||
212 | switch (card->bus) { | 218 | switch (card->bus) { |
213 | case ACT2000_BUS_ISA: | 219 | case ACT2000_BUS_ISA: |
214 | act2000_isa_receive(card); | 220 | act2000_isa_receive(card); |
@@ -227,7 +233,7 @@ act2000_poll(unsigned long data) | |||
227 | act2000_card * card = (act2000_card *)data; | 233 | act2000_card * card = (act2000_card *)data; |
228 | unsigned long flags; | 234 | unsigned long flags; |
229 | 235 | ||
230 | act2000_receive(card); | 236 | act2000_receive(&card->poll_tq); |
231 | spin_lock_irqsave(&card->lock, flags); | 237 | spin_lock_irqsave(&card->lock, flags); |
232 | mod_timer(&card->ptimer, jiffies+3); | 238 | mod_timer(&card->ptimer, jiffies+3); |
233 | spin_unlock_irqrestore(&card->lock, flags); | 239 | spin_unlock_irqrestore(&card->lock, flags); |
@@ -578,9 +584,9 @@ act2000_alloccard(int bus, int port, int irq, char *id) | |||
578 | skb_queue_head_init(&card->sndq); | 584 | skb_queue_head_init(&card->sndq); |
579 | skb_queue_head_init(&card->rcvq); | 585 | skb_queue_head_init(&card->rcvq); |
580 | skb_queue_head_init(&card->ackq); | 586 | skb_queue_head_init(&card->ackq); |
581 | INIT_WORK(&card->snd_tq, (void *) (void *) act2000_transmit, card); | 587 | INIT_WORK(&card->snd_tq, act2000_transmit); |
582 | INIT_WORK(&card->rcv_tq, (void *) (void *) actcapi_dispatch, card); | 588 | INIT_WORK(&card->rcv_tq, actcapi_dispatch); |
583 | INIT_WORK(&card->poll_tq, (void *) (void *) act2000_receive, card); | 589 | INIT_WORK(&card->poll_tq, act2000_receive); |
584 | init_timer(&card->ptimer); | 590 | init_timer(&card->ptimer); |
585 | card->interface.owner = THIS_MODULE; | 591 | card->interface.owner = THIS_MODULE; |
586 | card->interface.channels = ACT2000_BCH; | 592 | card->interface.channels = ACT2000_BCH; |
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index 8c4fcb9027b3..783a25526315 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c | |||
@@ -208,9 +208,10 @@ static void notify_down(u32 contr) | |||
208 | } | 208 | } |
209 | } | 209 | } |
210 | 210 | ||
211 | static void notify_handler(void *data) | 211 | static void notify_handler(struct work_struct *work) |
212 | { | 212 | { |
213 | struct capi_notifier *np = data; | 213 | struct capi_notifier *np = |
214 | container_of(work, struct capi_notifier, work); | ||
214 | 215 | ||
215 | switch (np->cmd) { | 216 | switch (np->cmd) { |
216 | case KCI_CONTRUP: | 217 | case KCI_CONTRUP: |
@@ -235,7 +236,7 @@ static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci) | |||
235 | if (!np) | 236 | if (!np) |
236 | return -ENOMEM; | 237 | return -ENOMEM; |
237 | 238 | ||
238 | INIT_WORK(&np->work, notify_handler, np); | 239 | INIT_WORK(&np->work, notify_handler); |
239 | np->cmd = cmd; | 240 | np->cmd = cmd; |
240 | np->controller = controller; | 241 | np->controller = controller; |
241 | np->applid = applid; | 242 | np->applid = applid; |
@@ -248,10 +249,11 @@ static int notify_push(unsigned int cmd, u32 controller, u16 applid, u32 ncci) | |||
248 | 249 | ||
249 | /* -------- Receiver ------------------------------------------ */ | 250 | /* -------- Receiver ------------------------------------------ */ |
250 | 251 | ||
251 | static void recv_handler(void *_ap) | 252 | static void recv_handler(struct work_struct *work) |
252 | { | 253 | { |
253 | struct sk_buff *skb; | 254 | struct sk_buff *skb; |
254 | struct capi20_appl *ap = (struct capi20_appl *) _ap; | 255 | struct capi20_appl *ap = |
256 | container_of(work, struct capi20_appl, recv_work); | ||
255 | 257 | ||
256 | if ((!ap) || (ap->release_in_progress)) | 258 | if ((!ap) || (ap->release_in_progress)) |
257 | return; | 259 | return; |
@@ -527,7 +529,7 @@ u16 capi20_register(struct capi20_appl *ap) | |||
527 | ap->callback = NULL; | 529 | ap->callback = NULL; |
528 | init_MUTEX(&ap->recv_sem); | 530 | init_MUTEX(&ap->recv_sem); |
529 | skb_queue_head_init(&ap->recv_queue); | 531 | skb_queue_head_init(&ap->recv_queue); |
530 | INIT_WORK(&ap->recv_work, recv_handler, (void *)ap); | 532 | INIT_WORK(&ap->recv_work, recv_handler); |
531 | ap->release_in_progress = 0; | 533 | ap->release_in_progress = 0; |
532 | 534 | ||
533 | write_unlock_irqrestore(&application_lock, flags); | 535 | write_unlock_irqrestore(&application_lock, flags); |
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 7bbfd85ab793..fd5d7364a487 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c | |||
@@ -194,41 +194,11 @@ static int avmcs_config(struct pcmcia_device *link) | |||
194 | 194 | ||
195 | dev = link->priv; | 195 | dev = link->priv; |
196 | 196 | ||
197 | /* | ||
198 | This reads the card's CONFIG tuple to find its configuration | ||
199 | registers. | ||
200 | */ | ||
201 | do { | 197 | do { |
202 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
203 | i = pcmcia_get_first_tuple(link, &tuple); | ||
204 | if (i != CS_SUCCESS) break; | ||
205 | tuple.TupleData = buf; | ||
206 | tuple.TupleDataMax = 64; | ||
207 | tuple.TupleOffset = 0; | ||
208 | i = pcmcia_get_tuple_data(link, &tuple); | ||
209 | if (i != CS_SUCCESS) break; | ||
210 | i = pcmcia_parse_tuple(link, &tuple, &parse); | ||
211 | if (i != CS_SUCCESS) break; | ||
212 | link->conf.ConfigBase = parse.config.base; | ||
213 | } while (0); | ||
214 | if (i != CS_SUCCESS) { | ||
215 | cs_error(link, ParseTuple, i); | ||
216 | return -ENODEV; | ||
217 | } | ||
218 | |||
219 | do { | ||
220 | |||
221 | tuple.Attributes = 0; | ||
222 | tuple.TupleData = buf; | ||
223 | tuple.TupleDataMax = 254; | ||
224 | tuple.TupleOffset = 0; | ||
225 | tuple.DesiredTuple = CISTPL_VERS_1; | ||
226 | |||
227 | devname[0] = 0; | 198 | devname[0] = 0; |
228 | if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) { | 199 | if (link->prod_id[1]) |
229 | strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], | 200 | strlcpy(devname, link->prod_id[1], sizeof(devname)); |
230 | sizeof(devname)); | 201 | |
231 | } | ||
232 | /* | 202 | /* |
233 | * find IO port | 203 | * find IO port |
234 | */ | 204 | */ |
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c index bec59010bc66..3b19caeba258 100644 --- a/drivers/isdn/hisax/amd7930_fn.c +++ b/drivers/isdn/hisax/amd7930_fn.c | |||
@@ -232,9 +232,10 @@ Amd7930_new_ph(struct IsdnCardState *cs) | |||
232 | 232 | ||
233 | 233 | ||
234 | static void | 234 | static void |
235 | Amd7930_bh(struct IsdnCardState *cs) | 235 | Amd7930_bh(struct work_struct *work) |
236 | { | 236 | { |
237 | 237 | struct IsdnCardState *cs = | |
238 | container_of(work, struct IsdnCardState, tqueue); | ||
238 | struct PStack *stptr; | 239 | struct PStack *stptr; |
239 | 240 | ||
240 | if (!cs) | 241 | if (!cs) |
@@ -789,7 +790,7 @@ Amd7930_init(struct IsdnCardState *cs) | |||
789 | void __devinit | 790 | void __devinit |
790 | setup_Amd7930(struct IsdnCardState *cs) | 791 | setup_Amd7930(struct IsdnCardState *cs) |
791 | { | 792 | { |
792 | INIT_WORK(&cs->tqueue, (void *)(void *) Amd7930_bh, cs); | 793 | INIT_WORK(&cs->tqueue, Amd7930_bh); |
793 | cs->dbusytimer.function = (void *) dbusy_timer_handler; | 794 | cs->dbusytimer.function = (void *) dbusy_timer_handler; |
794 | cs->dbusytimer.data = (long) cs; | 795 | cs->dbusytimer.data = (long) cs; |
795 | init_timer(&cs->dbusytimer); | 796 | init_timer(&cs->dbusytimer); |
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index ac28e3278ad9..876fec6c6be8 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c | |||
@@ -216,41 +216,11 @@ static int avma1cs_config(struct pcmcia_device *link) | |||
216 | 216 | ||
217 | DEBUG(0, "avma1cs_config(0x%p)\n", link); | 217 | DEBUG(0, "avma1cs_config(0x%p)\n", link); |
218 | 218 | ||
219 | /* | ||
220 | This reads the card's CONFIG tuple to find its configuration | ||
221 | registers. | ||
222 | */ | ||
223 | do { | 219 | do { |
224 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
225 | i = pcmcia_get_first_tuple(link, &tuple); | ||
226 | if (i != CS_SUCCESS) break; | ||
227 | tuple.TupleData = buf; | ||
228 | tuple.TupleDataMax = 64; | ||
229 | tuple.TupleOffset = 0; | ||
230 | i = pcmcia_get_tuple_data(link, &tuple); | ||
231 | if (i != CS_SUCCESS) break; | ||
232 | i = pcmcia_parse_tuple(link, &tuple, &parse); | ||
233 | if (i != CS_SUCCESS) break; | ||
234 | link->conf.ConfigBase = parse.config.base; | ||
235 | } while (0); | ||
236 | if (i != CS_SUCCESS) { | ||
237 | cs_error(link, ParseTuple, i); | ||
238 | return -ENODEV; | ||
239 | } | ||
240 | |||
241 | do { | ||
242 | |||
243 | tuple.Attributes = 0; | ||
244 | tuple.TupleData = buf; | ||
245 | tuple.TupleDataMax = 254; | ||
246 | tuple.TupleOffset = 0; | ||
247 | tuple.DesiredTuple = CISTPL_VERS_1; | ||
248 | |||
249 | devname[0] = 0; | 220 | devname[0] = 0; |
250 | if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) { | 221 | if (link->prod_id[1]) |
251 | strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], | 222 | strlcpy(devname, link->prod_id[1], sizeof(devname)); |
252 | sizeof(devname)); | 223 | |
253 | } | ||
254 | /* | 224 | /* |
255 | * find IO port | 225 | * find IO port |
256 | */ | 226 | */ |
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 785b08554fca..cede72cdbb31 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c | |||
@@ -1137,7 +1137,6 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow | |||
1137 | cs->tx_skb = NULL; | 1137 | cs->tx_skb = NULL; |
1138 | cs->tx_cnt = 0; | 1138 | cs->tx_cnt = 0; |
1139 | cs->event = 0; | 1139 | cs->event = 0; |
1140 | cs->tqueue.data = cs; | ||
1141 | 1140 | ||
1142 | skb_queue_head_init(&cs->rq); | 1141 | skb_queue_head_init(&cs->rq); |
1143 | skb_queue_head_init(&cs->sq); | 1142 | skb_queue_head_init(&cs->sq); |
@@ -1554,7 +1553,7 @@ static void hisax_b_l2l1(struct PStack *st, int pr, void *arg); | |||
1554 | static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg); | 1553 | static int hisax_cardmsg(struct IsdnCardState *cs, int mt, void *arg); |
1555 | static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs); | 1554 | static int hisax_bc_setstack(struct PStack *st, struct BCState *bcs); |
1556 | static void hisax_bc_close(struct BCState *bcs); | 1555 | static void hisax_bc_close(struct BCState *bcs); |
1557 | static void hisax_bh(struct IsdnCardState *cs); | 1556 | static void hisax_bh(struct work_struct *work); |
1558 | static void EChannel_proc_rcv(struct hisax_d_if *d_if); | 1557 | static void EChannel_proc_rcv(struct hisax_d_if *d_if); |
1559 | 1558 | ||
1560 | int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], | 1559 | int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], |
@@ -1586,7 +1585,7 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[], | |||
1586 | hisax_d_if->cs = cs; | 1585 | hisax_d_if->cs = cs; |
1587 | cs->hw.hisax_d_if = hisax_d_if; | 1586 | cs->hw.hisax_d_if = hisax_d_if; |
1588 | cs->cardmsg = hisax_cardmsg; | 1587 | cs->cardmsg = hisax_cardmsg; |
1589 | INIT_WORK(&cs->tqueue, (void *)(void *)hisax_bh, cs); | 1588 | INIT_WORK(&cs->tqueue, hisax_bh); |
1590 | cs->channel[0].d_st->l2.l2l1 = hisax_d_l2l1; | 1589 | cs->channel[0].d_st->l2.l2l1 = hisax_d_l2l1; |
1591 | for (i = 0; i < 2; i++) { | 1590 | for (i = 0; i < 2; i++) { |
1592 | cs->bcs[i].BC_SetStack = hisax_bc_setstack; | 1591 | cs->bcs[i].BC_SetStack = hisax_bc_setstack; |
@@ -1618,8 +1617,10 @@ static void hisax_sched_event(struct IsdnCardState *cs, int event) | |||
1618 | schedule_work(&cs->tqueue); | 1617 | schedule_work(&cs->tqueue); |
1619 | } | 1618 | } |
1620 | 1619 | ||
1621 | static void hisax_bh(struct IsdnCardState *cs) | 1620 | static void hisax_bh(struct work_struct *work) |
1622 | { | 1621 | { |
1622 | struct IsdnCardState *cs = | ||
1623 | container_of(work, struct IsdnCardState, tqueue); | ||
1623 | struct PStack *st; | 1624 | struct PStack *st; |
1624 | int pr; | 1625 | int pr; |
1625 | 1626 | ||
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index e18e75be8ed3..4e180d210faa 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c | |||
@@ -242,23 +242,6 @@ static int elsa_cs_config(struct pcmcia_device *link) | |||
242 | DEBUG(0, "elsa_config(0x%p)\n", link); | 242 | DEBUG(0, "elsa_config(0x%p)\n", link); |
243 | dev = link->priv; | 243 | dev = link->priv; |
244 | 244 | ||
245 | /* | ||
246 | This reads the card's CONFIG tuple to find its configuration | ||
247 | registers. | ||
248 | */ | ||
249 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
250 | tuple.TupleData = (cisdata_t *)buf; | ||
251 | tuple.TupleDataMax = 255; | ||
252 | tuple.TupleOffset = 0; | ||
253 | tuple.Attributes = 0; | ||
254 | i = first_tuple(link, &tuple, &parse); | ||
255 | if (i != CS_SUCCESS) { | ||
256 | last_fn = ParseTuple; | ||
257 | goto cs_failed; | ||
258 | } | ||
259 | link->conf.ConfigBase = parse.config.base; | ||
260 | link->conf.Present = parse.config.rmask[0]; | ||
261 | |||
262 | tuple.TupleData = (cisdata_t *)buf; | 245 | tuple.TupleData = (cisdata_t *)buf; |
263 | tuple.TupleOffset = 0; tuple.TupleDataMax = 255; | 246 | tuple.TupleOffset = 0; tuple.TupleDataMax = 255; |
264 | tuple.Attributes = 0; | 247 | tuple.Attributes = 0; |
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c index d852c9d998b2..de9b1a4d6bac 100644 --- a/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/drivers/isdn/hisax/hfc4s8s_l1.c | |||
@@ -1083,8 +1083,9 @@ tx_b_frame(struct hfc4s8s_btype *bch) | |||
1083 | /* bottom half handler for interrupt */ | 1083 | /* bottom half handler for interrupt */ |
1084 | /*************************************/ | 1084 | /*************************************/ |
1085 | static void | 1085 | static void |
1086 | hfc4s8s_bh(hfc4s8s_hw * hw) | 1086 | hfc4s8s_bh(struct work_struct *work) |
1087 | { | 1087 | { |
1088 | hfc4s8s_hw *hw = container_of(work, hfc4s8s_hw, tqueue); | ||
1088 | u_char b; | 1089 | u_char b; |
1089 | struct hfc4s8s_l1 *l1p; | 1090 | struct hfc4s8s_l1 *l1p; |
1090 | volatile u_char *fifo_stat; | 1091 | volatile u_char *fifo_stat; |
@@ -1550,7 +1551,7 @@ setup_instance(hfc4s8s_hw * hw) | |||
1550 | goto out; | 1551 | goto out; |
1551 | } | 1552 | } |
1552 | 1553 | ||
1553 | INIT_WORK(&hw->tqueue, (void *) (void *) hfc4s8s_bh, hw); | 1554 | INIT_WORK(&hw->tqueue, hfc4s8s_bh); |
1554 | 1555 | ||
1555 | if (request_irq | 1556 | if (request_irq |
1556 | (hw->irq, hfc4s8s_interrupt, IRQF_SHARED, hw->card_name, hw)) { | 1557 | (hw->irq, hfc4s8s_interrupt, IRQF_SHARED, hw->card_name, hw)) { |
diff --git a/drivers/isdn/hisax/hfc_2bds0.c b/drivers/isdn/hisax/hfc_2bds0.c index 6360e8214720..8d9864453a23 100644 --- a/drivers/isdn/hisax/hfc_2bds0.c +++ b/drivers/isdn/hisax/hfc_2bds0.c | |||
@@ -549,10 +549,11 @@ setstack_2b(struct PStack *st, struct BCState *bcs) | |||
549 | } | 549 | } |
550 | 550 | ||
551 | static void | 551 | static void |
552 | hfcd_bh(struct IsdnCardState *cs) | 552 | hfcd_bh(struct work_struct *work) |
553 | { | 553 | { |
554 | if (!cs) | 554 | struct IsdnCardState *cs = |
555 | return; | 555 | container_of(work, struct IsdnCardState, tqueue); |
556 | |||
556 | if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { | 557 | if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { |
557 | switch (cs->dc.hfcd.ph_state) { | 558 | switch (cs->dc.hfcd.ph_state) { |
558 | case (0): | 559 | case (0): |
@@ -1072,5 +1073,5 @@ set_cs_func(struct IsdnCardState *cs) | |||
1072 | cs->dbusytimer.function = (void *) hfc_dbusy_timer; | 1073 | cs->dbusytimer.function = (void *) hfc_dbusy_timer; |
1073 | cs->dbusytimer.data = (long) cs; | 1074 | cs->dbusytimer.data = (long) cs; |
1074 | init_timer(&cs->dbusytimer); | 1075 | init_timer(&cs->dbusytimer); |
1075 | INIT_WORK(&cs->tqueue, (void *)(void *) hfcd_bh, cs); | 1076 | INIT_WORK(&cs->tqueue, hfcd_bh); |
1076 | } | 1077 | } |
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 93f60b563515..5db0a85b827f 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c | |||
@@ -1506,8 +1506,10 @@ setstack_2b(struct PStack *st, struct BCState *bcs) | |||
1506 | /* handle L1 state changes */ | 1506 | /* handle L1 state changes */ |
1507 | /***************************/ | 1507 | /***************************/ |
1508 | static void | 1508 | static void |
1509 | hfcpci_bh(struct IsdnCardState *cs) | 1509 | hfcpci_bh(struct work_struct *work) |
1510 | { | 1510 | { |
1511 | struct IsdnCardState *cs = | ||
1512 | container_of(work, struct IsdnCardState, tqueue); | ||
1511 | u_long flags; | 1513 | u_long flags; |
1512 | // struct PStack *stptr; | 1514 | // struct PStack *stptr; |
1513 | 1515 | ||
@@ -1722,7 +1724,7 @@ setup_hfcpci(struct IsdnCard *card) | |||
1722 | Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); | 1724 | Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); |
1723 | /* At this point the needed PCI config is done */ | 1725 | /* At this point the needed PCI config is done */ |
1724 | /* fifos are still not enabled */ | 1726 | /* fifos are still not enabled */ |
1725 | INIT_WORK(&cs->tqueue, (void *)(void *) hfcpci_bh, cs); | 1727 | INIT_WORK(&cs->tqueue, hfcpci_bh); |
1726 | cs->setstack_d = setstack_hfcpci; | 1728 | cs->setstack_d = setstack_hfcpci; |
1727 | cs->BC_Send_Data = &hfcpci_send_data; | 1729 | cs->BC_Send_Data = &hfcpci_send_data; |
1728 | cs->readisac = NULL; | 1730 | cs->readisac = NULL; |
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index 954d1536db1f..4fd09d21a27f 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c | |||
@@ -1251,8 +1251,10 @@ setstack_2b(struct PStack *st, struct BCState *bcs) | |||
1251 | /* handle L1 state changes */ | 1251 | /* handle L1 state changes */ |
1252 | /***************************/ | 1252 | /***************************/ |
1253 | static void | 1253 | static void |
1254 | hfcsx_bh(struct IsdnCardState *cs) | 1254 | hfcsx_bh(struct work_struct *work) |
1255 | { | 1255 | { |
1256 | struct IsdnCardState *cs = | ||
1257 | container_of(work, struct IsdnCardState, tqueue); | ||
1256 | u_long flags; | 1258 | u_long flags; |
1257 | 1259 | ||
1258 | if (!cs) | 1260 | if (!cs) |
@@ -1499,7 +1501,7 @@ setup_hfcsx(struct IsdnCard *card) | |||
1499 | cs->dbusytimer.function = (void *) hfcsx_dbusy_timer; | 1501 | cs->dbusytimer.function = (void *) hfcsx_dbusy_timer; |
1500 | cs->dbusytimer.data = (long) cs; | 1502 | cs->dbusytimer.data = (long) cs; |
1501 | init_timer(&cs->dbusytimer); | 1503 | init_timer(&cs->dbusytimer); |
1502 | INIT_WORK(&cs->tqueue, (void *)(void *) hfcsx_bh, cs); | 1504 | INIT_WORK(&cs->tqueue, hfcsx_bh); |
1503 | cs->readisac = NULL; | 1505 | cs->readisac = NULL; |
1504 | cs->writeisac = NULL; | 1506 | cs->writeisac = NULL; |
1505 | cs->readisacfifo = NULL; | 1507 | cs->readisacfifo = NULL; |
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c index da706925d54d..682cac32f259 100644 --- a/drivers/isdn/hisax/icc.c +++ b/drivers/isdn/hisax/icc.c | |||
@@ -77,8 +77,10 @@ icc_new_ph(struct IsdnCardState *cs) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | static void | 79 | static void |
80 | icc_bh(struct IsdnCardState *cs) | 80 | icc_bh(struct work_struct *work) |
81 | { | 81 | { |
82 | struct IsdnCardState *cs = | ||
83 | container_of(work, struct IsdnCardState, tqueue); | ||
82 | struct PStack *stptr; | 84 | struct PStack *stptr; |
83 | 85 | ||
84 | if (!cs) | 86 | if (!cs) |
@@ -674,7 +676,7 @@ clear_pending_icc_ints(struct IsdnCardState *cs) | |||
674 | void __devinit | 676 | void __devinit |
675 | setup_icc(struct IsdnCardState *cs) | 677 | setup_icc(struct IsdnCardState *cs) |
676 | { | 678 | { |
677 | INIT_WORK(&cs->tqueue, (void *)(void *) icc_bh, cs); | 679 | INIT_WORK(&cs->tqueue, icc_bh); |
678 | cs->dbusytimer.function = (void *) dbusy_timer_handler; | 680 | cs->dbusytimer.function = (void *) dbusy_timer_handler; |
679 | cs->dbusytimer.data = (long) cs; | 681 | cs->dbusytimer.data = (long) cs; |
680 | init_timer(&cs->dbusytimer); | 682 | init_timer(&cs->dbusytimer); |
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c index 282f349408bc..4e9f23803dae 100644 --- a/drivers/isdn/hisax/isac.c +++ b/drivers/isdn/hisax/isac.c | |||
@@ -81,8 +81,10 @@ isac_new_ph(struct IsdnCardState *cs) | |||
81 | } | 81 | } |
82 | 82 | ||
83 | static void | 83 | static void |
84 | isac_bh(struct IsdnCardState *cs) | 84 | isac_bh(struct work_struct *work) |
85 | { | 85 | { |
86 | struct IsdnCardState *cs = | ||
87 | container_of(work, struct IsdnCardState, tqueue); | ||
86 | struct PStack *stptr; | 88 | struct PStack *stptr; |
87 | 89 | ||
88 | if (!cs) | 90 | if (!cs) |
@@ -674,7 +676,7 @@ clear_pending_isac_ints(struct IsdnCardState *cs) | |||
674 | void __devinit | 676 | void __devinit |
675 | setup_isac(struct IsdnCardState *cs) | 677 | setup_isac(struct IsdnCardState *cs) |
676 | { | 678 | { |
677 | INIT_WORK(&cs->tqueue, (void *)(void *) isac_bh, cs); | 679 | INIT_WORK(&cs->tqueue, isac_bh); |
678 | cs->dbusytimer.function = (void *) dbusy_timer_handler; | 680 | cs->dbusytimer.function = (void *) dbusy_timer_handler; |
679 | cs->dbusytimer.data = (long) cs; | 681 | cs->dbusytimer.data = (long) cs; |
680 | init_timer(&cs->dbusytimer); | 682 | init_timer(&cs->dbusytimer); |
diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 674af673ff96..6f1a6583b17d 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c | |||
@@ -437,8 +437,10 @@ extern void BChannel_bh(struct BCState *); | |||
437 | #define B_LL_OK 10 | 437 | #define B_LL_OK 10 |
438 | 438 | ||
439 | static void | 439 | static void |
440 | isar_bh(struct BCState *bcs) | 440 | isar_bh(struct work_struct *work) |
441 | { | 441 | { |
442 | struct BCState *bcs = container_of(work, struct BCState, tqueue); | ||
443 | |||
442 | BChannel_bh(bcs); | 444 | BChannel_bh(bcs); |
443 | if (test_and_clear_bit(B_LL_NOCARRIER, &bcs->event)) | 445 | if (test_and_clear_bit(B_LL_NOCARRIER, &bcs->event)) |
444 | ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_NOCARR); | 446 | ll_deliver_faxstat(bcs, ISDN_FAX_CLASS1_NOCARR); |
@@ -1580,7 +1582,7 @@ isar_setup(struct IsdnCardState *cs) | |||
1580 | cs->bcs[i].mode = 0; | 1582 | cs->bcs[i].mode = 0; |
1581 | cs->bcs[i].hw.isar.dpath = i + 1; | 1583 | cs->bcs[i].hw.isar.dpath = i + 1; |
1582 | modeisar(&cs->bcs[i], 0, 0); | 1584 | modeisar(&cs->bcs[i], 0, 0); |
1583 | INIT_WORK(&cs->bcs[i].tqueue, (void *)(void *) isar_bh, &cs->bcs[i]); | 1585 | INIT_WORK(&cs->bcs[i].tqueue, isar_bh); |
1584 | } | 1586 | } |
1585 | } | 1587 | } |
1586 | 1588 | ||
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c index bab356886483..a14204ec88ee 100644 --- a/drivers/isdn/hisax/isdnl1.c +++ b/drivers/isdn/hisax/isdnl1.c | |||
@@ -315,8 +315,10 @@ BChannel_proc_ack(struct BCState *bcs) | |||
315 | } | 315 | } |
316 | 316 | ||
317 | void | 317 | void |
318 | BChannel_bh(struct BCState *bcs) | 318 | BChannel_bh(struct work_struct *work) |
319 | { | 319 | { |
320 | struct BCState *bcs = container_of(work, struct BCState, tqueue); | ||
321 | |||
320 | if (!bcs) | 322 | if (!bcs) |
321 | return; | 323 | return; |
322 | if (test_and_clear_bit(B_RCVBUFREADY, &bcs->event)) | 324 | if (test_and_clear_bit(B_RCVBUFREADY, &bcs->event)) |
@@ -362,7 +364,7 @@ init_bcstate(struct IsdnCardState *cs, int bc) | |||
362 | 364 | ||
363 | bcs->cs = cs; | 365 | bcs->cs = cs; |
364 | bcs->channel = bc; | 366 | bcs->channel = bc; |
365 | INIT_WORK(&bcs->tqueue, (void *)(void *) BChannel_bh, bcs); | 367 | INIT_WORK(&bcs->tqueue, BChannel_bh); |
366 | spin_lock_init(&bcs->aclock); | 368 | spin_lock_init(&bcs->aclock); |
367 | bcs->BC_SetStack = NULL; | 369 | bcs->BC_SetStack = NULL; |
368 | bcs->BC_Close = NULL; | 370 | bcs->BC_Close = NULL; |
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index f9c14a2970bc..46ed65334c51 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c | |||
@@ -233,20 +233,10 @@ static int sedlbauer_config(struct pcmcia_device *link) | |||
233 | 233 | ||
234 | DEBUG(0, "sedlbauer_config(0x%p)\n", link); | 234 | DEBUG(0, "sedlbauer_config(0x%p)\n", link); |
235 | 235 | ||
236 | /* | ||
237 | This reads the card's CONFIG tuple to find its configuration | ||
238 | registers. | ||
239 | */ | ||
240 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
241 | tuple.Attributes = 0; | 236 | tuple.Attributes = 0; |
242 | tuple.TupleData = buf; | 237 | tuple.TupleData = buf; |
243 | tuple.TupleDataMax = sizeof(buf); | 238 | tuple.TupleDataMax = sizeof(buf); |
244 | tuple.TupleOffset = 0; | 239 | tuple.TupleOffset = 0; |
245 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
246 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
247 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
248 | link->conf.ConfigBase = parse.config.base; | ||
249 | link->conf.Present = parse.config.rmask[0]; | ||
250 | 240 | ||
251 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); | 241 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); |
252 | 242 | ||
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index afcc2aeadb34..6b754f183796 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c | |||
@@ -232,23 +232,6 @@ static int teles_cs_config(struct pcmcia_device *link) | |||
232 | DEBUG(0, "teles_config(0x%p)\n", link); | 232 | DEBUG(0, "teles_config(0x%p)\n", link); |
233 | dev = link->priv; | 233 | dev = link->priv; |
234 | 234 | ||
235 | /* | ||
236 | This reads the card's CONFIG tuple to find its configuration | ||
237 | registers. | ||
238 | */ | ||
239 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
240 | tuple.TupleData = (cisdata_t *)buf; | ||
241 | tuple.TupleDataMax = 255; | ||
242 | tuple.TupleOffset = 0; | ||
243 | tuple.Attributes = 0; | ||
244 | i = first_tuple(link, &tuple, &parse); | ||
245 | if (i != CS_SUCCESS) { | ||
246 | last_fn = ParseTuple; | ||
247 | goto cs_failed; | ||
248 | } | ||
249 | link->conf.ConfigBase = parse.config.base; | ||
250 | link->conf.Present = parse.config.rmask[0]; | ||
251 | |||
252 | tuple.TupleData = (cisdata_t *)buf; | 235 | tuple.TupleData = (cisdata_t *)buf; |
253 | tuple.TupleOffset = 0; tuple.TupleDataMax = 255; | 236 | tuple.TupleOffset = 0; tuple.TupleDataMax = 255; |
254 | tuple.Attributes = 0; | 237 | tuple.Attributes = 0; |
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c index 1655341797a9..3aeceaf9769e 100644 --- a/drivers/isdn/hisax/w6692.c +++ b/drivers/isdn/hisax/w6692.c | |||
@@ -101,8 +101,10 @@ W6692_new_ph(struct IsdnCardState *cs) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | static void | 103 | static void |
104 | W6692_bh(struct IsdnCardState *cs) | 104 | W6692_bh(struct work_struct *work) |
105 | { | 105 | { |
106 | struct IsdnCardState *cs = | ||
107 | container_of(work, struct IsdnCardState, tqueue); | ||
106 | struct PStack *stptr; | 108 | struct PStack *stptr; |
107 | 109 | ||
108 | if (!cs) | 110 | if (!cs) |
@@ -1070,7 +1072,7 @@ setup_w6692(struct IsdnCard *card) | |||
1070 | id_list[cs->subtyp].card_name, cs->irq, | 1072 | id_list[cs->subtyp].card_name, cs->irq, |
1071 | cs->hw.w6692.iobase); | 1073 | cs->hw.w6692.iobase); |
1072 | 1074 | ||
1073 | INIT_WORK(&cs->tqueue, (void *)(void *) W6692_bh, cs); | 1075 | INIT_WORK(&cs->tqueue, W6692_bh); |
1074 | cs->readW6692 = &ReadW6692; | 1076 | cs->readW6692 = &ReadW6692; |
1075 | cs->writeW6692 = &WriteW6692; | 1077 | cs->writeW6692 = &WriteW6692; |
1076 | cs->readisacfifo = &ReadISACfifo; | 1078 | cs->readisacfifo = &ReadISACfifo; |
diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c index 82e42a80dc4b..a1206498a1cf 100644 --- a/drivers/isdn/hysdn/boardergo.c +++ b/drivers/isdn/hysdn/boardergo.c | |||
@@ -71,8 +71,9 @@ ergo_interrupt(int intno, void *dev_id) | |||
71 | /* may be queued from everywhere (interrupts included). */ | 71 | /* may be queued from everywhere (interrupts included). */ |
72 | /******************************************************************************/ | 72 | /******************************************************************************/ |
73 | static void | 73 | static void |
74 | ergo_irq_bh(hysdn_card * card) | 74 | ergo_irq_bh(struct work_struct *ugli_api) |
75 | { | 75 | { |
76 | hysdn_card * card = container_of(ugli_api, hysdn_card, irq_queue); | ||
76 | tErgDpram *dpr; | 77 | tErgDpram *dpr; |
77 | int again; | 78 | int again; |
78 | unsigned long flags; | 79 | unsigned long flags; |
@@ -442,7 +443,7 @@ ergo_inithardware(hysdn_card * card) | |||
442 | card->writebootseq = ergo_writebootseq; | 443 | card->writebootseq = ergo_writebootseq; |
443 | card->waitpofready = ergo_waitpofready; | 444 | card->waitpofready = ergo_waitpofready; |
444 | card->set_errlog_state = ergo_set_errlog_state; | 445 | card->set_errlog_state = ergo_set_errlog_state; |
445 | INIT_WORK(&card->irq_queue, (void *) (void *) ergo_irq_bh, card); | 446 | INIT_WORK(&card->irq_queue, ergo_irq_bh); |
446 | card->hysdn_lock = SPIN_LOCK_UNLOCKED; | 447 | card->hysdn_lock = SPIN_LOCK_UNLOCKED; |
447 | 448 | ||
448 | return (0); | 449 | return (0); |
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 1f8d6ae66b41..2e4daebfb7e0 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c | |||
@@ -984,9 +984,9 @@ void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb) | |||
984 | /* | 984 | /* |
985 | * called from tq_immediate | 985 | * called from tq_immediate |
986 | */ | 986 | */ |
987 | static void isdn_net_softint(void *private) | 987 | static void isdn_net_softint(struct work_struct *work) |
988 | { | 988 | { |
989 | isdn_net_local *lp = private; | 989 | isdn_net_local *lp = container_of(work, isdn_net_local, tqueue); |
990 | struct sk_buff *skb; | 990 | struct sk_buff *skb; |
991 | 991 | ||
992 | spin_lock_bh(&lp->xmit_lock); | 992 | spin_lock_bh(&lp->xmit_lock); |
@@ -2596,7 +2596,7 @@ isdn_net_new(char *name, struct net_device *master) | |||
2596 | netdev->local->netdev = netdev; | 2596 | netdev->local->netdev = netdev; |
2597 | netdev->local->next = netdev->local; | 2597 | netdev->local->next = netdev->local; |
2598 | 2598 | ||
2599 | INIT_WORK(&netdev->local->tqueue, (void *)(void *) isdn_net_softint, netdev->local); | 2599 | INIT_WORK(&netdev->local->tqueue, isdn_net_softint); |
2600 | spin_lock_init(&netdev->local->xmit_lock); | 2600 | spin_lock_init(&netdev->local->xmit_lock); |
2601 | 2601 | ||
2602 | netdev->local->isdn_device = -1; | 2602 | netdev->local->isdn_device = -1; |
diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c index 6ead5e1508b7..1966f3410a13 100644 --- a/drivers/isdn/pcbit/drv.c +++ b/drivers/isdn/pcbit/drv.c | |||
@@ -68,8 +68,6 @@ static void pcbit_set_msn(struct pcbit_dev *dev, char *list); | |||
68 | static int pcbit_check_msn(struct pcbit_dev *dev, char *msn); | 68 | static int pcbit_check_msn(struct pcbit_dev *dev, char *msn); |
69 | 69 | ||
70 | 70 | ||
71 | extern void pcbit_deliver(void * data); | ||
72 | |||
73 | int pcbit_init_dev(int board, int mem_base, int irq) | 71 | int pcbit_init_dev(int board, int mem_base, int irq) |
74 | { | 72 | { |
75 | struct pcbit_dev *dev; | 73 | struct pcbit_dev *dev; |
@@ -129,7 +127,7 @@ int pcbit_init_dev(int board, int mem_base, int irq) | |||
129 | memset(dev->b2, 0, sizeof(struct pcbit_chan)); | 127 | memset(dev->b2, 0, sizeof(struct pcbit_chan)); |
130 | dev->b2->id = 1; | 128 | dev->b2->id = 1; |
131 | 129 | ||
132 | INIT_WORK(&dev->qdelivery, pcbit_deliver, dev); | 130 | INIT_WORK(&dev->qdelivery, pcbit_deliver); |
133 | 131 | ||
134 | /* | 132 | /* |
135 | * interrupts | 133 | * interrupts |
diff --git a/drivers/isdn/pcbit/layer2.c b/drivers/isdn/pcbit/layer2.c index 937fd2120381..0c9f6df873fc 100644 --- a/drivers/isdn/pcbit/layer2.c +++ b/drivers/isdn/pcbit/layer2.c | |||
@@ -67,7 +67,6 @@ extern void pcbit_l3_receive(struct pcbit_dev *dev, ulong msg, | |||
67 | * Prototypes | 67 | * Prototypes |
68 | */ | 68 | */ |
69 | 69 | ||
70 | void pcbit_deliver(void *data); | ||
71 | static void pcbit_transmit(struct pcbit_dev *dev); | 70 | static void pcbit_transmit(struct pcbit_dev *dev); |
72 | 71 | ||
73 | static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack); | 72 | static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack); |
@@ -299,11 +298,12 @@ pcbit_transmit(struct pcbit_dev *dev) | |||
299 | */ | 298 | */ |
300 | 299 | ||
301 | void | 300 | void |
302 | pcbit_deliver(void *data) | 301 | pcbit_deliver(struct work_struct *work) |
303 | { | 302 | { |
304 | struct frame_buf *frame; | 303 | struct frame_buf *frame; |
305 | unsigned long flags, msg; | 304 | unsigned long flags, msg; |
306 | struct pcbit_dev *dev = (struct pcbit_dev *) data; | 305 | struct pcbit_dev *dev = |
306 | container_of(work, struct pcbit_dev, qdelivery); | ||
307 | 307 | ||
308 | spin_lock_irqsave(&dev->lock, flags); | 308 | spin_lock_irqsave(&dev->lock, flags); |
309 | 309 | ||
diff --git a/drivers/isdn/pcbit/pcbit.h b/drivers/isdn/pcbit/pcbit.h index 388bacefd23a..19c18e88ff16 100644 --- a/drivers/isdn/pcbit/pcbit.h +++ b/drivers/isdn/pcbit/pcbit.h | |||
@@ -166,4 +166,6 @@ struct pcbit_ioctl { | |||
166 | #define L2_RUNNING 5 | 166 | #define L2_RUNNING 5 |
167 | #define L2_ERROR 6 | 167 | #define L2_ERROR 6 |
168 | 168 | ||
169 | extern void pcbit_deliver(struct work_struct *work); | ||
170 | |||
169 | #endif | 171 | #endif |
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 7f8477d3a661..92ccee85e2a2 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig | |||
@@ -228,4 +228,11 @@ config ANSLCD | |||
228 | tristate "Support for ANS LCD display" | 228 | tristate "Support for ANS LCD display" |
229 | depends on ADB_CUDA && PPC_PMAC | 229 | depends on ADB_CUDA && PPC_PMAC |
230 | 230 | ||
231 | config PMAC_RACKMETER | ||
232 | tristate "Support for Apple XServe front panel LEDs" | ||
233 | depends on PPC_PMAC | ||
234 | help | ||
235 | This driver procides some support to control the front panel | ||
236 | blue LEDs "vu-meter" of the XServer macs. | ||
237 | |||
231 | endmenu | 238 | endmenu |
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index b53d45f87b0b..2dfc3f4eaf42 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile | |||
@@ -42,3 +42,4 @@ obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \ | |||
42 | windfarm_smu_sensors.o \ | 42 | windfarm_smu_sensors.o \ |
43 | windfarm_max6690_sensor.o \ | 43 | windfarm_max6690_sensor.o \ |
44 | windfarm_lm75_sensor.o windfarm_pid.o | 44 | windfarm_lm75_sensor.o windfarm_pid.o |
45 | obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o | ||
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index be0bd34ff6f9..d43ea81d6df9 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c | |||
@@ -267,12 +267,12 @@ adb_probe_task(void *x) | |||
267 | } | 267 | } |
268 | 268 | ||
269 | static void | 269 | static void |
270 | __adb_probe_task(void *data) | 270 | __adb_probe_task(struct work_struct *bullshit) |
271 | { | 271 | { |
272 | adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL); | 272 | adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL); |
273 | } | 273 | } |
274 | 274 | ||
275 | static DECLARE_WORK(adb_reset_work, __adb_probe_task, NULL); | 275 | static DECLARE_WORK(adb_reset_work, __adb_probe_task); |
276 | 276 | ||
277 | int | 277 | int |
278 | adb_reset_bus(void) | 278 | adb_reset_bus(void) |
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c new file mode 100644 index 000000000000..5ed41fe84e57 --- /dev/null +++ b/drivers/macintosh/rack-meter.c | |||
@@ -0,0 +1,616 @@ | |||
1 | /* | ||
2 | * RackMac vu-meter driver | ||
3 | * | ||
4 | * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp. | ||
5 | * <benh@kernel.crashing.org> | ||
6 | * | ||
7 | * Released under the term of the GNU GPL v2. | ||
8 | * | ||
9 | * Support the CPU-meter LEDs of the Xserve G5 | ||
10 | * | ||
11 | * TODO: Implement PWM to do variable intensity and provide userland | ||
12 | * interface for fun. Also, the CPU-meter could be made nicer by being | ||
13 | * a bit less "immediate" but giving instead a more average load over | ||
14 | * time. Patches welcome :-) | ||
15 | * | ||
16 | */ | ||
17 | #undef DEBUG | ||
18 | |||
19 | #include <linux/types.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/device.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/dma-mapping.h> | ||
26 | #include <linux/kernel_stat.h> | ||
27 | |||
28 | #include <asm/io.h> | ||
29 | #include <asm/prom.h> | ||
30 | #include <asm/machdep.h> | ||
31 | #include <asm/pmac_feature.h> | ||
32 | #include <asm/dbdma.h> | ||
33 | #include <asm/dbdma.h> | ||
34 | #include <asm/macio.h> | ||
35 | #include <asm/keylargo.h> | ||
36 | |||
37 | /* Number of samples in a sample buffer */ | ||
38 | #define SAMPLE_COUNT 256 | ||
39 | |||
40 | /* CPU meter sampling rate in ms */ | ||
41 | #define CPU_SAMPLING_RATE 250 | ||
42 | |||
43 | struct rackmeter_dma { | ||
44 | struct dbdma_cmd cmd[4] ____cacheline_aligned; | ||
45 | u32 mark ____cacheline_aligned; | ||
46 | u32 buf1[SAMPLE_COUNT] ____cacheline_aligned; | ||
47 | u32 buf2[SAMPLE_COUNT] ____cacheline_aligned; | ||
48 | } ____cacheline_aligned; | ||
49 | |||
50 | struct rackmeter_cpu { | ||
51 | struct delayed_work sniffer; | ||
52 | struct rackmeter *rm; | ||
53 | cputime64_t prev_wall; | ||
54 | cputime64_t prev_idle; | ||
55 | int zero; | ||
56 | } ____cacheline_aligned; | ||
57 | |||
58 | struct rackmeter { | ||
59 | struct macio_dev *mdev; | ||
60 | unsigned int irq; | ||
61 | struct device_node *i2s; | ||
62 | u8 *ubuf; | ||
63 | struct dbdma_regs __iomem *dma_regs; | ||
64 | void __iomem *i2s_regs; | ||
65 | dma_addr_t dma_buf_p; | ||
66 | struct rackmeter_dma *dma_buf_v; | ||
67 | int stale_irq; | ||
68 | struct rackmeter_cpu cpu[2]; | ||
69 | int paused; | ||
70 | struct mutex sem; | ||
71 | }; | ||
72 | |||
73 | /* To be set as a tunable */ | ||
74 | static int rackmeter_ignore_nice; | ||
75 | |||
76 | /* This GPIO is whacked by the OS X driver when initializing */ | ||
77 | #define RACKMETER_MAGIC_GPIO 0x78 | ||
78 | |||
79 | /* This is copied from cpufreq_ondemand, maybe we should put it in | ||
80 | * a common header somewhere | ||
81 | */ | ||
82 | static inline cputime64_t get_cpu_idle_time(unsigned int cpu) | ||
83 | { | ||
84 | cputime64_t retval; | ||
85 | |||
86 | retval = cputime64_add(kstat_cpu(cpu).cpustat.idle, | ||
87 | kstat_cpu(cpu).cpustat.iowait); | ||
88 | |||
89 | if (rackmeter_ignore_nice) | ||
90 | retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice); | ||
91 | |||
92 | return retval; | ||
93 | } | ||
94 | |||
95 | static void rackmeter_setup_i2s(struct rackmeter *rm) | ||
96 | { | ||
97 | struct macio_chip *macio = rm->mdev->bus->chip; | ||
98 | |||
99 | /* First whack magic GPIO */ | ||
100 | pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, RACKMETER_MAGIC_GPIO, 5); | ||
101 | |||
102 | |||
103 | /* Call feature code to enable the sound channel and the proper | ||
104 | * clock sources | ||
105 | */ | ||
106 | pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, rm->i2s, 0, 1); | ||
107 | |||
108 | /* Power i2s and stop i2s clock. We whack MacIO FCRs directly for now. | ||
109 | * This is a bit racy, thus we should add new platform functions to | ||
110 | * handle that. snd-aoa needs that too | ||
111 | */ | ||
112 | MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE); | ||
113 | MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT); | ||
114 | (void)MACIO_IN32(KEYLARGO_FCR1); | ||
115 | udelay(10); | ||
116 | |||
117 | /* Then setup i2s. For now, we use the same magic value that | ||
118 | * the OS X driver seems to use. We might want to play around | ||
119 | * with the clock divisors later | ||
120 | */ | ||
121 | out_le32(rm->i2s_regs + 0x10, 0x01fa0000); | ||
122 | (void)in_le32(rm->i2s_regs + 0x10); | ||
123 | udelay(10); | ||
124 | |||
125 | /* Fully restart i2s*/ | ||
126 | MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE | | ||
127 | KL1_I2S0_CLK_ENABLE_BIT); | ||
128 | (void)MACIO_IN32(KEYLARGO_FCR1); | ||
129 | udelay(10); | ||
130 | } | ||
131 | |||
132 | static void rackmeter_set_default_pattern(struct rackmeter *rm) | ||
133 | { | ||
134 | int i; | ||
135 | |||
136 | for (i = 0; i < 16; i++) { | ||
137 | if (i < 8) | ||
138 | rm->ubuf[i] = (i & 1) * 255; | ||
139 | else | ||
140 | rm->ubuf[i] = ((~i) & 1) * 255; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | static void rackmeter_do_pause(struct rackmeter *rm, int pause) | ||
145 | { | ||
146 | struct rackmeter_dma *rdma = rm->dma_buf_v; | ||
147 | |||
148 | pr_debug("rackmeter: %s\n", pause ? "paused" : "started"); | ||
149 | |||
150 | rm->paused = pause; | ||
151 | if (pause) { | ||
152 | DBDMA_DO_STOP(rm->dma_regs); | ||
153 | return; | ||
154 | } | ||
155 | memset(rdma->buf1, 0, SAMPLE_COUNT & sizeof(u32)); | ||
156 | memset(rdma->buf2, 0, SAMPLE_COUNT & sizeof(u32)); | ||
157 | |||
158 | rm->dma_buf_v->mark = 0; | ||
159 | |||
160 | mb(); | ||
161 | out_le32(&rm->dma_regs->cmdptr_hi, 0); | ||
162 | out_le32(&rm->dma_regs->cmdptr, rm->dma_buf_p); | ||
163 | out_le32(&rm->dma_regs->control, (RUN << 16) | RUN); | ||
164 | } | ||
165 | |||
166 | static void rackmeter_setup_dbdma(struct rackmeter *rm) | ||
167 | { | ||
168 | struct rackmeter_dma *db = rm->dma_buf_v; | ||
169 | struct dbdma_cmd *cmd = db->cmd; | ||
170 | |||
171 | /* Make sure dbdma is reset */ | ||
172 | DBDMA_DO_RESET(rm->dma_regs); | ||
173 | |||
174 | pr_debug("rackmeter: mark offset=0x%lx\n", | ||
175 | offsetof(struct rackmeter_dma, mark)); | ||
176 | pr_debug("rackmeter: buf1 offset=0x%lx\n", | ||
177 | offsetof(struct rackmeter_dma, buf1)); | ||
178 | pr_debug("rackmeter: buf2 offset=0x%lx\n", | ||
179 | offsetof(struct rackmeter_dma, buf2)); | ||
180 | |||
181 | /* Prepare 4 dbdma commands for the 2 buffers */ | ||
182 | memset(cmd, 0, 4 * sizeof(struct dbdma_cmd)); | ||
183 | st_le16(&cmd->req_count, 4); | ||
184 | st_le16(&cmd->command, STORE_WORD | INTR_ALWAYS | KEY_SYSTEM); | ||
185 | st_le32(&cmd->phy_addr, rm->dma_buf_p + | ||
186 | offsetof(struct rackmeter_dma, mark)); | ||
187 | st_le32(&cmd->cmd_dep, 0x02000000); | ||
188 | cmd++; | ||
189 | |||
190 | st_le16(&cmd->req_count, SAMPLE_COUNT * 4); | ||
191 | st_le16(&cmd->command, OUTPUT_MORE); | ||
192 | st_le32(&cmd->phy_addr, rm->dma_buf_p + | ||
193 | offsetof(struct rackmeter_dma, buf1)); | ||
194 | cmd++; | ||
195 | |||
196 | st_le16(&cmd->req_count, 4); | ||
197 | st_le16(&cmd->command, STORE_WORD | INTR_ALWAYS | KEY_SYSTEM); | ||
198 | st_le32(&cmd->phy_addr, rm->dma_buf_p + | ||
199 | offsetof(struct rackmeter_dma, mark)); | ||
200 | st_le32(&cmd->cmd_dep, 0x01000000); | ||
201 | cmd++; | ||
202 | |||
203 | st_le16(&cmd->req_count, SAMPLE_COUNT * 4); | ||
204 | st_le16(&cmd->command, OUTPUT_MORE | BR_ALWAYS); | ||
205 | st_le32(&cmd->phy_addr, rm->dma_buf_p + | ||
206 | offsetof(struct rackmeter_dma, buf2)); | ||
207 | st_le32(&cmd->cmd_dep, rm->dma_buf_p); | ||
208 | |||
209 | rackmeter_do_pause(rm, 0); | ||
210 | } | ||
211 | |||
212 | static void rackmeter_do_timer(struct work_struct *work) | ||
213 | { | ||
214 | struct rackmeter_cpu *rcpu = | ||
215 | container_of(work, struct rackmeter_cpu, sniffer.work); | ||
216 | struct rackmeter *rm = rcpu->rm; | ||
217 | unsigned int cpu = smp_processor_id(); | ||
218 | cputime64_t cur_jiffies, total_idle_ticks; | ||
219 | unsigned int total_ticks, idle_ticks; | ||
220 | int i, offset, load, cumm, pause; | ||
221 | |||
222 | cur_jiffies = jiffies64_to_cputime64(get_jiffies_64()); | ||
223 | total_ticks = (unsigned int)cputime64_sub(cur_jiffies, | ||
224 | rcpu->prev_wall); | ||
225 | rcpu->prev_wall = cur_jiffies; | ||
226 | |||
227 | total_idle_ticks = get_cpu_idle_time(cpu); | ||
228 | idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks, | ||
229 | rcpu->prev_idle); | ||
230 | rcpu->prev_idle = total_idle_ticks; | ||
231 | |||
232 | /* We do a very dumb calculation to update the LEDs for now, | ||
233 | * we'll do better once we have actual PWM implemented | ||
234 | */ | ||
235 | load = (9 * (total_ticks - idle_ticks)) / total_ticks; | ||
236 | |||
237 | offset = cpu << 3; | ||
238 | cumm = 0; | ||
239 | for (i = 0; i < 8; i++) { | ||
240 | u8 ub = (load > i) ? 0xff : 0; | ||
241 | rm->ubuf[i + offset] = ub; | ||
242 | cumm |= ub; | ||
243 | } | ||
244 | rcpu->zero = (cumm == 0); | ||
245 | |||
246 | /* Now check if LEDs are all 0, we can stop DMA */ | ||
247 | pause = (rm->cpu[0].zero && rm->cpu[1].zero); | ||
248 | if (pause != rm->paused) { | ||
249 | mutex_lock(&rm->sem); | ||
250 | pause = (rm->cpu[0].zero && rm->cpu[1].zero); | ||
251 | rackmeter_do_pause(rm, pause); | ||
252 | mutex_unlock(&rm->sem); | ||
253 | } | ||
254 | schedule_delayed_work_on(cpu, &rcpu->sniffer, | ||
255 | msecs_to_jiffies(CPU_SAMPLING_RATE)); | ||
256 | } | ||
257 | |||
258 | static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm) | ||
259 | { | ||
260 | unsigned int cpu; | ||
261 | |||
262 | /* This driver works only with 1 or 2 CPUs numbered 0 and 1, | ||
263 | * but that's really all we have on Apple Xserve. It doesn't | ||
264 | * play very nice with CPU hotplug neither but we don't do that | ||
265 | * on those machines yet | ||
266 | */ | ||
267 | |||
268 | rm->cpu[0].rm = rm; | ||
269 | INIT_DELAYED_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer); | ||
270 | rm->cpu[1].rm = rm; | ||
271 | INIT_DELAYED_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer); | ||
272 | |||
273 | for_each_online_cpu(cpu) { | ||
274 | struct rackmeter_cpu *rcpu; | ||
275 | |||
276 | if (cpu > 1) | ||
277 | continue; | ||
278 | rcpu = &rm->cpu[cpu];; | ||
279 | rcpu->prev_idle = get_cpu_idle_time(cpu); | ||
280 | rcpu->prev_wall = jiffies64_to_cputime64(get_jiffies_64()); | ||
281 | schedule_delayed_work_on(cpu, &rm->cpu[cpu].sniffer, | ||
282 | msecs_to_jiffies(CPU_SAMPLING_RATE)); | ||
283 | } | ||
284 | } | ||
285 | |||
286 | static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm) | ||
287 | { | ||
288 | cancel_rearming_delayed_work(&rm->cpu[0].sniffer); | ||
289 | cancel_rearming_delayed_work(&rm->cpu[1].sniffer); | ||
290 | } | ||
291 | |||
292 | static int rackmeter_setup(struct rackmeter *rm) | ||
293 | { | ||
294 | pr_debug("rackmeter: setting up i2s..\n"); | ||
295 | rackmeter_setup_i2s(rm); | ||
296 | |||
297 | pr_debug("rackmeter: setting up default pattern..\n"); | ||
298 | rackmeter_set_default_pattern(rm); | ||
299 | |||
300 | pr_debug("rackmeter: setting up dbdma..\n"); | ||
301 | rackmeter_setup_dbdma(rm); | ||
302 | |||
303 | pr_debug("rackmeter: start CPU measurements..\n"); | ||
304 | rackmeter_init_cpu_sniffer(rm); | ||
305 | |||
306 | printk(KERN_INFO "RackMeter initialized\n"); | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | /* XXX FIXME: No PWM yet, this is 0/1 */ | ||
312 | static u32 rackmeter_calc_sample(struct rackmeter *rm, unsigned int index) | ||
313 | { | ||
314 | int led; | ||
315 | u32 sample = 0; | ||
316 | |||
317 | for (led = 0; led < 16; led++) { | ||
318 | sample >>= 1; | ||
319 | sample |= ((rm->ubuf[led] >= 0x80) << 15); | ||
320 | } | ||
321 | return (sample << 17) | (sample >> 15); | ||
322 | } | ||
323 | |||
324 | static irqreturn_t rackmeter_irq(int irq, void *arg) | ||
325 | { | ||
326 | struct rackmeter *rm = arg; | ||
327 | struct rackmeter_dma *db = rm->dma_buf_v; | ||
328 | unsigned int mark, i; | ||
329 | u32 *buf; | ||
330 | |||
331 | /* Flush PCI buffers with an MMIO read. Maybe we could actually | ||
332 | * check the status one day ... in case things go wrong, though | ||
333 | * this never happened to me | ||
334 | */ | ||
335 | (void)in_le32(&rm->dma_regs->status); | ||
336 | |||
337 | /* Make sure the CPU gets us in order */ | ||
338 | rmb(); | ||
339 | |||
340 | /* Read mark */ | ||
341 | mark = db->mark; | ||
342 | if (mark != 1 && mark != 2) { | ||
343 | printk(KERN_WARNING "rackmeter: Incorrect DMA mark 0x%08x\n", | ||
344 | mark); | ||
345 | /* We allow for 3 errors like that (stale DBDMA irqs) */ | ||
346 | if (++rm->stale_irq > 3) { | ||
347 | printk(KERN_ERR "rackmeter: Too many errors," | ||
348 | " stopping DMA\n"); | ||
349 | DBDMA_DO_RESET(rm->dma_regs); | ||
350 | } | ||
351 | return IRQ_HANDLED; | ||
352 | } | ||
353 | |||
354 | /* Next buffer we need to fill is mark value */ | ||
355 | buf = mark == 1 ? db->buf1 : db->buf2; | ||
356 | |||
357 | /* Fill it now. This routine converts the 8 bits depth sample array | ||
358 | * into the PWM bitmap for each LED. | ||
359 | */ | ||
360 | for (i = 0; i < SAMPLE_COUNT; i++) | ||
361 | buf[i] = rackmeter_calc_sample(rm, i); | ||
362 | |||
363 | |||
364 | return IRQ_HANDLED; | ||
365 | } | ||
366 | |||
367 | static int __devinit rackmeter_probe(struct macio_dev* mdev, | ||
368 | const struct of_device_id *match) | ||
369 | { | ||
370 | struct device_node *i2s = NULL, *np = NULL; | ||
371 | struct rackmeter *rm = NULL; | ||
372 | struct resource ri2s, rdma; | ||
373 | int rc = -ENODEV; | ||
374 | |||
375 | pr_debug("rackmeter_probe()\n"); | ||
376 | |||
377 | /* Get i2s-a node */ | ||
378 | while ((i2s = of_get_next_child(mdev->ofdev.node, i2s)) != NULL) | ||
379 | if (strcmp(i2s->name, "i2s-a") == 0) | ||
380 | break; | ||
381 | if (i2s == NULL) { | ||
382 | pr_debug(" i2s-a child not found\n"); | ||
383 | goto bail; | ||
384 | } | ||
385 | /* Get lightshow or virtual sound */ | ||
386 | while ((np = of_get_next_child(i2s, np)) != NULL) { | ||
387 | if (strcmp(np->name, "lightshow") == 0) | ||
388 | break; | ||
389 | if ((strcmp(np->name, "sound") == 0) && | ||
390 | get_property(np, "virtual", NULL) != NULL) | ||
391 | break; | ||
392 | } | ||
393 | if (np == NULL) { | ||
394 | pr_debug(" lightshow or sound+virtual child not found\n"); | ||
395 | goto bail; | ||
396 | } | ||
397 | |||
398 | /* Create and initialize our instance data */ | ||
399 | rm = kzalloc(sizeof(struct rackmeter), GFP_KERNEL); | ||
400 | if (rm == NULL) { | ||
401 | printk(KERN_ERR "rackmeter: failed to allocate memory !\n"); | ||
402 | rc = -ENOMEM; | ||
403 | goto bail_release; | ||
404 | } | ||
405 | rm->mdev = mdev; | ||
406 | rm->i2s = i2s; | ||
407 | mutex_init(&rm->sem); | ||
408 | dev_set_drvdata(&mdev->ofdev.dev, rm); | ||
409 | /* Check resources availability. We need at least resource 0 and 1 */ | ||
410 | #if 0 /* Use that when i2s-a is finally an mdev per-se */ | ||
411 | if (macio_resource_count(mdev) < 2 || macio_irq_count(mdev) < 2) { | ||
412 | printk(KERN_ERR | ||
413 | "rackmeter: found match but lacks resources: %s" | ||
414 | " (%d resources, %d interrupts)\n", | ||
415 | mdev->ofdev.node->full_name); | ||
416 | rc = -ENXIO; | ||
417 | goto bail_free; | ||
418 | } | ||
419 | if (macio_request_resources(mdev, "rackmeter")) { | ||
420 | printk(KERN_ERR | ||
421 | "rackmeter: failed to request resources: %s\n", | ||
422 | mdev->ofdev.node->full_name); | ||
423 | rc = -EBUSY; | ||
424 | goto bail_free; | ||
425 | } | ||
426 | rm->irq = macio_irq(mdev, 1); | ||
427 | #else | ||
428 | rm->irq = irq_of_parse_and_map(i2s, 1); | ||
429 | if (rm->irq == NO_IRQ || | ||
430 | of_address_to_resource(i2s, 0, &ri2s) || | ||
431 | of_address_to_resource(i2s, 1, &rdma)) { | ||
432 | printk(KERN_ERR | ||
433 | "rackmeter: found match but lacks resources: %s", | ||
434 | mdev->ofdev.node->full_name); | ||
435 | rc = -ENXIO; | ||
436 | goto bail_free; | ||
437 | } | ||
438 | #endif | ||
439 | |||
440 | pr_debug(" i2s @0x%08x\n", (unsigned int)ri2s.start); | ||
441 | pr_debug(" dma @0x%08x\n", (unsigned int)rdma.start); | ||
442 | pr_debug(" irq %d\n", rm->irq); | ||
443 | |||
444 | rm->ubuf = (u8 *)__get_free_page(GFP_KERNEL); | ||
445 | if (rm->ubuf == NULL) { | ||
446 | printk(KERN_ERR | ||
447 | "rackmeter: failed to allocate samples page !\n"); | ||
448 | rc = -ENOMEM; | ||
449 | goto bail_release; | ||
450 | } | ||
451 | |||
452 | rm->dma_buf_v = dma_alloc_coherent(&macio_get_pci_dev(mdev)->dev, | ||
453 | sizeof(struct rackmeter_dma), | ||
454 | &rm->dma_buf_p, GFP_KERNEL); | ||
455 | if (rm->dma_buf_v == NULL) { | ||
456 | printk(KERN_ERR | ||
457 | "rackmeter: failed to allocate dma buffer !\n"); | ||
458 | rc = -ENOMEM; | ||
459 | goto bail_free_samples; | ||
460 | } | ||
461 | #if 0 | ||
462 | rm->i2s_regs = ioremap(macio_resource_start(mdev, 0), 0x1000); | ||
463 | #else | ||
464 | rm->i2s_regs = ioremap(ri2s.start, 0x1000); | ||
465 | #endif | ||
466 | if (rm->i2s_regs == NULL) { | ||
467 | printk(KERN_ERR | ||
468 | "rackmeter: failed to map i2s registers !\n"); | ||
469 | rc = -ENXIO; | ||
470 | goto bail_free_dma; | ||
471 | } | ||
472 | #if 0 | ||
473 | rm->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x100); | ||
474 | #else | ||
475 | rm->dma_regs = ioremap(rdma.start, 0x100); | ||
476 | #endif | ||
477 | if (rm->dma_regs == NULL) { | ||
478 | printk(KERN_ERR | ||
479 | "rackmeter: failed to map dma registers !\n"); | ||
480 | rc = -ENXIO; | ||
481 | goto bail_unmap_i2s; | ||
482 | } | ||
483 | |||
484 | rc = rackmeter_setup(rm); | ||
485 | if (rc) { | ||
486 | printk(KERN_ERR | ||
487 | "rackmeter: failed to initialize !\n"); | ||
488 | rc = -ENXIO; | ||
489 | goto bail_unmap_dma; | ||
490 | } | ||
491 | |||
492 | rc = request_irq(rm->irq, rackmeter_irq, 0, "rackmeter", rm); | ||
493 | if (rc != 0) { | ||
494 | printk(KERN_ERR | ||
495 | "rackmeter: failed to request interrupt !\n"); | ||
496 | goto bail_stop_dma; | ||
497 | } | ||
498 | of_node_put(np); | ||
499 | return 0; | ||
500 | |||
501 | bail_stop_dma: | ||
502 | DBDMA_DO_RESET(rm->dma_regs); | ||
503 | bail_unmap_dma: | ||
504 | iounmap(rm->dma_regs); | ||
505 | bail_unmap_i2s: | ||
506 | iounmap(rm->i2s_regs); | ||
507 | bail_free_dma: | ||
508 | dma_free_coherent(&macio_get_pci_dev(mdev)->dev, | ||
509 | sizeof(struct rackmeter_dma), | ||
510 | rm->dma_buf_v, rm->dma_buf_p); | ||
511 | bail_free_samples: | ||
512 | free_page((unsigned long)rm->ubuf); | ||
513 | bail_release: | ||
514 | #if 0 | ||
515 | macio_release_resources(mdev); | ||
516 | #endif | ||
517 | bail_free: | ||
518 | kfree(rm); | ||
519 | bail: | ||
520 | of_node_put(i2s); | ||
521 | of_node_put(np); | ||
522 | dev_set_drvdata(&mdev->ofdev.dev, NULL); | ||
523 | return rc; | ||
524 | } | ||
525 | |||
526 | static int __devexit rackmeter_remove(struct macio_dev* mdev) | ||
527 | { | ||
528 | struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev); | ||
529 | |||
530 | /* Stop CPU sniffer timer & work queues */ | ||
531 | rackmeter_stop_cpu_sniffer(rm); | ||
532 | |||
533 | /* Clear reference to private data */ | ||
534 | dev_set_drvdata(&mdev->ofdev.dev, NULL); | ||
535 | |||
536 | /* Stop/reset dbdma */ | ||
537 | DBDMA_DO_RESET(rm->dma_regs); | ||
538 | |||
539 | /* Release the IRQ */ | ||
540 | free_irq(rm->irq, rm); | ||
541 | |||
542 | /* Unmap registers */ | ||
543 | iounmap(rm->dma_regs); | ||
544 | iounmap(rm->i2s_regs); | ||
545 | |||
546 | /* Free DMA */ | ||
547 | dma_free_coherent(&macio_get_pci_dev(mdev)->dev, | ||
548 | sizeof(struct rackmeter_dma), | ||
549 | rm->dma_buf_v, rm->dma_buf_p); | ||
550 | |||
551 | /* Free samples */ | ||
552 | free_page((unsigned long)rm->ubuf); | ||
553 | |||
554 | #if 0 | ||
555 | /* Release resources */ | ||
556 | macio_release_resources(mdev); | ||
557 | #endif | ||
558 | |||
559 | /* Get rid of me */ | ||
560 | kfree(rm); | ||
561 | |||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | static int rackmeter_shutdown(struct macio_dev* mdev) | ||
566 | { | ||
567 | struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev); | ||
568 | |||
569 | if (rm == NULL) | ||
570 | return -ENODEV; | ||
571 | |||
572 | /* Stop CPU sniffer timer & work queues */ | ||
573 | rackmeter_stop_cpu_sniffer(rm); | ||
574 | |||
575 | /* Stop/reset dbdma */ | ||
576 | DBDMA_DO_RESET(rm->dma_regs); | ||
577 | |||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | static struct of_device_id rackmeter_match[] = { | ||
582 | { .name = "i2s" }, | ||
583 | { } | ||
584 | }; | ||
585 | |||
586 | static struct macio_driver rackmeter_drv = { | ||
587 | .name = "rackmeter", | ||
588 | .owner = THIS_MODULE, | ||
589 | .match_table = rackmeter_match, | ||
590 | .probe = rackmeter_probe, | ||
591 | .remove = rackmeter_remove, | ||
592 | .shutdown = rackmeter_shutdown, | ||
593 | }; | ||
594 | |||
595 | |||
596 | static int __init rackmeter_init(void) | ||
597 | { | ||
598 | pr_debug("rackmeter_init()\n"); | ||
599 | |||
600 | return macio_register_driver(&rackmeter_drv); | ||
601 | } | ||
602 | |||
603 | static void __exit rackmeter_exit(void) | ||
604 | { | ||
605 | pr_debug("rackmeter_exit()\n"); | ||
606 | |||
607 | macio_unregister_driver(&rackmeter_drv); | ||
608 | } | ||
609 | |||
610 | module_init(rackmeter_init); | ||
611 | module_exit(rackmeter_exit); | ||
612 | |||
613 | |||
614 | MODULE_LICENSE("GPL"); | ||
615 | MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); | ||
616 | MODULE_DESCRIPTION("RackMeter: Support vu-meter on XServe front panel"); | ||
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index ade25b3fbb35..6dde27ab79a8 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <asm/abs_addr.h> | 46 | #include <asm/abs_addr.h> |
47 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
48 | #include <asm/of_device.h> | 48 | #include <asm/of_device.h> |
49 | #include <asm/of_platform.h> | ||
49 | 50 | ||
50 | #define VERSION "0.7" | 51 | #define VERSION "0.7" |
51 | #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." | 52 | #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." |
@@ -600,7 +601,7 @@ core_initcall(smu_late_init); | |||
600 | * sysfs visibility | 601 | * sysfs visibility |
601 | */ | 602 | */ |
602 | 603 | ||
603 | static void smu_expose_childs(void *unused) | 604 | static void smu_expose_childs(struct work_struct *unused) |
604 | { | 605 | { |
605 | struct device_node *np; | 606 | struct device_node *np; |
606 | 607 | ||
@@ -610,7 +611,7 @@ static void smu_expose_childs(void *unused) | |||
610 | &smu->of_dev->dev); | 611 | &smu->of_dev->dev); |
611 | } | 612 | } |
612 | 613 | ||
613 | static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL); | 614 | static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs); |
614 | 615 | ||
615 | static int smu_platform_probe(struct of_device* dev, | 616 | static int smu_platform_probe(struct of_device* dev, |
616 | const struct of_device_id *match) | 617 | const struct of_device_id *match) |
@@ -653,7 +654,7 @@ static int __init smu_init_sysfs(void) | |||
653 | * I'm a bit too far from figuring out how that works with those | 654 | * I'm a bit too far from figuring out how that works with those |
654 | * new chipsets, but that will come back and bite us | 655 | * new chipsets, but that will come back and bite us |
655 | */ | 656 | */ |
656 | of_register_driver(&smu_of_platform_driver); | 657 | of_register_platform_driver(&smu_of_platform_driver); |
657 | return 0; | 658 | return 0; |
658 | } | 659 | } |
659 | 660 | ||
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index a0f30d0853ea..13b953ae8ebc 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | #include <asm/system.h> | 31 | #include <asm/system.h> |
32 | #include <asm/sections.h> | 32 | #include <asm/sections.h> |
33 | #include <asm/of_device.h> | 33 | #include <asm/of_platform.h> |
34 | 34 | ||
35 | #undef DEBUG | 35 | #undef DEBUG |
36 | 36 | ||
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index d00c0c37a12e..2e4ad44a8636 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c | |||
@@ -129,6 +129,7 @@ | |||
129 | #include <asm/sections.h> | 129 | #include <asm/sections.h> |
130 | #include <asm/of_device.h> | 130 | #include <asm/of_device.h> |
131 | #include <asm/macio.h> | 131 | #include <asm/macio.h> |
132 | #include <asm/of_platform.h> | ||
132 | 133 | ||
133 | #include "therm_pm72.h" | 134 | #include "therm_pm72.h" |
134 | 135 | ||
@@ -2236,14 +2237,14 @@ static int __init therm_pm72_init(void) | |||
2236 | return -ENODEV; | 2237 | return -ENODEV; |
2237 | } | 2238 | } |
2238 | 2239 | ||
2239 | of_register_driver(&fcu_of_platform_driver); | 2240 | of_register_platform_driver(&fcu_of_platform_driver); |
2240 | 2241 | ||
2241 | return 0; | 2242 | return 0; |
2242 | } | 2243 | } |
2243 | 2244 | ||
2244 | static void __exit therm_pm72_exit(void) | 2245 | static void __exit therm_pm72_exit(void) |
2245 | { | 2246 | { |
2246 | of_unregister_driver(&fcu_of_platform_driver); | 2247 | of_unregister_platform_driver(&fcu_of_platform_driver); |
2247 | 2248 | ||
2248 | if (of_dev) | 2249 | if (of_dev) |
2249 | of_device_unregister(of_dev); | 2250 | of_device_unregister(of_dev); |
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 738faab1b22c..a1d3a987cb3a 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c | |||
@@ -36,12 +36,13 @@ | |||
36 | #include <linux/i2c.h> | 36 | #include <linux/i2c.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | |||
39 | #include <asm/prom.h> | 40 | #include <asm/prom.h> |
40 | #include <asm/machdep.h> | 41 | #include <asm/machdep.h> |
41 | #include <asm/io.h> | 42 | #include <asm/io.h> |
42 | #include <asm/system.h> | 43 | #include <asm/system.h> |
43 | #include <asm/sections.h> | 44 | #include <asm/sections.h> |
44 | #include <asm/of_device.h> | 45 | #include <asm/of_platform.h> |
45 | #include <asm/macio.h> | 46 | #include <asm/macio.h> |
46 | 47 | ||
47 | #define LOG_TEMP 0 /* continously log temperature */ | 48 | #define LOG_TEMP 0 /* continously log temperature */ |
@@ -511,14 +512,14 @@ g4fan_init( void ) | |||
511 | return -ENODEV; | 512 | return -ENODEV; |
512 | } | 513 | } |
513 | 514 | ||
514 | of_register_driver( &therm_of_driver ); | 515 | of_register_platform_driver( &therm_of_driver ); |
515 | return 0; | 516 | return 0; |
516 | } | 517 | } |
517 | 518 | ||
518 | static void __exit | 519 | static void __exit |
519 | g4fan_exit( void ) | 520 | g4fan_exit( void ) |
520 | { | 521 | { |
521 | of_unregister_driver( &therm_of_driver ); | 522 | of_unregister_platform_driver( &therm_of_driver ); |
522 | 523 | ||
523 | if( x.of_dev ) | 524 | if( x.of_dev ) |
524 | of_device_unregister( x.of_dev ); | 525 | of_device_unregister( x.of_dev ); |
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 08a40f4e4f60..ed2d4ef27fd8 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c | |||
@@ -458,11 +458,11 @@ static void dec_pending(struct crypt_io *io, int error) | |||
458 | * interrupt context. | 458 | * interrupt context. |
459 | */ | 459 | */ |
460 | static struct workqueue_struct *_kcryptd_workqueue; | 460 | static struct workqueue_struct *_kcryptd_workqueue; |
461 | static void kcryptd_do_work(void *data); | 461 | static void kcryptd_do_work(struct work_struct *work); |
462 | 462 | ||
463 | static void kcryptd_queue_io(struct crypt_io *io) | 463 | static void kcryptd_queue_io(struct crypt_io *io) |
464 | { | 464 | { |
465 | INIT_WORK(&io->work, kcryptd_do_work, io); | 465 | INIT_WORK(&io->work, kcryptd_do_work); |
466 | queue_work(_kcryptd_workqueue, &io->work); | 466 | queue_work(_kcryptd_workqueue, &io->work); |
467 | } | 467 | } |
468 | 468 | ||
@@ -618,9 +618,9 @@ static void process_read_endio(struct crypt_io *io) | |||
618 | dec_pending(io, crypt_convert(cc, &ctx)); | 618 | dec_pending(io, crypt_convert(cc, &ctx)); |
619 | } | 619 | } |
620 | 620 | ||
621 | static void kcryptd_do_work(void *data) | 621 | static void kcryptd_do_work(struct work_struct *work) |
622 | { | 622 | { |
623 | struct crypt_io *io = data; | 623 | struct crypt_io *io = container_of(work, struct crypt_io, work); |
624 | 624 | ||
625 | if (io->post_process) | 625 | if (io->post_process) |
626 | process_read_endio(io); | 626 | process_read_endio(io); |
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index d754e0bc6e90..e77ee6fd1044 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -104,8 +104,8 @@ typedef int (*action_fn) (struct pgpath *pgpath); | |||
104 | static kmem_cache_t *_mpio_cache; | 104 | static kmem_cache_t *_mpio_cache; |
105 | 105 | ||
106 | struct workqueue_struct *kmultipathd; | 106 | struct workqueue_struct *kmultipathd; |
107 | static void process_queued_ios(void *data); | 107 | static void process_queued_ios(struct work_struct *work); |
108 | static void trigger_event(void *data); | 108 | static void trigger_event(struct work_struct *work); |
109 | 109 | ||
110 | 110 | ||
111 | /*----------------------------------------------- | 111 | /*----------------------------------------------- |
@@ -173,8 +173,8 @@ static struct multipath *alloc_multipath(struct dm_target *ti) | |||
173 | INIT_LIST_HEAD(&m->priority_groups); | 173 | INIT_LIST_HEAD(&m->priority_groups); |
174 | spin_lock_init(&m->lock); | 174 | spin_lock_init(&m->lock); |
175 | m->queue_io = 1; | 175 | m->queue_io = 1; |
176 | INIT_WORK(&m->process_queued_ios, process_queued_ios, m); | 176 | INIT_WORK(&m->process_queued_ios, process_queued_ios); |
177 | INIT_WORK(&m->trigger_event, trigger_event, m); | 177 | INIT_WORK(&m->trigger_event, trigger_event); |
178 | m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); | 178 | m->mpio_pool = mempool_create_slab_pool(MIN_IOS, _mpio_cache); |
179 | if (!m->mpio_pool) { | 179 | if (!m->mpio_pool) { |
180 | kfree(m); | 180 | kfree(m); |
@@ -379,9 +379,10 @@ static void dispatch_queued_ios(struct multipath *m) | |||
379 | } | 379 | } |
380 | } | 380 | } |
381 | 381 | ||
382 | static void process_queued_ios(void *data) | 382 | static void process_queued_ios(struct work_struct *work) |
383 | { | 383 | { |
384 | struct multipath *m = (struct multipath *) data; | 384 | struct multipath *m = |
385 | container_of(work, struct multipath, process_queued_ios); | ||
385 | struct hw_handler *hwh = &m->hw_handler; | 386 | struct hw_handler *hwh = &m->hw_handler; |
386 | struct pgpath *pgpath = NULL; | 387 | struct pgpath *pgpath = NULL; |
387 | unsigned init_required = 0, must_queue = 1; | 388 | unsigned init_required = 0, must_queue = 1; |
@@ -421,9 +422,10 @@ out: | |||
421 | * An event is triggered whenever a path is taken out of use. | 422 | * An event is triggered whenever a path is taken out of use. |
422 | * Includes path failure and PG bypass. | 423 | * Includes path failure and PG bypass. |
423 | */ | 424 | */ |
424 | static void trigger_event(void *data) | 425 | static void trigger_event(struct work_struct *work) |
425 | { | 426 | { |
426 | struct multipath *m = (struct multipath *) data; | 427 | struct multipath *m = |
428 | container_of(work, struct multipath, trigger_event); | ||
427 | 429 | ||
428 | dm_table_event(m->ti->table); | 430 | dm_table_event(m->ti->table); |
429 | } | 431 | } |
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 48a653b3f518..fc8cbb168e3e 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -883,7 +883,7 @@ static void do_mirror(struct mirror_set *ms) | |||
883 | do_writes(ms, &writes); | 883 | do_writes(ms, &writes); |
884 | } | 884 | } |
885 | 885 | ||
886 | static void do_work(void *ignored) | 886 | static void do_work(struct work_struct *ignored) |
887 | { | 887 | { |
888 | struct mirror_set *ms; | 888 | struct mirror_set *ms; |
889 | 889 | ||
@@ -1269,7 +1269,7 @@ static int __init dm_mirror_init(void) | |||
1269 | dm_dirty_log_exit(); | 1269 | dm_dirty_log_exit(); |
1270 | return r; | 1270 | return r; |
1271 | } | 1271 | } |
1272 | INIT_WORK(&_kmirrord_work, do_work, NULL); | 1272 | INIT_WORK(&_kmirrord_work, do_work); |
1273 | 1273 | ||
1274 | r = dm_register_target(&mirror_target); | 1274 | r = dm_register_target(&mirror_target); |
1275 | if (r < 0) { | 1275 | if (r < 0) { |
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 5281e0094072..91c7aa1fed0e 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #define SNAPSHOT_PAGES 256 | 40 | #define SNAPSHOT_PAGES 256 |
41 | 41 | ||
42 | struct workqueue_struct *ksnapd; | 42 | struct workqueue_struct *ksnapd; |
43 | static void flush_queued_bios(void *data); | 43 | static void flush_queued_bios(struct work_struct *work); |
44 | 44 | ||
45 | struct pending_exception { | 45 | struct pending_exception { |
46 | struct exception e; | 46 | struct exception e; |
@@ -528,7 +528,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) | |||
528 | } | 528 | } |
529 | 529 | ||
530 | bio_list_init(&s->queued_bios); | 530 | bio_list_init(&s->queued_bios); |
531 | INIT_WORK(&s->queued_bios_work, flush_queued_bios, s); | 531 | INIT_WORK(&s->queued_bios_work, flush_queued_bios); |
532 | 532 | ||
533 | /* Add snapshot to the list of snapshots for this origin */ | 533 | /* Add snapshot to the list of snapshots for this origin */ |
534 | /* Exceptions aren't triggered till snapshot_resume() is called */ | 534 | /* Exceptions aren't triggered till snapshot_resume() is called */ |
@@ -603,9 +603,10 @@ static void flush_bios(struct bio *bio) | |||
603 | } | 603 | } |
604 | } | 604 | } |
605 | 605 | ||
606 | static void flush_queued_bios(void *data) | 606 | static void flush_queued_bios(struct work_struct *work) |
607 | { | 607 | { |
608 | struct dm_snapshot *s = (struct dm_snapshot *) data; | 608 | struct dm_snapshot *s = |
609 | container_of(work, struct dm_snapshot, queued_bios_work); | ||
609 | struct bio *queued_bios; | 610 | struct bio *queued_bios; |
610 | unsigned long flags; | 611 | unsigned long flags; |
611 | 612 | ||
diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c index f1db6eff4857..b3c01496c737 100644 --- a/drivers/md/kcopyd.c +++ b/drivers/md/kcopyd.c | |||
@@ -417,7 +417,7 @@ static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *)) | |||
417 | /* | 417 | /* |
418 | * kcopyd does this every time it's woken up. | 418 | * kcopyd does this every time it's woken up. |
419 | */ | 419 | */ |
420 | static void do_work(void *ignored) | 420 | static void do_work(struct work_struct *ignored) |
421 | { | 421 | { |
422 | /* | 422 | /* |
423 | * The order that these are called is *very* important. | 423 | * The order that these are called is *very* important. |
@@ -628,7 +628,7 @@ static int kcopyd_init(void) | |||
628 | } | 628 | } |
629 | 629 | ||
630 | kcopyd_clients++; | 630 | kcopyd_clients++; |
631 | INIT_WORK(&_kcopyd_work, do_work, NULL); | 631 | INIT_WORK(&_kcopyd_work, do_work); |
632 | mutex_unlock(&kcopyd_init_lock); | 632 | mutex_unlock(&kcopyd_init_lock); |
633 | return 0; | 633 | return 0; |
634 | } | 634 | } |
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index 06893243f3d4..6e166801505d 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c | |||
@@ -63,7 +63,7 @@ struct flexcop_pci { | |||
63 | 63 | ||
64 | unsigned long last_irq; | 64 | unsigned long last_irq; |
65 | 65 | ||
66 | struct work_struct irq_check_work; | 66 | struct delayed_work irq_check_work; |
67 | 67 | ||
68 | struct flexcop_device *fc_dev; | 68 | struct flexcop_device *fc_dev; |
69 | }; | 69 | }; |
@@ -97,9 +97,10 @@ static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_regi | |||
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | static void flexcop_pci_irq_check_work(void *data) | 100 | static void flexcop_pci_irq_check_work(struct work_struct *work) |
101 | { | 101 | { |
102 | struct flexcop_pci *fc_pci = data; | 102 | struct flexcop_pci *fc_pci = |
103 | container_of(work, struct flexcop_pci, irq_check_work.work); | ||
103 | struct flexcop_device *fc = fc_pci->fc_dev; | 104 | struct flexcop_device *fc = fc_pci->fc_dev; |
104 | 105 | ||
105 | flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); | 106 | flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); |
@@ -371,7 +372,7 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
371 | if ((ret = flexcop_pci_dma_init(fc_pci)) != 0) | 372 | if ((ret = flexcop_pci_dma_init(fc_pci)) != 0) |
372 | goto err_fc_exit; | 373 | goto err_fc_exit; |
373 | 374 | ||
374 | INIT_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work, fc_pci); | 375 | INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work); |
375 | 376 | ||
376 | return ret; | 377 | return ret; |
377 | 378 | ||
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 8a7dd507cf6e..206c13e47a06 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -128,7 +128,7 @@ struct cinergyt2 { | |||
128 | 128 | ||
129 | struct dvbt_set_parameters_msg param; | 129 | struct dvbt_set_parameters_msg param; |
130 | struct dvbt_get_status_msg status; | 130 | struct dvbt_get_status_msg status; |
131 | struct work_struct query_work; | 131 | struct delayed_work query_work; |
132 | 132 | ||
133 | wait_queue_head_t poll_wq; | 133 | wait_queue_head_t poll_wq; |
134 | int pending_fe_events; | 134 | int pending_fe_events; |
@@ -142,7 +142,7 @@ struct cinergyt2 { | |||
142 | #ifdef ENABLE_RC | 142 | #ifdef ENABLE_RC |
143 | struct input_dev *rc_input_dev; | 143 | struct input_dev *rc_input_dev; |
144 | char phys[64]; | 144 | char phys[64]; |
145 | struct work_struct rc_query_work; | 145 | struct delayed_work rc_query_work; |
146 | int rc_input_event; | 146 | int rc_input_event; |
147 | u32 rc_last_code; | 147 | u32 rc_last_code; |
148 | unsigned long last_event_jiffies; | 148 | unsigned long last_event_jiffies; |
@@ -723,9 +723,10 @@ static struct dvb_device cinergyt2_fe_template = { | |||
723 | 723 | ||
724 | #ifdef ENABLE_RC | 724 | #ifdef ENABLE_RC |
725 | 725 | ||
726 | static void cinergyt2_query_rc (void *data) | 726 | static void cinergyt2_query_rc (struct work_struct *work) |
727 | { | 727 | { |
728 | struct cinergyt2 *cinergyt2 = data; | 728 | struct cinergyt2 *cinergyt2 = |
729 | container_of(work, struct cinergyt2, rc_query_work.work); | ||
729 | char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS }; | 730 | char buf[1] = { CINERGYT2_EP1_GET_RC_EVENTS }; |
730 | struct cinergyt2_rc_event rc_events[12]; | 731 | struct cinergyt2_rc_event rc_events[12]; |
731 | int n, len, i; | 732 | int n, len, i; |
@@ -806,7 +807,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) | |||
806 | strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); | 807 | strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); |
807 | cinergyt2->rc_input_event = KEY_MAX; | 808 | cinergyt2->rc_input_event = KEY_MAX; |
808 | cinergyt2->rc_last_code = ~0; | 809 | cinergyt2->rc_last_code = ~0; |
809 | INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2); | 810 | INIT_DELAYED_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc); |
810 | 811 | ||
811 | input_dev->name = DRIVER_NAME " remote control"; | 812 | input_dev->name = DRIVER_NAME " remote control"; |
812 | input_dev->phys = cinergyt2->phys; | 813 | input_dev->phys = cinergyt2->phys; |
@@ -847,9 +848,10 @@ static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { } | |||
847 | 848 | ||
848 | #endif /* ENABLE_RC */ | 849 | #endif /* ENABLE_RC */ |
849 | 850 | ||
850 | static void cinergyt2_query (void *data) | 851 | static void cinergyt2_query (struct work_struct *work) |
851 | { | 852 | { |
852 | struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data; | 853 | struct cinergyt2 *cinergyt2 = |
854 | container_of(work, struct cinergyt2, query_work.work); | ||
853 | char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; | 855 | char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; |
854 | struct dvbt_get_status_msg *s = &cinergyt2->status; | 856 | struct dvbt_get_status_msg *s = &cinergyt2->status; |
855 | uint8_t lock_bits; | 857 | uint8_t lock_bits; |
@@ -893,7 +895,7 @@ static int cinergyt2_probe (struct usb_interface *intf, | |||
893 | 895 | ||
894 | mutex_init(&cinergyt2->sem); | 896 | mutex_init(&cinergyt2->sem); |
895 | init_waitqueue_head (&cinergyt2->poll_wq); | 897 | init_waitqueue_head (&cinergyt2->poll_wq); |
896 | INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2); | 898 | INIT_DELAYED_WORK(&cinergyt2->query_work, cinergyt2_query); |
897 | 899 | ||
898 | cinergyt2->udev = interface_to_usbdev(intf); | 900 | cinergyt2->udev = interface_to_usbdev(intf); |
899 | cinergyt2->param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; | 901 | cinergyt2->param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 8859ab74f0fe..ebf4dc5190f6 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -127,6 +127,7 @@ struct dvb_net_priv { | |||
127 | int in_use; | 127 | int in_use; |
128 | struct net_device_stats stats; | 128 | struct net_device_stats stats; |
129 | u16 pid; | 129 | u16 pid; |
130 | struct net_device *net; | ||
130 | struct dvb_net *host; | 131 | struct dvb_net *host; |
131 | struct dmx_demux *demux; | 132 | struct dmx_demux *demux; |
132 | struct dmx_section_feed *secfeed; | 133 | struct dmx_section_feed *secfeed; |
@@ -1123,10 +1124,11 @@ static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc) | |||
1123 | } | 1124 | } |
1124 | 1125 | ||
1125 | 1126 | ||
1126 | static void wq_set_multicast_list (void *data) | 1127 | static void wq_set_multicast_list (struct work_struct *work) |
1127 | { | 1128 | { |
1128 | struct net_device *dev = data; | 1129 | struct dvb_net_priv *priv = |
1129 | struct dvb_net_priv *priv = dev->priv; | 1130 | container_of(work, struct dvb_net_priv, set_multicast_list_wq); |
1131 | struct net_device *dev = priv->net; | ||
1130 | 1132 | ||
1131 | dvb_net_feed_stop(dev); | 1133 | dvb_net_feed_stop(dev); |
1132 | priv->rx_mode = RX_MODE_UNI; | 1134 | priv->rx_mode = RX_MODE_UNI; |
@@ -1167,9 +1169,11 @@ static void dvb_net_set_multicast_list (struct net_device *dev) | |||
1167 | } | 1169 | } |
1168 | 1170 | ||
1169 | 1171 | ||
1170 | static void wq_restart_net_feed (void *data) | 1172 | static void wq_restart_net_feed (struct work_struct *work) |
1171 | { | 1173 | { |
1172 | struct net_device *dev = data; | 1174 | struct dvb_net_priv *priv = |
1175 | container_of(work, struct dvb_net_priv, restart_net_feed_wq); | ||
1176 | struct net_device *dev = priv->net; | ||
1173 | 1177 | ||
1174 | if (netif_running(dev)) { | 1178 | if (netif_running(dev)) { |
1175 | dvb_net_feed_stop(dev); | 1179 | dvb_net_feed_stop(dev); |
@@ -1276,6 +1280,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) | |||
1276 | dvbnet->device[if_num] = net; | 1280 | dvbnet->device[if_num] = net; |
1277 | 1281 | ||
1278 | priv = net->priv; | 1282 | priv = net->priv; |
1283 | priv->net = net; | ||
1279 | priv->demux = dvbnet->demux; | 1284 | priv->demux = dvbnet->demux; |
1280 | priv->pid = pid; | 1285 | priv->pid = pid; |
1281 | priv->rx_mode = RX_MODE_UNI; | 1286 | priv->rx_mode = RX_MODE_UNI; |
@@ -1284,8 +1289,8 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) | |||
1284 | priv->feedtype = feedtype; | 1289 | priv->feedtype = feedtype; |
1285 | reset_ule(priv); | 1290 | reset_ule(priv); |
1286 | 1291 | ||
1287 | INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net); | 1292 | INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list); |
1288 | INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net); | 1293 | INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed); |
1289 | mutex_init(&priv->mutex); | 1294 | mutex_init(&priv->mutex); |
1290 | 1295 | ||
1291 | net->base_addr = pid; | 1296 | net->base_addr = pid; |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index 0a3a0b6c2350..794e4471561c 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c | |||
@@ -13,9 +13,10 @@ | |||
13 | * | 13 | * |
14 | * TODO: Fix the repeat rate of the input device. | 14 | * TODO: Fix the repeat rate of the input device. |
15 | */ | 15 | */ |
16 | static void dvb_usb_read_remote_control(void *data) | 16 | static void dvb_usb_read_remote_control(struct work_struct *work) |
17 | { | 17 | { |
18 | struct dvb_usb_device *d = data; | 18 | struct dvb_usb_device *d = |
19 | container_of(work, struct dvb_usb_device, rc_query_work.work); | ||
19 | u32 event; | 20 | u32 event; |
20 | int state; | 21 | int state; |
21 | 22 | ||
@@ -128,7 +129,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) | |||
128 | 129 | ||
129 | input_register_device(d->rc_input_dev); | 130 | input_register_device(d->rc_input_dev); |
130 | 131 | ||
131 | INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d); | 132 | INIT_DELAYED_WORK(&d->rc_query_work, dvb_usb_read_remote_control); |
132 | 133 | ||
133 | info("schedule remote query interval to %d msecs.", d->props.rc_interval); | 134 | info("schedule remote query interval to %d msecs.", d->props.rc_interval); |
134 | schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); | 135 | schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval)); |
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index 376c45a8e779..0d721731a524 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
@@ -369,7 +369,7 @@ struct dvb_usb_device { | |||
369 | /* remote control */ | 369 | /* remote control */ |
370 | struct input_dev *rc_input_dev; | 370 | struct input_dev *rc_input_dev; |
371 | char rc_phys[64]; | 371 | char rc_phys[64]; |
372 | struct work_struct rc_query_work; | 372 | struct delayed_work rc_query_work; |
373 | u32 last_event; | 373 | u32 last_event; |
374 | int last_state; | 374 | int last_state; |
375 | 375 | ||
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c index 41f4b8d17559..b12cec94f4cc 100644 --- a/drivers/media/video/cpia_pp.c +++ b/drivers/media/video/cpia_pp.c | |||
@@ -82,6 +82,8 @@ struct pp_cam_entry { | |||
82 | struct pardevice *pdev; | 82 | struct pardevice *pdev; |
83 | struct parport *port; | 83 | struct parport *port; |
84 | struct work_struct cb_task; | 84 | struct work_struct cb_task; |
85 | void (*cb_func)(void *cbdata); | ||
86 | void *cb_data; | ||
85 | int open_count; | 87 | int open_count; |
86 | wait_queue_head_t wq_stream; | 88 | wait_queue_head_t wq_stream; |
87 | /* image state flags */ | 89 | /* image state flags */ |
@@ -130,6 +132,20 @@ static void cpia_parport_disable_irq( struct parport *port ) { | |||
130 | #define PARPORT_CHUNK_SIZE PAGE_SIZE | 132 | #define PARPORT_CHUNK_SIZE PAGE_SIZE |
131 | 133 | ||
132 | 134 | ||
135 | static void cpia_pp_run_callback(struct work_struct *work) | ||
136 | { | ||
137 | void (*cb_func)(void *cbdata); | ||
138 | void *cb_data; | ||
139 | struct pp_cam_entry *cam; | ||
140 | |||
141 | cam = container_of(work, struct pp_cam_entry, cb_task); | ||
142 | cb_func = cam->cb_func; | ||
143 | cb_data = cam->cb_data; | ||
144 | work_release(work); | ||
145 | |||
146 | cb_func(cb_data); | ||
147 | } | ||
148 | |||
133 | /**************************************************************************** | 149 | /**************************************************************************** |
134 | * | 150 | * |
135 | * CPiA-specific low-level parport functions for nibble uploads | 151 | * CPiA-specific low-level parport functions for nibble uploads |
@@ -664,7 +680,9 @@ static int cpia_pp_registerCallback(void *privdata, void (*cb)(void *cbdata), vo | |||
664 | int retval = 0; | 680 | int retval = 0; |
665 | 681 | ||
666 | if(cam->port->irq != PARPORT_IRQ_NONE) { | 682 | if(cam->port->irq != PARPORT_IRQ_NONE) { |
667 | INIT_WORK(&cam->cb_task, cb, cbdata); | 683 | cam->cb_func = cb; |
684 | cam->cb_data = cbdata; | ||
685 | INIT_WORK_NAR(&cam->cb_task, cpia_pp_run_callback); | ||
668 | } else { | 686 | } else { |
669 | retval = -1; | 687 | retval = -1; |
670 | } | 688 | } |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index 57e1c024a547..e60a0a52e4b2 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -145,9 +145,9 @@ static void ir_timer(unsigned long data) | |||
145 | schedule_work(&ir->work); | 145 | schedule_work(&ir->work); |
146 | } | 146 | } |
147 | 147 | ||
148 | static void cx88_ir_work(void *data) | 148 | static void cx88_ir_work(struct work_struct *work) |
149 | { | 149 | { |
150 | struct cx88_IR *ir = data; | 150 | struct cx88_IR *ir = container_of(work, struct cx88_IR, work); |
151 | unsigned long timeout; | 151 | unsigned long timeout; |
152 | 152 | ||
153 | cx88_ir_handle_key(ir); | 153 | cx88_ir_handle_key(ir); |
@@ -308,7 +308,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
308 | core->ir = ir; | 308 | core->ir = ir; |
309 | 309 | ||
310 | if (ir->polling) { | 310 | if (ir->polling) { |
311 | INIT_WORK(&ir->work, cx88_ir_work, ir); | 311 | INIT_WORK(&ir->work, cx88_ir_work); |
312 | init_timer(&ir->timer); | 312 | init_timer(&ir->timer); |
313 | ir->timer.function = ir_timer; | 313 | ir->timer.function = ir_timer; |
314 | ir->timer.data = (unsigned long)ir; | 314 | ir->timer.data = (unsigned long)ir; |
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 1457b1602221..ab87e7bfe84f 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c | |||
@@ -268,9 +268,9 @@ static void ir_timer(unsigned long data) | |||
268 | schedule_work(&ir->work); | 268 | schedule_work(&ir->work); |
269 | } | 269 | } |
270 | 270 | ||
271 | static void ir_work(void *data) | 271 | static void ir_work(struct work_struct *work) |
272 | { | 272 | { |
273 | struct IR_i2c *ir = data; | 273 | struct IR_i2c *ir = container_of(work, struct IR_i2c, work); |
274 | ir_key_poll(ir); | 274 | ir_key_poll(ir); |
275 | mod_timer(&ir->timer, jiffies+HZ/10); | 275 | mod_timer(&ir->timer, jiffies+HZ/10); |
276 | } | 276 | } |
@@ -400,7 +400,7 @@ static int ir_attach(struct i2c_adapter *adap, int addr, | |||
400 | ir->input->name,ir->input->phys,adap->name); | 400 | ir->input->name,ir->input->phys,adap->name); |
401 | 401 | ||
402 | /* start polling via eventd */ | 402 | /* start polling via eventd */ |
403 | INIT_WORK(&ir->work, ir_work, ir); | 403 | INIT_WORK(&ir->work, ir_work); |
404 | init_timer(&ir->timer); | 404 | init_timer(&ir->timer); |
405 | ir->timer.function = ir_timer; | 405 | ir->timer.function = ir_timer; |
406 | ir->timer.data = (unsigned long)ir; | 406 | ir->timer.data = (unsigned long)ir; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-context.c b/drivers/media/video/pvrusb2/pvrusb2-context.c index f129f316d20e..cf129746205d 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-context.c +++ b/drivers/media/video/pvrusb2/pvrusb2-context.c | |||
@@ -45,16 +45,21 @@ static void pvr2_context_trigger_poll(struct pvr2_context *mp) | |||
45 | } | 45 | } |
46 | 46 | ||
47 | 47 | ||
48 | static void pvr2_context_poll(struct pvr2_context *mp) | 48 | static void pvr2_context_poll(struct work_struct *work) |
49 | { | 49 | { |
50 | struct pvr2_context *mp = | ||
51 | container_of(work, struct pvr2_context, workpoll); | ||
50 | pvr2_context_enter(mp); do { | 52 | pvr2_context_enter(mp); do { |
51 | pvr2_hdw_poll(mp->hdw); | 53 | pvr2_hdw_poll(mp->hdw); |
52 | } while (0); pvr2_context_exit(mp); | 54 | } while (0); pvr2_context_exit(mp); |
53 | } | 55 | } |
54 | 56 | ||
55 | 57 | ||
56 | static void pvr2_context_setup(struct pvr2_context *mp) | 58 | static void pvr2_context_setup(struct work_struct *work) |
57 | { | 59 | { |
60 | struct pvr2_context *mp = | ||
61 | container_of(work, struct pvr2_context, workinit); | ||
62 | |||
58 | pvr2_context_enter(mp); do { | 63 | pvr2_context_enter(mp); do { |
59 | if (!pvr2_hdw_dev_ok(mp->hdw)) break; | 64 | if (!pvr2_hdw_dev_ok(mp->hdw)) break; |
60 | pvr2_hdw_setup(mp->hdw); | 65 | pvr2_hdw_setup(mp->hdw); |
@@ -92,8 +97,8 @@ struct pvr2_context *pvr2_context_create( | |||
92 | } | 97 | } |
93 | 98 | ||
94 | mp->workqueue = create_singlethread_workqueue("pvrusb2"); | 99 | mp->workqueue = create_singlethread_workqueue("pvrusb2"); |
95 | INIT_WORK(&mp->workinit,(void (*)(void*))pvr2_context_setup,mp); | 100 | INIT_WORK(&mp->workinit, pvr2_context_setup); |
96 | INIT_WORK(&mp->workpoll,(void (*)(void*))pvr2_context_poll,mp); | 101 | INIT_WORK(&mp->workpoll, pvr2_context_poll); |
97 | queue_work(mp->workqueue,&mp->workinit); | 102 | queue_work(mp->workqueue,&mp->workinit); |
98 | done: | 103 | done: |
99 | return mp; | 104 | return mp; |
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c index 7b9859c33018..92eabf88a09b 100644 --- a/drivers/media/video/saa6588.c +++ b/drivers/media/video/saa6588.c | |||
@@ -324,9 +324,9 @@ static void saa6588_timer(unsigned long data) | |||
324 | schedule_work(&s->work); | 324 | schedule_work(&s->work); |
325 | } | 325 | } |
326 | 326 | ||
327 | static void saa6588_work(void *data) | 327 | static void saa6588_work(struct work_struct *work) |
328 | { | 328 | { |
329 | struct saa6588 *s = (struct saa6588 *)data; | 329 | struct saa6588 *s = container_of(work, struct saa6588, work); |
330 | 330 | ||
331 | saa6588_i2c_poll(s); | 331 | saa6588_i2c_poll(s); |
332 | mod_timer(&s->timer, jiffies + msecs_to_jiffies(20)); | 332 | mod_timer(&s->timer, jiffies + msecs_to_jiffies(20)); |
@@ -419,7 +419,7 @@ static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind) | |||
419 | saa6588_configure(s); | 419 | saa6588_configure(s); |
420 | 420 | ||
421 | /* start polling via eventd */ | 421 | /* start polling via eventd */ |
422 | INIT_WORK(&s->work, saa6588_work, s); | 422 | INIT_WORK(&s->work, saa6588_work); |
423 | init_timer(&s->timer); | 423 | init_timer(&s->timer); |
424 | s->timer.function = saa6588_timer; | 424 | s->timer.function = saa6588_timer; |
425 | s->timer.data = (unsigned long)s; | 425 | s->timer.data = (unsigned long)s; |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 65d044086ce9..daaae870a2c4 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -343,9 +343,10 @@ static struct video_device saa7134_empress_template = | |||
343 | .minor = -1, | 343 | .minor = -1, |
344 | }; | 344 | }; |
345 | 345 | ||
346 | static void empress_signal_update(void* data) | 346 | static void empress_signal_update(struct work_struct *work) |
347 | { | 347 | { |
348 | struct saa7134_dev* dev = (struct saa7134_dev*) data; | 348 | struct saa7134_dev* dev = |
349 | container_of(work, struct saa7134_dev, empress_workqueue); | ||
349 | 350 | ||
350 | if (dev->nosignal) { | 351 | if (dev->nosignal) { |
351 | dprintk("no video signal\n"); | 352 | dprintk("no video signal\n"); |
@@ -378,7 +379,7 @@ static int empress_init(struct saa7134_dev *dev) | |||
378 | "%s empress (%s)", dev->name, | 379 | "%s empress (%s)", dev->name, |
379 | saa7134_boards[dev->board].name); | 380 | saa7134_boards[dev->board].name); |
380 | 381 | ||
381 | INIT_WORK(&dev->empress_workqueue, empress_signal_update, (void*) dev); | 382 | INIT_WORK(&dev->empress_workqueue, empress_signal_update); |
382 | 383 | ||
383 | err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, | 384 | err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, |
384 | empress_nr[dev->nr]); | 385 | empress_nr[dev->nr]); |
@@ -399,7 +400,7 @@ static int empress_init(struct saa7134_dev *dev) | |||
399 | sizeof(struct saa7134_buf), | 400 | sizeof(struct saa7134_buf), |
400 | dev); | 401 | dev); |
401 | 402 | ||
402 | empress_signal_update(dev); | 403 | empress_signal_update(&dev->empress_workqueue); |
403 | return 0; | 404 | return 0; |
404 | } | 405 | } |
405 | 406 | ||
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index 1dd491773150..ef2b55e19910 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -1018,9 +1018,10 @@ mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum) | |||
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | static void | 1020 | static void |
1021 | mptfc_setup_reset(void *arg) | 1021 | mptfc_setup_reset(struct work_struct *work) |
1022 | { | 1022 | { |
1023 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; | 1023 | MPT_ADAPTER *ioc = |
1024 | container_of(work, MPT_ADAPTER, fc_setup_reset_work); | ||
1024 | u64 pn; | 1025 | u64 pn; |
1025 | struct mptfc_rport_info *ri; | 1026 | struct mptfc_rport_info *ri; |
1026 | 1027 | ||
@@ -1043,9 +1044,10 @@ mptfc_setup_reset(void *arg) | |||
1043 | } | 1044 | } |
1044 | 1045 | ||
1045 | static void | 1046 | static void |
1046 | mptfc_rescan_devices(void *arg) | 1047 | mptfc_rescan_devices(struct work_struct *work) |
1047 | { | 1048 | { |
1048 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; | 1049 | MPT_ADAPTER *ioc = |
1050 | container_of(work, MPT_ADAPTER, fc_rescan_work); | ||
1049 | int ii; | 1051 | int ii; |
1050 | u64 pn; | 1052 | u64 pn; |
1051 | struct mptfc_rport_info *ri; | 1053 | struct mptfc_rport_info *ri; |
@@ -1154,8 +1156,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1154 | } | 1156 | } |
1155 | 1157 | ||
1156 | spin_lock_init(&ioc->fc_rescan_work_lock); | 1158 | spin_lock_init(&ioc->fc_rescan_work_lock); |
1157 | INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc); | 1159 | INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices); |
1158 | INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset, (void *)ioc); | 1160 | INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset); |
1159 | 1161 | ||
1160 | spin_lock_irqsave(&ioc->FreeQlock, flags); | 1162 | spin_lock_irqsave(&ioc->FreeQlock, flags); |
1161 | 1163 | ||
diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index 314c3a27585d..b7c4407c5e3f 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c | |||
@@ -111,7 +111,8 @@ struct mpt_lan_priv { | |||
111 | u32 total_received; | 111 | u32 total_received; |
112 | struct net_device_stats stats; /* Per device statistics */ | 112 | struct net_device_stats stats; /* Per device statistics */ |
113 | 113 | ||
114 | struct work_struct post_buckets_task; | 114 | struct delayed_work post_buckets_task; |
115 | struct net_device *dev; | ||
115 | unsigned long post_buckets_active; | 116 | unsigned long post_buckets_active; |
116 | }; | 117 | }; |
117 | 118 | ||
@@ -132,7 +133,7 @@ static int lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, | |||
132 | static int mpt_lan_open(struct net_device *dev); | 133 | static int mpt_lan_open(struct net_device *dev); |
133 | static int mpt_lan_reset(struct net_device *dev); | 134 | static int mpt_lan_reset(struct net_device *dev); |
134 | static int mpt_lan_close(struct net_device *dev); | 135 | static int mpt_lan_close(struct net_device *dev); |
135 | static void mpt_lan_post_receive_buckets(void *dev_id); | 136 | static void mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv); |
136 | static void mpt_lan_wake_post_buckets_task(struct net_device *dev, | 137 | static void mpt_lan_wake_post_buckets_task(struct net_device *dev, |
137 | int priority); | 138 | int priority); |
138 | static int mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg); | 139 | static int mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg); |
@@ -345,7 +346,7 @@ mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
345 | priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i; | 346 | priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i; |
346 | spin_unlock_irqrestore(&priv->rxfidx_lock, flags); | 347 | spin_unlock_irqrestore(&priv->rxfidx_lock, flags); |
347 | } else { | 348 | } else { |
348 | mpt_lan_post_receive_buckets(dev); | 349 | mpt_lan_post_receive_buckets(priv); |
349 | netif_wake_queue(dev); | 350 | netif_wake_queue(dev); |
350 | } | 351 | } |
351 | 352 | ||
@@ -441,7 +442,7 @@ mpt_lan_open(struct net_device *dev) | |||
441 | 442 | ||
442 | dlprintk((KERN_INFO MYNAM "/lo: Finished initializing RcvCtl\n")); | 443 | dlprintk((KERN_INFO MYNAM "/lo: Finished initializing RcvCtl\n")); |
443 | 444 | ||
444 | mpt_lan_post_receive_buckets(dev); | 445 | mpt_lan_post_receive_buckets(priv); |
445 | printk(KERN_INFO MYNAM ": %s/%s: interface up & active\n", | 446 | printk(KERN_INFO MYNAM ": %s/%s: interface up & active\n", |
446 | IOC_AND_NETDEV_NAMES_s_s(dev)); | 447 | IOC_AND_NETDEV_NAMES_s_s(dev)); |
447 | 448 | ||
@@ -854,7 +855,7 @@ mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority) | |||
854 | 855 | ||
855 | if (test_and_set_bit(0, &priv->post_buckets_active) == 0) { | 856 | if (test_and_set_bit(0, &priv->post_buckets_active) == 0) { |
856 | if (priority) { | 857 | if (priority) { |
857 | schedule_work(&priv->post_buckets_task); | 858 | schedule_delayed_work(&priv->post_buckets_task, 0); |
858 | } else { | 859 | } else { |
859 | schedule_delayed_work(&priv->post_buckets_task, 1); | 860 | schedule_delayed_work(&priv->post_buckets_task, 1); |
860 | dioprintk((KERN_INFO MYNAM ": post_buckets queued on " | 861 | dioprintk((KERN_INFO MYNAM ": post_buckets queued on " |
@@ -1188,10 +1189,9 @@ mpt_lan_receive_post_reply(struct net_device *dev, | |||
1188 | /* Simple SGE's only at the moment */ | 1189 | /* Simple SGE's only at the moment */ |
1189 | 1190 | ||
1190 | static void | 1191 | static void |
1191 | mpt_lan_post_receive_buckets(void *dev_id) | 1192 | mpt_lan_post_receive_buckets(struct mpt_lan_priv *priv) |
1192 | { | 1193 | { |
1193 | struct net_device *dev = dev_id; | 1194 | struct net_device *dev = priv->dev; |
1194 | struct mpt_lan_priv *priv = dev->priv; | ||
1195 | MPT_ADAPTER *mpt_dev = priv->mpt_dev; | 1195 | MPT_ADAPTER *mpt_dev = priv->mpt_dev; |
1196 | MPT_FRAME_HDR *mf; | 1196 | MPT_FRAME_HDR *mf; |
1197 | LANReceivePostRequest_t *pRecvReq; | 1197 | LANReceivePostRequest_t *pRecvReq; |
@@ -1335,6 +1335,13 @@ out: | |||
1335 | clear_bit(0, &priv->post_buckets_active); | 1335 | clear_bit(0, &priv->post_buckets_active); |
1336 | } | 1336 | } |
1337 | 1337 | ||
1338 | static void | ||
1339 | mpt_lan_post_receive_buckets_work(struct work_struct *work) | ||
1340 | { | ||
1341 | mpt_lan_post_receive_buckets(container_of(work, struct mpt_lan_priv, | ||
1342 | post_buckets_task.work)); | ||
1343 | } | ||
1344 | |||
1338 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1345 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
1339 | static struct net_device * | 1346 | static struct net_device * |
1340 | mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) | 1347 | mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) |
@@ -1350,11 +1357,13 @@ mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum) | |||
1350 | 1357 | ||
1351 | priv = netdev_priv(dev); | 1358 | priv = netdev_priv(dev); |
1352 | 1359 | ||
1360 | priv->dev = dev; | ||
1353 | priv->mpt_dev = mpt_dev; | 1361 | priv->mpt_dev = mpt_dev; |
1354 | priv->pnum = pnum; | 1362 | priv->pnum = pnum; |
1355 | 1363 | ||
1356 | memset(&priv->post_buckets_task, 0, sizeof(struct work_struct)); | 1364 | memset(&priv->post_buckets_task, 0, sizeof(priv->post_buckets_task)); |
1357 | INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev); | 1365 | INIT_DELAYED_WORK(&priv->post_buckets_task, |
1366 | mpt_lan_post_receive_buckets_work); | ||
1358 | priv->post_buckets_active = 0; | 1367 | priv->post_buckets_active = 0; |
1359 | 1368 | ||
1360 | dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n", | 1369 | dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n", |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index b752a479f6db..4f0c530e47b0 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -2006,9 +2006,10 @@ __mptsas_discovery_work(MPT_ADAPTER *ioc) | |||
2006 | *(Mutex LOCKED) | 2006 | *(Mutex LOCKED) |
2007 | */ | 2007 | */ |
2008 | static void | 2008 | static void |
2009 | mptsas_discovery_work(void * arg) | 2009 | mptsas_discovery_work(struct work_struct *work) |
2010 | { | 2010 | { |
2011 | struct mptsas_discovery_event *ev = arg; | 2011 | struct mptsas_discovery_event *ev = |
2012 | container_of(work, struct mptsas_discovery_event, work); | ||
2012 | MPT_ADAPTER *ioc = ev->ioc; | 2013 | MPT_ADAPTER *ioc = ev->ioc; |
2013 | 2014 | ||
2014 | mutex_lock(&ioc->sas_discovery_mutex); | 2015 | mutex_lock(&ioc->sas_discovery_mutex); |
@@ -2068,9 +2069,9 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) | |||
2068 | * Work queue thread to clear the persitency table | 2069 | * Work queue thread to clear the persitency table |
2069 | */ | 2070 | */ |
2070 | static void | 2071 | static void |
2071 | mptsas_persist_clear_table(void * arg) | 2072 | mptsas_persist_clear_table(struct work_struct *work) |
2072 | { | 2073 | { |
2073 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; | 2074 | MPT_ADAPTER *ioc = container_of(work, MPT_ADAPTER, sas_persist_task); |
2074 | 2075 | ||
2075 | mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); | 2076 | mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); |
2076 | } | 2077 | } |
@@ -2093,9 +2094,10 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach) | |||
2093 | * Work queue thread to handle SAS hotplug events | 2094 | * Work queue thread to handle SAS hotplug events |
2094 | */ | 2095 | */ |
2095 | static void | 2096 | static void |
2096 | mptsas_hotplug_work(void *arg) | 2097 | mptsas_hotplug_work(struct work_struct *work) |
2097 | { | 2098 | { |
2098 | struct mptsas_hotplug_event *ev = arg; | 2099 | struct mptsas_hotplug_event *ev = |
2100 | container_of(work, struct mptsas_hotplug_event, work); | ||
2099 | MPT_ADAPTER *ioc = ev->ioc; | 2101 | MPT_ADAPTER *ioc = ev->ioc; |
2100 | struct mptsas_phyinfo *phy_info; | 2102 | struct mptsas_phyinfo *phy_info; |
2101 | struct sas_rphy *rphy; | 2103 | struct sas_rphy *rphy; |
@@ -2341,7 +2343,7 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc, | |||
2341 | break; | 2343 | break; |
2342 | } | 2344 | } |
2343 | 2345 | ||
2344 | INIT_WORK(&ev->work, mptsas_hotplug_work, ev); | 2346 | INIT_WORK(&ev->work, mptsas_hotplug_work); |
2345 | ev->ioc = ioc; | 2347 | ev->ioc = ioc; |
2346 | ev->handle = le16_to_cpu(sas_event_data->DevHandle); | 2348 | ev->handle = le16_to_cpu(sas_event_data->DevHandle); |
2347 | ev->parent_handle = | 2349 | ev->parent_handle = |
@@ -2366,7 +2368,7 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc, | |||
2366 | * Persistent table is full. | 2368 | * Persistent table is full. |
2367 | */ | 2369 | */ |
2368 | INIT_WORK(&ioc->sas_persist_task, | 2370 | INIT_WORK(&ioc->sas_persist_task, |
2369 | mptsas_persist_clear_table, (void *)ioc); | 2371 | mptsas_persist_clear_table); |
2370 | schedule_work(&ioc->sas_persist_task); | 2372 | schedule_work(&ioc->sas_persist_task); |
2371 | break; | 2373 | break; |
2372 | case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: | 2374 | case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: |
@@ -2395,7 +2397,7 @@ mptsas_send_raid_event(MPT_ADAPTER *ioc, | |||
2395 | return; | 2397 | return; |
2396 | } | 2398 | } |
2397 | 2399 | ||
2398 | INIT_WORK(&ev->work, mptsas_hotplug_work, ev); | 2400 | INIT_WORK(&ev->work, mptsas_hotplug_work); |
2399 | ev->ioc = ioc; | 2401 | ev->ioc = ioc; |
2400 | ev->id = raid_event_data->VolumeID; | 2402 | ev->id = raid_event_data->VolumeID; |
2401 | ev->event_type = MPTSAS_IGNORE_EVENT; | 2403 | ev->event_type = MPTSAS_IGNORE_EVENT; |
@@ -2474,7 +2476,7 @@ mptsas_send_discovery_event(MPT_ADAPTER *ioc, | |||
2474 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); | 2476 | ev = kzalloc(sizeof(*ev), GFP_ATOMIC); |
2475 | if (!ev) | 2477 | if (!ev) |
2476 | return; | 2478 | return; |
2477 | INIT_WORK(&ev->work, mptsas_discovery_work, ev); | 2479 | INIT_WORK(&ev->work, mptsas_discovery_work); |
2478 | ev->ioc = ioc; | 2480 | ev->ioc = ioc; |
2479 | schedule_work(&ev->work); | 2481 | schedule_work(&ev->work); |
2480 | }; | 2482 | }; |
@@ -2511,8 +2513,7 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) | |||
2511 | break; | 2513 | break; |
2512 | case MPI_EVENT_PERSISTENT_TABLE_FULL: | 2514 | case MPI_EVENT_PERSISTENT_TABLE_FULL: |
2513 | INIT_WORK(&ioc->sas_persist_task, | 2515 | INIT_WORK(&ioc->sas_persist_task, |
2514 | mptsas_persist_clear_table, | 2516 | mptsas_persist_clear_table); |
2515 | (void *)ioc); | ||
2516 | schedule_work(&ioc->sas_persist_task); | 2517 | schedule_work(&ioc->sas_persist_task); |
2517 | break; | 2518 | break; |
2518 | case MPI_EVENT_SAS_DISCOVERY: | 2519 | case MPI_EVENT_SAS_DISCOVERY: |
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index e4cc3dd5fc9f..f422c0d0621c 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -646,9 +646,10 @@ struct work_queue_wrapper { | |||
646 | int disk; | 646 | int disk; |
647 | }; | 647 | }; |
648 | 648 | ||
649 | static void mpt_work_wrapper(void *data) | 649 | static void mpt_work_wrapper(struct work_struct *work) |
650 | { | 650 | { |
651 | struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; | 651 | struct work_queue_wrapper *wqw = |
652 | container_of(work, struct work_queue_wrapper, work); | ||
652 | struct _MPT_SCSI_HOST *hd = wqw->hd; | 653 | struct _MPT_SCSI_HOST *hd = wqw->hd; |
653 | struct Scsi_Host *shost = hd->ioc->sh; | 654 | struct Scsi_Host *shost = hd->ioc->sh; |
654 | struct scsi_device *sdev; | 655 | struct scsi_device *sdev; |
@@ -695,7 +696,7 @@ static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk) | |||
695 | disk); | 696 | disk); |
696 | return; | 697 | return; |
697 | } | 698 | } |
698 | INIT_WORK(&wqw->work, mpt_work_wrapper, wqw); | 699 | INIT_WORK(&wqw->work, mpt_work_wrapper); |
699 | wqw->hd = hd; | 700 | wqw->hd = hd; |
700 | wqw->disk = disk; | 701 | wqw->disk = disk; |
701 | 702 | ||
@@ -784,9 +785,10 @@ MODULE_DEVICE_TABLE(pci, mptspi_pci_table); | |||
784 | * renegotiate for a given target | 785 | * renegotiate for a given target |
785 | */ | 786 | */ |
786 | static void | 787 | static void |
787 | mptspi_dv_renegotiate_work(void *data) | 788 | mptspi_dv_renegotiate_work(struct work_struct *work) |
788 | { | 789 | { |
789 | struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; | 790 | struct work_queue_wrapper *wqw = |
791 | container_of(work, struct work_queue_wrapper, work); | ||
790 | struct _MPT_SCSI_HOST *hd = wqw->hd; | 792 | struct _MPT_SCSI_HOST *hd = wqw->hd; |
791 | struct scsi_device *sdev; | 793 | struct scsi_device *sdev; |
792 | 794 | ||
@@ -804,7 +806,7 @@ mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd) | |||
804 | if (!wqw) | 806 | if (!wqw) |
805 | return; | 807 | return; |
806 | 808 | ||
807 | INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work, wqw); | 809 | INIT_WORK(&wqw->work, mptspi_dv_renegotiate_work); |
808 | wqw->hd = hd; | 810 | wqw->hd = hd; |
809 | 811 | ||
810 | schedule_work(&wqw->work); | 812 | schedule_work(&wqw->work); |
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c index 64130227574f..7fc7399bd2ec 100644 --- a/drivers/message/i2o/driver.c +++ b/drivers/message/i2o/driver.c | |||
@@ -232,7 +232,7 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m) | |||
232 | break; | 232 | break; |
233 | } | 233 | } |
234 | 234 | ||
235 | INIT_WORK(&evt->work, (void (*)(void *))drv->event, evt); | 235 | INIT_WORK(&evt->work, drv->event); |
236 | queue_work(drv->event_queue, &evt->work); | 236 | queue_work(drv->event_queue, &evt->work); |
237 | return 1; | 237 | return 1; |
238 | } | 238 | } |
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index a2350640384b..9e529d8dd5cb 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c | |||
@@ -371,8 +371,10 @@ static int i2o_exec_remove(struct device *dev) | |||
371 | * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY | 371 | * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY |
372 | * again, otherwise send LCT NOTIFY to get informed on next LCT change. | 372 | * again, otherwise send LCT NOTIFY to get informed on next LCT change. |
373 | */ | 373 | */ |
374 | static void i2o_exec_lct_modified(struct i2o_exec_lct_notify_work *work) | 374 | static void i2o_exec_lct_modified(struct work_struct *_work) |
375 | { | 375 | { |
376 | struct i2o_exec_lct_notify_work *work = | ||
377 | container_of(_work, struct i2o_exec_lct_notify_work, work); | ||
376 | u32 change_ind = 0; | 378 | u32 change_ind = 0; |
377 | struct i2o_controller *c = work->c; | 379 | struct i2o_controller *c = work->c; |
378 | 380 | ||
@@ -439,8 +441,7 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, | |||
439 | 441 | ||
440 | work->c = c; | 442 | work->c = c; |
441 | 443 | ||
442 | INIT_WORK(&work->work, (void (*)(void *))i2o_exec_lct_modified, | 444 | INIT_WORK(&work->work, i2o_exec_lct_modified); |
443 | work); | ||
444 | queue_work(i2o_exec_driver.event_queue, &work->work); | 445 | queue_work(i2o_exec_driver.event_queue, &work->work); |
445 | return 1; | 446 | return 1; |
446 | } | 447 | } |
@@ -460,13 +461,15 @@ static int i2o_exec_reply(struct i2o_controller *c, u32 m, | |||
460 | 461 | ||
461 | /** | 462 | /** |
462 | * i2o_exec_event - Event handling function | 463 | * i2o_exec_event - Event handling function |
463 | * @evt: Event which occurs | 464 | * @work: Work item in occurring event |
464 | * | 465 | * |
465 | * Handles events send by the Executive device. At the moment does not do | 466 | * Handles events send by the Executive device. At the moment does not do |
466 | * anything useful. | 467 | * anything useful. |
467 | */ | 468 | */ |
468 | static void i2o_exec_event(struct i2o_event *evt) | 469 | static void i2o_exec_event(struct work_struct *work) |
469 | { | 470 | { |
471 | struct i2o_event *evt = container_of(work, struct i2o_event, work); | ||
472 | |||
470 | if (likely(evt->i2o_dev)) | 473 | if (likely(evt->i2o_dev)) |
471 | osm_debug("Event received from device: %d\n", | 474 | osm_debug("Event received from device: %d\n", |
472 | evt->i2o_dev->lct_data.tid); | 475 | evt->i2o_dev->lct_data.tid); |
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index eaba81bf2eca..70ae00253321 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c | |||
@@ -419,16 +419,18 @@ static int i2o_block_prep_req_fn(struct request_queue *q, struct request *req) | |||
419 | 419 | ||
420 | /** | 420 | /** |
421 | * i2o_block_delayed_request_fn - delayed request queue function | 421 | * i2o_block_delayed_request_fn - delayed request queue function |
422 | * delayed_request: the delayed request with the queue to start | 422 | * @work: the delayed request with the queue to start |
423 | * | 423 | * |
424 | * If the request queue is stopped for a disk, and there is no open | 424 | * If the request queue is stopped for a disk, and there is no open |
425 | * request, a new event is created, which calls this function to start | 425 | * request, a new event is created, which calls this function to start |
426 | * the queue after I2O_BLOCK_REQUEST_TIME. Otherwise the queue will never | 426 | * the queue after I2O_BLOCK_REQUEST_TIME. Otherwise the queue will never |
427 | * be started again. | 427 | * be started again. |
428 | */ | 428 | */ |
429 | static void i2o_block_delayed_request_fn(void *delayed_request) | 429 | static void i2o_block_delayed_request_fn(struct work_struct *work) |
430 | { | 430 | { |
431 | struct i2o_block_delayed_request *dreq = delayed_request; | 431 | struct i2o_block_delayed_request *dreq = |
432 | container_of(work, struct i2o_block_delayed_request, | ||
433 | work.work); | ||
432 | struct request_queue *q = dreq->queue; | 434 | struct request_queue *q = dreq->queue; |
433 | unsigned long flags; | 435 | unsigned long flags; |
434 | 436 | ||
@@ -538,8 +540,9 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, | |||
538 | return 1; | 540 | return 1; |
539 | }; | 541 | }; |
540 | 542 | ||
541 | static void i2o_block_event(struct i2o_event *evt) | 543 | static void i2o_block_event(struct work_struct *work) |
542 | { | 544 | { |
545 | struct i2o_event *evt = container_of(work, struct i2o_event, work); | ||
543 | osm_debug("event received\n"); | 546 | osm_debug("event received\n"); |
544 | kfree(evt); | 547 | kfree(evt); |
545 | }; | 548 | }; |
@@ -938,8 +941,8 @@ static void i2o_block_request_fn(struct request_queue *q) | |||
938 | continue; | 941 | continue; |
939 | 942 | ||
940 | dreq->queue = q; | 943 | dreq->queue = q; |
941 | INIT_WORK(&dreq->work, i2o_block_delayed_request_fn, | 944 | INIT_DELAYED_WORK(&dreq->work, |
942 | dreq); | 945 | i2o_block_delayed_request_fn); |
943 | 946 | ||
944 | if (!queue_delayed_work(i2o_block_driver.event_queue, | 947 | if (!queue_delayed_work(i2o_block_driver.event_queue, |
945 | &dreq->work, | 948 | &dreq->work, |
diff --git a/drivers/message/i2o/i2o_block.h b/drivers/message/i2o/i2o_block.h index 4fdaa5bda412..d9fdc95b440d 100644 --- a/drivers/message/i2o/i2o_block.h +++ b/drivers/message/i2o/i2o_block.h | |||
@@ -96,7 +96,7 @@ struct i2o_block_request { | |||
96 | 96 | ||
97 | /* I2O Block device delayed request */ | 97 | /* I2O Block device delayed request */ |
98 | struct i2o_block_delayed_request { | 98 | struct i2o_block_delayed_request { |
99 | struct work_struct work; | 99 | struct delayed_work work; |
100 | struct request_queue *queue; | 100 | struct request_queue *queue; |
101 | }; | 101 | }; |
102 | 102 | ||
diff --git a/drivers/misc/tifm_7xx1.c b/drivers/misc/tifm_7xx1.c index 1ba8754e9383..2ab7add78f94 100644 --- a/drivers/misc/tifm_7xx1.c +++ b/drivers/misc/tifm_7xx1.c | |||
@@ -33,9 +33,10 @@ static void tifm_7xx1_eject(struct tifm_adapter *fm, struct tifm_dev *sock) | |||
33 | spin_unlock_irqrestore(&fm->lock, flags); | 33 | spin_unlock_irqrestore(&fm->lock, flags); |
34 | } | 34 | } |
35 | 35 | ||
36 | static void tifm_7xx1_remove_media(void *adapter) | 36 | static void tifm_7xx1_remove_media(struct work_struct *work) |
37 | { | 37 | { |
38 | struct tifm_adapter *fm = adapter; | 38 | struct tifm_adapter *fm = |
39 | container_of(work, struct tifm_adapter, media_remover); | ||
39 | unsigned long flags; | 40 | unsigned long flags; |
40 | int cnt; | 41 | int cnt; |
41 | struct tifm_dev *sock; | 42 | struct tifm_dev *sock; |
@@ -169,9 +170,10 @@ tifm_7xx1_sock_addr(char __iomem *base_addr, unsigned int sock_num) | |||
169 | return base_addr + ((sock_num + 1) << 10); | 170 | return base_addr + ((sock_num + 1) << 10); |
170 | } | 171 | } |
171 | 172 | ||
172 | static void tifm_7xx1_insert_media(void *adapter) | 173 | static void tifm_7xx1_insert_media(struct work_struct *work) |
173 | { | 174 | { |
174 | struct tifm_adapter *fm = adapter; | 175 | struct tifm_adapter *fm = |
176 | container_of(work, struct tifm_adapter, media_inserter); | ||
175 | unsigned long flags; | 177 | unsigned long flags; |
176 | tifm_media_id media_id; | 178 | tifm_media_id media_id; |
177 | char *card_name = "xx"; | 179 | char *card_name = "xx"; |
@@ -261,7 +263,7 @@ static int tifm_7xx1_suspend(struct pci_dev *dev, pm_message_t state) | |||
261 | spin_unlock_irqrestore(&fm->lock, flags); | 263 | spin_unlock_irqrestore(&fm->lock, flags); |
262 | flush_workqueue(fm->wq); | 264 | flush_workqueue(fm->wq); |
263 | 265 | ||
264 | tifm_7xx1_remove_media(fm); | 266 | tifm_7xx1_remove_media(&fm->media_remover); |
265 | 267 | ||
266 | pci_set_power_state(dev, PCI_D3hot); | 268 | pci_set_power_state(dev, PCI_D3hot); |
267 | pci_disable_device(dev); | 269 | pci_disable_device(dev); |
@@ -328,8 +330,8 @@ static int tifm_7xx1_probe(struct pci_dev *dev, | |||
328 | if (!fm->sockets) | 330 | if (!fm->sockets) |
329 | goto err_out_free; | 331 | goto err_out_free; |
330 | 332 | ||
331 | INIT_WORK(&fm->media_inserter, tifm_7xx1_insert_media, fm); | 333 | INIT_WORK(&fm->media_inserter, tifm_7xx1_insert_media); |
332 | INIT_WORK(&fm->media_remover, tifm_7xx1_remove_media, fm); | 334 | INIT_WORK(&fm->media_remover, tifm_7xx1_remove_media); |
333 | fm->eject = tifm_7xx1_eject; | 335 | fm->eject = tifm_7xx1_eject; |
334 | pci_set_drvdata(dev, fm); | 336 | pci_set_drvdata(dev, fm); |
335 | 337 | ||
@@ -384,7 +386,7 @@ static void tifm_7xx1_remove(struct pci_dev *dev) | |||
384 | 386 | ||
385 | flush_workqueue(fm->wq); | 387 | flush_workqueue(fm->wq); |
386 | 388 | ||
387 | tifm_7xx1_remove_media(fm); | 389 | tifm_7xx1_remove_media(&fm->media_remover); |
388 | 390 | ||
389 | writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); | 391 | writel(TIFM_IRQ_SETALL, fm->addr + FM_CLEAR_INTERRUPT_ENABLE); |
390 | free_irq(dev->irq, fm); | 392 | free_irq(dev->irq, fm); |
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 9d190022a490..6f2a282e2b97 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
@@ -1419,18 +1419,16 @@ static void mmc_setup(struct mmc_host *host) | |||
1419 | */ | 1419 | */ |
1420 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) | 1420 | void mmc_detect_change(struct mmc_host *host, unsigned long delay) |
1421 | { | 1421 | { |
1422 | if (delay) | 1422 | mmc_schedule_delayed_work(&host->detect, delay); |
1423 | mmc_schedule_delayed_work(&host->detect, delay); | ||
1424 | else | ||
1425 | mmc_schedule_work(&host->detect); | ||
1426 | } | 1423 | } |
1427 | 1424 | ||
1428 | EXPORT_SYMBOL(mmc_detect_change); | 1425 | EXPORT_SYMBOL(mmc_detect_change); |
1429 | 1426 | ||
1430 | 1427 | ||
1431 | static void mmc_rescan(void *data) | 1428 | static void mmc_rescan(struct work_struct *work) |
1432 | { | 1429 | { |
1433 | struct mmc_host *host = data; | 1430 | struct mmc_host *host = |
1431 | container_of(work, struct mmc_host, detect.work); | ||
1434 | struct list_head *l, *n; | 1432 | struct list_head *l, *n; |
1435 | unsigned char power_mode; | 1433 | unsigned char power_mode; |
1436 | 1434 | ||
@@ -1513,7 +1511,7 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
1513 | spin_lock_init(&host->lock); | 1511 | spin_lock_init(&host->lock); |
1514 | init_waitqueue_head(&host->wq); | 1512 | init_waitqueue_head(&host->wq); |
1515 | INIT_LIST_HEAD(&host->cards); | 1513 | INIT_LIST_HEAD(&host->cards); |
1516 | INIT_WORK(&host->detect, mmc_rescan, host); | 1514 | INIT_DELAYED_WORK(&host->detect, mmc_rescan); |
1517 | 1515 | ||
1518 | /* | 1516 | /* |
1519 | * By default, hosts do not support SGIO or large requests. | 1517 | * By default, hosts do not support SGIO or large requests. |
@@ -1611,7 +1609,7 @@ EXPORT_SYMBOL(mmc_suspend_host); | |||
1611 | */ | 1609 | */ |
1612 | int mmc_resume_host(struct mmc_host *host) | 1610 | int mmc_resume_host(struct mmc_host *host) |
1613 | { | 1611 | { |
1614 | mmc_rescan(host); | 1612 | mmc_rescan(&host->detect.work); |
1615 | 1613 | ||
1616 | return 0; | 1614 | return 0; |
1617 | } | 1615 | } |
diff --git a/drivers/mmc/mmc.h b/drivers/mmc/mmc.h index cd5e0ab3d84b..149affe0b686 100644 --- a/drivers/mmc/mmc.h +++ b/drivers/mmc/mmc.h | |||
@@ -20,6 +20,6 @@ void mmc_remove_host_sysfs(struct mmc_host *host); | |||
20 | void mmc_free_host_sysfs(struct mmc_host *host); | 20 | void mmc_free_host_sysfs(struct mmc_host *host); |
21 | 21 | ||
22 | int mmc_schedule_work(struct work_struct *work); | 22 | int mmc_schedule_work(struct work_struct *work); |
23 | int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay); | 23 | int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay); |
24 | void mmc_flush_scheduled_work(void); | 24 | void mmc_flush_scheduled_work(void); |
25 | #endif | 25 | #endif |
diff --git a/drivers/mmc/mmc_sysfs.c b/drivers/mmc/mmc_sysfs.c index ac5329636045..e334acd045bc 100644 --- a/drivers/mmc/mmc_sysfs.c +++ b/drivers/mmc/mmc_sysfs.c | |||
@@ -321,17 +321,9 @@ void mmc_free_host_sysfs(struct mmc_host *host) | |||
321 | static struct workqueue_struct *workqueue; | 321 | static struct workqueue_struct *workqueue; |
322 | 322 | ||
323 | /* | 323 | /* |
324 | * Internal function. Schedule work in the MMC work queue. | ||
325 | */ | ||
326 | int mmc_schedule_work(struct work_struct *work) | ||
327 | { | ||
328 | return queue_work(workqueue, work); | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * Internal function. Schedule delayed work in the MMC work queue. | 324 | * Internal function. Schedule delayed work in the MMC work queue. |
333 | */ | 325 | */ |
334 | int mmc_schedule_delayed_work(struct work_struct *work, unsigned long delay) | 326 | int mmc_schedule_delayed_work(struct delayed_work *work, unsigned long delay) |
335 | { | 327 | { |
336 | return queue_delayed_work(workqueue, work, delay); | 328 | return queue_delayed_work(workqueue, work, delay); |
337 | } | 329 | } |
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c index 0fdc55b08a6d..e846499a004c 100644 --- a/drivers/mmc/tifm_sd.c +++ b/drivers/mmc/tifm_sd.c | |||
@@ -99,7 +99,7 @@ struct tifm_sd { | |||
99 | 99 | ||
100 | struct mmc_request *req; | 100 | struct mmc_request *req; |
101 | struct work_struct cmd_handler; | 101 | struct work_struct cmd_handler; |
102 | struct work_struct abort_handler; | 102 | struct delayed_work abort_handler; |
103 | wait_queue_head_t can_eject; | 103 | wait_queue_head_t can_eject; |
104 | 104 | ||
105 | size_t written_blocks; | 105 | size_t written_blocks; |
@@ -496,9 +496,9 @@ err_out: | |||
496 | mmc_request_done(mmc, mrq); | 496 | mmc_request_done(mmc, mrq); |
497 | } | 497 | } |
498 | 498 | ||
499 | static void tifm_sd_end_cmd(void *data) | 499 | static void tifm_sd_end_cmd(struct work_struct *work) |
500 | { | 500 | { |
501 | struct tifm_sd *host = data; | 501 | struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); |
502 | struct tifm_dev *sock = host->dev; | 502 | struct tifm_dev *sock = host->dev; |
503 | struct mmc_host *mmc = tifm_get_drvdata(sock); | 503 | struct mmc_host *mmc = tifm_get_drvdata(sock); |
504 | struct mmc_request *mrq; | 504 | struct mmc_request *mrq; |
@@ -608,9 +608,9 @@ err_out: | |||
608 | mmc_request_done(mmc, mrq); | 608 | mmc_request_done(mmc, mrq); |
609 | } | 609 | } |
610 | 610 | ||
611 | static void tifm_sd_end_cmd_nodma(void *data) | 611 | static void tifm_sd_end_cmd_nodma(struct work_struct *work) |
612 | { | 612 | { |
613 | struct tifm_sd *host = (struct tifm_sd*)data; | 613 | struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); |
614 | struct tifm_dev *sock = host->dev; | 614 | struct tifm_dev *sock = host->dev; |
615 | struct mmc_host *mmc = tifm_get_drvdata(sock); | 615 | struct mmc_host *mmc = tifm_get_drvdata(sock); |
616 | struct mmc_request *mrq; | 616 | struct mmc_request *mrq; |
@@ -661,11 +661,14 @@ static void tifm_sd_end_cmd_nodma(void *data) | |||
661 | mmc_request_done(mmc, mrq); | 661 | mmc_request_done(mmc, mrq); |
662 | } | 662 | } |
663 | 663 | ||
664 | static void tifm_sd_abort(void *data) | 664 | static void tifm_sd_abort(struct work_struct *work) |
665 | { | 665 | { |
666 | struct tifm_sd *host = | ||
667 | container_of(work, struct tifm_sd, abort_handler.work); | ||
668 | |||
666 | printk(KERN_ERR DRIVER_NAME | 669 | printk(KERN_ERR DRIVER_NAME |
667 | ": card failed to respond for a long period of time"); | 670 | ": card failed to respond for a long period of time"); |
668 | tifm_eject(((struct tifm_sd*)data)->dev); | 671 | tifm_eject(host->dev); |
669 | } | 672 | } |
670 | 673 | ||
671 | static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 674 | static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
@@ -762,9 +765,9 @@ static struct mmc_host_ops tifm_sd_ops = { | |||
762 | .get_ro = tifm_sd_ro | 765 | .get_ro = tifm_sd_ro |
763 | }; | 766 | }; |
764 | 767 | ||
765 | static void tifm_sd_register_host(void *data) | 768 | static void tifm_sd_register_host(struct work_struct *work) |
766 | { | 769 | { |
767 | struct tifm_sd *host = (struct tifm_sd*)data; | 770 | struct tifm_sd *host = container_of(work, struct tifm_sd, cmd_handler); |
768 | struct tifm_dev *sock = host->dev; | 771 | struct tifm_dev *sock = host->dev; |
769 | struct mmc_host *mmc = tifm_get_drvdata(sock); | 772 | struct mmc_host *mmc = tifm_get_drvdata(sock); |
770 | unsigned long flags; | 773 | unsigned long flags; |
@@ -772,8 +775,7 @@ static void tifm_sd_register_host(void *data) | |||
772 | spin_lock_irqsave(&sock->lock, flags); | 775 | spin_lock_irqsave(&sock->lock, flags); |
773 | host->flags |= HOST_REG; | 776 | host->flags |= HOST_REG; |
774 | PREPARE_WORK(&host->cmd_handler, | 777 | PREPARE_WORK(&host->cmd_handler, |
775 | no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd, | 778 | no_dma ? tifm_sd_end_cmd_nodma : tifm_sd_end_cmd); |
776 | data); | ||
777 | spin_unlock_irqrestore(&sock->lock, flags); | 779 | spin_unlock_irqrestore(&sock->lock, flags); |
778 | dev_dbg(&sock->dev, "adding host\n"); | 780 | dev_dbg(&sock->dev, "adding host\n"); |
779 | mmc_add_host(mmc); | 781 | mmc_add_host(mmc); |
@@ -799,8 +801,8 @@ static int tifm_sd_probe(struct tifm_dev *sock) | |||
799 | host->dev = sock; | 801 | host->dev = sock; |
800 | host->clk_div = 61; | 802 | host->clk_div = 61; |
801 | init_waitqueue_head(&host->can_eject); | 803 | init_waitqueue_head(&host->can_eject); |
802 | INIT_WORK(&host->cmd_handler, tifm_sd_register_host, host); | 804 | INIT_WORK(&host->cmd_handler, tifm_sd_register_host); |
803 | INIT_WORK(&host->abort_handler, tifm_sd_abort, host); | 805 | INIT_DELAYED_WORK(&host->abort_handler, tifm_sd_abort); |
804 | 806 | ||
805 | tifm_set_drvdata(sock, mmc); | 807 | tifm_set_drvdata(sock, mmc); |
806 | sock->signal_irq = tifm_sd_signal_irq; | 808 | sock->signal_irq = tifm_sd_signal_irq; |
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index d02ed51abfcc..931028f672de 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -594,7 +594,7 @@ struct rtl8139_private { | |||
594 | u32 rx_config; | 594 | u32 rx_config; |
595 | struct rtl_extra_stats xstats; | 595 | struct rtl_extra_stats xstats; |
596 | 596 | ||
597 | struct work_struct thread; | 597 | struct delayed_work thread; |
598 | 598 | ||
599 | struct mii_if_info mii; | 599 | struct mii_if_info mii; |
600 | unsigned int regs_len; | 600 | unsigned int regs_len; |
@@ -636,8 +636,8 @@ static struct net_device_stats *rtl8139_get_stats (struct net_device *dev); | |||
636 | static void rtl8139_set_rx_mode (struct net_device *dev); | 636 | static void rtl8139_set_rx_mode (struct net_device *dev); |
637 | static void __set_rx_mode (struct net_device *dev); | 637 | static void __set_rx_mode (struct net_device *dev); |
638 | static void rtl8139_hw_start (struct net_device *dev); | 638 | static void rtl8139_hw_start (struct net_device *dev); |
639 | static void rtl8139_thread (void *_data); | 639 | static void rtl8139_thread (struct work_struct *work); |
640 | static void rtl8139_tx_timeout_task(void *_data); | 640 | static void rtl8139_tx_timeout_task(struct work_struct *work); |
641 | static const struct ethtool_ops rtl8139_ethtool_ops; | 641 | static const struct ethtool_ops rtl8139_ethtool_ops; |
642 | 642 | ||
643 | /* write MMIO register, with flush */ | 643 | /* write MMIO register, with flush */ |
@@ -1010,7 +1010,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, | |||
1010 | (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1)); | 1010 | (debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1)); |
1011 | spin_lock_init (&tp->lock); | 1011 | spin_lock_init (&tp->lock); |
1012 | spin_lock_init (&tp->rx_lock); | 1012 | spin_lock_init (&tp->rx_lock); |
1013 | INIT_WORK(&tp->thread, rtl8139_thread, dev); | 1013 | INIT_DELAYED_WORK(&tp->thread, rtl8139_thread); |
1014 | tp->mii.dev = dev; | 1014 | tp->mii.dev = dev; |
1015 | tp->mii.mdio_read = mdio_read; | 1015 | tp->mii.mdio_read = mdio_read; |
1016 | tp->mii.mdio_write = mdio_write; | 1016 | tp->mii.mdio_write = mdio_write; |
@@ -1596,15 +1596,16 @@ static inline void rtl8139_thread_iter (struct net_device *dev, | |||
1596 | RTL_R8 (Config1)); | 1596 | RTL_R8 (Config1)); |
1597 | } | 1597 | } |
1598 | 1598 | ||
1599 | static void rtl8139_thread (void *_data) | 1599 | static void rtl8139_thread (struct work_struct *work) |
1600 | { | 1600 | { |
1601 | struct net_device *dev = _data; | 1601 | struct rtl8139_private *tp = |
1602 | struct rtl8139_private *tp = netdev_priv(dev); | 1602 | container_of(work, struct rtl8139_private, thread.work); |
1603 | struct net_device *dev = tp->mii.dev; | ||
1603 | unsigned long thr_delay = next_tick; | 1604 | unsigned long thr_delay = next_tick; |
1604 | 1605 | ||
1605 | if (tp->watchdog_fired) { | 1606 | if (tp->watchdog_fired) { |
1606 | tp->watchdog_fired = 0; | 1607 | tp->watchdog_fired = 0; |
1607 | rtl8139_tx_timeout_task(_data); | 1608 | rtl8139_tx_timeout_task(work); |
1608 | } else if (rtnl_trylock()) { | 1609 | } else if (rtnl_trylock()) { |
1609 | rtl8139_thread_iter (dev, tp, tp->mmio_addr); | 1610 | rtl8139_thread_iter (dev, tp, tp->mmio_addr); |
1610 | rtnl_unlock (); | 1611 | rtnl_unlock (); |
@@ -1646,10 +1647,11 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp) | |||
1646 | /* XXX account for unsent Tx packets in tp->stats.tx_dropped */ | 1647 | /* XXX account for unsent Tx packets in tp->stats.tx_dropped */ |
1647 | } | 1648 | } |
1648 | 1649 | ||
1649 | static void rtl8139_tx_timeout_task (void *_data) | 1650 | static void rtl8139_tx_timeout_task (struct work_struct *work) |
1650 | { | 1651 | { |
1651 | struct net_device *dev = _data; | 1652 | struct rtl8139_private *tp = |
1652 | struct rtl8139_private *tp = netdev_priv(dev); | 1653 | container_of(work, struct rtl8139_private, thread.work); |
1654 | struct net_device *dev = tp->mii.dev; | ||
1653 | void __iomem *ioaddr = tp->mmio_addr; | 1655 | void __iomem *ioaddr = tp->mmio_addr; |
1654 | int i; | 1656 | int i; |
1655 | u8 tmp8; | 1657 | u8 tmp8; |
@@ -1695,7 +1697,7 @@ static void rtl8139_tx_timeout (struct net_device *dev) | |||
1695 | struct rtl8139_private *tp = netdev_priv(dev); | 1697 | struct rtl8139_private *tp = netdev_priv(dev); |
1696 | 1698 | ||
1697 | if (!tp->have_thread) { | 1699 | if (!tp->have_thread) { |
1698 | INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev); | 1700 | INIT_DELAYED_WORK(&tp->thread, rtl8139_tx_timeout_task); |
1699 | schedule_delayed_work(&tp->thread, next_tick); | 1701 | schedule_delayed_work(&tp->thread, next_tick); |
1700 | } else | 1702 | } else |
1701 | tp->watchdog_fired = 1; | 1703 | tp->watchdog_fired = 1; |
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index fc2f1d1c7ead..5bacb7587df4 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -4411,9 +4411,9 @@ bnx2_open(struct net_device *dev) | |||
4411 | } | 4411 | } |
4412 | 4412 | ||
4413 | static void | 4413 | static void |
4414 | bnx2_reset_task(void *data) | 4414 | bnx2_reset_task(struct work_struct *work) |
4415 | { | 4415 | { |
4416 | struct bnx2 *bp = data; | 4416 | struct bnx2 *bp = container_of(work, struct bnx2, reset_task); |
4417 | 4417 | ||
4418 | if (!netif_running(bp->dev)) | 4418 | if (!netif_running(bp->dev)) |
4419 | return; | 4419 | return; |
@@ -5702,7 +5702,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5702 | bp->pdev = pdev; | 5702 | bp->pdev = pdev; |
5703 | 5703 | ||
5704 | spin_lock_init(&bp->phy_lock); | 5704 | spin_lock_init(&bp->phy_lock); |
5705 | INIT_WORK(&bp->reset_task, bnx2_reset_task, bp); | 5705 | INIT_WORK(&bp->reset_task, bnx2_reset_task); |
5706 | 5706 | ||
5707 | dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0); | 5707 | dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0); |
5708 | mem_len = MB_GET_CID_ADDR(TX_TSS_CID + 1); | 5708 | mem_len = MB_GET_CID_ADDR(TX_TSS_CID + 1); |
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index fd2cc13f7d97..c8126484c2be 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c | |||
@@ -4066,9 +4066,9 @@ static int cas_alloc_rxds(struct cas *cp) | |||
4066 | return 0; | 4066 | return 0; |
4067 | } | 4067 | } |
4068 | 4068 | ||
4069 | static void cas_reset_task(void *data) | 4069 | static void cas_reset_task(struct work_struct *work) |
4070 | { | 4070 | { |
4071 | struct cas *cp = (struct cas *) data; | 4071 | struct cas *cp = container_of(work, struct cas, reset_task); |
4072 | #if 0 | 4072 | #if 0 |
4073 | int pending = atomic_read(&cp->reset_task_pending); | 4073 | int pending = atomic_read(&cp->reset_task_pending); |
4074 | #else | 4074 | #else |
@@ -5006,7 +5006,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev, | |||
5006 | atomic_set(&cp->reset_task_pending_spare, 0); | 5006 | atomic_set(&cp->reset_task_pending_spare, 0); |
5007 | atomic_set(&cp->reset_task_pending_mtu, 0); | 5007 | atomic_set(&cp->reset_task_pending_mtu, 0); |
5008 | #endif | 5008 | #endif |
5009 | INIT_WORK(&cp->reset_task, cas_reset_task, cp); | 5009 | INIT_WORK(&cp->reset_task, cas_reset_task); |
5010 | 5010 | ||
5011 | /* Default link parameters */ | 5011 | /* Default link parameters */ |
5012 | if (link_mode >= 0 && link_mode <= 6) | 5012 | if (link_mode >= 0 && link_mode <= 6) |
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h index b265941e1372..74758d2c7af8 100644 --- a/drivers/net/chelsio/common.h +++ b/drivers/net/chelsio/common.h | |||
@@ -279,7 +279,7 @@ struct adapter { | |||
279 | struct petp *tp; | 279 | struct petp *tp; |
280 | 280 | ||
281 | struct port_info port[MAX_NPORTS]; | 281 | struct port_info port[MAX_NPORTS]; |
282 | struct work_struct stats_update_task; | 282 | struct delayed_work stats_update_task; |
283 | struct timer_list stats_update_timer; | 283 | struct timer_list stats_update_timer; |
284 | 284 | ||
285 | spinlock_t tpi_lock; | 285 | spinlock_t tpi_lock; |
diff --git a/drivers/net/chelsio/cphy.h b/drivers/net/chelsio/cphy.h index 60901f25014e..cf9143499882 100644 --- a/drivers/net/chelsio/cphy.h +++ b/drivers/net/chelsio/cphy.h | |||
@@ -91,7 +91,7 @@ struct cphy { | |||
91 | int state; /* Link status state machine */ | 91 | int state; /* Link status state machine */ |
92 | adapter_t *adapter; /* associated adapter */ | 92 | adapter_t *adapter; /* associated adapter */ |
93 | 93 | ||
94 | struct work_struct phy_update; | 94 | struct delayed_work phy_update; |
95 | 95 | ||
96 | u16 bmsr; | 96 | u16 bmsr; |
97 | int count; | 97 | int count; |
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index 53bec6739812..de48eadddbc4 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c | |||
@@ -953,10 +953,11 @@ static void t1_netpoll(struct net_device *dev) | |||
953 | * Periodic accumulation of MAC statistics. This is used only if the MAC | 953 | * Periodic accumulation of MAC statistics. This is used only if the MAC |
954 | * does not have any other way to prevent stats counter overflow. | 954 | * does not have any other way to prevent stats counter overflow. |
955 | */ | 955 | */ |
956 | static void mac_stats_task(void *data) | 956 | static void mac_stats_task(struct work_struct *work) |
957 | { | 957 | { |
958 | int i; | 958 | int i; |
959 | struct adapter *adapter = data; | 959 | struct adapter *adapter = |
960 | container_of(work, struct adapter, stats_update_task.work); | ||
960 | 961 | ||
961 | for_each_port(adapter, i) { | 962 | for_each_port(adapter, i) { |
962 | struct port_info *p = &adapter->port[i]; | 963 | struct port_info *p = &adapter->port[i]; |
@@ -977,9 +978,10 @@ static void mac_stats_task(void *data) | |||
977 | /* | 978 | /* |
978 | * Processes elmer0 external interrupts in process context. | 979 | * Processes elmer0 external interrupts in process context. |
979 | */ | 980 | */ |
980 | static void ext_intr_task(void *data) | 981 | static void ext_intr_task(struct work_struct *work) |
981 | { | 982 | { |
982 | struct adapter *adapter = data; | 983 | struct adapter *adapter = |
984 | container_of(work, struct adapter, ext_intr_handler_task); | ||
983 | 985 | ||
984 | t1_elmer0_ext_intr_handler(adapter); | 986 | t1_elmer0_ext_intr_handler(adapter); |
985 | 987 | ||
@@ -1113,9 +1115,9 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
1113 | spin_lock_init(&adapter->mac_lock); | 1115 | spin_lock_init(&adapter->mac_lock); |
1114 | 1116 | ||
1115 | INIT_WORK(&adapter->ext_intr_handler_task, | 1117 | INIT_WORK(&adapter->ext_intr_handler_task, |
1116 | ext_intr_task, adapter); | 1118 | ext_intr_task); |
1117 | INIT_WORK(&adapter->stats_update_task, mac_stats_task, | 1119 | INIT_DELAYED_WORK(&adapter->stats_update_task, |
1118 | adapter); | 1120 | mac_stats_task); |
1119 | 1121 | ||
1120 | pci_set_drvdata(pdev, netdev); | 1122 | pci_set_drvdata(pdev, netdev); |
1121 | } | 1123 | } |
diff --git a/drivers/net/chelsio/my3126.c b/drivers/net/chelsio/my3126.c index 0b90014d5b3e..c7731b6f9de3 100644 --- a/drivers/net/chelsio/my3126.c +++ b/drivers/net/chelsio/my3126.c | |||
@@ -93,9 +93,11 @@ static int my3126_interrupt_handler(struct cphy *cphy) | |||
93 | return cphy_cause_link_change; | 93 | return cphy_cause_link_change; |
94 | } | 94 | } |
95 | 95 | ||
96 | static void my3216_poll(void *arg) | 96 | static void my3216_poll(struct work_struct *work) |
97 | { | 97 | { |
98 | my3126_interrupt_handler(arg); | 98 | struct cphy *cphy = container_of(work, struct cphy, phy_update.work); |
99 | |||
100 | my3126_interrupt_handler(cphy); | ||
99 | } | 101 | } |
100 | 102 | ||
101 | static int my3126_set_loopback(struct cphy *cphy, int on) | 103 | static int my3126_set_loopback(struct cphy *cphy, int on) |
@@ -171,7 +173,7 @@ static struct cphy *my3126_phy_create(adapter_t *adapter, | |||
171 | if (cphy) | 173 | if (cphy) |
172 | cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops); | 174 | cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops); |
173 | 175 | ||
174 | INIT_WORK(&cphy->phy_update, my3216_poll, cphy); | 176 | INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll); |
175 | cphy->bmsr = 0; | 177 | cphy->bmsr = 0; |
176 | 178 | ||
177 | return (cphy); | 179 | return (cphy); |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 3a8df479cbda..03bf164f9e8d 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -2102,9 +2102,10 @@ static void e100_tx_timeout(struct net_device *netdev) | |||
2102 | schedule_work(&nic->tx_timeout_task); | 2102 | schedule_work(&nic->tx_timeout_task); |
2103 | } | 2103 | } |
2104 | 2104 | ||
2105 | static void e100_tx_timeout_task(struct net_device *netdev) | 2105 | static void e100_tx_timeout_task(struct work_struct *work) |
2106 | { | 2106 | { |
2107 | struct nic *nic = netdev_priv(netdev); | 2107 | struct nic *nic = container_of(work, struct nic, tx_timeout_task); |
2108 | struct net_device *netdev = nic->netdev; | ||
2108 | 2109 | ||
2109 | DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n", | 2110 | DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n", |
2110 | readb(&nic->csr->scb.status)); | 2111 | readb(&nic->csr->scb.status)); |
@@ -2637,8 +2638,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, | |||
2637 | nic->blink_timer.function = e100_blink_led; | 2638 | nic->blink_timer.function = e100_blink_led; |
2638 | nic->blink_timer.data = (unsigned long)nic; | 2639 | nic->blink_timer.data = (unsigned long)nic; |
2639 | 2640 | ||
2640 | INIT_WORK(&nic->tx_timeout_task, | 2641 | INIT_WORK(&nic->tx_timeout_task, e100_tx_timeout_task); |
2641 | (void (*)(void *))e100_tx_timeout_task, netdev); | ||
2642 | 2642 | ||
2643 | if((err = e100_alloc(nic))) { | 2643 | if((err = e100_alloc(nic))) { |
2644 | DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n"); | 2644 | DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n"); |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 32dde0adb683..73f3a85fd238 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -190,7 +190,7 @@ void e1000_set_ethtool_ops(struct net_device *netdev); | |||
190 | static void e1000_enter_82542_rst(struct e1000_adapter *adapter); | 190 | static void e1000_enter_82542_rst(struct e1000_adapter *adapter); |
191 | static void e1000_leave_82542_rst(struct e1000_adapter *adapter); | 191 | static void e1000_leave_82542_rst(struct e1000_adapter *adapter); |
192 | static void e1000_tx_timeout(struct net_device *dev); | 192 | static void e1000_tx_timeout(struct net_device *dev); |
193 | static void e1000_reset_task(struct net_device *dev); | 193 | static void e1000_reset_task(struct work_struct *work); |
194 | static void e1000_smartspeed(struct e1000_adapter *adapter); | 194 | static void e1000_smartspeed(struct e1000_adapter *adapter); |
195 | static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, | 195 | static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter, |
196 | struct sk_buff *skb); | 196 | struct sk_buff *skb); |
@@ -914,8 +914,7 @@ e1000_probe(struct pci_dev *pdev, | |||
914 | adapter->phy_info_timer.function = &e1000_update_phy_info; | 914 | adapter->phy_info_timer.function = &e1000_update_phy_info; |
915 | adapter->phy_info_timer.data = (unsigned long) adapter; | 915 | adapter->phy_info_timer.data = (unsigned long) adapter; |
916 | 916 | ||
917 | INIT_WORK(&adapter->reset_task, | 917 | INIT_WORK(&adapter->reset_task, e1000_reset_task); |
918 | (void (*)(void *))e1000_reset_task, netdev); | ||
919 | 918 | ||
920 | e1000_check_options(adapter); | 919 | e1000_check_options(adapter); |
921 | 920 | ||
@@ -3306,9 +3305,10 @@ e1000_tx_timeout(struct net_device *netdev) | |||
3306 | } | 3305 | } |
3307 | 3306 | ||
3308 | static void | 3307 | static void |
3309 | e1000_reset_task(struct net_device *netdev) | 3308 | e1000_reset_task(struct work_struct *work) |
3310 | { | 3309 | { |
3311 | struct e1000_adapter *adapter = netdev_priv(netdev); | 3310 | struct e1000_adapter *adapter = |
3311 | container_of(work, struct e1000_adapter, reset_task); | ||
3312 | 3312 | ||
3313 | e1000_reinit_locked(adapter); | 3313 | e1000_reinit_locked(adapter); |
3314 | } | 3314 | } |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 6ad696101418..83fa32f72398 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -2224,11 +2224,12 @@ static int ehea_stop(struct net_device *dev) | |||
2224 | return ret; | 2224 | return ret; |
2225 | } | 2225 | } |
2226 | 2226 | ||
2227 | static void ehea_reset_port(void *data) | 2227 | static void ehea_reset_port(struct work_struct *work) |
2228 | { | 2228 | { |
2229 | int ret; | 2229 | int ret; |
2230 | struct net_device *dev = data; | 2230 | struct ehea_port *port = |
2231 | struct ehea_port *port = netdev_priv(dev); | 2231 | container_of(work, struct ehea_port, reset_task); |
2232 | struct net_device *dev = port->netdev; | ||
2232 | 2233 | ||
2233 | port->resets++; | 2234 | port->resets++; |
2234 | down(&port->port_lock); | 2235 | down(&port->port_lock); |
@@ -2379,7 +2380,7 @@ static int ehea_setup_single_port(struct ehea_port *port, | |||
2379 | dev->tx_timeout = &ehea_tx_watchdog; | 2380 | dev->tx_timeout = &ehea_tx_watchdog; |
2380 | dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; | 2381 | dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; |
2381 | 2382 | ||
2382 | INIT_WORK(&port->reset_task, ehea_reset_port, dev); | 2383 | INIT_WORK(&port->reset_task, ehea_reset_port); |
2383 | 2384 | ||
2384 | ehea_set_ethtool_ops(dev); | 2385 | ehea_set_ethtool_ops(dev); |
2385 | 2386 | ||
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 1ed9cccd3c11..3c33d6f6a6a6 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -168,8 +168,9 @@ struct baycom_state { | |||
168 | int magic; | 168 | int magic; |
169 | 169 | ||
170 | struct pardevice *pdev; | 170 | struct pardevice *pdev; |
171 | struct net_device *dev; | ||
171 | unsigned int work_running; | 172 | unsigned int work_running; |
172 | struct work_struct run_work; | 173 | struct delayed_work run_work; |
173 | unsigned int modem; | 174 | unsigned int modem; |
174 | unsigned int bitrate; | 175 | unsigned int bitrate; |
175 | unsigned char stat; | 176 | unsigned char stat; |
@@ -659,16 +660,18 @@ static int receive(struct net_device *dev, int cnt) | |||
659 | #define GETTICK(x) | 660 | #define GETTICK(x) |
660 | #endif /* __i386__ */ | 661 | #endif /* __i386__ */ |
661 | 662 | ||
662 | static void epp_bh(struct net_device *dev) | 663 | static void epp_bh(struct work_struct *work) |
663 | { | 664 | { |
665 | struct net_device *dev; | ||
664 | struct baycom_state *bc; | 666 | struct baycom_state *bc; |
665 | struct parport *pp; | 667 | struct parport *pp; |
666 | unsigned char stat; | 668 | unsigned char stat; |
667 | unsigned char tmp[2]; | 669 | unsigned char tmp[2]; |
668 | unsigned int time1 = 0, time2 = 0, time3 = 0; | 670 | unsigned int time1 = 0, time2 = 0, time3 = 0; |
669 | int cnt, cnt2; | 671 | int cnt, cnt2; |
670 | 672 | ||
671 | bc = netdev_priv(dev); | 673 | bc = container_of(work, struct baycom_state, run_work.work); |
674 | dev = bc->dev; | ||
672 | if (!bc->work_running) | 675 | if (!bc->work_running) |
673 | return; | 676 | return; |
674 | baycom_int_freq(bc); | 677 | baycom_int_freq(bc); |
@@ -889,7 +892,7 @@ static int epp_open(struct net_device *dev) | |||
889 | return -EBUSY; | 892 | return -EBUSY; |
890 | } | 893 | } |
891 | dev->irq = /*pp->irq*/ 0; | 894 | dev->irq = /*pp->irq*/ 0; |
892 | INIT_WORK(&bc->run_work, (void *)(void *)epp_bh, dev); | 895 | INIT_DELAYED_WORK(&bc->run_work, epp_bh); |
893 | bc->work_running = 1; | 896 | bc->work_running = 1; |
894 | bc->modem = EPP_CONVENTIONAL; | 897 | bc->modem = EPP_CONVENTIONAL; |
895 | if (eppconfig(bc)) | 898 | if (eppconfig(bc)) |
@@ -1213,6 +1216,7 @@ static void __init baycom_epp_dev_setup(struct net_device *dev) | |||
1213 | /* | 1216 | /* |
1214 | * initialize part of the baycom_state struct | 1217 | * initialize part of the baycom_state struct |
1215 | */ | 1218 | */ |
1219 | bc->dev = dev; | ||
1216 | bc->magic = BAYCOM_MAGIC; | 1220 | bc->magic = BAYCOM_MAGIC; |
1217 | bc->cfg.fclk = 19666600; | 1221 | bc->cfg.fclk = 19666600; |
1218 | bc->cfg.bps = 9600; | 1222 | bc->cfg.bps = 9600; |
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c index 0f8b9afd55b4..e6e721aff6f6 100644 --- a/drivers/net/hamradio/dmascc.c +++ b/drivers/net/hamradio/dmascc.c | |||
@@ -252,7 +252,7 @@ static inline void z8530_isr(struct scc_info *info); | |||
252 | static irqreturn_t scc_isr(int irq, void *dev_id); | 252 | static irqreturn_t scc_isr(int irq, void *dev_id); |
253 | static void rx_isr(struct scc_priv *priv); | 253 | static void rx_isr(struct scc_priv *priv); |
254 | static void special_condition(struct scc_priv *priv, int rc); | 254 | static void special_condition(struct scc_priv *priv, int rc); |
255 | static void rx_bh(void *arg); | 255 | static void rx_bh(struct work_struct *); |
256 | static void tx_isr(struct scc_priv *priv); | 256 | static void tx_isr(struct scc_priv *priv); |
257 | static void es_isr(struct scc_priv *priv); | 257 | static void es_isr(struct scc_priv *priv); |
258 | static void tm_isr(struct scc_priv *priv); | 258 | static void tm_isr(struct scc_priv *priv); |
@@ -579,7 +579,7 @@ static int __init setup_adapter(int card_base, int type, int n) | |||
579 | priv->param.clocks = TCTRxCP | RCRTxCP; | 579 | priv->param.clocks = TCTRxCP | RCRTxCP; |
580 | priv->param.persist = 256; | 580 | priv->param.persist = 256; |
581 | priv->param.dma = -1; | 581 | priv->param.dma = -1; |
582 | INIT_WORK(&priv->rx_work, rx_bh, priv); | 582 | INIT_WORK(&priv->rx_work, rx_bh); |
583 | dev->priv = priv; | 583 | dev->priv = priv; |
584 | sprintf(dev->name, "dmascc%i", 2 * n + i); | 584 | sprintf(dev->name, "dmascc%i", 2 * n + i); |
585 | dev->base_addr = card_base; | 585 | dev->base_addr = card_base; |
@@ -1272,9 +1272,9 @@ static void special_condition(struct scc_priv *priv, int rc) | |||
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | 1274 | ||
1275 | static void rx_bh(void *arg) | 1275 | static void rx_bh(struct work_struct *ugli_api) |
1276 | { | 1276 | { |
1277 | struct scc_priv *priv = arg; | 1277 | struct scc_priv *priv = container_of(ugli_api, struct scc_priv, rx_work); |
1278 | int i = priv->rx_tail; | 1278 | int i = priv->rx_tail; |
1279 | int cb; | 1279 | int cb; |
1280 | unsigned long flags; | 1280 | unsigned long flags; |
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h index f73f10a0a562..407d2acbf7c7 100644 --- a/drivers/net/ibm_emac/ibm_emac_mal.h +++ b/drivers/net/ibm_emac/ibm_emac_mal.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/netdevice.h> | 24 | #include <linux/netdevice.h> |
25 | 25 | ||
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <asm/dcr.h> | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * These MAL "versions" probably aren't the real versions IBM uses for these | 30 | * These MAL "versions" probably aren't the real versions IBM uses for these |
@@ -191,6 +192,7 @@ struct mal_commac { | |||
191 | 192 | ||
192 | struct ibm_ocp_mal { | 193 | struct ibm_ocp_mal { |
193 | int dcrbase; | 194 | int dcrbase; |
195 | dcr_host_t dcrhost; | ||
194 | 196 | ||
195 | struct list_head poll_list; | 197 | struct list_head poll_list; |
196 | struct net_device poll_dev; | 198 | struct net_device poll_dev; |
@@ -207,12 +209,12 @@ struct ibm_ocp_mal { | |||
207 | 209 | ||
208 | static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg) | 210 | static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg) |
209 | { | 211 | { |
210 | return mfdcr(mal->dcrbase + reg); | 212 | return dcr_read(mal->dcrhost, mal->dcrbase + reg); |
211 | } | 213 | } |
212 | 214 | ||
213 | static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val) | 215 | static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val) |
214 | { | 216 | { |
215 | mtdcr(mal->dcrbase + reg, val); | 217 | dcr_write(mal->dcrhost, mal->dcrbase + reg, val); |
216 | } | 218 | } |
217 | 219 | ||
218 | /* Register MAL devices */ | 220 | /* Register MAL devices */ |
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 44c9f993dcc4..99343b5836b8 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <asm/semaphore.h> | 50 | #include <asm/semaphore.h> |
51 | #include <asm/hvcall.h> | 51 | #include <asm/hvcall.h> |
52 | #include <asm/atomic.h> | 52 | #include <asm/atomic.h> |
53 | #include <asm/iommu.h> | ||
54 | #include <asm/vio.h> | 53 | #include <asm/vio.h> |
55 | #include <asm/uaccess.h> | 54 | #include <asm/uaccess.h> |
56 | #include <linux/seq_file.h> | 55 | #include <linux/seq_file.h> |
@@ -1000,8 +999,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ | |||
1000 | adapter->mac_addr = 0; | 999 | adapter->mac_addr = 0; |
1001 | memcpy(&adapter->mac_addr, mac_addr_p, 6); | 1000 | memcpy(&adapter->mac_addr, mac_addr_p, 6); |
1002 | 1001 | ||
1003 | adapter->liobn = dev->iommu_table->it_index; | ||
1004 | |||
1005 | netdev->irq = dev->irq; | 1002 | netdev->irq = dev->irq; |
1006 | netdev->open = ibmveth_open; | 1003 | netdev->open = ibmveth_open; |
1007 | netdev->poll = ibmveth_poll; | 1004 | netdev->poll = ibmveth_poll; |
@@ -1115,7 +1112,6 @@ static int ibmveth_seq_show(struct seq_file *seq, void *v) | |||
1115 | seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version); | 1112 | seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version); |
1116 | 1113 | ||
1117 | seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address); | 1114 | seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address); |
1118 | seq_printf(seq, "LIOBN: 0x%lx\n", adapter->liobn); | ||
1119 | seq_printf(seq, "Current MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", | 1115 | seq_printf(seq, "Current MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", |
1120 | current_mac[0], current_mac[1], current_mac[2], | 1116 | current_mac[0], current_mac[1], current_mac[2], |
1121 | current_mac[3], current_mac[4], current_mac[5]); | 1117 | current_mac[3], current_mac[4], current_mac[5]); |
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index f5b25bff1540..bb69ccae8ace 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h | |||
@@ -118,7 +118,6 @@ struct ibmveth_adapter { | |||
118 | struct net_device_stats stats; | 118 | struct net_device_stats stats; |
119 | unsigned int mcastFilterSize; | 119 | unsigned int mcastFilterSize; |
120 | unsigned long mac_addr; | 120 | unsigned long mac_addr; |
121 | unsigned long liobn; | ||
122 | void * buffer_list_addr; | 121 | void * buffer_list_addr; |
123 | void * filter_list_addr; | 122 | void * filter_list_addr; |
124 | dma_addr_t buffer_list_dma; | 123 | dma_addr_t buffer_list_dma; |
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index b32c52ed19d7..f0c61f3b2a82 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c | |||
@@ -560,9 +560,9 @@ static inline int mcs_find_endpoints(struct mcs_cb *mcs, | |||
560 | return ret; | 560 | return ret; |
561 | } | 561 | } |
562 | 562 | ||
563 | static void mcs_speed_work(void *arg) | 563 | static void mcs_speed_work(struct work_struct *work) |
564 | { | 564 | { |
565 | struct mcs_cb *mcs = arg; | 565 | struct mcs_cb *mcs = container_of(work, struct mcs_cb, work); |
566 | struct net_device *netdev = mcs->netdev; | 566 | struct net_device *netdev = mcs->netdev; |
567 | 567 | ||
568 | mcs_speed_change(mcs); | 568 | mcs_speed_change(mcs); |
@@ -927,7 +927,7 @@ static int mcs_probe(struct usb_interface *intf, | |||
927 | irda_qos_bits_to_value(&mcs->qos); | 927 | irda_qos_bits_to_value(&mcs->qos); |
928 | 928 | ||
929 | /* Speed change work initialisation*/ | 929 | /* Speed change work initialisation*/ |
930 | INIT_WORK(&mcs->work, mcs_speed_work, mcs); | 930 | INIT_WORK(&mcs->work, mcs_speed_work); |
931 | 931 | ||
932 | /* Override the network functions we need to use */ | 932 | /* Override the network functions we need to use */ |
933 | ndev->hard_start_xmit = mcs_hard_xmit; | 933 | ndev->hard_start_xmit = mcs_hard_xmit; |
diff --git a/drivers/net/irda/sir-dev.h b/drivers/net/irda/sir-dev.h index 9fa294a546d6..2a57bc67ce35 100644 --- a/drivers/net/irda/sir-dev.h +++ b/drivers/net/irda/sir-dev.h | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | struct sir_fsm { | 23 | struct sir_fsm { |
24 | struct semaphore sem; | 24 | struct semaphore sem; |
25 | struct work_struct work; | 25 | struct delayed_work work; |
26 | unsigned state, substate; | 26 | unsigned state, substate; |
27 | int param; | 27 | int param; |
28 | int result; | 28 | int result; |
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 3b5854d10c17..17b0c3ab6201 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c | |||
@@ -100,9 +100,9 @@ static int sirdev_tx_complete_fsm(struct sir_dev *dev) | |||
100 | * Both must be unlocked/restarted on completion - but only on final exit. | 100 | * Both must be unlocked/restarted on completion - but only on final exit. |
101 | */ | 101 | */ |
102 | 102 | ||
103 | static void sirdev_config_fsm(void *data) | 103 | static void sirdev_config_fsm(struct work_struct *work) |
104 | { | 104 | { |
105 | struct sir_dev *dev = data; | 105 | struct sir_dev *dev = container_of(work, struct sir_dev, fsm.work.work); |
106 | struct sir_fsm *fsm = &dev->fsm; | 106 | struct sir_fsm *fsm = &dev->fsm; |
107 | int next_state; | 107 | int next_state; |
108 | int ret = -1; | 108 | int ret = -1; |
@@ -309,8 +309,8 @@ int sirdev_schedule_request(struct sir_dev *dev, int initial_state, unsigned par | |||
309 | fsm->param = param; | 309 | fsm->param = param; |
310 | fsm->result = 0; | 310 | fsm->result = 0; |
311 | 311 | ||
312 | INIT_WORK(&fsm->work, sirdev_config_fsm, dev); | 312 | INIT_DELAYED_WORK(&fsm->work, sirdev_config_fsm); |
313 | queue_work(irda_sir_wq, &fsm->work); | 313 | queue_delayed_work(irda_sir_wq, &fsm->work, 0); |
314 | return 0; | 314 | return 0; |
315 | } | 315 | } |
316 | 316 | ||
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 2284e2ce1692..d6f4f185bf37 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c | |||
@@ -166,7 +166,7 @@ struct veth_msg { | |||
166 | 166 | ||
167 | struct veth_lpar_connection { | 167 | struct veth_lpar_connection { |
168 | HvLpIndex remote_lp; | 168 | HvLpIndex remote_lp; |
169 | struct work_struct statemachine_wq; | 169 | struct delayed_work statemachine_wq; |
170 | struct veth_msg *msgs; | 170 | struct veth_msg *msgs; |
171 | int num_events; | 171 | int num_events; |
172 | struct veth_cap_data local_caps; | 172 | struct veth_cap_data local_caps; |
@@ -456,7 +456,7 @@ static struct kobj_type veth_port_ktype = { | |||
456 | 456 | ||
457 | static inline void veth_kick_statemachine(struct veth_lpar_connection *cnx) | 457 | static inline void veth_kick_statemachine(struct veth_lpar_connection *cnx) |
458 | { | 458 | { |
459 | schedule_work(&cnx->statemachine_wq); | 459 | schedule_delayed_work(&cnx->statemachine_wq, 0); |
460 | } | 460 | } |
461 | 461 | ||
462 | static void veth_take_cap(struct veth_lpar_connection *cnx, | 462 | static void veth_take_cap(struct veth_lpar_connection *cnx, |
@@ -638,9 +638,11 @@ static int veth_process_caps(struct veth_lpar_connection *cnx) | |||
638 | } | 638 | } |
639 | 639 | ||
640 | /* FIXME: The gotos here are a bit dubious */ | 640 | /* FIXME: The gotos here are a bit dubious */ |
641 | static void veth_statemachine(void *p) | 641 | static void veth_statemachine(struct work_struct *work) |
642 | { | 642 | { |
643 | struct veth_lpar_connection *cnx = (struct veth_lpar_connection *)p; | 643 | struct veth_lpar_connection *cnx = |
644 | container_of(work, struct veth_lpar_connection, | ||
645 | statemachine_wq.work); | ||
644 | int rlp = cnx->remote_lp; | 646 | int rlp = cnx->remote_lp; |
645 | int rc; | 647 | int rc; |
646 | 648 | ||
@@ -827,7 +829,7 @@ static int veth_init_connection(u8 rlp) | |||
827 | 829 | ||
828 | cnx->remote_lp = rlp; | 830 | cnx->remote_lp = rlp; |
829 | spin_lock_init(&cnx->lock); | 831 | spin_lock_init(&cnx->lock); |
830 | INIT_WORK(&cnx->statemachine_wq, veth_statemachine, cnx); | 832 | INIT_DELAYED_WORK(&cnx->statemachine_wq, veth_statemachine); |
831 | 833 | ||
832 | init_timer(&cnx->ack_timer); | 834 | init_timer(&cnx->ack_timer); |
833 | cnx->ack_timer.function = veth_timed_ack; | 835 | cnx->ack_timer.function = veth_timed_ack; |
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 7b127212e62b..e628126c9c49 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c | |||
@@ -106,7 +106,7 @@ static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter); | |||
106 | static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter); | 106 | static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter); |
107 | void ixgb_set_ethtool_ops(struct net_device *netdev); | 107 | void ixgb_set_ethtool_ops(struct net_device *netdev); |
108 | static void ixgb_tx_timeout(struct net_device *dev); | 108 | static void ixgb_tx_timeout(struct net_device *dev); |
109 | static void ixgb_tx_timeout_task(struct net_device *dev); | 109 | static void ixgb_tx_timeout_task(struct work_struct *work); |
110 | static void ixgb_vlan_rx_register(struct net_device *netdev, | 110 | static void ixgb_vlan_rx_register(struct net_device *netdev, |
111 | struct vlan_group *grp); | 111 | struct vlan_group *grp); |
112 | static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); | 112 | static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); |
@@ -489,8 +489,7 @@ ixgb_probe(struct pci_dev *pdev, | |||
489 | adapter->watchdog_timer.function = &ixgb_watchdog; | 489 | adapter->watchdog_timer.function = &ixgb_watchdog; |
490 | adapter->watchdog_timer.data = (unsigned long)adapter; | 490 | adapter->watchdog_timer.data = (unsigned long)adapter; |
491 | 491 | ||
492 | INIT_WORK(&adapter->tx_timeout_task, | 492 | INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task); |
493 | (void (*)(void *))ixgb_tx_timeout_task, netdev); | ||
494 | 493 | ||
495 | strcpy(netdev->name, "eth%d"); | 494 | strcpy(netdev->name, "eth%d"); |
496 | if((err = register_netdev(netdev))) | 495 | if((err = register_netdev(netdev))) |
@@ -1493,9 +1492,10 @@ ixgb_tx_timeout(struct net_device *netdev) | |||
1493 | } | 1492 | } |
1494 | 1493 | ||
1495 | static void | 1494 | static void |
1496 | ixgb_tx_timeout_task(struct net_device *netdev) | 1495 | ixgb_tx_timeout_task(struct work_struct *work) |
1497 | { | 1496 | { |
1498 | struct ixgb_adapter *adapter = netdev_priv(netdev); | 1497 | struct ixgb_adapter *adapter = |
1498 | container_of(work, struct ixgb_adapter, tx_timeout_task); | ||
1499 | 1499 | ||
1500 | adapter->tx_timeout_count++; | 1500 | adapter->tx_timeout_count++; |
1501 | ixgb_down(adapter, TRUE); | 1501 | ixgb_down(adapter, TRUE); |
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 21d0137b6004..c41ae4286eea 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -277,9 +277,11 @@ static void mv643xx_eth_tx_timeout(struct net_device *dev) | |||
277 | * | 277 | * |
278 | * Actual routine to reset the adapter when a timeout on Tx has occurred | 278 | * Actual routine to reset the adapter when a timeout on Tx has occurred |
279 | */ | 279 | */ |
280 | static void mv643xx_eth_tx_timeout_task(struct net_device *dev) | 280 | static void mv643xx_eth_tx_timeout_task(struct work_struct *ugly) |
281 | { | 281 | { |
282 | struct mv643xx_private *mp = netdev_priv(dev); | 282 | struct mv643xx_private *mp = container_of(ugly, struct mv643xx_private, |
283 | tx_timeout_task); | ||
284 | struct net_device *dev = mp->mii.dev; /* yuck */ | ||
283 | 285 | ||
284 | if (!netif_running(dev)) | 286 | if (!netif_running(dev)) |
285 | return; | 287 | return; |
@@ -1360,8 +1362,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
1360 | #endif | 1362 | #endif |
1361 | 1363 | ||
1362 | /* Configure the timeout task */ | 1364 | /* Configure the timeout task */ |
1363 | INIT_WORK(&mp->tx_timeout_task, | 1365 | INIT_WORK(&mp->tx_timeout_task, mv643xx_eth_tx_timeout_task); |
1364 | (void (*)(void *))mv643xx_eth_tx_timeout_task, dev); | ||
1365 | 1366 | ||
1366 | spin_lock_init(&mp->lock); | 1367 | spin_lock_init(&mp->lock); |
1367 | 1368 | ||
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index d320bbeeeff6..b8f57df1091a 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -2620,9 +2620,10 @@ static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp) | |||
2620 | * This watchdog is used to check whether the board has suffered | 2620 | * This watchdog is used to check whether the board has suffered |
2621 | * from a parity error and needs to be recovered. | 2621 | * from a parity error and needs to be recovered. |
2622 | */ | 2622 | */ |
2623 | static void myri10ge_watchdog(void *arg) | 2623 | static void myri10ge_watchdog(struct work_struct *work) |
2624 | { | 2624 | { |
2625 | struct myri10ge_priv *mgp = arg; | 2625 | struct myri10ge_priv *mgp = |
2626 | container_of(work, struct myri10ge_priv, watchdog_work); | ||
2626 | u32 reboot; | 2627 | u32 reboot; |
2627 | int status; | 2628 | int status; |
2628 | u16 cmd, vendor; | 2629 | u16 cmd, vendor; |
@@ -2892,7 +2893,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2892 | (unsigned long)mgp); | 2893 | (unsigned long)mgp); |
2893 | 2894 | ||
2894 | SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops); | 2895 | SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops); |
2895 | INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog, mgp); | 2896 | INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog); |
2896 | status = register_netdev(netdev); | 2897 | status = register_netdev(netdev); |
2897 | if (status != 0) { | 2898 | if (status != 0) { |
2898 | dev_err(&pdev->dev, "register_netdev failed: %d\n", status); | 2899 | dev_err(&pdev->dev, "register_netdev failed: %d\n", status); |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 3151aaa7906e..b5410bee5f21 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -852,7 +852,8 @@ struct netxen_adapter { | |||
852 | spinlock_t tx_lock; | 852 | spinlock_t tx_lock; |
853 | spinlock_t lock; | 853 | spinlock_t lock; |
854 | struct work_struct watchdog_task; | 854 | struct work_struct watchdog_task; |
855 | struct work_struct tx_timeout_task[NETXEN_MAX_PORTS]; | 855 | struct work_struct tx_timeout_task; |
856 | struct net_device *netdev; | ||
856 | struct timer_list watchdog_timer; | 857 | struct timer_list watchdog_timer; |
857 | 858 | ||
858 | u32 curr_window; | 859 | u32 curr_window; |
@@ -1071,7 +1072,7 @@ netxen_nic_do_ioctl(struct netxen_adapter *adapter, void *u_data, | |||
1071 | struct netxen_port *port); | 1072 | struct netxen_port *port); |
1072 | int netxen_nic_rx_has_work(struct netxen_adapter *adapter); | 1073 | int netxen_nic_rx_has_work(struct netxen_adapter *adapter); |
1073 | int netxen_nic_tx_has_work(struct netxen_adapter *adapter); | 1074 | int netxen_nic_tx_has_work(struct netxen_adapter *adapter); |
1074 | void netxen_watchdog_task(unsigned long v); | 1075 | void netxen_watchdog_task(struct work_struct *work); |
1075 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, | 1076 | void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, |
1076 | u32 ringid); | 1077 | u32 ringid); |
1077 | void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, u32 ctx, | 1078 | void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, u32 ctx, |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index f78668030ec6..290145ec08e7 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -746,12 +746,13 @@ static inline int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
746 | return rv; | 746 | return rv; |
747 | } | 747 | } |
748 | 748 | ||
749 | void netxen_watchdog_task(unsigned long v) | 749 | void netxen_watchdog_task(struct work_struct *work) |
750 | { | 750 | { |
751 | int port_num; | 751 | int port_num; |
752 | struct netxen_port *port; | 752 | struct netxen_port *port; |
753 | struct net_device *netdev; | 753 | struct net_device *netdev; |
754 | struct netxen_adapter *adapter = (struct netxen_adapter *)v; | 754 | struct netxen_adapter *adapter = |
755 | container_of(work, struct netxen_adapter, watchdog_task); | ||
755 | 756 | ||
756 | if (netxen_nic_check_temp(adapter)) | 757 | if (netxen_nic_check_temp(adapter)) |
757 | return; | 758 | return; |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 06c4778f5200..913e8147114f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -72,7 +72,7 @@ static int netxen_nic_open(struct net_device *netdev); | |||
72 | static int netxen_nic_close(struct net_device *netdev); | 72 | static int netxen_nic_close(struct net_device *netdev); |
73 | static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *); | 73 | static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *); |
74 | static void netxen_tx_timeout(struct net_device *netdev); | 74 | static void netxen_tx_timeout(struct net_device *netdev); |
75 | static void netxen_tx_timeout_task(struct net_device *netdev); | 75 | static void netxen_tx_timeout_task(struct work_struct *work); |
76 | static void netxen_watchdog(unsigned long); | 76 | static void netxen_watchdog(unsigned long); |
77 | static int netxen_handle_int(struct netxen_adapter *, struct net_device *); | 77 | static int netxen_handle_int(struct netxen_adapter *, struct net_device *); |
78 | static int netxen_nic_ioctl(struct net_device *netdev, | 78 | static int netxen_nic_ioctl(struct net_device *netdev, |
@@ -318,8 +318,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
318 | adapter->ahw.xg_linkup = 0; | 318 | adapter->ahw.xg_linkup = 0; |
319 | adapter->watchdog_timer.function = &netxen_watchdog; | 319 | adapter->watchdog_timer.function = &netxen_watchdog; |
320 | adapter->watchdog_timer.data = (unsigned long)adapter; | 320 | adapter->watchdog_timer.data = (unsigned long)adapter; |
321 | INIT_WORK(&adapter->watchdog_task, | 321 | INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); |
322 | (void (*)(void *))netxen_watchdog_task, adapter); | ||
323 | adapter->ahw.pdev = pdev; | 322 | adapter->ahw.pdev = pdev; |
324 | adapter->proc_cmd_buf_counter = 0; | 323 | adapter->proc_cmd_buf_counter = 0; |
325 | adapter->ahw.revision_id = nx_p2_id; | 324 | adapter->ahw.revision_id = nx_p2_id; |
@@ -429,8 +428,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
429 | netdev->dev_addr); | 428 | netdev->dev_addr); |
430 | } | 429 | } |
431 | } | 430 | } |
432 | INIT_WORK(adapter->tx_timeout_task + i, | 431 | adapter->netdev = netdev; |
433 | (void (*)(void *))netxen_tx_timeout_task, netdev); | 432 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); |
434 | netif_carrier_off(netdev); | 433 | netif_carrier_off(netdev); |
435 | netif_stop_queue(netdev); | 434 | netif_stop_queue(netdev); |
436 | 435 | ||
@@ -973,18 +972,20 @@ static void netxen_tx_timeout(struct net_device *netdev) | |||
973 | SCHEDULE_WORK(port->adapter->tx_timeout_task + port->portnum); | 972 | SCHEDULE_WORK(port->adapter->tx_timeout_task + port->portnum); |
974 | } | 973 | } |
975 | 974 | ||
976 | static void netxen_tx_timeout_task(struct net_device *netdev) | 975 | static void netxen_tx_timeout_task(struct work_struct *work) |
977 | { | 976 | { |
978 | struct netxen_port *port = (struct netxen_port *)netdev_priv(netdev); | 977 | struct netxen_adapter *adapter = |
978 | container_of(work, struct netxen_adapter, tx_timeout_task); | ||
979 | struct net_device *netdev = adapter->netdev; | ||
979 | unsigned long flags; | 980 | unsigned long flags; |
980 | 981 | ||
981 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 982 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
982 | netxen_nic_driver_name, netdev->name); | 983 | netxen_nic_driver_name, netdev->name); |
983 | 984 | ||
984 | spin_lock_irqsave(&port->adapter->lock, flags); | 985 | spin_lock_irqsave(&adapter->lock, flags); |
985 | netxen_nic_close(netdev); | 986 | netxen_nic_close(netdev); |
986 | netxen_nic_open(netdev); | 987 | netxen_nic_open(netdev); |
987 | spin_unlock_irqrestore(&port->adapter->lock, flags); | 988 | spin_unlock_irqrestore(&adapter->lock, flags); |
988 | netdev->trans_start = jiffies; | 989 | netdev->trans_start = jiffies; |
989 | netif_wake_queue(netdev); | 990 | netif_wake_queue(netdev); |
990 | } | 991 | } |
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index eb0e119bc0d6..568daeb3e9d8 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c | |||
@@ -427,6 +427,7 @@ struct ns83820 { | |||
427 | u8 __iomem *base; | 427 | u8 __iomem *base; |
428 | 428 | ||
429 | struct pci_dev *pci_dev; | 429 | struct pci_dev *pci_dev; |
430 | struct net_device *ndev; | ||
430 | 431 | ||
431 | #ifdef NS83820_VLAN_ACCEL_SUPPORT | 432 | #ifdef NS83820_VLAN_ACCEL_SUPPORT |
432 | struct vlan_group *vlgrp; | 433 | struct vlan_group *vlgrp; |
@@ -631,10 +632,10 @@ static void fastcall rx_refill_atomic(struct net_device *ndev) | |||
631 | } | 632 | } |
632 | 633 | ||
633 | /* REFILL */ | 634 | /* REFILL */ |
634 | static inline void queue_refill(void *_dev) | 635 | static inline void queue_refill(struct work_struct *work) |
635 | { | 636 | { |
636 | struct net_device *ndev = _dev; | 637 | struct ns83820 *dev = container_of(work, struct ns83820, tq_refill); |
637 | struct ns83820 *dev = PRIV(ndev); | 638 | struct net_device *ndev = dev->ndev; |
638 | 639 | ||
639 | rx_refill(ndev, GFP_KERNEL); | 640 | rx_refill(ndev, GFP_KERNEL); |
640 | if (dev->rx_info.up) | 641 | if (dev->rx_info.up) |
@@ -1844,6 +1845,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ | |||
1844 | 1845 | ||
1845 | ndev = alloc_etherdev(sizeof(struct ns83820)); | 1846 | ndev = alloc_etherdev(sizeof(struct ns83820)); |
1846 | dev = PRIV(ndev); | 1847 | dev = PRIV(ndev); |
1848 | dev->ndev = ndev; | ||
1847 | err = -ENOMEM; | 1849 | err = -ENOMEM; |
1848 | if (!dev) | 1850 | if (!dev) |
1849 | goto out; | 1851 | goto out; |
@@ -1856,7 +1858,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ | |||
1856 | SET_MODULE_OWNER(ndev); | 1858 | SET_MODULE_OWNER(ndev); |
1857 | SET_NETDEV_DEV(ndev, &pci_dev->dev); | 1859 | SET_NETDEV_DEV(ndev, &pci_dev->dev); |
1858 | 1860 | ||
1859 | INIT_WORK(&dev->tq_refill, queue_refill, ndev); | 1861 | INIT_WORK(&dev->tq_refill, queue_refill); |
1860 | tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)ndev); | 1862 | tasklet_init(&dev->rx_tasklet, rx_action, (unsigned long)ndev); |
1861 | 1863 | ||
1862 | err = pci_enable_device(pci_dev); | 1864 | err = pci_enable_device(pci_dev); |
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 046009928526..794cc61819dd 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c | |||
@@ -338,7 +338,6 @@ static int tc574_config(struct pcmcia_device *link) | |||
338 | struct net_device *dev = link->priv; | 338 | struct net_device *dev = link->priv; |
339 | struct el3_private *lp = netdev_priv(dev); | 339 | struct el3_private *lp = netdev_priv(dev); |
340 | tuple_t tuple; | 340 | tuple_t tuple; |
341 | cisparse_t parse; | ||
342 | unsigned short buf[32]; | 341 | unsigned short buf[32]; |
343 | int last_fn, last_ret, i, j; | 342 | int last_fn, last_ret, i, j; |
344 | kio_addr_t ioaddr; | 343 | kio_addr_t ioaddr; |
@@ -350,17 +349,6 @@ static int tc574_config(struct pcmcia_device *link) | |||
350 | 349 | ||
351 | DEBUG(0, "3c574_config(0x%p)\n", link); | 350 | DEBUG(0, "3c574_config(0x%p)\n", link); |
352 | 351 | ||
353 | tuple.Attributes = 0; | ||
354 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
355 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
356 | tuple.TupleData = (cisdata_t *)buf; | ||
357 | tuple.TupleDataMax = 64; | ||
358 | tuple.TupleOffset = 0; | ||
359 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
360 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
361 | link->conf.ConfigBase = parse.config.base; | ||
362 | link->conf.Present = parse.config.rmask[0]; | ||
363 | |||
364 | link->io.IOAddrLines = 16; | 352 | link->io.IOAddrLines = 16; |
365 | for (i = j = 0; j < 0x400; j += 0x20) { | 353 | for (i = j = 0; j < 0x400; j += 0x20) { |
366 | link->io.BasePort1 = j ^ 0x300; | 354 | link->io.BasePort1 = j ^ 0x300; |
@@ -382,6 +370,10 @@ static int tc574_config(struct pcmcia_device *link) | |||
382 | /* The 3c574 normally uses an EEPROM for configuration info, including | 370 | /* The 3c574 normally uses an EEPROM for configuration info, including |
383 | the hardware address. The future products may include a modem chip | 371 | the hardware address. The future products may include a modem chip |
384 | and put the address in the CIS. */ | 372 | and put the address in the CIS. */ |
373 | tuple.Attributes = 0; | ||
374 | tuple.TupleData = (cisdata_t *)buf; | ||
375 | tuple.TupleDataMax = 64; | ||
376 | tuple.TupleOffset = 0; | ||
385 | tuple.DesiredTuple = 0x88; | 377 | tuple.DesiredTuple = 0x88; |
386 | if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { | 378 | if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { |
387 | pcmcia_get_tuple_data(link, &tuple); | 379 | pcmcia_get_tuple_data(link, &tuple); |
@@ -397,12 +389,9 @@ static int tc574_config(struct pcmcia_device *link) | |||
397 | goto failed; | 389 | goto failed; |
398 | } | 390 | } |
399 | } | 391 | } |
400 | tuple.DesiredTuple = CISTPL_VERS_1; | 392 | if (link->prod_id[1]) |
401 | if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS && | 393 | cardname = link->prod_id[1]; |
402 | pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS && | 394 | else |
403 | pcmcia_parse_tuple(link, &tuple, &parse) == CS_SUCCESS) { | ||
404 | cardname = parse.version_1.str + parse.version_1.ofs[1]; | ||
405 | } else | ||
406 | cardname = "3Com 3c574"; | 395 | cardname = "3Com 3c574"; |
407 | 396 | ||
408 | { | 397 | { |
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 231fa2c9ec6c..1e73ff7d5d8e 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c | |||
@@ -253,7 +253,6 @@ static int tc589_config(struct pcmcia_device *link) | |||
253 | struct net_device *dev = link->priv; | 253 | struct net_device *dev = link->priv; |
254 | struct el3_private *lp = netdev_priv(dev); | 254 | struct el3_private *lp = netdev_priv(dev); |
255 | tuple_t tuple; | 255 | tuple_t tuple; |
256 | cisparse_t parse; | ||
257 | u16 buf[32], *phys_addr; | 256 | u16 buf[32], *phys_addr; |
258 | int last_fn, last_ret, i, j, multi = 0, fifo; | 257 | int last_fn, last_ret, i, j, multi = 0, fifo; |
259 | kio_addr_t ioaddr; | 258 | kio_addr_t ioaddr; |
@@ -263,26 +262,16 @@ static int tc589_config(struct pcmcia_device *link) | |||
263 | 262 | ||
264 | phys_addr = (u16 *)dev->dev_addr; | 263 | phys_addr = (u16 *)dev->dev_addr; |
265 | tuple.Attributes = 0; | 264 | tuple.Attributes = 0; |
266 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
267 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
268 | tuple.TupleData = (cisdata_t *)buf; | 265 | tuple.TupleData = (cisdata_t *)buf; |
269 | tuple.TupleDataMax = sizeof(buf); | 266 | tuple.TupleDataMax = sizeof(buf); |
270 | tuple.TupleOffset = 0; | 267 | tuple.TupleOffset = 0; |
271 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
272 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
273 | link->conf.ConfigBase = parse.config.base; | ||
274 | link->conf.Present = parse.config.rmask[0]; | ||
275 | |||
276 | /* Is this a 3c562? */ | ||
277 | tuple.DesiredTuple = CISTPL_MANFID; | ||
278 | tuple.Attributes = TUPLE_RETURN_COMMON; | 268 | tuple.Attributes = TUPLE_RETURN_COMMON; |
279 | if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && | 269 | |
280 | (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) { | 270 | /* Is this a 3c562? */ |
281 | if (le16_to_cpu(buf[0]) != MANFID_3COM) | 271 | if (link->manf_id != MANFID_3COM) |
282 | printk(KERN_INFO "3c589_cs: hmmm, is this really a " | 272 | printk(KERN_INFO "3c589_cs: hmmm, is this really a " |
283 | "3Com card??\n"); | 273 | "3Com card??\n"); |
284 | multi = (le16_to_cpu(buf[1]) == PRODID_3COM_3C562); | 274 | multi = (link->card_id == PRODID_3COM_3C562); |
285 | } | ||
286 | 275 | ||
287 | /* For the 3c562, the base address must be xx00-xx7f */ | 276 | /* For the 3c562, the base address must be xx00-xx7f */ |
288 | link->io.IOAddrLines = 16; | 277 | link->io.IOAddrLines = 16; |
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 5ddd5742f779..6139048f8117 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
@@ -299,11 +299,7 @@ static int axnet_config(struct pcmcia_device *link) | |||
299 | tuple.TupleData = (cisdata_t *)buf; | 299 | tuple.TupleData = (cisdata_t *)buf; |
300 | tuple.TupleDataMax = sizeof(buf); | 300 | tuple.TupleDataMax = sizeof(buf); |
301 | tuple.TupleOffset = 0; | 301 | tuple.TupleOffset = 0; |
302 | tuple.DesiredTuple = CISTPL_CONFIG; | 302 | |
303 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
304 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
305 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
306 | link->conf.ConfigBase = parse.config.base; | ||
307 | /* don't trust the CIS on this; Linksys got it wrong */ | 303 | /* don't trust the CIS on this; Linksys got it wrong */ |
308 | link->conf.Present = 0x63; | 304 | link->conf.Present = 0x63; |
309 | 305 | ||
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index 48434d7924eb..91f65e91cd5f 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c | |||
@@ -249,12 +249,9 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | |||
249 | static int com20020_config(struct pcmcia_device *link) | 249 | static int com20020_config(struct pcmcia_device *link) |
250 | { | 250 | { |
251 | struct arcnet_local *lp; | 251 | struct arcnet_local *lp; |
252 | tuple_t tuple; | ||
253 | cisparse_t parse; | ||
254 | com20020_dev_t *info; | 252 | com20020_dev_t *info; |
255 | struct net_device *dev; | 253 | struct net_device *dev; |
256 | int i, last_ret, last_fn; | 254 | int i, last_ret, last_fn; |
257 | u_char buf[64]; | ||
258 | int ioaddr; | 255 | int ioaddr; |
259 | 256 | ||
260 | info = link->priv; | 257 | info = link->priv; |
@@ -264,16 +261,6 @@ static int com20020_config(struct pcmcia_device *link) | |||
264 | 261 | ||
265 | DEBUG(0, "com20020_config(0x%p)\n", link); | 262 | DEBUG(0, "com20020_config(0x%p)\n", link); |
266 | 263 | ||
267 | tuple.Attributes = 0; | ||
268 | tuple.TupleData = buf; | ||
269 | tuple.TupleDataMax = 64; | ||
270 | tuple.TupleOffset = 0; | ||
271 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
272 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
273 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
274 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
275 | link->conf.ConfigBase = parse.config.base; | ||
276 | |||
277 | DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1); | 264 | DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1); |
278 | i = !CS_SUCCESS; | 265 | i = !CS_SUCCESS; |
279 | if (!link->io.BasePort1) | 266 | if (!link->io.BasePort1) |
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 65f6fdf43725..0d7de617e535 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c | |||
@@ -342,7 +342,7 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
342 | tuple_t tuple; | 342 | tuple_t tuple; |
343 | cisparse_t parse; | 343 | cisparse_t parse; |
344 | u_short buf[32]; | 344 | u_short buf[32]; |
345 | int i, last_fn, last_ret, ret; | 345 | int i, last_fn = 0, last_ret = 0, ret; |
346 | kio_addr_t ioaddr; | 346 | kio_addr_t ioaddr; |
347 | cardtype_t cardtype; | 347 | cardtype_t cardtype; |
348 | char *card_name = "unknown"; | 348 | char *card_name = "unknown"; |
@@ -350,21 +350,9 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
350 | 350 | ||
351 | DEBUG(0, "fmvj18x_config(0x%p)\n", link); | 351 | DEBUG(0, "fmvj18x_config(0x%p)\n", link); |
352 | 352 | ||
353 | /* | ||
354 | This reads the card's CONFIG tuple to find its configuration | ||
355 | registers. | ||
356 | */ | ||
357 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
358 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
359 | tuple.TupleData = (u_char *)buf; | 353 | tuple.TupleData = (u_char *)buf; |
360 | tuple.TupleDataMax = 64; | 354 | tuple.TupleDataMax = 64; |
361 | tuple.TupleOffset = 0; | 355 | tuple.TupleOffset = 0; |
362 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
363 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
364 | |||
365 | link->conf.ConfigBase = parse.config.base; | ||
366 | link->conf.Present = parse.config.rmask[0]; | ||
367 | |||
368 | tuple.DesiredTuple = CISTPL_FUNCE; | 356 | tuple.DesiredTuple = CISTPL_FUNCE; |
369 | tuple.TupleOffset = 0; | 357 | tuple.TupleOffset = 0; |
370 | if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { | 358 | if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) { |
@@ -374,17 +362,12 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
374 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | 362 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); |
375 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | 363 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); |
376 | link->conf.ConfigIndex = parse.cftable_entry.index; | 364 | link->conf.ConfigIndex = parse.cftable_entry.index; |
377 | tuple.DesiredTuple = CISTPL_MANFID; | 365 | switch (link->manf_id) { |
378 | if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) | ||
379 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
380 | else | ||
381 | buf[0] = 0xffff; | ||
382 | switch (le16_to_cpu(buf[0])) { | ||
383 | case MANFID_TDK: | 366 | case MANFID_TDK: |
384 | cardtype = TDK; | 367 | cardtype = TDK; |
385 | if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410 | 368 | if (link->card_id == PRODID_TDK_GN3410 |
386 | || le16_to_cpu(buf[1]) == PRODID_TDK_NP9610 | 369 | || link->card_id == PRODID_TDK_NP9610 |
387 | || le16_to_cpu(buf[1]) == PRODID_TDK_MN3200) { | 370 | || link->card_id == PRODID_TDK_MN3200) { |
388 | /* MultiFunction Card */ | 371 | /* MultiFunction Card */ |
389 | link->conf.ConfigBase = 0x800; | 372 | link->conf.ConfigBase = 0x800; |
390 | link->conf.ConfigIndex = 0x47; | 373 | link->conf.ConfigIndex = 0x47; |
@@ -395,11 +378,11 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
395 | cardtype = CONTEC; | 378 | cardtype = CONTEC; |
396 | break; | 379 | break; |
397 | case MANFID_FUJITSU: | 380 | case MANFID_FUJITSU: |
398 | if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10302) | 381 | if (link->card_id == PRODID_FUJITSU_MBH10302) |
399 | /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302), | 382 | /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302), |
400 | but these are MBH10304 based card. */ | 383 | but these are MBH10304 based card. */ |
401 | cardtype = MBH10304; | 384 | cardtype = MBH10304; |
402 | else if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) | 385 | else if (link->card_id == PRODID_FUJITSU_MBH10304) |
403 | cardtype = MBH10304; | 386 | cardtype = MBH10304; |
404 | else | 387 | else |
405 | cardtype = LA501; | 388 | cardtype = LA501; |
@@ -409,14 +392,9 @@ static int fmvj18x_config(struct pcmcia_device *link) | |||
409 | } | 392 | } |
410 | } else { | 393 | } else { |
411 | /* old type card */ | 394 | /* old type card */ |
412 | tuple.DesiredTuple = CISTPL_MANFID; | 395 | switch (link->manf_id) { |
413 | if (pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) | ||
414 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
415 | else | ||
416 | buf[0] = 0xffff; | ||
417 | switch (le16_to_cpu(buf[0])) { | ||
418 | case MANFID_FUJITSU: | 396 | case MANFID_FUJITSU: |
419 | if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) { | 397 | if (link->card_id == PRODID_FUJITSU_MBH10304) { |
420 | cardtype = XXX10304; /* MBH10304 with buggy CIS */ | 398 | cardtype = XXX10304; /* MBH10304 with buggy CIS */ |
421 | link->conf.ConfigIndex = 0x20; | 399 | link->conf.ConfigIndex = 0x20; |
422 | } else { | 400 | } else { |
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index bc0ca41a0542..a956a51d284f 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c | |||
@@ -222,24 +222,12 @@ static int ibmtr_config(struct pcmcia_device *link) | |||
222 | ibmtr_dev_t *info = link->priv; | 222 | ibmtr_dev_t *info = link->priv; |
223 | struct net_device *dev = info->dev; | 223 | struct net_device *dev = info->dev; |
224 | struct tok_info *ti = netdev_priv(dev); | 224 | struct tok_info *ti = netdev_priv(dev); |
225 | tuple_t tuple; | ||
226 | cisparse_t parse; | ||
227 | win_req_t req; | 225 | win_req_t req; |
228 | memreq_t mem; | 226 | memreq_t mem; |
229 | int i, last_ret, last_fn; | 227 | int i, last_ret, last_fn; |
230 | u_char buf[64]; | ||
231 | 228 | ||
232 | DEBUG(0, "ibmtr_config(0x%p)\n", link); | 229 | DEBUG(0, "ibmtr_config(0x%p)\n", link); |
233 | 230 | ||
234 | tuple.Attributes = 0; | ||
235 | tuple.TupleData = buf; | ||
236 | tuple.TupleDataMax = 64; | ||
237 | tuple.TupleOffset = 0; | ||
238 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
239 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
240 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
241 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
242 | link->conf.ConfigBase = parse.config.base; | ||
243 | link->conf.ConfigIndex = 0x61; | 231 | link->conf.ConfigIndex = 0x61; |
244 | 232 | ||
245 | /* Determine if this is PRIMARY or ALTERNATE. */ | 233 | /* Determine if this is PRIMARY or ALTERNATE. */ |
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index e77110e4c288..3b707747a811 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c | |||
@@ -656,23 +656,12 @@ static int nmclan_config(struct pcmcia_device *link) | |||
656 | struct net_device *dev = link->priv; | 656 | struct net_device *dev = link->priv; |
657 | mace_private *lp = netdev_priv(dev); | 657 | mace_private *lp = netdev_priv(dev); |
658 | tuple_t tuple; | 658 | tuple_t tuple; |
659 | cisparse_t parse; | ||
660 | u_char buf[64]; | 659 | u_char buf[64]; |
661 | int i, last_ret, last_fn; | 660 | int i, last_ret, last_fn; |
662 | kio_addr_t ioaddr; | 661 | kio_addr_t ioaddr; |
663 | 662 | ||
664 | DEBUG(0, "nmclan_config(0x%p)\n", link); | 663 | DEBUG(0, "nmclan_config(0x%p)\n", link); |
665 | 664 | ||
666 | tuple.Attributes = 0; | ||
667 | tuple.TupleData = buf; | ||
668 | tuple.TupleDataMax = 64; | ||
669 | tuple.TupleOffset = 0; | ||
670 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
671 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
672 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
673 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
674 | link->conf.ConfigBase = parse.config.base; | ||
675 | |||
676 | CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); | 665 | CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); |
677 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); | 666 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
678 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); | 667 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); |
@@ -686,6 +675,7 @@ static int nmclan_config(struct pcmcia_device *link) | |||
686 | tuple.TupleData = buf; | 675 | tuple.TupleData = buf; |
687 | tuple.TupleDataMax = 64; | 676 | tuple.TupleDataMax = 64; |
688 | tuple.TupleOffset = 0; | 677 | tuple.TupleOffset = 0; |
678 | tuple.Attributes = 0; | ||
689 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 679 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
690 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | 680 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); |
691 | memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN); | 681 | memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN); |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index c51cc5d8789a..2b1238e2dbdb 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -519,31 +519,15 @@ static int pcnet_config(struct pcmcia_device *link) | |||
519 | tuple_t tuple; | 519 | tuple_t tuple; |
520 | cisparse_t parse; | 520 | cisparse_t parse; |
521 | int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; | 521 | int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; |
522 | int manfid = 0, prodid = 0, has_shmem = 0; | 522 | int has_shmem = 0; |
523 | u_short buf[64]; | 523 | u_short buf[64]; |
524 | hw_info_t *hw_info; | 524 | hw_info_t *hw_info; |
525 | 525 | ||
526 | DEBUG(0, "pcnet_config(0x%p)\n", link); | 526 | DEBUG(0, "pcnet_config(0x%p)\n", link); |
527 | 527 | ||
528 | tuple.Attributes = 0; | ||
529 | tuple.TupleData = (cisdata_t *)buf; | 528 | tuple.TupleData = (cisdata_t *)buf; |
530 | tuple.TupleDataMax = sizeof(buf); | 529 | tuple.TupleDataMax = sizeof(buf); |
531 | tuple.TupleOffset = 0; | 530 | tuple.TupleOffset = 0; |
532 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
533 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
534 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
535 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
536 | link->conf.ConfigBase = parse.config.base; | ||
537 | link->conf.Present = parse.config.rmask[0]; | ||
538 | |||
539 | tuple.DesiredTuple = CISTPL_MANFID; | ||
540 | tuple.Attributes = TUPLE_RETURN_COMMON; | ||
541 | if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && | ||
542 | (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) { | ||
543 | manfid = le16_to_cpu(buf[0]); | ||
544 | prodid = le16_to_cpu(buf[1]); | ||
545 | } | ||
546 | |||
547 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 531 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
548 | tuple.Attributes = 0; | 532 | tuple.Attributes = 0; |
549 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 533 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
@@ -589,8 +573,8 @@ static int pcnet_config(struct pcmcia_device *link) | |||
589 | link->conf.Attributes |= CONF_ENABLE_SPKR; | 573 | link->conf.Attributes |= CONF_ENABLE_SPKR; |
590 | link->conf.Status = CCSR_AUDIO_ENA; | 574 | link->conf.Status = CCSR_AUDIO_ENA; |
591 | } | 575 | } |
592 | if ((manfid == MANFID_IBM) && | 576 | if ((link->manf_id == MANFID_IBM) && |
593 | (prodid == PRODID_IBM_HOME_AND_AWAY)) | 577 | (link->card_id == PRODID_IBM_HOME_AND_AWAY)) |
594 | link->conf.ConfigIndex |= 0x10; | 578 | link->conf.ConfigIndex |= 0x10; |
595 | 579 | ||
596 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); | 580 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); |
@@ -624,10 +608,10 @@ static int pcnet_config(struct pcmcia_device *link) | |||
624 | info->flags = hw_info->flags; | 608 | info->flags = hw_info->flags; |
625 | /* Check for user overrides */ | 609 | /* Check for user overrides */ |
626 | info->flags |= (delay_output) ? DELAY_OUTPUT : 0; | 610 | info->flags |= (delay_output) ? DELAY_OUTPUT : 0; |
627 | if ((manfid == MANFID_SOCKET) && | 611 | if ((link->manf_id == MANFID_SOCKET) && |
628 | ((prodid == PRODID_SOCKET_LPE) || | 612 | ((link->card_id == PRODID_SOCKET_LPE) || |
629 | (prodid == PRODID_SOCKET_LPE_CF) || | 613 | (link->card_id == PRODID_SOCKET_LPE_CF) || |
630 | (prodid == PRODID_SOCKET_EIO))) | 614 | (link->card_id == PRODID_SOCKET_EIO))) |
631 | info->flags &= ~USE_BIG_BUF; | 615 | info->flags &= ~USE_BIG_BUF; |
632 | if (!use_big_buf) | 616 | if (!use_big_buf) |
633 | info->flags &= ~USE_BIG_BUF; | 617 | info->flags &= ~USE_BIG_BUF; |
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 20fcc3576202..530df8883fe5 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c | |||
@@ -560,16 +560,8 @@ static int mhz_setup(struct pcmcia_device *link) | |||
560 | 560 | ||
561 | /* Read the station address from the CIS. It is stored as the last | 561 | /* Read the station address from the CIS. It is stored as the last |
562 | (fourth) string in the Version 1 Version/ID tuple. */ | 562 | (fourth) string in the Version 1 Version/ID tuple. */ |
563 | tuple->DesiredTuple = CISTPL_VERS_1; | 563 | if (link->prod_id[3]) { |
564 | if (first_tuple(link, tuple, parse) != CS_SUCCESS) { | 564 | station_addr = link->prod_id[3]; |
565 | rc = -1; | ||
566 | goto free_cfg_mem; | ||
567 | } | ||
568 | /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ | ||
569 | if (next_tuple(link, tuple, parse) != CS_SUCCESS) | ||
570 | first_tuple(link, tuple, parse); | ||
571 | if (parse->version_1.ns > 3) { | ||
572 | station_addr = parse->version_1.str + parse->version_1.ofs[3]; | ||
573 | if (cvt_ascii_address(dev, station_addr) == 0) { | 565 | if (cvt_ascii_address(dev, station_addr) == 0) { |
574 | rc = 0; | 566 | rc = 0; |
575 | goto free_cfg_mem; | 567 | goto free_cfg_mem; |
@@ -744,15 +736,12 @@ static int smc_setup(struct pcmcia_device *link) | |||
744 | } | 736 | } |
745 | } | 737 | } |
746 | /* Try the third string in the Version 1 Version/ID tuple. */ | 738 | /* Try the third string in the Version 1 Version/ID tuple. */ |
747 | tuple->DesiredTuple = CISTPL_VERS_1; | 739 | if (link->prod_id[2]) { |
748 | if (first_tuple(link, tuple, parse) != CS_SUCCESS) { | 740 | station_addr = link->prod_id[2]; |
749 | rc = -1; | 741 | if (cvt_ascii_address(dev, station_addr) == 0) { |
750 | goto free_cfg_mem; | 742 | rc = 0; |
751 | } | 743 | goto free_cfg_mem; |
752 | station_addr = parse->version_1.str + parse->version_1.ofs[2]; | 744 | } |
753 | if (cvt_ascii_address(dev, station_addr) == 0) { | ||
754 | rc = 0; | ||
755 | goto free_cfg_mem; | ||
756 | } | 745 | } |
757 | 746 | ||
758 | rc = -1; | 747 | rc = -1; |
@@ -970,10 +959,6 @@ static int smc91c92_config(struct pcmcia_device *link) | |||
970 | { | 959 | { |
971 | struct net_device *dev = link->priv; | 960 | struct net_device *dev = link->priv; |
972 | struct smc_private *smc = netdev_priv(dev); | 961 | struct smc_private *smc = netdev_priv(dev); |
973 | struct smc_cfg_mem *cfg_mem; | ||
974 | tuple_t *tuple; | ||
975 | cisparse_t *parse; | ||
976 | u_char *buf; | ||
977 | char *name; | 962 | char *name; |
978 | int i, j, rev; | 963 | int i, j, rev; |
979 | kio_addr_t ioaddr; | 964 | kio_addr_t ioaddr; |
@@ -981,30 +966,8 @@ static int smc91c92_config(struct pcmcia_device *link) | |||
981 | 966 | ||
982 | DEBUG(0, "smc91c92_config(0x%p)\n", link); | 967 | DEBUG(0, "smc91c92_config(0x%p)\n", link); |
983 | 968 | ||
984 | cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); | 969 | smc->manfid = link->manf_id; |
985 | if (!cfg_mem) | 970 | smc->cardid = link->card_id; |
986 | goto config_failed; | ||
987 | |||
988 | tuple = &cfg_mem->tuple; | ||
989 | parse = &cfg_mem->parse; | ||
990 | buf = cfg_mem->buf; | ||
991 | |||
992 | tuple->Attributes = tuple->TupleOffset = 0; | ||
993 | tuple->TupleData = (cisdata_t *)buf; | ||
994 | tuple->TupleDataMax = 64; | ||
995 | |||
996 | tuple->DesiredTuple = CISTPL_CONFIG; | ||
997 | i = first_tuple(link, tuple, parse); | ||
998 | CS_EXIT_TEST(i, ParseTuple, config_failed); | ||
999 | link->conf.ConfigBase = parse->config.base; | ||
1000 | link->conf.Present = parse->config.rmask[0]; | ||
1001 | |||
1002 | tuple->DesiredTuple = CISTPL_MANFID; | ||
1003 | tuple->Attributes = TUPLE_RETURN_COMMON; | ||
1004 | if (first_tuple(link, tuple, parse) == CS_SUCCESS) { | ||
1005 | smc->manfid = parse->manfid.manf; | ||
1006 | smc->cardid = parse->manfid.card; | ||
1007 | } | ||
1008 | 971 | ||
1009 | if ((smc->manfid == MANFID_OSITECH) && | 972 | if ((smc->manfid == MANFID_OSITECH) && |
1010 | (smc->cardid != PRODID_OSITECH_SEVEN)) { | 973 | (smc->cardid != PRODID_OSITECH_SEVEN)) { |
@@ -1134,14 +1097,12 @@ static int smc91c92_config(struct pcmcia_device *link) | |||
1134 | printk(KERN_NOTICE " No MII transceivers found!\n"); | 1097 | printk(KERN_NOTICE " No MII transceivers found!\n"); |
1135 | } | 1098 | } |
1136 | } | 1099 | } |
1137 | kfree(cfg_mem); | ||
1138 | return 0; | 1100 | return 0; |
1139 | 1101 | ||
1140 | config_undo: | 1102 | config_undo: |
1141 | unregister_netdev(dev); | 1103 | unregister_netdev(dev); |
1142 | config_failed: /* CS_EXIT_TEST() calls jump to here... */ | 1104 | config_failed: /* CS_EXIT_TEST() calls jump to here... */ |
1143 | smc91c92_release(link); | 1105 | smc91c92_release(link); |
1144 | kfree(cfg_mem); | ||
1145 | return -ENODEV; | 1106 | return -ENODEV; |
1146 | } /* smc91c92_config */ | 1107 | } /* smc91c92_config */ |
1147 | 1108 | ||
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index f3914f58d67f..8478dca3d8d1 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c | |||
@@ -332,6 +332,7 @@ static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id); | |||
332 | */ | 332 | */ |
333 | 333 | ||
334 | typedef struct local_info_t { | 334 | typedef struct local_info_t { |
335 | struct net_device *dev; | ||
335 | struct pcmcia_device *p_dev; | 336 | struct pcmcia_device *p_dev; |
336 | dev_node_t node; | 337 | dev_node_t node; |
337 | struct net_device_stats stats; | 338 | struct net_device_stats stats; |
@@ -353,7 +354,7 @@ typedef struct local_info_t { | |||
353 | */ | 354 | */ |
354 | static int do_start_xmit(struct sk_buff *skb, struct net_device *dev); | 355 | static int do_start_xmit(struct sk_buff *skb, struct net_device *dev); |
355 | static void do_tx_timeout(struct net_device *dev); | 356 | static void do_tx_timeout(struct net_device *dev); |
356 | static void xirc2ps_tx_timeout_task(void *data); | 357 | static void xirc2ps_tx_timeout_task(struct work_struct *work); |
357 | static struct net_device_stats *do_get_stats(struct net_device *dev); | 358 | static struct net_device_stats *do_get_stats(struct net_device *dev); |
358 | static void set_addresses(struct net_device *dev); | 359 | static void set_addresses(struct net_device *dev); |
359 | static void set_multicast_list(struct net_device *dev); | 360 | static void set_multicast_list(struct net_device *dev); |
@@ -567,6 +568,7 @@ xirc2ps_probe(struct pcmcia_device *link) | |||
567 | if (!dev) | 568 | if (!dev) |
568 | return -ENOMEM; | 569 | return -ENOMEM; |
569 | local = netdev_priv(dev); | 570 | local = netdev_priv(dev); |
571 | local->dev = dev; | ||
570 | local->p_dev = link; | 572 | local->p_dev = link; |
571 | link->priv = dev; | 573 | link->priv = dev; |
572 | 574 | ||
@@ -591,7 +593,7 @@ xirc2ps_probe(struct pcmcia_device *link) | |||
591 | #ifdef HAVE_TX_TIMEOUT | 593 | #ifdef HAVE_TX_TIMEOUT |
592 | dev->tx_timeout = do_tx_timeout; | 594 | dev->tx_timeout = do_tx_timeout; |
593 | dev->watchdog_timeo = TX_TIMEOUT; | 595 | dev->watchdog_timeo = TX_TIMEOUT; |
594 | INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task, dev); | 596 | INIT_WORK(&local->tx_timeout_task, xirc2ps_tx_timeout_task); |
595 | #endif | 597 | #endif |
596 | 598 | ||
597 | return xirc2ps_config(link); | 599 | return xirc2ps_config(link); |
@@ -707,22 +709,11 @@ set_card_type(struct pcmcia_device *link, const void *s) | |||
707 | * Returns: true if this is a CE2 | 709 | * Returns: true if this is a CE2 |
708 | */ | 710 | */ |
709 | static int | 711 | static int |
710 | has_ce2_string(struct pcmcia_device * link) | 712 | has_ce2_string(struct pcmcia_device * p_dev) |
711 | { | 713 | { |
712 | tuple_t tuple; | 714 | if (p_dev->prod_id[2] && strstr(p_dev->prod_id[2], "CE2")) |
713 | cisparse_t parse; | 715 | return 1; |
714 | u_char buf[256]; | 716 | return 0; |
715 | |||
716 | tuple.Attributes = 0; | ||
717 | tuple.TupleData = buf; | ||
718 | tuple.TupleDataMax = 254; | ||
719 | tuple.TupleOffset = 0; | ||
720 | tuple.DesiredTuple = CISTPL_VERS_1; | ||
721 | if (!first_tuple(link, &tuple, &parse) && parse.version_1.ns > 2) { | ||
722 | if (strstr(parse.version_1.str + parse.version_1.ofs[2], "CE2")) | ||
723 | return 1; | ||
724 | } | ||
725 | return 0; | ||
726 | } | 717 | } |
727 | 718 | ||
728 | /**************** | 719 | /**************** |
@@ -792,13 +783,6 @@ xirc2ps_config(struct pcmcia_device * link) | |||
792 | goto failure; | 783 | goto failure; |
793 | } | 784 | } |
794 | 785 | ||
795 | /* get configuration stuff */ | ||
796 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
797 | if ((err=first_tuple(link, &tuple, &parse))) | ||
798 | goto cis_error; | ||
799 | link->conf.ConfigBase = parse.config.base; | ||
800 | link->conf.Present = parse.config.rmask[0]; | ||
801 | |||
802 | /* get the ethernet address from the CIS */ | 786 | /* get the ethernet address from the CIS */ |
803 | tuple.DesiredTuple = CISTPL_FUNCE; | 787 | tuple.DesiredTuple = CISTPL_FUNCE; |
804 | for (err = first_tuple(link, &tuple, &parse); !err; | 788 | for (err = first_tuple(link, &tuple, &parse); !err; |
@@ -1062,8 +1046,6 @@ xirc2ps_config(struct pcmcia_device * link) | |||
1062 | xirc2ps_release(link); | 1046 | xirc2ps_release(link); |
1063 | return -ENODEV; | 1047 | return -ENODEV; |
1064 | 1048 | ||
1065 | cis_error: | ||
1066 | printk(KNOT_XIRC "unable to parse CIS\n"); | ||
1067 | failure: | 1049 | failure: |
1068 | return -ENODEV; | 1050 | return -ENODEV; |
1069 | } /* xirc2ps_config */ | 1051 | } /* xirc2ps_config */ |
@@ -1344,9 +1326,11 @@ xirc2ps_interrupt(int irq, void *dev_id) | |||
1344 | /*====================================================================*/ | 1326 | /*====================================================================*/ |
1345 | 1327 | ||
1346 | static void | 1328 | static void |
1347 | xirc2ps_tx_timeout_task(void *data) | 1329 | xirc2ps_tx_timeout_task(struct work_struct *work) |
1348 | { | 1330 | { |
1349 | struct net_device *dev = data; | 1331 | local_info_t *local = |
1332 | container_of(work, local_info_t, tx_timeout_task); | ||
1333 | struct net_device *dev = local->dev; | ||
1350 | /* reset the card */ | 1334 | /* reset the card */ |
1351 | do_reset(dev,1); | 1335 | do_reset(dev,1); |
1352 | dev->trans_start = jiffies; | 1336 | dev->trans_start = jiffies; |
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index f14e99276dba..096d4a100bf2 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c | |||
@@ -254,7 +254,7 @@ static int fixed_mdio_register_device(int number, int speed, int duplex) | |||
254 | goto device_create_fail; | 254 | goto device_create_fail; |
255 | } | 255 | } |
256 | 256 | ||
257 | phydev->irq = -1; | 257 | phydev->irq = PHY_IGNORE_INTERRUPT; |
258 | phydev->dev.bus = &mdio_bus_type; | 258 | phydev->dev.bus = &mdio_bus_type; |
259 | 259 | ||
260 | if(number) | 260 | if(number) |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 88237bdb5255..4044bb1ada86 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -397,7 +397,7 @@ out_unlock: | |||
397 | EXPORT_SYMBOL(phy_start_aneg); | 397 | EXPORT_SYMBOL(phy_start_aneg); |
398 | 398 | ||
399 | 399 | ||
400 | static void phy_change(void *data); | 400 | static void phy_change(struct work_struct *work); |
401 | static void phy_timer(unsigned long data); | 401 | static void phy_timer(unsigned long data); |
402 | 402 | ||
403 | /* phy_start_machine: | 403 | /* phy_start_machine: |
@@ -555,7 +555,7 @@ int phy_start_interrupts(struct phy_device *phydev) | |||
555 | { | 555 | { |
556 | int err = 0; | 556 | int err = 0; |
557 | 557 | ||
558 | INIT_WORK(&phydev->phy_queue, phy_change, phydev); | 558 | INIT_WORK(&phydev->phy_queue, phy_change); |
559 | 559 | ||
560 | if (request_irq(phydev->irq, phy_interrupt, | 560 | if (request_irq(phydev->irq, phy_interrupt, |
561 | IRQF_SHARED, | 561 | IRQF_SHARED, |
@@ -598,10 +598,11 @@ EXPORT_SYMBOL(phy_stop_interrupts); | |||
598 | 598 | ||
599 | 599 | ||
600 | /* Scheduled by the phy_interrupt/timer to handle PHY changes */ | 600 | /* Scheduled by the phy_interrupt/timer to handle PHY changes */ |
601 | static void phy_change(void *data) | 601 | static void phy_change(struct work_struct *work) |
602 | { | 602 | { |
603 | int err; | 603 | int err; |
604 | struct phy_device *phydev = data; | 604 | struct phy_device *phydev = |
605 | container_of(work, struct phy_device, phy_queue); | ||
605 | 606 | ||
606 | err = phy_disable_interrupts(phydev); | 607 | err = phy_disable_interrupts(phydev); |
607 | 608 | ||
diff --git a/drivers/net/plip.c b/drivers/net/plip.c index 71afb274498f..6bb085f54437 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c | |||
@@ -138,9 +138,9 @@ static const unsigned int net_debug = NET_DEBUG; | |||
138 | #define PLIP_NIBBLE_WAIT 3000 | 138 | #define PLIP_NIBBLE_WAIT 3000 |
139 | 139 | ||
140 | /* Bottom halves */ | 140 | /* Bottom halves */ |
141 | static void plip_kick_bh(struct net_device *dev); | 141 | static void plip_kick_bh(struct work_struct *work); |
142 | static void plip_bh(struct net_device *dev); | 142 | static void plip_bh(struct work_struct *work); |
143 | static void plip_timer_bh(struct net_device *dev); | 143 | static void plip_timer_bh(struct work_struct *work); |
144 | 144 | ||
145 | /* Interrupt handler */ | 145 | /* Interrupt handler */ |
146 | static void plip_interrupt(int irq, void *dev_id); | 146 | static void plip_interrupt(int irq, void *dev_id); |
@@ -207,9 +207,10 @@ struct plip_local { | |||
207 | 207 | ||
208 | struct net_local { | 208 | struct net_local { |
209 | struct net_device_stats enet_stats; | 209 | struct net_device_stats enet_stats; |
210 | struct net_device *dev; | ||
210 | struct work_struct immediate; | 211 | struct work_struct immediate; |
211 | struct work_struct deferred; | 212 | struct delayed_work deferred; |
212 | struct work_struct timer; | 213 | struct delayed_work timer; |
213 | struct plip_local snd_data; | 214 | struct plip_local snd_data; |
214 | struct plip_local rcv_data; | 215 | struct plip_local rcv_data; |
215 | struct pardevice *pardev; | 216 | struct pardevice *pardev; |
@@ -306,11 +307,11 @@ plip_init_netdev(struct net_device *dev) | |||
306 | nl->nibble = PLIP_NIBBLE_WAIT; | 307 | nl->nibble = PLIP_NIBBLE_WAIT; |
307 | 308 | ||
308 | /* Initialize task queue structures */ | 309 | /* Initialize task queue structures */ |
309 | INIT_WORK(&nl->immediate, (void (*)(void *))plip_bh, dev); | 310 | INIT_WORK(&nl->immediate, plip_bh); |
310 | INIT_WORK(&nl->deferred, (void (*)(void *))plip_kick_bh, dev); | 311 | INIT_DELAYED_WORK(&nl->deferred, plip_kick_bh); |
311 | 312 | ||
312 | if (dev->irq == -1) | 313 | if (dev->irq == -1) |
313 | INIT_WORK(&nl->timer, (void (*)(void *))plip_timer_bh, dev); | 314 | INIT_DELAYED_WORK(&nl->timer, plip_timer_bh); |
314 | 315 | ||
315 | spin_lock_init(&nl->lock); | 316 | spin_lock_init(&nl->lock); |
316 | } | 317 | } |
@@ -319,9 +320,10 @@ plip_init_netdev(struct net_device *dev) | |||
319 | This routine is kicked by do_timer(). | 320 | This routine is kicked by do_timer(). |
320 | Request `plip_bh' to be invoked. */ | 321 | Request `plip_bh' to be invoked. */ |
321 | static void | 322 | static void |
322 | plip_kick_bh(struct net_device *dev) | 323 | plip_kick_bh(struct work_struct *work) |
323 | { | 324 | { |
324 | struct net_local *nl = netdev_priv(dev); | 325 | struct net_local *nl = |
326 | container_of(work, struct net_local, deferred.work); | ||
325 | 327 | ||
326 | if (nl->is_deferred) | 328 | if (nl->is_deferred) |
327 | schedule_work(&nl->immediate); | 329 | schedule_work(&nl->immediate); |
@@ -362,9 +364,9 @@ static const plip_func connection_state_table[] = | |||
362 | 364 | ||
363 | /* Bottom half handler of PLIP. */ | 365 | /* Bottom half handler of PLIP. */ |
364 | static void | 366 | static void |
365 | plip_bh(struct net_device *dev) | 367 | plip_bh(struct work_struct *work) |
366 | { | 368 | { |
367 | struct net_local *nl = netdev_priv(dev); | 369 | struct net_local *nl = container_of(work, struct net_local, immediate); |
368 | struct plip_local *snd = &nl->snd_data; | 370 | struct plip_local *snd = &nl->snd_data; |
369 | struct plip_local *rcv = &nl->rcv_data; | 371 | struct plip_local *rcv = &nl->rcv_data; |
370 | plip_func f; | 372 | plip_func f; |
@@ -372,20 +374,21 @@ plip_bh(struct net_device *dev) | |||
372 | 374 | ||
373 | nl->is_deferred = 0; | 375 | nl->is_deferred = 0; |
374 | f = connection_state_table[nl->connection]; | 376 | f = connection_state_table[nl->connection]; |
375 | if ((r = (*f)(dev, nl, snd, rcv)) != OK | 377 | if ((r = (*f)(nl->dev, nl, snd, rcv)) != OK |
376 | && (r = plip_bh_timeout_error(dev, nl, snd, rcv, r)) != OK) { | 378 | && (r = plip_bh_timeout_error(nl->dev, nl, snd, rcv, r)) != OK) { |
377 | nl->is_deferred = 1; | 379 | nl->is_deferred = 1; |
378 | schedule_delayed_work(&nl->deferred, 1); | 380 | schedule_delayed_work(&nl->deferred, 1); |
379 | } | 381 | } |
380 | } | 382 | } |
381 | 383 | ||
382 | static void | 384 | static void |
383 | plip_timer_bh(struct net_device *dev) | 385 | plip_timer_bh(struct work_struct *work) |
384 | { | 386 | { |
385 | struct net_local *nl = netdev_priv(dev); | 387 | struct net_local *nl = |
388 | container_of(work, struct net_local, timer.work); | ||
386 | 389 | ||
387 | if (!(atomic_read (&nl->kill_timer))) { | 390 | if (!(atomic_read (&nl->kill_timer))) { |
388 | plip_interrupt (-1, dev); | 391 | plip_interrupt (-1, nl->dev); |
389 | 392 | ||
390 | schedule_delayed_work(&nl->timer, 1); | 393 | schedule_delayed_work(&nl->timer, 1); |
391 | } | 394 | } |
@@ -1284,6 +1287,7 @@ static void plip_attach (struct parport *port) | |||
1284 | } | 1287 | } |
1285 | 1288 | ||
1286 | nl = netdev_priv(dev); | 1289 | nl = netdev_priv(dev); |
1290 | nl->dev = dev; | ||
1287 | nl->pardev = parport_register_device(port, name, plip_preempt, | 1291 | nl->pardev = parport_register_device(port, name, plip_preempt, |
1288 | plip_wakeup, plip_interrupt, | 1292 | plip_wakeup, plip_interrupt, |
1289 | 0, dev); | 1293 | 0, dev); |
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index ec640f6229ae..d79d141a601d 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c | |||
@@ -2008,7 +2008,7 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id) | |||
2008 | "%s: Another function issued a reset to the " | 2008 | "%s: Another function issued a reset to the " |
2009 | "chip. ISR value = %x.\n", ndev->name, value); | 2009 | "chip. ISR value = %x.\n", ndev->name, value); |
2010 | } | 2010 | } |
2011 | queue_work(qdev->workqueue, &qdev->reset_work); | 2011 | queue_delayed_work(qdev->workqueue, &qdev->reset_work, 0); |
2012 | spin_unlock(&qdev->adapter_lock); | 2012 | spin_unlock(&qdev->adapter_lock); |
2013 | } else if (value & ISP_IMR_DISABLE_CMPL_INT) { | 2013 | } else if (value & ISP_IMR_DISABLE_CMPL_INT) { |
2014 | ql_disable_interrupts(qdev); | 2014 | ql_disable_interrupts(qdev); |
@@ -3182,11 +3182,13 @@ static void ql3xxx_tx_timeout(struct net_device *ndev) | |||
3182 | /* | 3182 | /* |
3183 | * Wake up the worker to process this event. | 3183 | * Wake up the worker to process this event. |
3184 | */ | 3184 | */ |
3185 | queue_work(qdev->workqueue, &qdev->tx_timeout_work); | 3185 | queue_delayed_work(qdev->workqueue, &qdev->tx_timeout_work, 0); |
3186 | } | 3186 | } |
3187 | 3187 | ||
3188 | static void ql_reset_work(struct ql3_adapter *qdev) | 3188 | static void ql_reset_work(struct work_struct *work) |
3189 | { | 3189 | { |
3190 | struct ql3_adapter *qdev = | ||
3191 | container_of(work, struct ql3_adapter, reset_work.work); | ||
3190 | struct net_device *ndev = qdev->ndev; | 3192 | struct net_device *ndev = qdev->ndev; |
3191 | u32 value; | 3193 | u32 value; |
3192 | struct ql_tx_buf_cb *tx_cb; | 3194 | struct ql_tx_buf_cb *tx_cb; |
@@ -3278,9 +3280,12 @@ static void ql_reset_work(struct ql3_adapter *qdev) | |||
3278 | } | 3280 | } |
3279 | } | 3281 | } |
3280 | 3282 | ||
3281 | static void ql_tx_timeout_work(struct ql3_adapter *qdev) | 3283 | static void ql_tx_timeout_work(struct work_struct *work) |
3282 | { | 3284 | { |
3283 | ql_cycle_adapter(qdev,QL_DO_RESET); | 3285 | struct ql3_adapter *qdev = |
3286 | container_of(work, struct ql3_adapter, tx_timeout_work.work); | ||
3287 | |||
3288 | ql_cycle_adapter(qdev, QL_DO_RESET); | ||
3284 | } | 3289 | } |
3285 | 3290 | ||
3286 | static void ql_get_board_info(struct ql3_adapter *qdev) | 3291 | static void ql_get_board_info(struct ql3_adapter *qdev) |
@@ -3459,9 +3464,8 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, | |||
3459 | netif_stop_queue(ndev); | 3464 | netif_stop_queue(ndev); |
3460 | 3465 | ||
3461 | qdev->workqueue = create_singlethread_workqueue(ndev->name); | 3466 | qdev->workqueue = create_singlethread_workqueue(ndev->name); |
3462 | INIT_WORK(&qdev->reset_work, (void (*)(void *))ql_reset_work, qdev); | 3467 | INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work); |
3463 | INIT_WORK(&qdev->tx_timeout_work, | 3468 | INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work); |
3464 | (void (*)(void *))ql_tx_timeout_work, qdev); | ||
3465 | 3469 | ||
3466 | init_timer(&qdev->adapter_timer); | 3470 | init_timer(&qdev->adapter_timer); |
3467 | qdev->adapter_timer.function = ql3xxx_timer; | 3471 | qdev->adapter_timer.function = ql3xxx_timer; |
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h index 65da2c0bfda6..ea94de7fd071 100644 --- a/drivers/net/qla3xxx.h +++ b/drivers/net/qla3xxx.h | |||
@@ -1186,8 +1186,8 @@ struct ql3_adapter { | |||
1186 | u32 numPorts; | 1186 | u32 numPorts; |
1187 | struct net_device_stats stats; | 1187 | struct net_device_stats stats; |
1188 | struct workqueue_struct *workqueue; | 1188 | struct workqueue_struct *workqueue; |
1189 | struct work_struct reset_work; | 1189 | struct delayed_work reset_work; |
1190 | struct work_struct tx_timeout_work; | 1190 | struct delayed_work tx_timeout_work; |
1191 | u32 max_frame_size; | 1191 | u32 max_frame_size; |
1192 | }; | 1192 | }; |
1193 | 1193 | ||
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 45d3ca431957..85a392fab5cc 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -424,6 +424,7 @@ struct ring_info { | |||
424 | struct rtl8169_private { | 424 | struct rtl8169_private { |
425 | void __iomem *mmio_addr; /* memory map physical address */ | 425 | void __iomem *mmio_addr; /* memory map physical address */ |
426 | struct pci_dev *pci_dev; /* Index of PCI device */ | 426 | struct pci_dev *pci_dev; /* Index of PCI device */ |
427 | struct net_device *dev; | ||
427 | struct net_device_stats stats; /* statistics of net device */ | 428 | struct net_device_stats stats; /* statistics of net device */ |
428 | spinlock_t lock; /* spin lock flag */ | 429 | spinlock_t lock; /* spin lock flag */ |
429 | u32 msg_enable; | 430 | u32 msg_enable; |
@@ -455,7 +456,7 @@ struct rtl8169_private { | |||
455 | void (*phy_reset_enable)(void __iomem *); | 456 | void (*phy_reset_enable)(void __iomem *); |
456 | unsigned int (*phy_reset_pending)(void __iomem *); | 457 | unsigned int (*phy_reset_pending)(void __iomem *); |
457 | unsigned int (*link_ok)(void __iomem *); | 458 | unsigned int (*link_ok)(void __iomem *); |
458 | struct work_struct task; | 459 | struct delayed_work task; |
459 | unsigned wol_enabled : 1; | 460 | unsigned wol_enabled : 1; |
460 | }; | 461 | }; |
461 | 462 | ||
@@ -1510,6 +1511,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1510 | SET_MODULE_OWNER(dev); | 1511 | SET_MODULE_OWNER(dev); |
1511 | SET_NETDEV_DEV(dev, &pdev->dev); | 1512 | SET_NETDEV_DEV(dev, &pdev->dev); |
1512 | tp = netdev_priv(dev); | 1513 | tp = netdev_priv(dev); |
1514 | tp->dev = dev; | ||
1513 | tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); | 1515 | tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT); |
1514 | 1516 | ||
1515 | /* enable device (incl. PCI PM wakeup and hotplug setup) */ | 1517 | /* enable device (incl. PCI PM wakeup and hotplug setup) */ |
@@ -1782,7 +1784,7 @@ static int rtl8169_open(struct net_device *dev) | |||
1782 | if (retval < 0) | 1784 | if (retval < 0) |
1783 | goto err_free_rx; | 1785 | goto err_free_rx; |
1784 | 1786 | ||
1785 | INIT_WORK(&tp->task, NULL, dev); | 1787 | INIT_DELAYED_WORK(&tp->task, NULL); |
1786 | 1788 | ||
1787 | rtl8169_hw_start(dev); | 1789 | rtl8169_hw_start(dev); |
1788 | 1790 | ||
@@ -2105,11 +2107,11 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp) | |||
2105 | tp->cur_tx = tp->dirty_tx = 0; | 2107 | tp->cur_tx = tp->dirty_tx = 0; |
2106 | } | 2108 | } |
2107 | 2109 | ||
2108 | static void rtl8169_schedule_work(struct net_device *dev, void (*task)(void *)) | 2110 | static void rtl8169_schedule_work(struct net_device *dev, work_func_t task) |
2109 | { | 2111 | { |
2110 | struct rtl8169_private *tp = netdev_priv(dev); | 2112 | struct rtl8169_private *tp = netdev_priv(dev); |
2111 | 2113 | ||
2112 | PREPARE_WORK(&tp->task, task, dev); | 2114 | PREPARE_DELAYED_WORK(&tp->task, task); |
2113 | schedule_delayed_work(&tp->task, 4); | 2115 | schedule_delayed_work(&tp->task, 4); |
2114 | } | 2116 | } |
2115 | 2117 | ||
@@ -2128,9 +2130,11 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) | |||
2128 | netif_poll_enable(dev); | 2130 | netif_poll_enable(dev); |
2129 | } | 2131 | } |
2130 | 2132 | ||
2131 | static void rtl8169_reinit_task(void *_data) | 2133 | static void rtl8169_reinit_task(struct work_struct *work) |
2132 | { | 2134 | { |
2133 | struct net_device *dev = _data; | 2135 | struct rtl8169_private *tp = |
2136 | container_of(work, struct rtl8169_private, task.work); | ||
2137 | struct net_device *dev = tp->dev; | ||
2134 | int ret; | 2138 | int ret; |
2135 | 2139 | ||
2136 | if (netif_running(dev)) { | 2140 | if (netif_running(dev)) { |
@@ -2153,10 +2157,11 @@ static void rtl8169_reinit_task(void *_data) | |||
2153 | } | 2157 | } |
2154 | } | 2158 | } |
2155 | 2159 | ||
2156 | static void rtl8169_reset_task(void *_data) | 2160 | static void rtl8169_reset_task(struct work_struct *work) |
2157 | { | 2161 | { |
2158 | struct net_device *dev = _data; | 2162 | struct rtl8169_private *tp = |
2159 | struct rtl8169_private *tp = netdev_priv(dev); | 2163 | container_of(work, struct rtl8169_private, task.work); |
2164 | struct net_device *dev = tp->dev; | ||
2160 | 2165 | ||
2161 | if (!netif_running(dev)) | 2166 | if (!netif_running(dev)) |
2162 | return; | 2167 | return; |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 33569ec9dbfc..250cdbeefdfd 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -5872,9 +5872,9 @@ static void s2io_tasklet(unsigned long dev_addr) | |||
5872 | * Description: Sets the link status for the adapter | 5872 | * Description: Sets the link status for the adapter |
5873 | */ | 5873 | */ |
5874 | 5874 | ||
5875 | static void s2io_set_link(unsigned long data) | 5875 | static void s2io_set_link(struct work_struct *work) |
5876 | { | 5876 | { |
5877 | nic_t *nic = (nic_t *) data; | 5877 | nic_t *nic = container_of(work, nic_t, set_link_task); |
5878 | struct net_device *dev = nic->dev; | 5878 | struct net_device *dev = nic->dev; |
5879 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 5879 | XENA_dev_config_t __iomem *bar0 = nic->bar0; |
5880 | register u64 val64; | 5880 | register u64 val64; |
@@ -6379,10 +6379,10 @@ static int s2io_card_up(nic_t * sp) | |||
6379 | * spin lock. | 6379 | * spin lock. |
6380 | */ | 6380 | */ |
6381 | 6381 | ||
6382 | static void s2io_restart_nic(unsigned long data) | 6382 | static void s2io_restart_nic(struct work_struct *work) |
6383 | { | 6383 | { |
6384 | struct net_device *dev = (struct net_device *) data; | 6384 | nic_t *sp = container_of(work, nic_t, rst_timer_task); |
6385 | nic_t *sp = dev->priv; | 6385 | struct net_device *dev = sp->dev; |
6386 | 6386 | ||
6387 | s2io_card_down(sp); | 6387 | s2io_card_down(sp); |
6388 | if (s2io_card_up(sp)) { | 6388 | if (s2io_card_up(sp)) { |
@@ -6992,10 +6992,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
6992 | 6992 | ||
6993 | dev->tx_timeout = &s2io_tx_watchdog; | 6993 | dev->tx_timeout = &s2io_tx_watchdog; |
6994 | dev->watchdog_timeo = WATCH_DOG_TIMEOUT; | 6994 | dev->watchdog_timeo = WATCH_DOG_TIMEOUT; |
6995 | INIT_WORK(&sp->rst_timer_task, | 6995 | INIT_WORK(&sp->rst_timer_task, s2io_restart_nic); |
6996 | (void (*)(void *)) s2io_restart_nic, dev); | 6996 | INIT_WORK(&sp->set_link_task, s2io_set_link); |
6997 | INIT_WORK(&sp->set_link_task, | ||
6998 | (void (*)(void *)) s2io_set_link, sp); | ||
6999 | 6997 | ||
7000 | pci_save_state(sp->pdev); | 6998 | pci_save_state(sp->pdev); |
7001 | 6999 | ||
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 12b719f4d00f..3b0bafd273c8 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -1000,7 +1000,7 @@ s2io_msix_fifo_handle(int irq, void *dev_id); | |||
1000 | static irqreturn_t s2io_isr(int irq, void *dev_id); | 1000 | static irqreturn_t s2io_isr(int irq, void *dev_id); |
1001 | static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag); | 1001 | static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag); |
1002 | static const struct ethtool_ops netdev_ethtool_ops; | 1002 | static const struct ethtool_ops netdev_ethtool_ops; |
1003 | static void s2io_set_link(unsigned long data); | 1003 | static void s2io_set_link(struct work_struct *work); |
1004 | static int s2io_set_swapper(nic_t * sp); | 1004 | static int s2io_set_swapper(nic_t * sp); |
1005 | static void s2io_card_down(nic_t *nic); | 1005 | static void s2io_card_down(nic_t *nic); |
1006 | static int s2io_card_up(nic_t *nic); | 1006 | static int s2io_card_up(nic_t *nic); |
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c index aaba458584fb..b70ed79d4121 100644 --- a/drivers/net/sis190.c +++ b/drivers/net/sis190.c | |||
@@ -280,6 +280,7 @@ enum sis190_feature { | |||
280 | struct sis190_private { | 280 | struct sis190_private { |
281 | void __iomem *mmio_addr; | 281 | void __iomem *mmio_addr; |
282 | struct pci_dev *pci_dev; | 282 | struct pci_dev *pci_dev; |
283 | struct net_device *dev; | ||
283 | struct net_device_stats stats; | 284 | struct net_device_stats stats; |
284 | spinlock_t lock; | 285 | spinlock_t lock; |
285 | u32 rx_buf_sz; | 286 | u32 rx_buf_sz; |
@@ -897,10 +898,11 @@ static void sis190_hw_start(struct net_device *dev) | |||
897 | netif_start_queue(dev); | 898 | netif_start_queue(dev); |
898 | } | 899 | } |
899 | 900 | ||
900 | static void sis190_phy_task(void * data) | 901 | static void sis190_phy_task(struct work_struct *work) |
901 | { | 902 | { |
902 | struct net_device *dev = data; | 903 | struct sis190_private *tp = |
903 | struct sis190_private *tp = netdev_priv(dev); | 904 | container_of(work, struct sis190_private, phy_task); |
905 | struct net_device *dev = tp->dev; | ||
904 | void __iomem *ioaddr = tp->mmio_addr; | 906 | void __iomem *ioaddr = tp->mmio_addr; |
905 | int phy_id = tp->mii_if.phy_id; | 907 | int phy_id = tp->mii_if.phy_id; |
906 | u16 val; | 908 | u16 val; |
@@ -1047,7 +1049,7 @@ static int sis190_open(struct net_device *dev) | |||
1047 | if (rc < 0) | 1049 | if (rc < 0) |
1048 | goto err_free_rx_1; | 1050 | goto err_free_rx_1; |
1049 | 1051 | ||
1050 | INIT_WORK(&tp->phy_task, sis190_phy_task, dev); | 1052 | INIT_WORK(&tp->phy_task, sis190_phy_task); |
1051 | 1053 | ||
1052 | sis190_request_timer(dev); | 1054 | sis190_request_timer(dev); |
1053 | 1055 | ||
@@ -1436,6 +1438,7 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev) | |||
1436 | SET_NETDEV_DEV(dev, &pdev->dev); | 1438 | SET_NETDEV_DEV(dev, &pdev->dev); |
1437 | 1439 | ||
1438 | tp = netdev_priv(dev); | 1440 | tp = netdev_priv(dev); |
1441 | tp->dev = dev; | ||
1439 | tp->msg_enable = netif_msg_init(debug.msg_enable, SIS190_MSG_DEFAULT); | 1442 | tp->msg_enable = netif_msg_init(debug.msg_enable, SIS190_MSG_DEFAULT); |
1440 | 1443 | ||
1441 | rc = pci_enable_device(pdev); | 1444 | rc = pci_enable_device(pdev); |
@@ -1798,7 +1801,7 @@ static int __devinit sis190_init_one(struct pci_dev *pdev, | |||
1798 | 1801 | ||
1799 | sis190_init_rxfilter(dev); | 1802 | sis190_init_rxfilter(dev); |
1800 | 1803 | ||
1801 | INIT_WORK(&tp->phy_task, sis190_phy_task, dev); | 1804 | INIT_WORK(&tp->phy_task, sis190_phy_task); |
1802 | 1805 | ||
1803 | dev->open = sis190_open; | 1806 | dev->open = sis190_open; |
1804 | dev->stop = sis190_close; | 1807 | dev->stop = sis190_close; |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 5513907e8393..b60f0451f6cd 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -1327,10 +1327,11 @@ static void xm_check_link(struct net_device *dev) | |||
1327 | * Since internal PHY is wired to a level triggered pin, can't | 1327 | * Since internal PHY is wired to a level triggered pin, can't |
1328 | * get an interrupt when carrier is detected. | 1328 | * get an interrupt when carrier is detected. |
1329 | */ | 1329 | */ |
1330 | static void xm_link_timer(void *arg) | 1330 | static void xm_link_timer(struct work_struct *work) |
1331 | { | 1331 | { |
1332 | struct net_device *dev = arg; | 1332 | struct skge_port *skge = |
1333 | struct skge_port *skge = netdev_priv(arg); | 1333 | container_of(work, struct skge_port, link_thread.work); |
1334 | struct net_device *dev = skge->netdev; | ||
1334 | struct skge_hw *hw = skge->hw; | 1335 | struct skge_hw *hw = skge->hw; |
1335 | int port = skge->port; | 1336 | int port = skge->port; |
1336 | 1337 | ||
@@ -3072,9 +3073,9 @@ static void skge_error_irq(struct skge_hw *hw) | |||
3072 | * because accessing phy registers requires spin wait which might | 3073 | * because accessing phy registers requires spin wait which might |
3073 | * cause excess interrupt latency. | 3074 | * cause excess interrupt latency. |
3074 | */ | 3075 | */ |
3075 | static void skge_extirq(void *arg) | 3076 | static void skge_extirq(struct work_struct *work) |
3076 | { | 3077 | { |
3077 | struct skge_hw *hw = arg; | 3078 | struct skge_hw *hw = container_of(work, struct skge_hw, phy_work); |
3078 | int port; | 3079 | int port; |
3079 | 3080 | ||
3080 | mutex_lock(&hw->phy_mutex); | 3081 | mutex_lock(&hw->phy_mutex); |
@@ -3456,7 +3457,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
3456 | skge->port = port; | 3457 | skge->port = port; |
3457 | 3458 | ||
3458 | /* Only used for Genesis XMAC */ | 3459 | /* Only used for Genesis XMAC */ |
3459 | INIT_WORK(&skge->link_thread, xm_link_timer, dev); | 3460 | INIT_DELAYED_WORK(&skge->link_thread, xm_link_timer); |
3460 | 3461 | ||
3461 | if (hw->chip_id != CHIP_ID_GENESIS) { | 3462 | if (hw->chip_id != CHIP_ID_GENESIS) { |
3462 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | 3463 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; |
@@ -3543,7 +3544,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, | |||
3543 | 3544 | ||
3544 | hw->pdev = pdev; | 3545 | hw->pdev = pdev; |
3545 | mutex_init(&hw->phy_mutex); | 3546 | mutex_init(&hw->phy_mutex); |
3546 | INIT_WORK(&hw->phy_work, skge_extirq, hw); | 3547 | INIT_WORK(&hw->phy_work, skge_extirq); |
3547 | spin_lock_init(&hw->hw_lock); | 3548 | spin_lock_init(&hw->hw_lock); |
3548 | 3549 | ||
3549 | hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); | 3550 | hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 537c0aaa1db8..23e5275d920c 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
@@ -2456,7 +2456,7 @@ struct skge_port { | |||
2456 | 2456 | ||
2457 | struct net_device_stats net_stats; | 2457 | struct net_device_stats net_stats; |
2458 | 2458 | ||
2459 | struct work_struct link_thread; | 2459 | struct delayed_work link_thread; |
2460 | enum pause_control flow_control; | 2460 | enum pause_control flow_control; |
2461 | enum pause_status flow_status; | 2461 | enum pause_status flow_status; |
2462 | u8 rx_csum; | 2462 | u8 rx_csum; |
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 95b6478f55c6..e62a9586fb95 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -210,6 +210,7 @@ struct smc_local { | |||
210 | 210 | ||
211 | /* work queue */ | 211 | /* work queue */ |
212 | struct work_struct phy_configure; | 212 | struct work_struct phy_configure; |
213 | struct net_device *dev; | ||
213 | int work_pending; | 214 | int work_pending; |
214 | 215 | ||
215 | spinlock_t lock; | 216 | spinlock_t lock; |
@@ -1114,10 +1115,11 @@ static void smc_phy_check_media(struct net_device *dev, int init) | |||
1114 | * of autonegotiation.) If the RPC ANEG bit is cleared, the selection | 1115 | * of autonegotiation.) If the RPC ANEG bit is cleared, the selection |
1115 | * is controlled by the RPC SPEED and RPC DPLX bits. | 1116 | * is controlled by the RPC SPEED and RPC DPLX bits. |
1116 | */ | 1117 | */ |
1117 | static void smc_phy_configure(void *data) | 1118 | static void smc_phy_configure(struct work_struct *work) |
1118 | { | 1119 | { |
1119 | struct net_device *dev = data; | 1120 | struct smc_local *lp = |
1120 | struct smc_local *lp = netdev_priv(dev); | 1121 | container_of(work, struct smc_local, phy_configure); |
1122 | struct net_device *dev = lp->dev; | ||
1121 | void __iomem *ioaddr = lp->base; | 1123 | void __iomem *ioaddr = lp->base; |
1122 | int phyaddr = lp->mii.phy_id; | 1124 | int phyaddr = lp->mii.phy_id; |
1123 | int my_phy_caps; /* My PHY capabilities */ | 1125 | int my_phy_caps; /* My PHY capabilities */ |
@@ -1592,7 +1594,7 @@ smc_open(struct net_device *dev) | |||
1592 | 1594 | ||
1593 | /* Configure the PHY, initialize the link state */ | 1595 | /* Configure the PHY, initialize the link state */ |
1594 | if (lp->phy_type != 0) | 1596 | if (lp->phy_type != 0) |
1595 | smc_phy_configure(dev); | 1597 | smc_phy_configure(&lp->phy_configure); |
1596 | else { | 1598 | else { |
1597 | spin_lock_irq(&lp->lock); | 1599 | spin_lock_irq(&lp->lock); |
1598 | smc_10bt_check_media(dev, 1); | 1600 | smc_10bt_check_media(dev, 1); |
@@ -1972,7 +1974,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) | |||
1972 | #endif | 1974 | #endif |
1973 | 1975 | ||
1974 | tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev); | 1976 | tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev); |
1975 | INIT_WORK(&lp->phy_configure, smc_phy_configure, dev); | 1977 | INIT_WORK(&lp->phy_configure, smc_phy_configure); |
1978 | lp->dev = dev; | ||
1976 | lp->mii.phy_id_mask = 0x1f; | 1979 | lp->mii.phy_id_mask = 0x1f; |
1977 | lp->mii.reg_num_mask = 0x1f; | 1980 | lp->mii.reg_num_mask = 0x1f; |
1978 | lp->mii.force_media = 0; | 1981 | lp->mii.force_media = 0; |
@@ -2322,7 +2325,7 @@ static int smc_drv_resume(struct platform_device *dev) | |||
2322 | smc_reset(ndev); | 2325 | smc_reset(ndev); |
2323 | smc_enable(ndev); | 2326 | smc_enable(ndev); |
2324 | if (lp->phy_type != 0) | 2327 | if (lp->phy_type != 0) |
2325 | smc_phy_configure(ndev); | 2328 | smc_phy_configure(&lp->phy_configure); |
2326 | netif_device_attach(ndev); | 2329 | netif_device_attach(ndev); |
2327 | } | 2330 | } |
2328 | } | 2331 | } |
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index cef7e6671c49..ebb6aa39f9c7 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -88,12 +88,11 @@ MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl); | |||
88 | static inline u32 | 88 | static inline u32 |
89 | spider_net_read_reg(struct spider_net_card *card, u32 reg) | 89 | spider_net_read_reg(struct spider_net_card *card, u32 reg) |
90 | { | 90 | { |
91 | u32 value; | 91 | /* We use the powerpc specific variants instead of readl_be() because |
92 | 92 | * we know spidernet is not a real PCI device and we can thus avoid the | |
93 | value = readl(card->regs + reg); | 93 | * performance hit caused by the PCI workarounds. |
94 | value = le32_to_cpu(value); | 94 | */ |
95 | 95 | return in_be32(card->regs + reg); | |
96 | return value; | ||
97 | } | 96 | } |
98 | 97 | ||
99 | /** | 98 | /** |
@@ -105,8 +104,11 @@ spider_net_read_reg(struct spider_net_card *card, u32 reg) | |||
105 | static inline void | 104 | static inline void |
106 | spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) | 105 | spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) |
107 | { | 106 | { |
108 | value = cpu_to_le32(value); | 107 | /* We use the powerpc specific variants instead of writel_be() because |
109 | writel(value, card->regs + reg); | 108 | * we know spidernet is not a real PCI device and we can thus avoid the |
109 | * performance hit caused by the PCI workarounds. | ||
110 | */ | ||
111 | out_be32(card->regs + reg, value); | ||
110 | } | 112 | } |
111 | 113 | ||
112 | /** spider_net_write_phy - write to phy register | 114 | /** spider_net_write_phy - write to phy register |
@@ -1937,10 +1939,11 @@ spider_net_stop(struct net_device *netdev) | |||
1937 | * called as task when tx hangs, resets interface (if interface is up) | 1939 | * called as task when tx hangs, resets interface (if interface is up) |
1938 | */ | 1940 | */ |
1939 | static void | 1941 | static void |
1940 | spider_net_tx_timeout_task(void *data) | 1942 | spider_net_tx_timeout_task(struct work_struct *work) |
1941 | { | 1943 | { |
1942 | struct net_device *netdev = data; | 1944 | struct spider_net_card *card = |
1943 | struct spider_net_card *card = netdev_priv(netdev); | 1945 | container_of(work, struct spider_net_card, tx_timeout_task); |
1946 | struct net_device *netdev = card->netdev; | ||
1944 | 1947 | ||
1945 | if (!(netdev->flags & IFF_UP)) | 1948 | if (!(netdev->flags & IFF_UP)) |
1946 | goto out; | 1949 | goto out; |
@@ -2114,7 +2117,7 @@ spider_net_alloc_card(void) | |||
2114 | card = netdev_priv(netdev); | 2117 | card = netdev_priv(netdev); |
2115 | card->netdev = netdev; | 2118 | card->netdev = netdev; |
2116 | card->msg_enable = SPIDER_NET_DEFAULT_MSG; | 2119 | card->msg_enable = SPIDER_NET_DEFAULT_MSG; |
2117 | INIT_WORK(&card->tx_timeout_task, spider_net_tx_timeout_task, netdev); | 2120 | INIT_WORK(&card->tx_timeout_task, spider_net_tx_timeout_task); |
2118 | init_waitqueue_head(&card->waitq); | 2121 | init_waitqueue_head(&card->waitq); |
2119 | atomic_set(&card->tx_timeout_task_counter, 0); | 2122 | atomic_set(&card->tx_timeout_task_counter, 0); |
2120 | 2123 | ||
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index cf44e72399b9..785e4a535f9e 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c | |||
@@ -2282,9 +2282,9 @@ static void gem_do_stop(struct net_device *dev, int wol) | |||
2282 | } | 2282 | } |
2283 | } | 2283 | } |
2284 | 2284 | ||
2285 | static void gem_reset_task(void *data) | 2285 | static void gem_reset_task(struct work_struct *work) |
2286 | { | 2286 | { |
2287 | struct gem *gp = (struct gem *) data; | 2287 | struct gem *gp = container_of(work, struct gem, reset_task); |
2288 | 2288 | ||
2289 | mutex_lock(&gp->pm_mutex); | 2289 | mutex_lock(&gp->pm_mutex); |
2290 | 2290 | ||
@@ -3044,7 +3044,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, | |||
3044 | gp->link_timer.function = gem_link_timer; | 3044 | gp->link_timer.function = gem_link_timer; |
3045 | gp->link_timer.data = (unsigned long) gp; | 3045 | gp->link_timer.data = (unsigned long) gp; |
3046 | 3046 | ||
3047 | INIT_WORK(&gp->reset_task, gem_reset_task, gp); | 3047 | INIT_WORK(&gp->reset_task, gem_reset_task); |
3048 | 3048 | ||
3049 | gp->lstate = link_down; | 3049 | gp->lstate = link_down; |
3050 | gp->timer_ticks = 0; | 3050 | gp->timer_ticks = 0; |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index c20bb998e0e5..d9123c9adc1e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -3654,9 +3654,9 @@ static void tg3_poll_controller(struct net_device *dev) | |||
3654 | } | 3654 | } |
3655 | #endif | 3655 | #endif |
3656 | 3656 | ||
3657 | static void tg3_reset_task(void *_data) | 3657 | static void tg3_reset_task(struct work_struct *work) |
3658 | { | 3658 | { |
3659 | struct tg3 *tp = _data; | 3659 | struct tg3 *tp = container_of(work, struct tg3, reset_task); |
3660 | unsigned int restart_timer; | 3660 | unsigned int restart_timer; |
3661 | 3661 | ||
3662 | tg3_full_lock(tp, 0); | 3662 | tg3_full_lock(tp, 0); |
@@ -11734,7 +11734,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
11734 | #endif | 11734 | #endif |
11735 | spin_lock_init(&tp->lock); | 11735 | spin_lock_init(&tp->lock); |
11736 | spin_lock_init(&tp->indirect_lock); | 11736 | spin_lock_init(&tp->indirect_lock); |
11737 | INIT_WORK(&tp->reset_task, tg3_reset_task, tp); | 11737 | INIT_WORK(&tp->reset_task, tg3_reset_task); |
11738 | 11738 | ||
11739 | tp->regs = ioremap_nocache(tg3reg_base, tg3reg_len); | 11739 | tp->regs = ioremap_nocache(tg3reg_base, tg3reg_len); |
11740 | if (tp->regs == 0UL) { | 11740 | if (tp->regs == 0UL) { |
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index e14f5a00f65a..f85f00251123 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c | |||
@@ -296,6 +296,7 @@ static void TLan_SetMulticastList( struct net_device *); | |||
296 | static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd); | 296 | static int TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd); |
297 | static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent); | 297 | static int TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent); |
298 | static void TLan_tx_timeout( struct net_device *dev); | 298 | static void TLan_tx_timeout( struct net_device *dev); |
299 | static void TLan_tx_timeout_work(struct work_struct *work); | ||
299 | static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent); | 300 | static int tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent); |
300 | 301 | ||
301 | static u32 TLan_HandleInvalid( struct net_device *, u16 ); | 302 | static u32 TLan_HandleInvalid( struct net_device *, u16 ); |
@@ -562,6 +563,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, | |||
562 | priv = netdev_priv(dev); | 563 | priv = netdev_priv(dev); |
563 | 564 | ||
564 | priv->pciDev = pdev; | 565 | priv->pciDev = pdev; |
566 | priv->dev = dev; | ||
565 | 567 | ||
566 | /* Is this a PCI device? */ | 568 | /* Is this a PCI device? */ |
567 | if (pdev) { | 569 | if (pdev) { |
@@ -634,7 +636,7 @@ static int __devinit TLan_probe1(struct pci_dev *pdev, | |||
634 | 636 | ||
635 | /* This will be used when we get an adapter error from | 637 | /* This will be used when we get an adapter error from |
636 | * within our irq handler */ | 638 | * within our irq handler */ |
637 | INIT_WORK(&priv->tlan_tqueue, (void *)(void*)TLan_tx_timeout, dev); | 639 | INIT_WORK(&priv->tlan_tqueue, TLan_tx_timeout_work); |
638 | 640 | ||
639 | spin_lock_init(&priv->lock); | 641 | spin_lock_init(&priv->lock); |
640 | 642 | ||
@@ -1040,6 +1042,25 @@ static void TLan_tx_timeout(struct net_device *dev) | |||
1040 | } | 1042 | } |
1041 | 1043 | ||
1042 | 1044 | ||
1045 | /*************************************************************** | ||
1046 | * TLan_tx_timeout_work | ||
1047 | * | ||
1048 | * Returns: nothing | ||
1049 | * | ||
1050 | * Params: | ||
1051 | * work work item of device which timed out | ||
1052 | * | ||
1053 | **************************************************************/ | ||
1054 | |||
1055 | static void TLan_tx_timeout_work(struct work_struct *work) | ||
1056 | { | ||
1057 | TLanPrivateInfo *priv = | ||
1058 | container_of(work, TLanPrivateInfo, tlan_tqueue); | ||
1059 | |||
1060 | TLan_tx_timeout(priv->dev); | ||
1061 | } | ||
1062 | |||
1063 | |||
1043 | 1064 | ||
1044 | /*************************************************************** | 1065 | /*************************************************************** |
1045 | * TLan_StartTx | 1066 | * TLan_StartTx |
diff --git a/drivers/net/tlan.h b/drivers/net/tlan.h index a44e2f2ef62a..41ce0b665937 100644 --- a/drivers/net/tlan.h +++ b/drivers/net/tlan.h | |||
@@ -170,6 +170,7 @@ typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE]; | |||
170 | typedef struct tlan_private_tag { | 170 | typedef struct tlan_private_tag { |
171 | struct net_device *nextDevice; | 171 | struct net_device *nextDevice; |
172 | struct pci_dev *pciDev; | 172 | struct pci_dev *pciDev; |
173 | struct net_device *dev; | ||
173 | void *dmaStorage; | 174 | void *dmaStorage; |
174 | dma_addr_t dmaStorageDMA; | 175 | dma_addr_t dmaStorageDMA; |
175 | unsigned int dmaSize; | 176 | unsigned int dmaSize; |
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index bfe59865b1dd..0d97e10ccac5 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c | |||
@@ -1826,7 +1826,7 @@ static void tr_rx(struct net_device *dev) | |||
1826 | skb->protocol = tr_type_trans(skb, dev); | 1826 | skb->protocol = tr_type_trans(skb, dev); |
1827 | if (IPv4_p) { | 1827 | if (IPv4_p) { |
1828 | skb->csum = chksum; | 1828 | skb->csum = chksum; |
1829 | skb->ip_summed = 1; | 1829 | skb->ip_summed = CHECKSUM_COMPLETE; |
1830 | } | 1830 | } |
1831 | netif_rx(skb); | 1831 | netif_rx(skb); |
1832 | dev->last_rx = jiffies; | 1832 | dev->last_rx = jiffies; |
diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c index fa3a2bb105ad..942b839ccc5b 100644 --- a/drivers/net/tulip/21142.c +++ b/drivers/net/tulip/21142.c | |||
@@ -26,10 +26,11 @@ static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; | |||
26 | 26 | ||
27 | /* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list | 27 | /* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list |
28 | of available transceivers. */ | 28 | of available transceivers. */ |
29 | void t21142_media_task(void *data) | 29 | void t21142_media_task(struct work_struct *work) |
30 | { | 30 | { |
31 | struct net_device *dev = data; | 31 | struct tulip_private *tp = |
32 | struct tulip_private *tp = netdev_priv(dev); | 32 | container_of(work, struct tulip_private, media_work); |
33 | struct net_device *dev = tp->dev; | ||
33 | void __iomem *ioaddr = tp->base_addr; | 34 | void __iomem *ioaddr = tp->base_addr; |
34 | int csr12 = ioread32(ioaddr + CSR12); | 35 | int csr12 = ioread32(ioaddr + CSR12); |
35 | int next_tick = 60*HZ; | 36 | int next_tick = 60*HZ; |
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 3f4b6408b755..4b3cd3d8b62a 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c | |||
@@ -473,9 +473,9 @@ | |||
473 | #include <asm/byteorder.h> | 473 | #include <asm/byteorder.h> |
474 | #include <asm/unaligned.h> | 474 | #include <asm/unaligned.h> |
475 | #include <asm/uaccess.h> | 475 | #include <asm/uaccess.h> |
476 | #ifdef CONFIG_PPC_MULTIPLATFORM | 476 | #ifdef CONFIG_PPC_PMAC |
477 | #include <asm/machdep.h> | 477 | #include <asm/machdep.h> |
478 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 478 | #endif /* CONFIG_PPC_PMAC */ |
479 | 479 | ||
480 | #include "de4x5.h" | 480 | #include "de4x5.h" |
481 | 481 | ||
@@ -4151,7 +4151,7 @@ get_hw_addr(struct net_device *dev) | |||
4151 | /* If possible, try to fix a broken card - SMC only so far */ | 4151 | /* If possible, try to fix a broken card - SMC only so far */ |
4152 | srom_repair(dev, broken); | 4152 | srom_repair(dev, broken); |
4153 | 4153 | ||
4154 | #ifdef CONFIG_PPC_MULTIPLATFORM | 4154 | #ifdef CONFIG_PPC_PMAC |
4155 | /* | 4155 | /* |
4156 | ** If the address starts with 00 a0, we have to bit-reverse | 4156 | ** If the address starts with 00 a0, we have to bit-reverse |
4157 | ** each byte of the address. | 4157 | ** each byte of the address. |
@@ -4168,7 +4168,7 @@ get_hw_addr(struct net_device *dev) | |||
4168 | dev->dev_addr[i] = ((x & 0x55) << 1) + ((x & 0xaa) >> 1); | 4168 | dev->dev_addr[i] = ((x & 0x55) << 1) + ((x & 0xaa) >> 1); |
4169 | } | 4169 | } |
4170 | } | 4170 | } |
4171 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 4171 | #endif /* CONFIG_PPC_PMAC */ |
4172 | 4172 | ||
4173 | /* Test for a bad enet address */ | 4173 | /* Test for a bad enet address */ |
4174 | status = test_bad_enet(dev, status); | 4174 | status = test_bad_enet(dev, status); |
diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c index 066e5d6bcbd8..df326fe1cc8f 100644 --- a/drivers/net/tulip/timer.c +++ b/drivers/net/tulip/timer.c | |||
@@ -18,10 +18,11 @@ | |||
18 | #include "tulip.h" | 18 | #include "tulip.h" |
19 | 19 | ||
20 | 20 | ||
21 | void tulip_media_task(void *data) | 21 | void tulip_media_task(struct work_struct *work) |
22 | { | 22 | { |
23 | struct net_device *dev = data; | 23 | struct tulip_private *tp = |
24 | struct tulip_private *tp = netdev_priv(dev); | 24 | container_of(work, struct tulip_private, media_work); |
25 | struct net_device *dev = tp->dev; | ||
25 | void __iomem *ioaddr = tp->base_addr; | 26 | void __iomem *ioaddr = tp->base_addr; |
26 | u32 csr12 = ioread32(ioaddr + CSR12); | 27 | u32 csr12 = ioread32(ioaddr + CSR12); |
27 | int next_tick = 2*HZ; | 28 | int next_tick = 2*HZ; |
diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index ad107f45c7b1..25f25da76917 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h | |||
@@ -44,7 +44,7 @@ struct tulip_chip_table { | |||
44 | int valid_intrs; /* CSR7 interrupt enable settings */ | 44 | int valid_intrs; /* CSR7 interrupt enable settings */ |
45 | int flags; | 45 | int flags; |
46 | void (*media_timer) (unsigned long); | 46 | void (*media_timer) (unsigned long); |
47 | void (*media_task) (void *); | 47 | work_func_t media_task; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | 50 | ||
@@ -392,6 +392,7 @@ struct tulip_private { | |||
392 | int csr12_shadow; | 392 | int csr12_shadow; |
393 | int pad0; /* Used for 8-byte alignment */ | 393 | int pad0; /* Used for 8-byte alignment */ |
394 | struct work_struct media_work; | 394 | struct work_struct media_work; |
395 | struct net_device *dev; | ||
395 | }; | 396 | }; |
396 | 397 | ||
397 | 398 | ||
@@ -406,7 +407,7 @@ struct eeprom_fixup { | |||
406 | 407 | ||
407 | /* 21142.c */ | 408 | /* 21142.c */ |
408 | extern u16 t21142_csr14[]; | 409 | extern u16 t21142_csr14[]; |
409 | void t21142_media_task(void *data); | 410 | void t21142_media_task(struct work_struct *work); |
410 | void t21142_start_nway(struct net_device *dev); | 411 | void t21142_start_nway(struct net_device *dev); |
411 | void t21142_lnk_change(struct net_device *dev, int csr5); | 412 | void t21142_lnk_change(struct net_device *dev, int csr5); |
412 | 413 | ||
@@ -444,7 +445,7 @@ void pnic_lnk_change(struct net_device *dev, int csr5); | |||
444 | void pnic_timer(unsigned long data); | 445 | void pnic_timer(unsigned long data); |
445 | 446 | ||
446 | /* timer.c */ | 447 | /* timer.c */ |
447 | void tulip_media_task(void *data); | 448 | void tulip_media_task(struct work_struct *work); |
448 | void mxic_timer(unsigned long data); | 449 | void mxic_timer(unsigned long data); |
449 | void comet_timer(unsigned long data); | 450 | void comet_timer(unsigned long data); |
450 | 451 | ||
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 0aee618f883c..5a35354aa523 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -1367,6 +1367,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, | |||
1367 | * it is zeroed and aligned in alloc_etherdev | 1367 | * it is zeroed and aligned in alloc_etherdev |
1368 | */ | 1368 | */ |
1369 | tp = netdev_priv(dev); | 1369 | tp = netdev_priv(dev); |
1370 | tp->dev = dev; | ||
1370 | 1371 | ||
1371 | tp->rx_ring = pci_alloc_consistent(pdev, | 1372 | tp->rx_ring = pci_alloc_consistent(pdev, |
1372 | sizeof(struct tulip_rx_desc) * RX_RING_SIZE + | 1373 | sizeof(struct tulip_rx_desc) * RX_RING_SIZE + |
@@ -1389,7 +1390,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, | |||
1389 | tp->timer.data = (unsigned long)dev; | 1390 | tp->timer.data = (unsigned long)dev; |
1390 | tp->timer.function = tulip_tbl[tp->chip_id].media_timer; | 1391 | tp->timer.function = tulip_tbl[tp->chip_id].media_timer; |
1391 | 1392 | ||
1392 | INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task, dev); | 1393 | INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task); |
1393 | 1394 | ||
1394 | dev->base_addr = (unsigned long)ioaddr; | 1395 | dev->base_addr = (unsigned long)ioaddr; |
1395 | 1396 | ||
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 931cbdf6d791..b2a23aed4428 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c | |||
@@ -125,8 +125,8 @@ static int cpc_tty_write_room(struct tty_struct *tty); | |||
125 | static int cpc_tty_chars_in_buffer(struct tty_struct *tty); | 125 | static int cpc_tty_chars_in_buffer(struct tty_struct *tty); |
126 | static void cpc_tty_flush_buffer(struct tty_struct *tty); | 126 | static void cpc_tty_flush_buffer(struct tty_struct *tty); |
127 | static void cpc_tty_hangup(struct tty_struct *tty); | 127 | static void cpc_tty_hangup(struct tty_struct *tty); |
128 | static void cpc_tty_rx_work(void *data); | 128 | static void cpc_tty_rx_work(struct work_struct *work); |
129 | static void cpc_tty_tx_work(void *data); | 129 | static void cpc_tty_tx_work(struct work_struct *work); |
130 | static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len); | 130 | static int cpc_tty_send_to_card(pc300dev_t *dev,void *buf, int len); |
131 | static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx); | 131 | static void cpc_tty_trace(pc300dev_t *dev, char* buf, int len, char rxtx); |
132 | static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char); | 132 | static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char); |
@@ -261,8 +261,8 @@ void cpc_tty_init(pc300dev_t *pc300dev) | |||
261 | cpc_tty->tty_minor = port + CPC_TTY_MINOR_START; | 261 | cpc_tty->tty_minor = port + CPC_TTY_MINOR_START; |
262 | cpc_tty->pc300dev = pc300dev; | 262 | cpc_tty->pc300dev = pc300dev; |
263 | 263 | ||
264 | INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work, (void *)cpc_tty); | 264 | INIT_WORK(&cpc_tty->tty_tx_work, cpc_tty_tx_work); |
265 | INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work, (void *)port); | 265 | INIT_WORK(&cpc_tty->tty_rx_work, cpc_tty_rx_work); |
266 | 266 | ||
267 | cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL; | 267 | cpc_tty->buf_rx.first = cpc_tty->buf_rx.last = NULL; |
268 | 268 | ||
@@ -659,21 +659,23 @@ static void cpc_tty_hangup(struct tty_struct *tty) | |||
659 | * o call the line disc. read | 659 | * o call the line disc. read |
660 | * o free memory | 660 | * o free memory |
661 | */ | 661 | */ |
662 | static void cpc_tty_rx_work(void * data) | 662 | static void cpc_tty_rx_work(struct work_struct *work) |
663 | { | 663 | { |
664 | st_cpc_tty_area *cpc_tty; | ||
664 | unsigned long port; | 665 | unsigned long port; |
665 | int i, j; | 666 | int i, j; |
666 | st_cpc_tty_area *cpc_tty; | ||
667 | volatile st_cpc_rx_buf *buf; | 667 | volatile st_cpc_rx_buf *buf; |
668 | char flags=0,flg_rx=1; | 668 | char flags=0,flg_rx=1; |
669 | struct tty_ldisc *ld; | 669 | struct tty_ldisc *ld; |
670 | 670 | ||
671 | if (cpc_tty_cnt == 0) return; | 671 | if (cpc_tty_cnt == 0) return; |
672 | |||
673 | 672 | ||
674 | for (i=0; (i < 4) && flg_rx ; i++) { | 673 | for (i=0; (i < 4) && flg_rx ; i++) { |
675 | flg_rx = 0; | 674 | flg_rx = 0; |
676 | port = (unsigned long)data; | 675 | |
676 | cpc_tty = container_of(work, st_cpc_tty_area, tty_rx_work); | ||
677 | port = cpc_tty - cpc_tty_area; | ||
678 | |||
677 | for (j=0; j < CPC_TTY_NPORTS; j++) { | 679 | for (j=0; j < CPC_TTY_NPORTS; j++) { |
678 | cpc_tty = &cpc_tty_area[port]; | 680 | cpc_tty = &cpc_tty_area[port]; |
679 | 681 | ||
@@ -882,9 +884,10 @@ void cpc_tty_receive(pc300dev_t *pc300dev) | |||
882 | * o if need call line discipline wakeup | 884 | * o if need call line discipline wakeup |
883 | * o call wake_up_interruptible | 885 | * o call wake_up_interruptible |
884 | */ | 886 | */ |
885 | static void cpc_tty_tx_work(void *data) | 887 | static void cpc_tty_tx_work(struct work_struct *work) |
886 | { | 888 | { |
887 | st_cpc_tty_area *cpc_tty = (st_cpc_tty_area *) data; | 889 | st_cpc_tty_area *cpc_tty = |
890 | container_of(work, st_cpc_tty_area, tty_tx_work); | ||
888 | struct tty_struct *tty; | 891 | struct tty_struct *tty; |
889 | 892 | ||
890 | CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name); | 893 | CPC_TTY_DBG("%s: cpc_tty_tx_work init\n",cpc_tty->name); |
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index ac9437d497f0..f12355398fe7 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c | |||
@@ -219,21 +219,6 @@ static int airo_config(struct pcmcia_device *link) | |||
219 | dev = link->priv; | 219 | dev = link->priv; |
220 | 220 | ||
221 | DEBUG(0, "airo_config(0x%p)\n", link); | 221 | DEBUG(0, "airo_config(0x%p)\n", link); |
222 | |||
223 | /* | ||
224 | This reads the card's CONFIG tuple to find its configuration | ||
225 | registers. | ||
226 | */ | ||
227 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
228 | tuple.Attributes = 0; | ||
229 | tuple.TupleData = buf; | ||
230 | tuple.TupleDataMax = sizeof(buf); | ||
231 | tuple.TupleOffset = 0; | ||
232 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
233 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
234 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
235 | link->conf.ConfigBase = parse.config.base; | ||
236 | link->conf.Present = parse.config.rmask[0]; | ||
237 | 222 | ||
238 | /* | 223 | /* |
239 | In this loop, we scan the CIS for configuration table entries, | 224 | In this loop, we scan the CIS for configuration table entries, |
@@ -247,6 +232,10 @@ static int airo_config(struct pcmcia_device *link) | |||
247 | these things without consulting the CIS, and most client drivers | 232 | these things without consulting the CIS, and most client drivers |
248 | will only use the CIS to fill in implementation-defined details. | 233 | will only use the CIS to fill in implementation-defined details. |
249 | */ | 234 | */ |
235 | tuple.Attributes = 0; | ||
236 | tuple.TupleData = buf; | ||
237 | tuple.TupleDataMax = sizeof(buf); | ||
238 | tuple.TupleOffset = 0; | ||
250 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 239 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
251 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 240 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
252 | while (1) { | 241 | while (1) { |
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 5c410989c4d7..12617cd0b78e 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c | |||
@@ -244,17 +244,6 @@ static int atmel_config(struct pcmcia_device *link) | |||
244 | tuple.TupleOffset = 0; | 244 | tuple.TupleOffset = 0; |
245 | 245 | ||
246 | /* | 246 | /* |
247 | This reads the card's CONFIG tuple to find its configuration | ||
248 | registers. | ||
249 | */ | ||
250 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
251 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
252 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
253 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
254 | link->conf.ConfigBase = parse.config.base; | ||
255 | link->conf.Present = parse.config.rmask[0]; | ||
256 | |||
257 | /* | ||
258 | In this loop, we scan the CIS for configuration table entries, | 247 | In this loop, we scan the CIS for configuration table entries, |
259 | each of which describes a valid card configuration, including | 248 | each of which describes a valid card configuration, including |
260 | voltage, IO window, memory window, and interrupt settings. | 249 | voltage, IO window, memory window, and interrupt settings. |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index 94dfb92fab5c..8286678513b9 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h | |||
@@ -819,7 +819,7 @@ struct bcm43xx_private { | |||
819 | struct tasklet_struct isr_tasklet; | 819 | struct tasklet_struct isr_tasklet; |
820 | 820 | ||
821 | /* Periodic tasks */ | 821 | /* Periodic tasks */ |
822 | struct work_struct periodic_work; | 822 | struct delayed_work periodic_work; |
823 | unsigned int periodic_state; | 823 | unsigned int periodic_state; |
824 | 824 | ||
825 | struct work_struct restart_work; | 825 | struct work_struct restart_work; |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 5b3c27359a18..2ec2e5afce67 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -3215,9 +3215,10 @@ static void do_periodic_work(struct bcm43xx_private *bcm) | |||
3215 | schedule_delayed_work(&bcm->periodic_work, HZ * 15); | 3215 | schedule_delayed_work(&bcm->periodic_work, HZ * 15); |
3216 | } | 3216 | } |
3217 | 3217 | ||
3218 | static void bcm43xx_periodic_work_handler(void *d) | 3218 | static void bcm43xx_periodic_work_handler(struct work_struct *work) |
3219 | { | 3219 | { |
3220 | struct bcm43xx_private *bcm = d; | 3220 | struct bcm43xx_private *bcm = |
3221 | container_of(work, struct bcm43xx_private, periodic_work.work); | ||
3221 | struct net_device *net_dev = bcm->net_dev; | 3222 | struct net_device *net_dev = bcm->net_dev; |
3222 | unsigned long flags; | 3223 | unsigned long flags; |
3223 | u32 savedirqs = 0; | 3224 | u32 savedirqs = 0; |
@@ -3279,11 +3280,11 @@ void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm) | |||
3279 | 3280 | ||
3280 | void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) | 3281 | void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm) |
3281 | { | 3282 | { |
3282 | struct work_struct *work = &(bcm->periodic_work); | 3283 | struct delayed_work *work = &bcm->periodic_work; |
3283 | 3284 | ||
3284 | assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); | 3285 | assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED); |
3285 | INIT_WORK(work, bcm43xx_periodic_work_handler, bcm); | 3286 | INIT_DELAYED_WORK(work, bcm43xx_periodic_work_handler); |
3286 | schedule_work(work); | 3287 | schedule_delayed_work(work, 0); |
3287 | } | 3288 | } |
3288 | 3289 | ||
3289 | static void bcm43xx_security_init(struct bcm43xx_private *bcm) | 3290 | static void bcm43xx_security_init(struct bcm43xx_private *bcm) |
@@ -3635,7 +3636,7 @@ static int bcm43xx_init_board(struct bcm43xx_private *bcm) | |||
3635 | bcm43xx_periodic_tasks_setup(bcm); | 3636 | bcm43xx_periodic_tasks_setup(bcm); |
3636 | 3637 | ||
3637 | /*FIXME: This should be handled by softmac instead. */ | 3638 | /*FIXME: This should be handled by softmac instead. */ |
3638 | schedule_work(&bcm->softmac->associnfo.work); | 3639 | schedule_delayed_work(&bcm->softmac->associnfo.work, 0); |
3639 | 3640 | ||
3640 | out: | 3641 | out: |
3641 | mutex_unlock(&(bcm)->mutex); | 3642 | mutex_unlock(&(bcm)->mutex); |
@@ -4182,9 +4183,10 @@ static void __devexit bcm43xx_remove_one(struct pci_dev *pdev) | |||
4182 | /* Hard-reset the chip. Do not call this directly. | 4183 | /* Hard-reset the chip. Do not call this directly. |
4183 | * Use bcm43xx_controller_restart() | 4184 | * Use bcm43xx_controller_restart() |
4184 | */ | 4185 | */ |
4185 | static void bcm43xx_chip_reset(void *_bcm) | 4186 | static void bcm43xx_chip_reset(struct work_struct *work) |
4186 | { | 4187 | { |
4187 | struct bcm43xx_private *bcm = _bcm; | 4188 | struct bcm43xx_private *bcm = |
4189 | container_of(work, struct bcm43xx_private, restart_work); | ||
4188 | struct bcm43xx_phyinfo *phy; | 4190 | struct bcm43xx_phyinfo *phy; |
4189 | int err = -ENODEV; | 4191 | int err = -ENODEV; |
4190 | 4192 | ||
@@ -4211,7 +4213,7 @@ void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char *reason) | |||
4211 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) | 4213 | if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) |
4212 | return; | 4214 | return; |
4213 | printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); | 4215 | printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason); |
4214 | INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm); | 4216 | INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset); |
4215 | schedule_work(&bcm->restart_work); | 4217 | schedule_work(&bcm->restart_work); |
4216 | } | 4218 | } |
4217 | 4219 | ||
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h index e663518bd570..e89c890d16fd 100644 --- a/drivers/net/wireless/hostap/hostap.h +++ b/drivers/net/wireless/hostap/hostap.h | |||
@@ -35,7 +35,7 @@ int hostap_80211_get_hdrlen(u16 fc); | |||
35 | struct net_device_stats *hostap_get_stats(struct net_device *dev); | 35 | struct net_device_stats *hostap_get_stats(struct net_device *dev); |
36 | void hostap_setup_dev(struct net_device *dev, local_info_t *local, | 36 | void hostap_setup_dev(struct net_device *dev, local_info_t *local, |
37 | int main_dev); | 37 | int main_dev); |
38 | void hostap_set_multicast_list_queue(void *data); | 38 | void hostap_set_multicast_list_queue(struct work_struct *work); |
39 | int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked); | 39 | int hostap_set_hostapd(local_info_t *local, int val, int rtnl_locked); |
40 | int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked); | 40 | int hostap_set_hostapd_sta(local_info_t *local, int val, int rtnl_locked); |
41 | void hostap_cleanup(local_info_t *local); | 41 | void hostap_cleanup(local_info_t *local); |
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index ba13125024cb..08bc57a4b895 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c | |||
@@ -49,10 +49,10 @@ MODULE_PARM_DESC(autom_ap_wds, "Add WDS connections to other APs " | |||
49 | static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta); | 49 | static struct sta_info* ap_get_sta(struct ap_data *ap, u8 *sta); |
50 | static void hostap_event_expired_sta(struct net_device *dev, | 50 | static void hostap_event_expired_sta(struct net_device *dev, |
51 | struct sta_info *sta); | 51 | struct sta_info *sta); |
52 | static void handle_add_proc_queue(void *data); | 52 | static void handle_add_proc_queue(struct work_struct *work); |
53 | 53 | ||
54 | #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT | 54 | #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT |
55 | static void handle_wds_oper_queue(void *data); | 55 | static void handle_wds_oper_queue(struct work_struct *work); |
56 | static void prism2_send_mgmt(struct net_device *dev, | 56 | static void prism2_send_mgmt(struct net_device *dev, |
57 | u16 type_subtype, char *body, | 57 | u16 type_subtype, char *body, |
58 | int body_len, u8 *addr, u16 tx_cb_idx); | 58 | int body_len, u8 *addr, u16 tx_cb_idx); |
@@ -807,7 +807,7 @@ void hostap_init_data(local_info_t *local) | |||
807 | INIT_LIST_HEAD(&ap->sta_list); | 807 | INIT_LIST_HEAD(&ap->sta_list); |
808 | 808 | ||
809 | /* Initialize task queue structure for AP management */ | 809 | /* Initialize task queue structure for AP management */ |
810 | INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue, ap); | 810 | INIT_WORK(&local->ap->add_sta_proc_queue, handle_add_proc_queue); |
811 | 811 | ||
812 | ap->tx_callback_idx = | 812 | ap->tx_callback_idx = |
813 | hostap_tx_callback_register(local, hostap_ap_tx_cb, ap); | 813 | hostap_tx_callback_register(local, hostap_ap_tx_cb, ap); |
@@ -815,7 +815,7 @@ void hostap_init_data(local_info_t *local) | |||
815 | printk(KERN_WARNING "%s: failed to register TX callback for " | 815 | printk(KERN_WARNING "%s: failed to register TX callback for " |
816 | "AP\n", local->dev->name); | 816 | "AP\n", local->dev->name); |
817 | #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT | 817 | #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT |
818 | INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue, local); | 818 | INIT_WORK(&local->ap->wds_oper_queue, handle_wds_oper_queue); |
819 | 819 | ||
820 | ap->tx_callback_auth = | 820 | ap->tx_callback_auth = |
821 | hostap_tx_callback_register(local, hostap_ap_tx_cb_auth, ap); | 821 | hostap_tx_callback_register(local, hostap_ap_tx_cb_auth, ap); |
@@ -1062,9 +1062,10 @@ static int prism2_sta_proc_read(char *page, char **start, off_t off, | |||
1062 | } | 1062 | } |
1063 | 1063 | ||
1064 | 1064 | ||
1065 | static void handle_add_proc_queue(void *data) | 1065 | static void handle_add_proc_queue(struct work_struct *work) |
1066 | { | 1066 | { |
1067 | struct ap_data *ap = (struct ap_data *) data; | 1067 | struct ap_data *ap = container_of(work, struct ap_data, |
1068 | add_sta_proc_queue); | ||
1068 | struct sta_info *sta; | 1069 | struct sta_info *sta; |
1069 | char name[20]; | 1070 | char name[20]; |
1070 | struct add_sta_proc_data *entry, *prev; | 1071 | struct add_sta_proc_data *entry, *prev; |
@@ -1952,9 +1953,11 @@ static void handle_pspoll(local_info_t *local, | |||
1952 | 1953 | ||
1953 | #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT | 1954 | #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT |
1954 | 1955 | ||
1955 | static void handle_wds_oper_queue(void *data) | 1956 | static void handle_wds_oper_queue(struct work_struct *work) |
1956 | { | 1957 | { |
1957 | local_info_t *local = data; | 1958 | struct ap_data *ap = container_of(work, struct ap_data, |
1959 | wds_oper_queue); | ||
1960 | local_info_t *local = ap->local; | ||
1958 | struct wds_oper_data *entry, *prev; | 1961 | struct wds_oper_data *entry, *prev; |
1959 | 1962 | ||
1960 | spin_lock_bh(&local->lock); | 1963 | spin_lock_bh(&local->lock); |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index f63909e4bc32..ee542ec6d6a8 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -293,15 +293,12 @@ static int sandisk_enable_wireless(struct net_device *dev) | |||
293 | goto done; | 293 | goto done; |
294 | } | 294 | } |
295 | 295 | ||
296 | tuple.DesiredTuple = CISTPL_MANFID; | ||
297 | tuple.Attributes = TUPLE_RETURN_COMMON; | 296 | tuple.Attributes = TUPLE_RETURN_COMMON; |
298 | tuple.TupleData = buf; | 297 | tuple.TupleData = buf; |
299 | tuple.TupleDataMax = sizeof(buf); | 298 | tuple.TupleDataMax = sizeof(buf); |
300 | tuple.TupleOffset = 0; | 299 | tuple.TupleOffset = 0; |
301 | if (pcmcia_get_first_tuple(hw_priv->link, &tuple) || | 300 | |
302 | pcmcia_get_tuple_data(hw_priv->link, &tuple) || | 301 | if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) { |
303 | pcmcia_parse_tuple(hw_priv->link, &tuple, parse) || | ||
304 | parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) { | ||
305 | /* No SanDisk manfid found */ | 302 | /* No SanDisk manfid found */ |
306 | ret = -ENODEV; | 303 | ret = -ENODEV; |
307 | goto done; | 304 | goto done; |
@@ -573,16 +570,10 @@ static int prism2_config(struct pcmcia_device *link) | |||
573 | } | 570 | } |
574 | memset(hw_priv, 0, sizeof(*hw_priv)); | 571 | memset(hw_priv, 0, sizeof(*hw_priv)); |
575 | 572 | ||
576 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
577 | tuple.Attributes = 0; | 573 | tuple.Attributes = 0; |
578 | tuple.TupleData = buf; | 574 | tuple.TupleData = buf; |
579 | tuple.TupleDataMax = sizeof(buf); | 575 | tuple.TupleDataMax = sizeof(buf); |
580 | tuple.TupleOffset = 0; | 576 | tuple.TupleOffset = 0; |
581 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
582 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
583 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse)); | ||
584 | link->conf.ConfigBase = parse->config.base; | ||
585 | link->conf.Present = parse->config.rmask[0]; | ||
586 | 577 | ||
587 | CS_CHECK(GetConfigurationInfo, | 578 | CS_CHECK(GetConfigurationInfo, |
588 | pcmcia_get_configuration_info(link, &conf)); | 579 | pcmcia_get_configuration_info(link, &conf)); |
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index ed00ebb6e7f4..c19e68636a1c 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c | |||
@@ -1645,9 +1645,9 @@ static void prism2_schedule_reset(local_info_t *local) | |||
1645 | 1645 | ||
1646 | /* Called only as scheduled task after noticing card timeout in interrupt | 1646 | /* Called only as scheduled task after noticing card timeout in interrupt |
1647 | * context */ | 1647 | * context */ |
1648 | static void handle_reset_queue(void *data) | 1648 | static void handle_reset_queue(struct work_struct *work) |
1649 | { | 1649 | { |
1650 | local_info_t *local = (local_info_t *) data; | 1650 | local_info_t *local = container_of(work, local_info_t, reset_queue); |
1651 | 1651 | ||
1652 | printk(KERN_DEBUG "%s: scheduled card reset\n", local->dev->name); | 1652 | printk(KERN_DEBUG "%s: scheduled card reset\n", local->dev->name); |
1653 | prism2_hw_reset(local->dev); | 1653 | prism2_hw_reset(local->dev); |
@@ -2896,9 +2896,10 @@ static void hostap_passive_scan(unsigned long data) | |||
2896 | 2896 | ||
2897 | /* Called only as a scheduled task when communications quality values should | 2897 | /* Called only as a scheduled task when communications quality values should |
2898 | * be updated. */ | 2898 | * be updated. */ |
2899 | static void handle_comms_qual_update(void *data) | 2899 | static void handle_comms_qual_update(struct work_struct *work) |
2900 | { | 2900 | { |
2901 | local_info_t *local = data; | 2901 | local_info_t *local = |
2902 | container_of(work, local_info_t, comms_qual_update); | ||
2902 | prism2_update_comms_qual(local->dev); | 2903 | prism2_update_comms_qual(local->dev); |
2903 | } | 2904 | } |
2904 | 2905 | ||
@@ -3050,9 +3051,9 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set) | |||
3050 | } | 3051 | } |
3051 | 3052 | ||
3052 | 3053 | ||
3053 | static void handle_set_tim_queue(void *data) | 3054 | static void handle_set_tim_queue(struct work_struct *work) |
3054 | { | 3055 | { |
3055 | local_info_t *local = (local_info_t *) data; | 3056 | local_info_t *local = container_of(work, local_info_t, set_tim_queue); |
3056 | struct set_tim_data *entry; | 3057 | struct set_tim_data *entry; |
3057 | u16 val; | 3058 | u16 val; |
3058 | 3059 | ||
@@ -3209,15 +3210,15 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, | |||
3209 | local->scan_channel_mask = 0xffff; | 3210 | local->scan_channel_mask = 0xffff; |
3210 | 3211 | ||
3211 | /* Initialize task queue structures */ | 3212 | /* Initialize task queue structures */ |
3212 | INIT_WORK(&local->reset_queue, handle_reset_queue, local); | 3213 | INIT_WORK(&local->reset_queue, handle_reset_queue); |
3213 | INIT_WORK(&local->set_multicast_list_queue, | 3214 | INIT_WORK(&local->set_multicast_list_queue, |
3214 | hostap_set_multicast_list_queue, local->dev); | 3215 | hostap_set_multicast_list_queue); |
3215 | 3216 | ||
3216 | INIT_WORK(&local->set_tim_queue, handle_set_tim_queue, local); | 3217 | INIT_WORK(&local->set_tim_queue, handle_set_tim_queue); |
3217 | INIT_LIST_HEAD(&local->set_tim_list); | 3218 | INIT_LIST_HEAD(&local->set_tim_list); |
3218 | spin_lock_init(&local->set_tim_lock); | 3219 | spin_lock_init(&local->set_tim_lock); |
3219 | 3220 | ||
3220 | INIT_WORK(&local->comms_qual_update, handle_comms_qual_update, local); | 3221 | INIT_WORK(&local->comms_qual_update, handle_comms_qual_update); |
3221 | 3222 | ||
3222 | /* Initialize tasklets for handling hardware IRQ related operations | 3223 | /* Initialize tasklets for handling hardware IRQ related operations |
3223 | * outside hw IRQ handler */ | 3224 | * outside hw IRQ handler */ |
diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c index 50f72d831cf4..5fd2b1ad7f5e 100644 --- a/drivers/net/wireless/hostap/hostap_info.c +++ b/drivers/net/wireless/hostap/hostap_info.c | |||
@@ -474,9 +474,9 @@ static void handle_info_queue_scanresults(local_info_t *local) | |||
474 | 474 | ||
475 | /* Called only as scheduled task after receiving info frames (used to avoid | 475 | /* Called only as scheduled task after receiving info frames (used to avoid |
476 | * pending too much time in HW IRQ handler). */ | 476 | * pending too much time in HW IRQ handler). */ |
477 | static void handle_info_queue(void *data) | 477 | static void handle_info_queue(struct work_struct *work) |
478 | { | 478 | { |
479 | local_info_t *local = (local_info_t *) data; | 479 | local_info_t *local = container_of(work, local_info_t, info_queue); |
480 | 480 | ||
481 | if (test_and_clear_bit(PRISM2_INFO_PENDING_LINKSTATUS, | 481 | if (test_and_clear_bit(PRISM2_INFO_PENDING_LINKSTATUS, |
482 | &local->pending_info)) | 482 | &local->pending_info)) |
@@ -493,7 +493,7 @@ void hostap_info_init(local_info_t *local) | |||
493 | { | 493 | { |
494 | skb_queue_head_init(&local->info_list); | 494 | skb_queue_head_init(&local->info_list); |
495 | #ifndef PRISM2_NO_STATION_MODES | 495 | #ifndef PRISM2_NO_STATION_MODES |
496 | INIT_WORK(&local->info_queue, handle_info_queue, local); | 496 | INIT_WORK(&local->info_queue, handle_info_queue); |
497 | #endif /* PRISM2_NO_STATION_MODES */ | 497 | #endif /* PRISM2_NO_STATION_MODES */ |
498 | } | 498 | } |
499 | 499 | ||
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 53374fcba77e..0796be9d9e77 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c | |||
@@ -767,14 +767,14 @@ static int prism2_set_mac_address(struct net_device *dev, void *p) | |||
767 | 767 | ||
768 | /* TODO: to be further implemented as soon as Prism2 fully supports | 768 | /* TODO: to be further implemented as soon as Prism2 fully supports |
769 | * GroupAddresses and correct documentation is available */ | 769 | * GroupAddresses and correct documentation is available */ |
770 | void hostap_set_multicast_list_queue(void *data) | 770 | void hostap_set_multicast_list_queue(struct work_struct *work) |
771 | { | 771 | { |
772 | struct net_device *dev = (struct net_device *) data; | 772 | local_info_t *local = |
773 | container_of(work, local_info_t, set_multicast_list_queue); | ||
774 | struct net_device *dev = local->dev; | ||
773 | struct hostap_interface *iface; | 775 | struct hostap_interface *iface; |
774 | local_info_t *local; | ||
775 | 776 | ||
776 | iface = netdev_priv(dev); | 777 | iface = netdev_priv(dev); |
777 | local = iface->local; | ||
778 | if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, | 778 | if (hostap_set_word(dev, HFA384X_RID_PROMISCUOUSMODE, |
779 | local->is_promisc)) { | 779 | local->is_promisc)) { |
780 | printk(KERN_INFO "%s: %sabling promiscuous mode failed\n", | 780 | printk(KERN_INFO "%s: %sabling promiscuous mode failed\n", |
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c index 79607b8b877c..1bcd352a813b 100644 --- a/drivers/net/wireless/ipw2100.c +++ b/drivers/net/wireless/ipw2100.c | |||
@@ -316,7 +316,7 @@ static void ipw2100_release_firmware(struct ipw2100_priv *priv, | |||
316 | struct ipw2100_fw *fw); | 316 | struct ipw2100_fw *fw); |
317 | static int ipw2100_ucode_download(struct ipw2100_priv *priv, | 317 | static int ipw2100_ucode_download(struct ipw2100_priv *priv, |
318 | struct ipw2100_fw *fw); | 318 | struct ipw2100_fw *fw); |
319 | static void ipw2100_wx_event_work(struct ipw2100_priv *priv); | 319 | static void ipw2100_wx_event_work(struct work_struct *work); |
320 | static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev); | 320 | static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev); |
321 | static struct iw_handler_def ipw2100_wx_handler_def; | 321 | static struct iw_handler_def ipw2100_wx_handler_def; |
322 | 322 | ||
@@ -679,7 +679,8 @@ static void schedule_reset(struct ipw2100_priv *priv) | |||
679 | queue_delayed_work(priv->workqueue, &priv->reset_work, | 679 | queue_delayed_work(priv->workqueue, &priv->reset_work, |
680 | priv->reset_backoff * HZ); | 680 | priv->reset_backoff * HZ); |
681 | else | 681 | else |
682 | queue_work(priv->workqueue, &priv->reset_work); | 682 | queue_delayed_work(priv->workqueue, &priv->reset_work, |
683 | 0); | ||
683 | 684 | ||
684 | if (priv->reset_backoff < MAX_RESET_BACKOFF) | 685 | if (priv->reset_backoff < MAX_RESET_BACKOFF) |
685 | priv->reset_backoff++; | 686 | priv->reset_backoff++; |
@@ -1873,8 +1874,10 @@ static void ipw2100_down(struct ipw2100_priv *priv) | |||
1873 | netif_stop_queue(priv->net_dev); | 1874 | netif_stop_queue(priv->net_dev); |
1874 | } | 1875 | } |
1875 | 1876 | ||
1876 | static void ipw2100_reset_adapter(struct ipw2100_priv *priv) | 1877 | static void ipw2100_reset_adapter(struct work_struct *work) |
1877 | { | 1878 | { |
1879 | struct ipw2100_priv *priv = | ||
1880 | container_of(work, struct ipw2100_priv, reset_work.work); | ||
1878 | unsigned long flags; | 1881 | unsigned long flags; |
1879 | union iwreq_data wrqu = { | 1882 | union iwreq_data wrqu = { |
1880 | .ap_addr = { | 1883 | .ap_addr = { |
@@ -2071,9 +2074,9 @@ static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status) | |||
2071 | return; | 2074 | return; |
2072 | 2075 | ||
2073 | if (priv->status & STATUS_SECURITY_UPDATED) | 2076 | if (priv->status & STATUS_SECURITY_UPDATED) |
2074 | queue_work(priv->workqueue, &priv->security_work); | 2077 | queue_delayed_work(priv->workqueue, &priv->security_work, 0); |
2075 | 2078 | ||
2076 | queue_work(priv->workqueue, &priv->wx_event_work); | 2079 | queue_delayed_work(priv->workqueue, &priv->wx_event_work, 0); |
2077 | } | 2080 | } |
2078 | 2081 | ||
2079 | static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) | 2082 | static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) |
@@ -5524,8 +5527,11 @@ static int ipw2100_configure_security(struct ipw2100_priv *priv, int batch_mode) | |||
5524 | return err; | 5527 | return err; |
5525 | } | 5528 | } |
5526 | 5529 | ||
5527 | static void ipw2100_security_work(struct ipw2100_priv *priv) | 5530 | static void ipw2100_security_work(struct work_struct *work) |
5528 | { | 5531 | { |
5532 | struct ipw2100_priv *priv = | ||
5533 | container_of(work, struct ipw2100_priv, security_work.work); | ||
5534 | |||
5529 | /* If we happen to have reconnected before we get a chance to | 5535 | /* If we happen to have reconnected before we get a chance to |
5530 | * process this, then update the security settings--which causes | 5536 | * process this, then update the security settings--which causes |
5531 | * a disassociation to occur */ | 5537 | * a disassociation to occur */ |
@@ -5748,7 +5754,7 @@ static int ipw2100_set_address(struct net_device *dev, void *p) | |||
5748 | 5754 | ||
5749 | priv->reset_backoff = 0; | 5755 | priv->reset_backoff = 0; |
5750 | mutex_unlock(&priv->action_mutex); | 5756 | mutex_unlock(&priv->action_mutex); |
5751 | ipw2100_reset_adapter(priv); | 5757 | ipw2100_reset_adapter(&priv->reset_work.work); |
5752 | return 0; | 5758 | return 0; |
5753 | 5759 | ||
5754 | done: | 5760 | done: |
@@ -5910,9 +5916,10 @@ static const struct ethtool_ops ipw2100_ethtool_ops = { | |||
5910 | .get_drvinfo = ipw_ethtool_get_drvinfo, | 5916 | .get_drvinfo = ipw_ethtool_get_drvinfo, |
5911 | }; | 5917 | }; |
5912 | 5918 | ||
5913 | static void ipw2100_hang_check(void *adapter) | 5919 | static void ipw2100_hang_check(struct work_struct *work) |
5914 | { | 5920 | { |
5915 | struct ipw2100_priv *priv = adapter; | 5921 | struct ipw2100_priv *priv = |
5922 | container_of(work, struct ipw2100_priv, hang_check.work); | ||
5916 | unsigned long flags; | 5923 | unsigned long flags; |
5917 | u32 rtc = 0xa5a5a5a5; | 5924 | u32 rtc = 0xa5a5a5a5; |
5918 | u32 len = sizeof(rtc); | 5925 | u32 len = sizeof(rtc); |
@@ -5952,9 +5959,10 @@ static void ipw2100_hang_check(void *adapter) | |||
5952 | spin_unlock_irqrestore(&priv->low_lock, flags); | 5959 | spin_unlock_irqrestore(&priv->low_lock, flags); |
5953 | } | 5960 | } |
5954 | 5961 | ||
5955 | static void ipw2100_rf_kill(void *adapter) | 5962 | static void ipw2100_rf_kill(struct work_struct *work) |
5956 | { | 5963 | { |
5957 | struct ipw2100_priv *priv = adapter; | 5964 | struct ipw2100_priv *priv = |
5965 | container_of(work, struct ipw2100_priv, rf_kill.work); | ||
5958 | unsigned long flags; | 5966 | unsigned long flags; |
5959 | 5967 | ||
5960 | spin_lock_irqsave(&priv->low_lock, flags); | 5968 | spin_lock_irqsave(&priv->low_lock, flags); |
@@ -6103,14 +6111,11 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, | |||
6103 | 6111 | ||
6104 | priv->workqueue = create_workqueue(DRV_NAME); | 6112 | priv->workqueue = create_workqueue(DRV_NAME); |
6105 | 6113 | ||
6106 | INIT_WORK(&priv->reset_work, | 6114 | INIT_DELAYED_WORK(&priv->reset_work, ipw2100_reset_adapter); |
6107 | (void (*)(void *))ipw2100_reset_adapter, priv); | 6115 | INIT_DELAYED_WORK(&priv->security_work, ipw2100_security_work); |
6108 | INIT_WORK(&priv->security_work, | 6116 | INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work); |
6109 | (void (*)(void *))ipw2100_security_work, priv); | 6117 | INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check); |
6110 | INIT_WORK(&priv->wx_event_work, | 6118 | INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill); |
6111 | (void (*)(void *))ipw2100_wx_event_work, priv); | ||
6112 | INIT_WORK(&priv->hang_check, ipw2100_hang_check, priv); | ||
6113 | INIT_WORK(&priv->rf_kill, ipw2100_rf_kill, priv); | ||
6114 | 6119 | ||
6115 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) | 6120 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) |
6116 | ipw2100_irq_tasklet, (unsigned long)priv); | 6121 | ipw2100_irq_tasklet, (unsigned long)priv); |
@@ -8281,8 +8286,10 @@ static struct iw_handler_def ipw2100_wx_handler_def = { | |||
8281 | .get_wireless_stats = ipw2100_wx_wireless_stats, | 8286 | .get_wireless_stats = ipw2100_wx_wireless_stats, |
8282 | }; | 8287 | }; |
8283 | 8288 | ||
8284 | static void ipw2100_wx_event_work(struct ipw2100_priv *priv) | 8289 | static void ipw2100_wx_event_work(struct work_struct *work) |
8285 | { | 8290 | { |
8291 | struct ipw2100_priv *priv = | ||
8292 | container_of(work, struct ipw2100_priv, wx_event_work.work); | ||
8286 | union iwreq_data wrqu; | 8293 | union iwreq_data wrqu; |
8287 | int len = ETH_ALEN; | 8294 | int len = ETH_ALEN; |
8288 | 8295 | ||
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h index 55b7227198df..de7d384d38af 100644 --- a/drivers/net/wireless/ipw2100.h +++ b/drivers/net/wireless/ipw2100.h | |||
@@ -583,11 +583,11 @@ struct ipw2100_priv { | |||
583 | struct tasklet_struct irq_tasklet; | 583 | struct tasklet_struct irq_tasklet; |
584 | 584 | ||
585 | struct workqueue_struct *workqueue; | 585 | struct workqueue_struct *workqueue; |
586 | struct work_struct reset_work; | 586 | struct delayed_work reset_work; |
587 | struct work_struct security_work; | 587 | struct delayed_work security_work; |
588 | struct work_struct wx_event_work; | 588 | struct delayed_work wx_event_work; |
589 | struct work_struct hang_check; | 589 | struct delayed_work hang_check; |
590 | struct work_struct rf_kill; | 590 | struct delayed_work rf_kill; |
591 | 591 | ||
592 | u32 interrupts; | 592 | u32 interrupts; |
593 | int tx_interrupts; | 593 | int tx_interrupts; |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index c692d01a76ca..e82e56bb85e1 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -187,9 +187,9 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *); | |||
187 | static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *); | 187 | static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *); |
188 | static void ipw_rx_queue_replenish(void *); | 188 | static void ipw_rx_queue_replenish(void *); |
189 | static int ipw_up(struct ipw_priv *); | 189 | static int ipw_up(struct ipw_priv *); |
190 | static void ipw_bg_up(void *); | 190 | static void ipw_bg_up(struct work_struct *work); |
191 | static void ipw_down(struct ipw_priv *); | 191 | static void ipw_down(struct ipw_priv *); |
192 | static void ipw_bg_down(void *); | 192 | static void ipw_bg_down(struct work_struct *work); |
193 | static int ipw_config(struct ipw_priv *); | 193 | static int ipw_config(struct ipw_priv *); |
194 | static int init_supported_rates(struct ipw_priv *priv, | 194 | static int init_supported_rates(struct ipw_priv *priv, |
195 | struct ipw_supported_rates *prates); | 195 | struct ipw_supported_rates *prates); |
@@ -862,11 +862,12 @@ static void ipw_led_link_on(struct ipw_priv *priv) | |||
862 | spin_unlock_irqrestore(&priv->lock, flags); | 862 | spin_unlock_irqrestore(&priv->lock, flags); |
863 | } | 863 | } |
864 | 864 | ||
865 | static void ipw_bg_led_link_on(void *data) | 865 | static void ipw_bg_led_link_on(struct work_struct *work) |
866 | { | 866 | { |
867 | struct ipw_priv *priv = data; | 867 | struct ipw_priv *priv = |
868 | container_of(work, struct ipw_priv, led_link_on.work); | ||
868 | mutex_lock(&priv->mutex); | 869 | mutex_lock(&priv->mutex); |
869 | ipw_led_link_on(data); | 870 | ipw_led_link_on(priv); |
870 | mutex_unlock(&priv->mutex); | 871 | mutex_unlock(&priv->mutex); |
871 | } | 872 | } |
872 | 873 | ||
@@ -906,11 +907,12 @@ static void ipw_led_link_off(struct ipw_priv *priv) | |||
906 | spin_unlock_irqrestore(&priv->lock, flags); | 907 | spin_unlock_irqrestore(&priv->lock, flags); |
907 | } | 908 | } |
908 | 909 | ||
909 | static void ipw_bg_led_link_off(void *data) | 910 | static void ipw_bg_led_link_off(struct work_struct *work) |
910 | { | 911 | { |
911 | struct ipw_priv *priv = data; | 912 | struct ipw_priv *priv = |
913 | container_of(work, struct ipw_priv, led_link_off.work); | ||
912 | mutex_lock(&priv->mutex); | 914 | mutex_lock(&priv->mutex); |
913 | ipw_led_link_off(data); | 915 | ipw_led_link_off(priv); |
914 | mutex_unlock(&priv->mutex); | 916 | mutex_unlock(&priv->mutex); |
915 | } | 917 | } |
916 | 918 | ||
@@ -985,11 +987,12 @@ static void ipw_led_activity_off(struct ipw_priv *priv) | |||
985 | spin_unlock_irqrestore(&priv->lock, flags); | 987 | spin_unlock_irqrestore(&priv->lock, flags); |
986 | } | 988 | } |
987 | 989 | ||
988 | static void ipw_bg_led_activity_off(void *data) | 990 | static void ipw_bg_led_activity_off(struct work_struct *work) |
989 | { | 991 | { |
990 | struct ipw_priv *priv = data; | 992 | struct ipw_priv *priv = |
993 | container_of(work, struct ipw_priv, led_act_off.work); | ||
991 | mutex_lock(&priv->mutex); | 994 | mutex_lock(&priv->mutex); |
992 | ipw_led_activity_off(data); | 995 | ipw_led_activity_off(priv); |
993 | mutex_unlock(&priv->mutex); | 996 | mutex_unlock(&priv->mutex); |
994 | } | 997 | } |
995 | 998 | ||
@@ -2228,11 +2231,12 @@ static void ipw_adapter_restart(void *adapter) | |||
2228 | } | 2231 | } |
2229 | } | 2232 | } |
2230 | 2233 | ||
2231 | static void ipw_bg_adapter_restart(void *data) | 2234 | static void ipw_bg_adapter_restart(struct work_struct *work) |
2232 | { | 2235 | { |
2233 | struct ipw_priv *priv = data; | 2236 | struct ipw_priv *priv = |
2237 | container_of(work, struct ipw_priv, adapter_restart); | ||
2234 | mutex_lock(&priv->mutex); | 2238 | mutex_lock(&priv->mutex); |
2235 | ipw_adapter_restart(data); | 2239 | ipw_adapter_restart(priv); |
2236 | mutex_unlock(&priv->mutex); | 2240 | mutex_unlock(&priv->mutex); |
2237 | } | 2241 | } |
2238 | 2242 | ||
@@ -2249,11 +2253,12 @@ static void ipw_scan_check(void *data) | |||
2249 | } | 2253 | } |
2250 | } | 2254 | } |
2251 | 2255 | ||
2252 | static void ipw_bg_scan_check(void *data) | 2256 | static void ipw_bg_scan_check(struct work_struct *work) |
2253 | { | 2257 | { |
2254 | struct ipw_priv *priv = data; | 2258 | struct ipw_priv *priv = |
2259 | container_of(work, struct ipw_priv, scan_check.work); | ||
2255 | mutex_lock(&priv->mutex); | 2260 | mutex_lock(&priv->mutex); |
2256 | ipw_scan_check(data); | 2261 | ipw_scan_check(priv); |
2257 | mutex_unlock(&priv->mutex); | 2262 | mutex_unlock(&priv->mutex); |
2258 | } | 2263 | } |
2259 | 2264 | ||
@@ -3831,17 +3836,19 @@ static int ipw_disassociate(void *data) | |||
3831 | return 1; | 3836 | return 1; |
3832 | } | 3837 | } |
3833 | 3838 | ||
3834 | static void ipw_bg_disassociate(void *data) | 3839 | static void ipw_bg_disassociate(struct work_struct *work) |
3835 | { | 3840 | { |
3836 | struct ipw_priv *priv = data; | 3841 | struct ipw_priv *priv = |
3842 | container_of(work, struct ipw_priv, disassociate); | ||
3837 | mutex_lock(&priv->mutex); | 3843 | mutex_lock(&priv->mutex); |
3838 | ipw_disassociate(data); | 3844 | ipw_disassociate(priv); |
3839 | mutex_unlock(&priv->mutex); | 3845 | mutex_unlock(&priv->mutex); |
3840 | } | 3846 | } |
3841 | 3847 | ||
3842 | static void ipw_system_config(void *data) | 3848 | static void ipw_system_config(struct work_struct *work) |
3843 | { | 3849 | { |
3844 | struct ipw_priv *priv = data; | 3850 | struct ipw_priv *priv = |
3851 | container_of(work, struct ipw_priv, system_config); | ||
3845 | 3852 | ||
3846 | #ifdef CONFIG_IPW2200_PROMISCUOUS | 3853 | #ifdef CONFIG_IPW2200_PROMISCUOUS |
3847 | if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) { | 3854 | if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) { |
@@ -4208,11 +4215,12 @@ static void ipw_gather_stats(struct ipw_priv *priv) | |||
4208 | IPW_STATS_INTERVAL); | 4215 | IPW_STATS_INTERVAL); |
4209 | } | 4216 | } |
4210 | 4217 | ||
4211 | static void ipw_bg_gather_stats(void *data) | 4218 | static void ipw_bg_gather_stats(struct work_struct *work) |
4212 | { | 4219 | { |
4213 | struct ipw_priv *priv = data; | 4220 | struct ipw_priv *priv = |
4221 | container_of(work, struct ipw_priv, gather_stats.work); | ||
4214 | mutex_lock(&priv->mutex); | 4222 | mutex_lock(&priv->mutex); |
4215 | ipw_gather_stats(data); | 4223 | ipw_gather_stats(priv); |
4216 | mutex_unlock(&priv->mutex); | 4224 | mutex_unlock(&priv->mutex); |
4217 | } | 4225 | } |
4218 | 4226 | ||
@@ -4268,8 +4276,8 @@ static void ipw_handle_missed_beacon(struct ipw_priv *priv, | |||
4268 | if (!(priv->status & STATUS_ROAMING)) { | 4276 | if (!(priv->status & STATUS_ROAMING)) { |
4269 | priv->status |= STATUS_ROAMING; | 4277 | priv->status |= STATUS_ROAMING; |
4270 | if (!(priv->status & STATUS_SCANNING)) | 4278 | if (!(priv->status & STATUS_SCANNING)) |
4271 | queue_work(priv->workqueue, | 4279 | queue_delayed_work(priv->workqueue, |
4272 | &priv->request_scan); | 4280 | &priv->request_scan, 0); |
4273 | } | 4281 | } |
4274 | return; | 4282 | return; |
4275 | } | 4283 | } |
@@ -4607,8 +4615,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4607 | #ifdef CONFIG_IPW2200_MONITOR | 4615 | #ifdef CONFIG_IPW2200_MONITOR |
4608 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { | 4616 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { |
4609 | priv->status |= STATUS_SCAN_FORCED; | 4617 | priv->status |= STATUS_SCAN_FORCED; |
4610 | queue_work(priv->workqueue, | 4618 | queue_delayed_work(priv->workqueue, |
4611 | &priv->request_scan); | 4619 | &priv->request_scan, 0); |
4612 | break; | 4620 | break; |
4613 | } | 4621 | } |
4614 | priv->status &= ~STATUS_SCAN_FORCED; | 4622 | priv->status &= ~STATUS_SCAN_FORCED; |
@@ -4631,8 +4639,8 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4631 | /* Don't schedule if we aborted the scan */ | 4639 | /* Don't schedule if we aborted the scan */ |
4632 | priv->status &= ~STATUS_ROAMING; | 4640 | priv->status &= ~STATUS_ROAMING; |
4633 | } else if (priv->status & STATUS_SCAN_PENDING) | 4641 | } else if (priv->status & STATUS_SCAN_PENDING) |
4634 | queue_work(priv->workqueue, | 4642 | queue_delayed_work(priv->workqueue, |
4635 | &priv->request_scan); | 4643 | &priv->request_scan, 0); |
4636 | else if (priv->config & CFG_BACKGROUND_SCAN | 4644 | else if (priv->config & CFG_BACKGROUND_SCAN |
4637 | && priv->status & STATUS_ASSOCIATED) | 4645 | && priv->status & STATUS_ASSOCIATED) |
4638 | queue_delayed_work(priv->workqueue, | 4646 | queue_delayed_work(priv->workqueue, |
@@ -5055,11 +5063,12 @@ static void ipw_rx_queue_replenish(void *data) | |||
5055 | ipw_rx_queue_restock(priv); | 5063 | ipw_rx_queue_restock(priv); |
5056 | } | 5064 | } |
5057 | 5065 | ||
5058 | static void ipw_bg_rx_queue_replenish(void *data) | 5066 | static void ipw_bg_rx_queue_replenish(struct work_struct *work) |
5059 | { | 5067 | { |
5060 | struct ipw_priv *priv = data; | 5068 | struct ipw_priv *priv = |
5069 | container_of(work, struct ipw_priv, rx_replenish); | ||
5061 | mutex_lock(&priv->mutex); | 5070 | mutex_lock(&priv->mutex); |
5062 | ipw_rx_queue_replenish(data); | 5071 | ipw_rx_queue_replenish(priv); |
5063 | mutex_unlock(&priv->mutex); | 5072 | mutex_unlock(&priv->mutex); |
5064 | } | 5073 | } |
5065 | 5074 | ||
@@ -5489,9 +5498,10 @@ static int ipw_find_adhoc_network(struct ipw_priv *priv, | |||
5489 | return 1; | 5498 | return 1; |
5490 | } | 5499 | } |
5491 | 5500 | ||
5492 | static void ipw_merge_adhoc_network(void *data) | 5501 | static void ipw_merge_adhoc_network(struct work_struct *work) |
5493 | { | 5502 | { |
5494 | struct ipw_priv *priv = data; | 5503 | struct ipw_priv *priv = |
5504 | container_of(work, struct ipw_priv, merge_networks); | ||
5495 | struct ieee80211_network *network = NULL; | 5505 | struct ieee80211_network *network = NULL; |
5496 | struct ipw_network_match match = { | 5506 | struct ipw_network_match match = { |
5497 | .network = priv->assoc_network | 5507 | .network = priv->assoc_network |
@@ -5948,11 +5958,12 @@ static void ipw_adhoc_check(void *data) | |||
5948 | priv->assoc_request.beacon_interval); | 5958 | priv->assoc_request.beacon_interval); |
5949 | } | 5959 | } |
5950 | 5960 | ||
5951 | static void ipw_bg_adhoc_check(void *data) | 5961 | static void ipw_bg_adhoc_check(struct work_struct *work) |
5952 | { | 5962 | { |
5953 | struct ipw_priv *priv = data; | 5963 | struct ipw_priv *priv = |
5964 | container_of(work, struct ipw_priv, adhoc_check.work); | ||
5954 | mutex_lock(&priv->mutex); | 5965 | mutex_lock(&priv->mutex); |
5955 | ipw_adhoc_check(data); | 5966 | ipw_adhoc_check(priv); |
5956 | mutex_unlock(&priv->mutex); | 5967 | mutex_unlock(&priv->mutex); |
5957 | } | 5968 | } |
5958 | 5969 | ||
@@ -6299,19 +6310,26 @@ done: | |||
6299 | return err; | 6310 | return err; |
6300 | } | 6311 | } |
6301 | 6312 | ||
6302 | static int ipw_request_passive_scan(struct ipw_priv *priv) { | 6313 | static void ipw_request_passive_scan(struct work_struct *work) |
6303 | return ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE); | 6314 | { |
6315 | struct ipw_priv *priv = | ||
6316 | container_of(work, struct ipw_priv, request_passive_scan); | ||
6317 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE); | ||
6304 | } | 6318 | } |
6305 | 6319 | ||
6306 | static int ipw_request_scan(struct ipw_priv *priv) { | 6320 | static void ipw_request_scan(struct work_struct *work) |
6307 | return ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE); | 6321 | { |
6322 | struct ipw_priv *priv = | ||
6323 | container_of(work, struct ipw_priv, request_scan.work); | ||
6324 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE); | ||
6308 | } | 6325 | } |
6309 | 6326 | ||
6310 | static void ipw_bg_abort_scan(void *data) | 6327 | static void ipw_bg_abort_scan(struct work_struct *work) |
6311 | { | 6328 | { |
6312 | struct ipw_priv *priv = data; | 6329 | struct ipw_priv *priv = |
6330 | container_of(work, struct ipw_priv, abort_scan); | ||
6313 | mutex_lock(&priv->mutex); | 6331 | mutex_lock(&priv->mutex); |
6314 | ipw_abort_scan(data); | 6332 | ipw_abort_scan(priv); |
6315 | mutex_unlock(&priv->mutex); | 6333 | mutex_unlock(&priv->mutex); |
6316 | } | 6334 | } |
6317 | 6335 | ||
@@ -7084,9 +7102,10 @@ static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv, | |||
7084 | /* | 7102 | /* |
7085 | * background support to run QoS activate functionality | 7103 | * background support to run QoS activate functionality |
7086 | */ | 7104 | */ |
7087 | static void ipw_bg_qos_activate(void *data) | 7105 | static void ipw_bg_qos_activate(struct work_struct *work) |
7088 | { | 7106 | { |
7089 | struct ipw_priv *priv = data; | 7107 | struct ipw_priv *priv = |
7108 | container_of(work, struct ipw_priv, qos_activate); | ||
7090 | 7109 | ||
7091 | if (priv == NULL) | 7110 | if (priv == NULL) |
7092 | return; | 7111 | return; |
@@ -7394,11 +7413,12 @@ static void ipw_roam(void *data) | |||
7394 | priv->status &= ~STATUS_ROAMING; | 7413 | priv->status &= ~STATUS_ROAMING; |
7395 | } | 7414 | } |
7396 | 7415 | ||
7397 | static void ipw_bg_roam(void *data) | 7416 | static void ipw_bg_roam(struct work_struct *work) |
7398 | { | 7417 | { |
7399 | struct ipw_priv *priv = data; | 7418 | struct ipw_priv *priv = |
7419 | container_of(work, struct ipw_priv, roam); | ||
7400 | mutex_lock(&priv->mutex); | 7420 | mutex_lock(&priv->mutex); |
7401 | ipw_roam(data); | 7421 | ipw_roam(priv); |
7402 | mutex_unlock(&priv->mutex); | 7422 | mutex_unlock(&priv->mutex); |
7403 | } | 7423 | } |
7404 | 7424 | ||
@@ -7479,8 +7499,8 @@ static int ipw_associate(void *data) | |||
7479 | &priv->request_scan, | 7499 | &priv->request_scan, |
7480 | SCAN_INTERVAL); | 7500 | SCAN_INTERVAL); |
7481 | else | 7501 | else |
7482 | queue_work(priv->workqueue, | 7502 | queue_delayed_work(priv->workqueue, |
7483 | &priv->request_scan); | 7503 | &priv->request_scan, 0); |
7484 | } | 7504 | } |
7485 | 7505 | ||
7486 | return 0; | 7506 | return 0; |
@@ -7491,11 +7511,12 @@ static int ipw_associate(void *data) | |||
7491 | return 1; | 7511 | return 1; |
7492 | } | 7512 | } |
7493 | 7513 | ||
7494 | static void ipw_bg_associate(void *data) | 7514 | static void ipw_bg_associate(struct work_struct *work) |
7495 | { | 7515 | { |
7496 | struct ipw_priv *priv = data; | 7516 | struct ipw_priv *priv = |
7517 | container_of(work, struct ipw_priv, associate); | ||
7497 | mutex_lock(&priv->mutex); | 7518 | mutex_lock(&priv->mutex); |
7498 | ipw_associate(data); | 7519 | ipw_associate(priv); |
7499 | mutex_unlock(&priv->mutex); | 7520 | mutex_unlock(&priv->mutex); |
7500 | } | 7521 | } |
7501 | 7522 | ||
@@ -9410,7 +9431,7 @@ static int ipw_wx_set_scan(struct net_device *dev, | |||
9410 | 9431 | ||
9411 | IPW_DEBUG_WX("Start scan\n"); | 9432 | IPW_DEBUG_WX("Start scan\n"); |
9412 | 9433 | ||
9413 | queue_work(priv->workqueue, &priv->request_scan); | 9434 | queue_delayed_work(priv->workqueue, &priv->request_scan, 0); |
9414 | 9435 | ||
9415 | return 0; | 9436 | return 0; |
9416 | } | 9437 | } |
@@ -10547,11 +10568,12 @@ static void ipw_rf_kill(void *adapter) | |||
10547 | spin_unlock_irqrestore(&priv->lock, flags); | 10568 | spin_unlock_irqrestore(&priv->lock, flags); |
10548 | } | 10569 | } |
10549 | 10570 | ||
10550 | static void ipw_bg_rf_kill(void *data) | 10571 | static void ipw_bg_rf_kill(struct work_struct *work) |
10551 | { | 10572 | { |
10552 | struct ipw_priv *priv = data; | 10573 | struct ipw_priv *priv = |
10574 | container_of(work, struct ipw_priv, rf_kill.work); | ||
10553 | mutex_lock(&priv->mutex); | 10575 | mutex_lock(&priv->mutex); |
10554 | ipw_rf_kill(data); | 10576 | ipw_rf_kill(priv); |
10555 | mutex_unlock(&priv->mutex); | 10577 | mutex_unlock(&priv->mutex); |
10556 | } | 10578 | } |
10557 | 10579 | ||
@@ -10582,11 +10604,12 @@ static void ipw_link_up(struct ipw_priv *priv) | |||
10582 | queue_delayed_work(priv->workqueue, &priv->request_scan, HZ); | 10604 | queue_delayed_work(priv->workqueue, &priv->request_scan, HZ); |
10583 | } | 10605 | } |
10584 | 10606 | ||
10585 | static void ipw_bg_link_up(void *data) | 10607 | static void ipw_bg_link_up(struct work_struct *work) |
10586 | { | 10608 | { |
10587 | struct ipw_priv *priv = data; | 10609 | struct ipw_priv *priv = |
10610 | container_of(work, struct ipw_priv, link_up); | ||
10588 | mutex_lock(&priv->mutex); | 10611 | mutex_lock(&priv->mutex); |
10589 | ipw_link_up(data); | 10612 | ipw_link_up(priv); |
10590 | mutex_unlock(&priv->mutex); | 10613 | mutex_unlock(&priv->mutex); |
10591 | } | 10614 | } |
10592 | 10615 | ||
@@ -10606,15 +10629,16 @@ static void ipw_link_down(struct ipw_priv *priv) | |||
10606 | 10629 | ||
10607 | if (!(priv->status & STATUS_EXIT_PENDING)) { | 10630 | if (!(priv->status & STATUS_EXIT_PENDING)) { |
10608 | /* Queue up another scan... */ | 10631 | /* Queue up another scan... */ |
10609 | queue_work(priv->workqueue, &priv->request_scan); | 10632 | queue_delayed_work(priv->workqueue, &priv->request_scan, 0); |
10610 | } | 10633 | } |
10611 | } | 10634 | } |
10612 | 10635 | ||
10613 | static void ipw_bg_link_down(void *data) | 10636 | static void ipw_bg_link_down(struct work_struct *work) |
10614 | { | 10637 | { |
10615 | struct ipw_priv *priv = data; | 10638 | struct ipw_priv *priv = |
10639 | container_of(work, struct ipw_priv, link_down); | ||
10616 | mutex_lock(&priv->mutex); | 10640 | mutex_lock(&priv->mutex); |
10617 | ipw_link_down(data); | 10641 | ipw_link_down(priv); |
10618 | mutex_unlock(&priv->mutex); | 10642 | mutex_unlock(&priv->mutex); |
10619 | } | 10643 | } |
10620 | 10644 | ||
@@ -10626,38 +10650,30 @@ static int ipw_setup_deferred_work(struct ipw_priv *priv) | |||
10626 | init_waitqueue_head(&priv->wait_command_queue); | 10650 | init_waitqueue_head(&priv->wait_command_queue); |
10627 | init_waitqueue_head(&priv->wait_state); | 10651 | init_waitqueue_head(&priv->wait_state); |
10628 | 10652 | ||
10629 | INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv); | 10653 | INIT_DELAYED_WORK(&priv->adhoc_check, ipw_bg_adhoc_check); |
10630 | INIT_WORK(&priv->associate, ipw_bg_associate, priv); | 10654 | INIT_WORK(&priv->associate, ipw_bg_associate); |
10631 | INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv); | 10655 | INIT_WORK(&priv->disassociate, ipw_bg_disassociate); |
10632 | INIT_WORK(&priv->system_config, ipw_system_config, priv); | 10656 | INIT_WORK(&priv->system_config, ipw_system_config); |
10633 | INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv); | 10657 | INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish); |
10634 | INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv); | 10658 | INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart); |
10635 | INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv); | 10659 | INIT_DELAYED_WORK(&priv->rf_kill, ipw_bg_rf_kill); |
10636 | INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv); | 10660 | INIT_WORK(&priv->up, ipw_bg_up); |
10637 | INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv); | 10661 | INIT_WORK(&priv->down, ipw_bg_down); |
10638 | INIT_WORK(&priv->request_scan, | 10662 | INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan); |
10639 | (void (*)(void *))ipw_request_scan, priv); | 10663 | INIT_WORK(&priv->request_passive_scan, ipw_request_passive_scan); |
10640 | INIT_WORK(&priv->request_passive_scan, | 10664 | INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats); |
10641 | (void (*)(void *))ipw_request_passive_scan, priv); | 10665 | INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan); |
10642 | INIT_WORK(&priv->gather_stats, | 10666 | INIT_WORK(&priv->roam, ipw_bg_roam); |
10643 | (void (*)(void *))ipw_bg_gather_stats, priv); | 10667 | INIT_DELAYED_WORK(&priv->scan_check, ipw_bg_scan_check); |
10644 | INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv); | 10668 | INIT_WORK(&priv->link_up, ipw_bg_link_up); |
10645 | INIT_WORK(&priv->roam, ipw_bg_roam, priv); | 10669 | INIT_WORK(&priv->link_down, ipw_bg_link_down); |
10646 | INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv); | 10670 | INIT_DELAYED_WORK(&priv->led_link_on, ipw_bg_led_link_on); |
10647 | INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv); | 10671 | INIT_DELAYED_WORK(&priv->led_link_off, ipw_bg_led_link_off); |
10648 | INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv); | 10672 | INIT_DELAYED_WORK(&priv->led_act_off, ipw_bg_led_activity_off); |
10649 | INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on, | 10673 | INIT_WORK(&priv->merge_networks, ipw_merge_adhoc_network); |
10650 | priv); | ||
10651 | INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off, | ||
10652 | priv); | ||
10653 | INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off, | ||
10654 | priv); | ||
10655 | INIT_WORK(&priv->merge_networks, | ||
10656 | (void (*)(void *))ipw_merge_adhoc_network, priv); | ||
10657 | 10674 | ||
10658 | #ifdef CONFIG_IPW2200_QOS | 10675 | #ifdef CONFIG_IPW2200_QOS |
10659 | INIT_WORK(&priv->qos_activate, (void (*)(void *))ipw_bg_qos_activate, | 10676 | INIT_WORK(&priv->qos_activate, ipw_bg_qos_activate); |
10660 | priv); | ||
10661 | #endif /* CONFIG_IPW2200_QOS */ | 10677 | #endif /* CONFIG_IPW2200_QOS */ |
10662 | 10678 | ||
10663 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) | 10679 | tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) |
@@ -11190,7 +11206,8 @@ static int ipw_up(struct ipw_priv *priv) | |||
11190 | 11206 | ||
11191 | /* If configure to try and auto-associate, kick | 11207 | /* If configure to try and auto-associate, kick |
11192 | * off a scan. */ | 11208 | * off a scan. */ |
11193 | queue_work(priv->workqueue, &priv->request_scan); | 11209 | queue_delayed_work(priv->workqueue, |
11210 | &priv->request_scan, 0); | ||
11194 | 11211 | ||
11195 | return 0; | 11212 | return 0; |
11196 | } | 11213 | } |
@@ -11211,11 +11228,12 @@ static int ipw_up(struct ipw_priv *priv) | |||
11211 | return -EIO; | 11228 | return -EIO; |
11212 | } | 11229 | } |
11213 | 11230 | ||
11214 | static void ipw_bg_up(void *data) | 11231 | static void ipw_bg_up(struct work_struct *work) |
11215 | { | 11232 | { |
11216 | struct ipw_priv *priv = data; | 11233 | struct ipw_priv *priv = |
11234 | container_of(work, struct ipw_priv, up); | ||
11217 | mutex_lock(&priv->mutex); | 11235 | mutex_lock(&priv->mutex); |
11218 | ipw_up(data); | 11236 | ipw_up(priv); |
11219 | mutex_unlock(&priv->mutex); | 11237 | mutex_unlock(&priv->mutex); |
11220 | } | 11238 | } |
11221 | 11239 | ||
@@ -11282,11 +11300,12 @@ static void ipw_down(struct ipw_priv *priv) | |||
11282 | ipw_led_radio_off(priv); | 11300 | ipw_led_radio_off(priv); |
11283 | } | 11301 | } |
11284 | 11302 | ||
11285 | static void ipw_bg_down(void *data) | 11303 | static void ipw_bg_down(struct work_struct *work) |
11286 | { | 11304 | { |
11287 | struct ipw_priv *priv = data; | 11305 | struct ipw_priv *priv = |
11306 | container_of(work, struct ipw_priv, down); | ||
11288 | mutex_lock(&priv->mutex); | 11307 | mutex_lock(&priv->mutex); |
11289 | ipw_down(data); | 11308 | ipw_down(priv); |
11290 | mutex_unlock(&priv->mutex); | 11309 | mutex_unlock(&priv->mutex); |
11291 | } | 11310 | } |
11292 | 11311 | ||
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h index dad5eedefbf1..626a240a87d8 100644 --- a/drivers/net/wireless/ipw2200.h +++ b/drivers/net/wireless/ipw2200.h | |||
@@ -1290,21 +1290,21 @@ struct ipw_priv { | |||
1290 | 1290 | ||
1291 | struct workqueue_struct *workqueue; | 1291 | struct workqueue_struct *workqueue; |
1292 | 1292 | ||
1293 | struct work_struct adhoc_check; | 1293 | struct delayed_work adhoc_check; |
1294 | struct work_struct associate; | 1294 | struct work_struct associate; |
1295 | struct work_struct disassociate; | 1295 | struct work_struct disassociate; |
1296 | struct work_struct system_config; | 1296 | struct work_struct system_config; |
1297 | struct work_struct rx_replenish; | 1297 | struct work_struct rx_replenish; |
1298 | struct work_struct request_scan; | 1298 | struct delayed_work request_scan; |
1299 | struct work_struct request_passive_scan; | 1299 | struct work_struct request_passive_scan; |
1300 | struct work_struct adapter_restart; | 1300 | struct work_struct adapter_restart; |
1301 | struct work_struct rf_kill; | 1301 | struct delayed_work rf_kill; |
1302 | struct work_struct up; | 1302 | struct work_struct up; |
1303 | struct work_struct down; | 1303 | struct work_struct down; |
1304 | struct work_struct gather_stats; | 1304 | struct delayed_work gather_stats; |
1305 | struct work_struct abort_scan; | 1305 | struct work_struct abort_scan; |
1306 | struct work_struct roam; | 1306 | struct work_struct roam; |
1307 | struct work_struct scan_check; | 1307 | struct delayed_work scan_check; |
1308 | struct work_struct link_up; | 1308 | struct work_struct link_up; |
1309 | struct work_struct link_down; | 1309 | struct work_struct link_down; |
1310 | 1310 | ||
@@ -1319,9 +1319,9 @@ struct ipw_priv { | |||
1319 | u32 led_ofdm_on; | 1319 | u32 led_ofdm_on; |
1320 | u32 led_ofdm_off; | 1320 | u32 led_ofdm_off; |
1321 | 1321 | ||
1322 | struct work_struct led_link_on; | 1322 | struct delayed_work led_link_on; |
1323 | struct work_struct led_link_off; | 1323 | struct delayed_work led_link_off; |
1324 | struct work_struct led_act_off; | 1324 | struct delayed_work led_act_off; |
1325 | struct work_struct merge_networks; | 1325 | struct work_struct merge_networks; |
1326 | 1326 | ||
1327 | struct ipw_cmd_log *cmdlog; | 1327 | struct ipw_cmd_log *cmdlog; |
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index 6714e0dfa8d6..644b4741ef74 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c | |||
@@ -735,10 +735,7 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | |||
735 | static int netwave_pcmcia_config(struct pcmcia_device *link) { | 735 | static int netwave_pcmcia_config(struct pcmcia_device *link) { |
736 | struct net_device *dev = link->priv; | 736 | struct net_device *dev = link->priv; |
737 | netwave_private *priv = netdev_priv(dev); | 737 | netwave_private *priv = netdev_priv(dev); |
738 | tuple_t tuple; | ||
739 | cisparse_t parse; | ||
740 | int i, j, last_ret, last_fn; | 738 | int i, j, last_ret, last_fn; |
741 | u_char buf[64]; | ||
742 | win_req_t req; | 739 | win_req_t req; |
743 | memreq_t mem; | 740 | memreq_t mem; |
744 | u_char __iomem *ramBase = NULL; | 741 | u_char __iomem *ramBase = NULL; |
@@ -746,21 +743,6 @@ static int netwave_pcmcia_config(struct pcmcia_device *link) { | |||
746 | DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link); | 743 | DEBUG(0, "netwave_pcmcia_config(0x%p)\n", link); |
747 | 744 | ||
748 | /* | 745 | /* |
749 | This reads the card's CONFIG tuple to find its configuration | ||
750 | registers. | ||
751 | */ | ||
752 | tuple.Attributes = 0; | ||
753 | tuple.TupleData = (cisdata_t *) buf; | ||
754 | tuple.TupleDataMax = 64; | ||
755 | tuple.TupleOffset = 0; | ||
756 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
757 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
758 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
759 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
760 | link->conf.ConfigBase = parse.config.base; | ||
761 | link->conf.Present = parse.config.rmask[0]; | ||
762 | |||
763 | /* | ||
764 | * Try allocating IO ports. This tries a few fixed addresses. | 746 | * Try allocating IO ports. This tries a few fixed addresses. |
765 | * If you want, you can also read the card's config table to | 747 | * If you want, you can also read the card's config table to |
766 | * pick addresses -- see the serial driver for an example. | 748 | * pick addresses -- see the serial driver for an example. |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 336cabac13b3..936c888e03e1 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -980,9 +980,11 @@ static void print_linkstatus(struct net_device *dev, u16 status) | |||
980 | } | 980 | } |
981 | 981 | ||
982 | /* Search scan results for requested BSSID, join it if found */ | 982 | /* Search scan results for requested BSSID, join it if found */ |
983 | static void orinoco_join_ap(struct net_device *dev) | 983 | static void orinoco_join_ap(struct work_struct *work) |
984 | { | 984 | { |
985 | struct orinoco_private *priv = netdev_priv(dev); | 985 | struct orinoco_private *priv = |
986 | container_of(work, struct orinoco_private, join_work); | ||
987 | struct net_device *dev = priv->ndev; | ||
986 | struct hermes *hw = &priv->hw; | 988 | struct hermes *hw = &priv->hw; |
987 | int err; | 989 | int err; |
988 | unsigned long flags; | 990 | unsigned long flags; |
@@ -1055,9 +1057,11 @@ static void orinoco_join_ap(struct net_device *dev) | |||
1055 | } | 1057 | } |
1056 | 1058 | ||
1057 | /* Send new BSSID to userspace */ | 1059 | /* Send new BSSID to userspace */ |
1058 | static void orinoco_send_wevents(struct net_device *dev) | 1060 | static void orinoco_send_wevents(struct work_struct *work) |
1059 | { | 1061 | { |
1060 | struct orinoco_private *priv = netdev_priv(dev); | 1062 | struct orinoco_private *priv = |
1063 | container_of(work, struct orinoco_private, wevent_work); | ||
1064 | struct net_device *dev = priv->ndev; | ||
1061 | struct hermes *hw = &priv->hw; | 1065 | struct hermes *hw = &priv->hw; |
1062 | union iwreq_data wrqu; | 1066 | union iwreq_data wrqu; |
1063 | int err; | 1067 | int err; |
@@ -1864,9 +1868,11 @@ __orinoco_set_multicast_list(struct net_device *dev) | |||
1864 | 1868 | ||
1865 | /* This must be called from user context, without locks held - use | 1869 | /* This must be called from user context, without locks held - use |
1866 | * schedule_work() */ | 1870 | * schedule_work() */ |
1867 | static void orinoco_reset(struct net_device *dev) | 1871 | static void orinoco_reset(struct work_struct *work) |
1868 | { | 1872 | { |
1869 | struct orinoco_private *priv = netdev_priv(dev); | 1873 | struct orinoco_private *priv = |
1874 | container_of(work, struct orinoco_private, reset_work); | ||
1875 | struct net_device *dev = priv->ndev; | ||
1870 | struct hermes *hw = &priv->hw; | 1876 | struct hermes *hw = &priv->hw; |
1871 | int err; | 1877 | int err; |
1872 | unsigned long flags; | 1878 | unsigned long flags; |
@@ -2434,9 +2440,9 @@ struct net_device *alloc_orinocodev(int sizeof_card, | |||
2434 | priv->hw_unavailable = 1; /* orinoco_init() must clear this | 2440 | priv->hw_unavailable = 1; /* orinoco_init() must clear this |
2435 | * before anything else touches the | 2441 | * before anything else touches the |
2436 | * hardware */ | 2442 | * hardware */ |
2437 | INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev); | 2443 | INIT_WORK(&priv->reset_work, orinoco_reset); |
2438 | INIT_WORK(&priv->join_work, (void (*)(void *))orinoco_join_ap, dev); | 2444 | INIT_WORK(&priv->join_work, orinoco_join_ap); |
2439 | INIT_WORK(&priv->wevent_work, (void (*)(void *))orinoco_send_wevents, dev); | 2445 | INIT_WORK(&priv->wevent_work, orinoco_send_wevents); |
2440 | 2446 | ||
2441 | netif_carrier_off(dev); | 2447 | netif_carrier_off(dev); |
2442 | priv->last_linkstatus = 0xffff; | 2448 | priv->last_linkstatus = 0xffff; |
@@ -3608,7 +3614,7 @@ static int orinoco_ioctl_reset(struct net_device *dev, | |||
3608 | printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name); | 3614 | printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name); |
3609 | 3615 | ||
3610 | /* Firmware reset */ | 3616 | /* Firmware reset */ |
3611 | orinoco_reset(dev); | 3617 | orinoco_reset(&priv->reset_work); |
3612 | } else { | 3618 | } else { |
3613 | printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name); | 3619 | printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name); |
3614 | 3620 | ||
@@ -4154,7 +4160,7 @@ static int orinoco_ioctl_commit(struct net_device *dev, | |||
4154 | return 0; | 4160 | return 0; |
4155 | 4161 | ||
4156 | if (priv->broken_disableport) { | 4162 | if (priv->broken_disableport) { |
4157 | orinoco_reset(dev); | 4163 | orinoco_reset(&priv->reset_work); |
4158 | return 0; | 4164 | return 0; |
4159 | } | 4165 | } |
4160 | 4166 | ||
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index bc14689cbf24..d08ae8d2726c 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c | |||
@@ -178,21 +178,6 @@ orinoco_cs_config(struct pcmcia_device *link) | |||
178 | cisparse_t parse; | 178 | cisparse_t parse; |
179 | void __iomem *mem; | 179 | void __iomem *mem; |
180 | 180 | ||
181 | /* | ||
182 | * This reads the card's CONFIG tuple to find its | ||
183 | * configuration registers. | ||
184 | */ | ||
185 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
186 | tuple.Attributes = 0; | ||
187 | tuple.TupleData = buf; | ||
188 | tuple.TupleDataMax = sizeof(buf); | ||
189 | tuple.TupleOffset = 0; | ||
190 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
191 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
192 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
193 | link->conf.ConfigBase = parse.config.base; | ||
194 | link->conf.Present = parse.config.rmask[0]; | ||
195 | |||
196 | /* Look up the current Vcc */ | 181 | /* Look up the current Vcc */ |
197 | CS_CHECK(GetConfigurationInfo, | 182 | CS_CHECK(GetConfigurationInfo, |
198 | pcmcia_get_configuration_info(link, &conf)); | 183 | pcmcia_get_configuration_info(link, &conf)); |
@@ -211,6 +196,10 @@ orinoco_cs_config(struct pcmcia_device *link) | |||
211 | * and most client drivers will only use the CIS to fill in | 196 | * and most client drivers will only use the CIS to fill in |
212 | * implementation-defined details. | 197 | * implementation-defined details. |
213 | */ | 198 | */ |
199 | tuple.Attributes = 0; | ||
200 | tuple.TupleData = buf; | ||
201 | tuple.TupleDataMax = sizeof(buf); | ||
202 | tuple.TupleOffset = 0; | ||
214 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 203 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
215 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 204 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
216 | while (1) { | 205 | while (1) { |
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 4a20e45de3ca..a87eb51886c8 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
@@ -157,8 +157,9 @@ prism54_mib_init(islpci_private *priv) | |||
157 | * schedule_work(), thus we can as well use sleeping semaphore | 157 | * schedule_work(), thus we can as well use sleeping semaphore |
158 | * locking */ | 158 | * locking */ |
159 | void | 159 | void |
160 | prism54_update_stats(islpci_private *priv) | 160 | prism54_update_stats(struct work_struct *work) |
161 | { | 161 | { |
162 | islpci_private *priv = container_of(work, islpci_private, stats_work); | ||
162 | char *data; | 163 | char *data; |
163 | int j; | 164 | int j; |
164 | struct obj_bss bss, *bss2; | 165 | struct obj_bss bss, *bss2; |
@@ -2493,9 +2494,10 @@ prism54_process_trap_helper(islpci_private *priv, enum oid_num_t oid, | |||
2493 | * interrupt context, no locks held. | 2494 | * interrupt context, no locks held. |
2494 | */ | 2495 | */ |
2495 | void | 2496 | void |
2496 | prism54_process_trap(void *data) | 2497 | prism54_process_trap(struct work_struct *work) |
2497 | { | 2498 | { |
2498 | struct islpci_mgmtframe *frame = data; | 2499 | struct islpci_mgmtframe *frame = |
2500 | container_of(work, struct islpci_mgmtframe, ws); | ||
2499 | struct net_device *ndev = frame->ndev; | 2501 | struct net_device *ndev = frame->ndev; |
2500 | enum oid_num_t n = mgt_oidtonum(frame->header->oid); | 2502 | enum oid_num_t n = mgt_oidtonum(frame->header->oid); |
2501 | 2503 | ||
diff --git a/drivers/net/wireless/prism54/isl_ioctl.h b/drivers/net/wireless/prism54/isl_ioctl.h index e8183d30c52e..bcfbfb9281d2 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.h +++ b/drivers/net/wireless/prism54/isl_ioctl.h | |||
@@ -31,12 +31,12 @@ | |||
31 | void prism54_mib_init(islpci_private *); | 31 | void prism54_mib_init(islpci_private *); |
32 | 32 | ||
33 | struct iw_statistics *prism54_get_wireless_stats(struct net_device *); | 33 | struct iw_statistics *prism54_get_wireless_stats(struct net_device *); |
34 | void prism54_update_stats(islpci_private *); | 34 | void prism54_update_stats(struct work_struct *); |
35 | 35 | ||
36 | void prism54_acl_init(struct islpci_acl *); | 36 | void prism54_acl_init(struct islpci_acl *); |
37 | void prism54_acl_clean(struct islpci_acl *); | 37 | void prism54_acl_clean(struct islpci_acl *); |
38 | 38 | ||
39 | void prism54_process_trap(void *); | 39 | void prism54_process_trap(struct work_struct *); |
40 | 40 | ||
41 | void prism54_wpa_bss_ie_init(islpci_private *priv); | 41 | void prism54_wpa_bss_ie_init(islpci_private *priv); |
42 | void prism54_wpa_bss_ie_clean(islpci_private *priv); | 42 | void prism54_wpa_bss_ie_clean(islpci_private *priv); |
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 1e0603ca436c..f057fd9fcd79 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c | |||
@@ -860,11 +860,10 @@ islpci_setup(struct pci_dev *pdev) | |||
860 | priv->state_off = 1; | 860 | priv->state_off = 1; |
861 | 861 | ||
862 | /* initialize workqueue's */ | 862 | /* initialize workqueue's */ |
863 | INIT_WORK(&priv->stats_work, | 863 | INIT_WORK(&priv->stats_work, prism54_update_stats); |
864 | (void (*)(void *)) prism54_update_stats, priv); | ||
865 | priv->stats_timestamp = 0; | 864 | priv->stats_timestamp = 0; |
866 | 865 | ||
867 | INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake, priv); | 866 | INIT_WORK(&priv->reset_task, islpci_do_reset_and_wake); |
868 | priv->reset_task_pending = 0; | 867 | priv->reset_task_pending = 0; |
869 | 868 | ||
870 | /* allocate various memory areas */ | 869 | /* allocate various memory areas */ |
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index 676d83813dc8..b1122912ee2d 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c | |||
@@ -480,9 +480,9 @@ islpci_eth_receive(islpci_private *priv) | |||
480 | } | 480 | } |
481 | 481 | ||
482 | void | 482 | void |
483 | islpci_do_reset_and_wake(void *data) | 483 | islpci_do_reset_and_wake(struct work_struct *work) |
484 | { | 484 | { |
485 | islpci_private *priv = data; | 485 | islpci_private *priv = container_of(work, islpci_private, reset_task); |
486 | 486 | ||
487 | islpci_reset(priv, 1); | 487 | islpci_reset(priv, 1); |
488 | priv->reset_task_pending = 0; | 488 | priv->reset_task_pending = 0; |
diff --git a/drivers/net/wireless/prism54/islpci_eth.h b/drivers/net/wireless/prism54/islpci_eth.h index 26789454067c..5bf820defbd0 100644 --- a/drivers/net/wireless/prism54/islpci_eth.h +++ b/drivers/net/wireless/prism54/islpci_eth.h | |||
@@ -67,6 +67,6 @@ void islpci_eth_cleanup_transmit(islpci_private *, isl38xx_control_block *); | |||
67 | int islpci_eth_transmit(struct sk_buff *, struct net_device *); | 67 | int islpci_eth_transmit(struct sk_buff *, struct net_device *); |
68 | int islpci_eth_receive(islpci_private *); | 68 | int islpci_eth_receive(islpci_private *); |
69 | void islpci_eth_tx_timeout(struct net_device *); | 69 | void islpci_eth_tx_timeout(struct net_device *); |
70 | void islpci_do_reset_and_wake(void *data); | 70 | void islpci_do_reset_and_wake(struct work_struct *); |
71 | 71 | ||
72 | #endif /* _ISL_GEN_H */ | 72 | #endif /* _ISL_GEN_H */ |
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c index 036a875054c9..2246f7930b4e 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.c +++ b/drivers/net/wireless/prism54/islpci_mgt.c | |||
@@ -386,7 +386,7 @@ islpci_mgt_receive(struct net_device *ndev) | |||
386 | 386 | ||
387 | /* Create work to handle trap out of interrupt | 387 | /* Create work to handle trap out of interrupt |
388 | * context. */ | 388 | * context. */ |
389 | INIT_WORK(&frame->ws, prism54_process_trap, frame); | 389 | INIT_WORK(&frame->ws, prism54_process_trap); |
390 | schedule_work(&frame->ws); | 390 | schedule_work(&frame->ws); |
391 | 391 | ||
392 | } else { | 392 | } else { |
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 7fbfc9e41d07..88e10c9bc4ac 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -408,11 +408,8 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | |||
408 | #define MAX_TUPLE_SIZE 128 | 408 | #define MAX_TUPLE_SIZE 128 |
409 | static int ray_config(struct pcmcia_device *link) | 409 | static int ray_config(struct pcmcia_device *link) |
410 | { | 410 | { |
411 | tuple_t tuple; | ||
412 | cisparse_t parse; | ||
413 | int last_fn = 0, last_ret = 0; | 411 | int last_fn = 0, last_ret = 0; |
414 | int i; | 412 | int i; |
415 | u_char buf[MAX_TUPLE_SIZE]; | ||
416 | win_req_t req; | 413 | win_req_t req; |
417 | memreq_t mem; | 414 | memreq_t mem; |
418 | struct net_device *dev = (struct net_device *)link->priv; | 415 | struct net_device *dev = (struct net_device *)link->priv; |
@@ -420,29 +417,12 @@ static int ray_config(struct pcmcia_device *link) | |||
420 | 417 | ||
421 | DEBUG(1, "ray_config(0x%p)\n", link); | 418 | DEBUG(1, "ray_config(0x%p)\n", link); |
422 | 419 | ||
423 | /* This reads the card's CONFIG tuple to find its configuration regs */ | ||
424 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
425 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
426 | tuple.TupleData = buf; | ||
427 | tuple.TupleDataMax = MAX_TUPLE_SIZE; | ||
428 | tuple.TupleOffset = 0; | ||
429 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
430 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
431 | link->conf.ConfigBase = parse.config.base; | ||
432 | link->conf.Present = parse.config.rmask[0]; | ||
433 | |||
434 | /* Determine card type and firmware version */ | 420 | /* Determine card type and firmware version */ |
435 | buf[0] = buf[MAX_TUPLE_SIZE - 1] = 0; | 421 | printk(KERN_INFO "ray_cs Detected: %s%s%s%s\n", |
436 | tuple.DesiredTuple = CISTPL_VERS_1; | 422 | link->prod_id[0] ? link->prod_id[0] : " ", |
437 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 423 | link->prod_id[1] ? link->prod_id[1] : " ", |
438 | tuple.TupleData = buf; | 424 | link->prod_id[2] ? link->prod_id[2] : " ", |
439 | tuple.TupleDataMax = MAX_TUPLE_SIZE; | 425 | link->prod_id[3] ? link->prod_id[3] : " "); |
440 | tuple.TupleOffset = 2; | ||
441 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
442 | |||
443 | for (i=0; i<tuple.TupleDataLen - 4; i++) | ||
444 | if (buf[i] == 0) buf[i] = ' '; | ||
445 | printk(KERN_INFO "ray_cs Detected: %s\n",buf); | ||
446 | 426 | ||
447 | /* Now allocate an interrupt line. Note that this does not | 427 | /* Now allocate an interrupt line. Note that this does not |
448 | actually assign a handler to the interrupt. | 428 | actually assign a handler to the interrupt. |
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c index bcc7038130f6..cf2d1486b01d 100644 --- a/drivers/net/wireless/spectrum_cs.c +++ b/drivers/net/wireless/spectrum_cs.c | |||
@@ -647,21 +647,6 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
647 | cisparse_t parse; | 647 | cisparse_t parse; |
648 | void __iomem *mem; | 648 | void __iomem *mem; |
649 | 649 | ||
650 | /* | ||
651 | * This reads the card's CONFIG tuple to find its | ||
652 | * configuration registers. | ||
653 | */ | ||
654 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
655 | tuple.Attributes = 0; | ||
656 | tuple.TupleData = buf; | ||
657 | tuple.TupleDataMax = sizeof(buf); | ||
658 | tuple.TupleOffset = 0; | ||
659 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
660 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
661 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
662 | link->conf.ConfigBase = parse.config.base; | ||
663 | link->conf.Present = parse.config.rmask[0]; | ||
664 | |||
665 | /* Look up the current Vcc */ | 650 | /* Look up the current Vcc */ |
666 | CS_CHECK(GetConfigurationInfo, | 651 | CS_CHECK(GetConfigurationInfo, |
667 | pcmcia_get_configuration_info(link, &conf)); | 652 | pcmcia_get_configuration_info(link, &conf)); |
@@ -681,6 +666,10 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
681 | * implementation-defined details. | 666 | * implementation-defined details. |
682 | */ | 667 | */ |
683 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 668 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
669 | tuple.Attributes = 0; | ||
670 | tuple.TupleData = buf; | ||
671 | tuple.TupleDataMax = sizeof(buf); | ||
672 | tuple.TupleOffset = 0; | ||
684 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 673 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
685 | while (1) { | 674 | while (1) { |
686 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); | 675 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); |
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index aafb301041b1..233d906c08f0 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c | |||
@@ -3939,11 +3939,8 @@ wv_hw_reset(struct net_device * dev) | |||
3939 | static inline int | 3939 | static inline int |
3940 | wv_pcmcia_config(struct pcmcia_device * link) | 3940 | wv_pcmcia_config(struct pcmcia_device * link) |
3941 | { | 3941 | { |
3942 | tuple_t tuple; | ||
3943 | cisparse_t parse; | ||
3944 | struct net_device * dev = (struct net_device *) link->priv; | 3942 | struct net_device * dev = (struct net_device *) link->priv; |
3945 | int i; | 3943 | int i; |
3946 | u_char buf[64]; | ||
3947 | win_req_t req; | 3944 | win_req_t req; |
3948 | memreq_t mem; | 3945 | memreq_t mem; |
3949 | net_local * lp = netdev_priv(dev); | 3946 | net_local * lp = netdev_priv(dev); |
@@ -3953,36 +3950,6 @@ wv_pcmcia_config(struct pcmcia_device * link) | |||
3953 | printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link); | 3950 | printk(KERN_DEBUG "->wv_pcmcia_config(0x%p)\n", link); |
3954 | #endif | 3951 | #endif |
3955 | 3952 | ||
3956 | /* | ||
3957 | * This reads the card's CONFIG tuple to find its configuration | ||
3958 | * registers. | ||
3959 | */ | ||
3960 | do | ||
3961 | { | ||
3962 | tuple.Attributes = 0; | ||
3963 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
3964 | i = pcmcia_get_first_tuple(link, &tuple); | ||
3965 | if(i != CS_SUCCESS) | ||
3966 | break; | ||
3967 | tuple.TupleData = (cisdata_t *)buf; | ||
3968 | tuple.TupleDataMax = 64; | ||
3969 | tuple.TupleOffset = 0; | ||
3970 | i = pcmcia_get_tuple_data(link, &tuple); | ||
3971 | if(i != CS_SUCCESS) | ||
3972 | break; | ||
3973 | i = pcmcia_parse_tuple(link, &tuple, &parse); | ||
3974 | if(i != CS_SUCCESS) | ||
3975 | break; | ||
3976 | link->conf.ConfigBase = parse.config.base; | ||
3977 | link->conf.Present = parse.config.rmask[0]; | ||
3978 | } | ||
3979 | while(0); | ||
3980 | if(i != CS_SUCCESS) | ||
3981 | { | ||
3982 | cs_error(link, ParseTuple, i); | ||
3983 | return FALSE; | ||
3984 | } | ||
3985 | |||
3986 | do | 3953 | do |
3987 | { | 3954 | { |
3988 | i = pcmcia_request_io(link, &link->io); | 3955 | i = pcmcia_request_io(link, &link->io); |
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 5b98a7876982..583e0d655a98 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
@@ -1966,25 +1966,10 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | |||
1966 | */ | 1966 | */ |
1967 | static int wl3501_config(struct pcmcia_device *link) | 1967 | static int wl3501_config(struct pcmcia_device *link) |
1968 | { | 1968 | { |
1969 | tuple_t tuple; | ||
1970 | cisparse_t parse; | ||
1971 | struct net_device *dev = link->priv; | 1969 | struct net_device *dev = link->priv; |
1972 | int i = 0, j, last_fn, last_ret; | 1970 | int i = 0, j, last_fn, last_ret; |
1973 | unsigned char bf[64]; | ||
1974 | struct wl3501_card *this; | 1971 | struct wl3501_card *this; |
1975 | 1972 | ||
1976 | /* This reads the card's CONFIG tuple to find its config registers. */ | ||
1977 | tuple.Attributes = 0; | ||
1978 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
1979 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
1980 | tuple.TupleData = bf; | ||
1981 | tuple.TupleDataMax = sizeof(bf); | ||
1982 | tuple.TupleOffset = 0; | ||
1983 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
1984 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
1985 | link->conf.ConfigBase = parse.config.base; | ||
1986 | link->conf.Present = parse.config.rmask[0]; | ||
1987 | |||
1988 | /* Try allocating IO ports. This tries a few fixed addresses. If you | 1973 | /* Try allocating IO ports. This tries a few fixed addresses. If you |
1989 | * want, you can also read the card's config table to pick addresses -- | 1974 | * want, you can also read the card's config table to pick addresses -- |
1990 | * see the serial driver for an example. */ | 1975 | * see the serial driver for an example. */ |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 2696f95b9278..f1573a9c2336 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -32,8 +32,8 @@ | |||
32 | 32 | ||
33 | static void ieee_init(struct ieee80211_device *ieee); | 33 | static void ieee_init(struct ieee80211_device *ieee); |
34 | static void softmac_init(struct ieee80211softmac_device *sm); | 34 | static void softmac_init(struct ieee80211softmac_device *sm); |
35 | static void set_rts_cts_work(void *d); | 35 | static void set_rts_cts_work(struct work_struct *work); |
36 | static void set_basic_rates_work(void *d); | 36 | static void set_basic_rates_work(struct work_struct *work); |
37 | 37 | ||
38 | static void housekeeping_init(struct zd_mac *mac); | 38 | static void housekeeping_init(struct zd_mac *mac); |
39 | static void housekeeping_enable(struct zd_mac *mac); | 39 | static void housekeeping_enable(struct zd_mac *mac); |
@@ -48,8 +48,8 @@ int zd_mac_init(struct zd_mac *mac, | |||
48 | memset(mac, 0, sizeof(*mac)); | 48 | memset(mac, 0, sizeof(*mac)); |
49 | spin_lock_init(&mac->lock); | 49 | spin_lock_init(&mac->lock); |
50 | mac->netdev = netdev; | 50 | mac->netdev = netdev; |
51 | INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work, mac); | 51 | INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work); |
52 | INIT_WORK(&mac->set_basic_rates_work, set_basic_rates_work, mac); | 52 | INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work); |
53 | 53 | ||
54 | ieee_init(ieee); | 54 | ieee_init(ieee); |
55 | softmac_init(ieee80211_priv(netdev)); | 55 | softmac_init(ieee80211_priv(netdev)); |
@@ -366,9 +366,10 @@ static void try_enable_tx(struct zd_mac *mac) | |||
366 | spin_unlock_irqrestore(&mac->lock, flags); | 366 | spin_unlock_irqrestore(&mac->lock, flags); |
367 | } | 367 | } |
368 | 368 | ||
369 | static void set_rts_cts_work(void *d) | 369 | static void set_rts_cts_work(struct work_struct *work) |
370 | { | 370 | { |
371 | struct zd_mac *mac = d; | 371 | struct zd_mac *mac = |
372 | container_of(work, struct zd_mac, set_rts_cts_work.work); | ||
372 | unsigned long flags; | 373 | unsigned long flags; |
373 | u8 rts_rate; | 374 | u8 rts_rate; |
374 | unsigned int short_preamble; | 375 | unsigned int short_preamble; |
@@ -387,9 +388,10 @@ static void set_rts_cts_work(void *d) | |||
387 | try_enable_tx(mac); | 388 | try_enable_tx(mac); |
388 | } | 389 | } |
389 | 390 | ||
390 | static void set_basic_rates_work(void *d) | 391 | static void set_basic_rates_work(struct work_struct *work) |
391 | { | 392 | { |
392 | struct zd_mac *mac = d; | 393 | struct zd_mac *mac = |
394 | container_of(work, struct zd_mac, set_basic_rates_work.work); | ||
393 | unsigned long flags; | 395 | unsigned long flags; |
394 | u16 basic_rates; | 396 | u16 basic_rates; |
395 | 397 | ||
@@ -467,12 +469,13 @@ static void bssinfo_change(struct net_device *netdev, u32 changes) | |||
467 | if (need_set_rts_cts && !mac->updating_rts_rate) { | 469 | if (need_set_rts_cts && !mac->updating_rts_rate) { |
468 | mac->updating_rts_rate = 1; | 470 | mac->updating_rts_rate = 1; |
469 | netif_stop_queue(mac->netdev); | 471 | netif_stop_queue(mac->netdev); |
470 | queue_work(zd_workqueue, &mac->set_rts_cts_work); | 472 | queue_delayed_work(zd_workqueue, &mac->set_rts_cts_work, 0); |
471 | } | 473 | } |
472 | if (need_set_rates && !mac->updating_basic_rates) { | 474 | if (need_set_rates && !mac->updating_basic_rates) { |
473 | mac->updating_basic_rates = 1; | 475 | mac->updating_basic_rates = 1; |
474 | netif_stop_queue(mac->netdev); | 476 | netif_stop_queue(mac->netdev); |
475 | queue_work(zd_workqueue, &mac->set_basic_rates_work); | 477 | queue_delayed_work(zd_workqueue, &mac->set_basic_rates_work, |
478 | 0); | ||
476 | } | 479 | } |
477 | spin_unlock_irqrestore(&mac->lock, flags); | 480 | spin_unlock_irqrestore(&mac->lock, flags); |
478 | } | 481 | } |
@@ -1182,9 +1185,10 @@ struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev) | |||
1182 | 1185 | ||
1183 | #define LINK_LED_WORK_DELAY HZ | 1186 | #define LINK_LED_WORK_DELAY HZ |
1184 | 1187 | ||
1185 | static void link_led_handler(void *p) | 1188 | static void link_led_handler(struct work_struct *work) |
1186 | { | 1189 | { |
1187 | struct zd_mac *mac = p; | 1190 | struct zd_mac *mac = |
1191 | container_of(work, struct zd_mac, housekeeping.link_led_work.work); | ||
1188 | struct zd_chip *chip = &mac->chip; | 1192 | struct zd_chip *chip = &mac->chip; |
1189 | struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev); | 1193 | struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev); |
1190 | int is_associated; | 1194 | int is_associated; |
@@ -1205,7 +1209,7 @@ static void link_led_handler(void *p) | |||
1205 | 1209 | ||
1206 | static void housekeeping_init(struct zd_mac *mac) | 1210 | static void housekeeping_init(struct zd_mac *mac) |
1207 | { | 1211 | { |
1208 | INIT_WORK(&mac->housekeeping.link_led_work, link_led_handler, mac); | 1212 | INIT_DELAYED_WORK(&mac->housekeeping.link_led_work, link_led_handler); |
1209 | } | 1213 | } |
1210 | 1214 | ||
1211 | static void housekeeping_enable(struct zd_mac *mac) | 1215 | static void housekeeping_enable(struct zd_mac *mac) |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 5dcfb251f02e..d4e8b870409d 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h | |||
@@ -119,7 +119,7 @@ struct rx_status { | |||
119 | #define ZD_RX_ERROR 0x80 | 119 | #define ZD_RX_ERROR 0x80 |
120 | 120 | ||
121 | struct housekeeping { | 121 | struct housekeeping { |
122 | struct work_struct link_led_work; | 122 | struct delayed_work link_led_work; |
123 | }; | 123 | }; |
124 | 124 | ||
125 | #define ZD_MAC_STATS_BUFFER_SIZE 16 | 125 | #define ZD_MAC_STATS_BUFFER_SIZE 16 |
@@ -133,8 +133,8 @@ struct zd_mac { | |||
133 | struct iw_statistics iw_stats; | 133 | struct iw_statistics iw_stats; |
134 | 134 | ||
135 | struct housekeeping housekeeping; | 135 | struct housekeeping housekeeping; |
136 | struct work_struct set_rts_cts_work; | 136 | struct delayed_work set_rts_cts_work; |
137 | struct work_struct set_basic_rates_work; | 137 | struct delayed_work set_basic_rates_work; |
138 | 138 | ||
139 | unsigned int stats_count; | 139 | unsigned int stats_count; |
140 | u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; | 140 | u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; |
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index fc4bc9b94c74..a83c3db7d18f 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | struct oprofile_cpu_buffer cpu_buffer[NR_CPUS] __cacheline_aligned; | 30 | struct oprofile_cpu_buffer cpu_buffer[NR_CPUS] __cacheline_aligned; |
31 | 31 | ||
32 | static void wq_sync_buffer(void *); | 32 | static void wq_sync_buffer(struct work_struct *work); |
33 | 33 | ||
34 | #define DEFAULT_TIMER_EXPIRE (HZ / 10) | 34 | #define DEFAULT_TIMER_EXPIRE (HZ / 10) |
35 | static int work_enabled; | 35 | static int work_enabled; |
@@ -65,7 +65,7 @@ int alloc_cpu_buffers(void) | |||
65 | b->sample_received = 0; | 65 | b->sample_received = 0; |
66 | b->sample_lost_overflow = 0; | 66 | b->sample_lost_overflow = 0; |
67 | b->cpu = i; | 67 | b->cpu = i; |
68 | INIT_WORK(&b->work, wq_sync_buffer, b); | 68 | INIT_DELAYED_WORK(&b->work, wq_sync_buffer); |
69 | } | 69 | } |
70 | return 0; | 70 | return 0; |
71 | 71 | ||
@@ -282,9 +282,10 @@ void oprofile_add_trace(unsigned long pc) | |||
282 | * By using schedule_delayed_work_on and then schedule_delayed_work | 282 | * By using schedule_delayed_work_on and then schedule_delayed_work |
283 | * we guarantee this will stay on the correct cpu | 283 | * we guarantee this will stay on the correct cpu |
284 | */ | 284 | */ |
285 | static void wq_sync_buffer(void * data) | 285 | static void wq_sync_buffer(struct work_struct *work) |
286 | { | 286 | { |
287 | struct oprofile_cpu_buffer * b = data; | 287 | struct oprofile_cpu_buffer * b = |
288 | container_of(work, struct oprofile_cpu_buffer, work.work); | ||
288 | if (b->cpu != smp_processor_id()) { | 289 | if (b->cpu != smp_processor_id()) { |
289 | printk("WQ on CPU%d, prefer CPU%d\n", | 290 | printk("WQ on CPU%d, prefer CPU%d\n", |
290 | smp_processor_id(), b->cpu); | 291 | smp_processor_id(), b->cpu); |
diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h index 09abb80e0570..49900d9e3235 100644 --- a/drivers/oprofile/cpu_buffer.h +++ b/drivers/oprofile/cpu_buffer.h | |||
@@ -43,7 +43,7 @@ struct oprofile_cpu_buffer { | |||
43 | unsigned long sample_lost_overflow; | 43 | unsigned long sample_lost_overflow; |
44 | unsigned long backtrace_aborted; | 44 | unsigned long backtrace_aborted; |
45 | int cpu; | 45 | int cpu; |
46 | struct work_struct work; | 46 | struct delayed_work work; |
47 | } ____cacheline_aligned; | 47 | } ____cacheline_aligned; |
48 | 48 | ||
49 | extern struct oprofile_cpu_buffer cpu_buffer[]; | 49 | extern struct oprofile_cpu_buffer cpu_buffer[]; |
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index b953d5907c05..e60b4bf6bae8 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c | |||
@@ -166,14 +166,6 @@ static int parport_config(struct pcmcia_device *link) | |||
166 | 166 | ||
167 | tuple.TupleData = (cisdata_t *)buf; | 167 | tuple.TupleData = (cisdata_t *)buf; |
168 | tuple.TupleOffset = 0; tuple.TupleDataMax = 255; | 168 | tuple.TupleOffset = 0; tuple.TupleDataMax = 255; |
169 | tuple.Attributes = 0; | ||
170 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
171 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
172 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
173 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
174 | link->conf.ConfigBase = parse.config.base; | ||
175 | link->conf.Present = parse.config.rmask[0]; | ||
176 | |||
177 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 169 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
178 | tuple.Attributes = 0; | 170 | tuple.Attributes = 0; |
179 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 171 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
@@ -263,6 +255,7 @@ void parport_cs_release(struct pcmcia_device *link) | |||
263 | 255 | ||
264 | static struct pcmcia_device_id parport_ids[] = { | 256 | static struct pcmcia_device_id parport_ids[] = { |
265 | PCMCIA_DEVICE_FUNC_ID(3), | 257 | PCMCIA_DEVICE_FUNC_ID(3), |
258 | PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc), | ||
266 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0003), | 259 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0003), |
267 | PCMCIA_DEVICE_NULL | 260 | PCMCIA_DEVICE_NULL |
268 | }; | 261 | }; |
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index ea2087c34149..50757695844f 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h | |||
@@ -70,7 +70,7 @@ struct slot { | |||
70 | struct hotplug_slot *hotplug_slot; | 70 | struct hotplug_slot *hotplug_slot; |
71 | struct list_head slot_list; | 71 | struct list_head slot_list; |
72 | char name[SLOT_NAME_SIZE]; | 72 | char name[SLOT_NAME_SIZE]; |
73 | struct work_struct work; /* work for button event */ | 73 | struct delayed_work work; /* work for button event */ |
74 | struct mutex lock; | 74 | struct mutex lock; |
75 | }; | 75 | }; |
76 | 76 | ||
@@ -187,7 +187,7 @@ extern int shpchp_configure_device(struct slot *p_slot); | |||
187 | extern int shpchp_unconfigure_device(struct slot *p_slot); | 187 | extern int shpchp_unconfigure_device(struct slot *p_slot); |
188 | extern void shpchp_remove_ctrl_files(struct controller *ctrl); | 188 | extern void shpchp_remove_ctrl_files(struct controller *ctrl); |
189 | extern void cleanup_slots(struct controller *ctrl); | 189 | extern void cleanup_slots(struct controller *ctrl); |
190 | extern void queue_pushbutton_work(void *data); | 190 | extern void queue_pushbutton_work(struct work_struct *work); |
191 | 191 | ||
192 | 192 | ||
193 | #ifdef CONFIG_ACPI | 193 | #ifdef CONFIG_ACPI |
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 235c18a22393..4eac85b3d90e 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -159,7 +159,7 @@ static int init_slots(struct controller *ctrl) | |||
159 | goto error_info; | 159 | goto error_info; |
160 | 160 | ||
161 | slot->number = sun; | 161 | slot->number = sun; |
162 | INIT_WORK(&slot->work, queue_pushbutton_work, slot); | 162 | INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); |
163 | 163 | ||
164 | /* register this slot with the hotplug pci core */ | 164 | /* register this slot with the hotplug pci core */ |
165 | hotplug_slot->private = slot; | 165 | hotplug_slot->private = slot; |
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index c39901dbff20..158ac7836096 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include "../pci.h" | 36 | #include "../pci.h" |
37 | #include "shpchp.h" | 37 | #include "shpchp.h" |
38 | 38 | ||
39 | static void interrupt_event_handler(void *data); | 39 | static void interrupt_event_handler(struct work_struct *work); |
40 | static int shpchp_enable_slot(struct slot *p_slot); | 40 | static int shpchp_enable_slot(struct slot *p_slot); |
41 | static int shpchp_disable_slot(struct slot *p_slot); | 41 | static int shpchp_disable_slot(struct slot *p_slot); |
42 | 42 | ||
@@ -50,7 +50,7 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) | |||
50 | 50 | ||
51 | info->event_type = event_type; | 51 | info->event_type = event_type; |
52 | info->p_slot = p_slot; | 52 | info->p_slot = p_slot; |
53 | INIT_WORK(&info->work, interrupt_event_handler, info); | 53 | INIT_WORK(&info->work, interrupt_event_handler); |
54 | 54 | ||
55 | schedule_work(&info->work); | 55 | schedule_work(&info->work); |
56 | 56 | ||
@@ -408,9 +408,10 @@ struct pushbutton_work_info { | |||
408 | * Handles all pending events and exits. | 408 | * Handles all pending events and exits. |
409 | * | 409 | * |
410 | */ | 410 | */ |
411 | static void shpchp_pushbutton_thread(void *data) | 411 | static void shpchp_pushbutton_thread(struct work_struct *work) |
412 | { | 412 | { |
413 | struct pushbutton_work_info *info = data; | 413 | struct pushbutton_work_info *info = |
414 | container_of(work, struct pushbutton_work_info, work); | ||
414 | struct slot *p_slot = info->p_slot; | 415 | struct slot *p_slot = info->p_slot; |
415 | 416 | ||
416 | mutex_lock(&p_slot->lock); | 417 | mutex_lock(&p_slot->lock); |
@@ -436,9 +437,9 @@ static void shpchp_pushbutton_thread(void *data) | |||
436 | kfree(info); | 437 | kfree(info); |
437 | } | 438 | } |
438 | 439 | ||
439 | void queue_pushbutton_work(void *data) | 440 | void queue_pushbutton_work(struct work_struct *work) |
440 | { | 441 | { |
441 | struct slot *p_slot = data; | 442 | struct slot *p_slot = container_of(work, struct slot, work.work); |
442 | struct pushbutton_work_info *info; | 443 | struct pushbutton_work_info *info; |
443 | 444 | ||
444 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 445 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
@@ -447,7 +448,7 @@ void queue_pushbutton_work(void *data) | |||
447 | return; | 448 | return; |
448 | } | 449 | } |
449 | info->p_slot = p_slot; | 450 | info->p_slot = p_slot; |
450 | INIT_WORK(&info->work, shpchp_pushbutton_thread, info); | 451 | INIT_WORK(&info->work, shpchp_pushbutton_thread); |
451 | 452 | ||
452 | mutex_lock(&p_slot->lock); | 453 | mutex_lock(&p_slot->lock); |
453 | switch (p_slot->state) { | 454 | switch (p_slot->state) { |
@@ -541,9 +542,9 @@ static void handle_button_press_event(struct slot *p_slot) | |||
541 | } | 542 | } |
542 | } | 543 | } |
543 | 544 | ||
544 | static void interrupt_event_handler(void *data) | 545 | static void interrupt_event_handler(struct work_struct *work) |
545 | { | 546 | { |
546 | struct event_info *info = data; | 547 | struct event_info *info = container_of(work, struct event_info, work); |
547 | struct slot *p_slot = info->p_slot; | 548 | struct slot *p_slot = info->p_slot; |
548 | 549 | ||
549 | mutex_lock(&p_slot->lock); | 550 | mutex_lock(&p_slot->lock); |
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index 04c43ef529ac..55866b6b26fa 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -160,7 +160,7 @@ static struct aer_rpc* aer_alloc_rpc(struct pcie_device *dev) | |||
160 | rpc->e_lock = SPIN_LOCK_UNLOCKED; | 160 | rpc->e_lock = SPIN_LOCK_UNLOCKED; |
161 | 161 | ||
162 | rpc->rpd = dev; | 162 | rpc->rpd = dev; |
163 | INIT_WORK(&rpc->dpc_handler, aer_isr, (void *)dev); | 163 | INIT_WORK(&rpc->dpc_handler, aer_isr); |
164 | rpc->prod_idx = rpc->cons_idx = 0; | 164 | rpc->prod_idx = rpc->cons_idx = 0; |
165 | mutex_init(&rpc->rpc_mutex); | 165 | mutex_init(&rpc->rpc_mutex); |
166 | init_waitqueue_head(&rpc->wait_release); | 166 | init_waitqueue_head(&rpc->wait_release); |
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index daf0cad88fc8..3c0a58f64dd8 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h | |||
@@ -118,7 +118,7 @@ extern struct bus_type pcie_port_bus_type; | |||
118 | extern void aer_enable_rootport(struct aer_rpc *rpc); | 118 | extern void aer_enable_rootport(struct aer_rpc *rpc); |
119 | extern void aer_delete_rootport(struct aer_rpc *rpc); | 119 | extern void aer_delete_rootport(struct aer_rpc *rpc); |
120 | extern int aer_init(struct pcie_device *dev); | 120 | extern int aer_init(struct pcie_device *dev); |
121 | extern void aer_isr(void *context); | 121 | extern void aer_isr(struct work_struct *work); |
122 | extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); | 122 | extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); |
123 | extern int aer_osc_setup(struct pci_dev *dev); | 123 | extern int aer_osc_setup(struct pci_dev *dev); |
124 | 124 | ||
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 1c7e660d6535..08e13033ced8 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -690,14 +690,14 @@ static void aer_isr_one_error(struct pcie_device *p_device, | |||
690 | 690 | ||
691 | /** | 691 | /** |
692 | * aer_isr - consume errors detected by root port | 692 | * aer_isr - consume errors detected by root port |
693 | * @context: pointer to a private data of pcie device | 693 | * @work: definition of this work item |
694 | * | 694 | * |
695 | * Invoked, as DPC, when root port records new detected error | 695 | * Invoked, as DPC, when root port records new detected error |
696 | **/ | 696 | **/ |
697 | void aer_isr(void *context) | 697 | void aer_isr(struct work_struct *work) |
698 | { | 698 | { |
699 | struct pcie_device *p_device = (struct pcie_device *) context; | 699 | struct aer_rpc *rpc = container_of(work, struct aer_rpc, dpc_handler); |
700 | struct aer_rpc *rpc = get_service_data(p_device); | 700 | struct pcie_device *p_device = rpc->rpd; |
701 | struct aer_err_source *e_src; | 701 | struct aer_err_source *e_src; |
702 | 702 | ||
703 | mutex_lock(&rpc->rpc_mutex); | 703 | mutex_lock(&rpc->rpc_mutex); |
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c index 3bcb7dc32995..b6746301d9a9 100644 --- a/drivers/pcmcia/at91_cf.c +++ b/drivers/pcmcia/at91_cf.c | |||
@@ -32,10 +32,11 @@ | |||
32 | * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; | 32 | * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW; |
33 | * some other bit in {A24,A22..A11} is nREG to flag memory access | 33 | * some other bit in {A24,A22..A11} is nREG to flag memory access |
34 | * (vs attributes). So more than 2KB/region would just be waste. | 34 | * (vs attributes). So more than 2KB/region would just be waste. |
35 | * Note: These are offsets from the physical base address. | ||
35 | */ | 36 | */ |
36 | #define CF_ATTR_PHYS (AT91_CF_BASE) | 37 | #define CF_ATTR_PHYS (0) |
37 | #define CF_IO_PHYS (AT91_CF_BASE + (1 << 23)) | 38 | #define CF_IO_PHYS (1 << 23) |
38 | #define CF_MEM_PHYS (AT91_CF_BASE + 0x017ff800) | 39 | #define CF_MEM_PHYS (0x017ff800) |
39 | 40 | ||
40 | /*--------------------------------------------------------------------------*/ | 41 | /*--------------------------------------------------------------------------*/ |
41 | 42 | ||
@@ -48,6 +49,8 @@ struct at91_cf_socket { | |||
48 | 49 | ||
49 | struct platform_device *pdev; | 50 | struct platform_device *pdev; |
50 | struct at91_cf_data *board; | 51 | struct at91_cf_data *board; |
52 | |||
53 | unsigned long phys_baseaddr; | ||
51 | }; | 54 | }; |
52 | 55 | ||
53 | #define SZ_2K (2 * SZ_1K) | 56 | #define SZ_2K (2 * SZ_1K) |
@@ -154,9 +157,8 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) | |||
154 | 157 | ||
155 | /* | 158 | /* |
156 | * Use 16 bit accesses unless/until we need 8-bit i/o space. | 159 | * Use 16 bit accesses unless/until we need 8-bit i/o space. |
157 | * Always set CSR4 ... PCMCIA won't always unmap things. | ||
158 | */ | 160 | */ |
159 | csr = at91_sys_read(AT91_SMC_CSR(4)) & ~AT91_SMC_DBW; | 161 | csr = at91_sys_read(AT91_SMC_CSR(cf->board->chipselect)) & ~AT91_SMC_DBW; |
160 | 162 | ||
161 | /* | 163 | /* |
162 | * NOTE: this CF controller ignores IOIS16, so we can't really do | 164 | * NOTE: this CF controller ignores IOIS16, so we can't really do |
@@ -168,14 +170,14 @@ static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io) | |||
168 | * some cards only like that way to get at the odd byte, despite | 170 | * some cards only like that way to get at the odd byte, despite |
169 | * CF 3.0 spec table 35 also giving the D8-D15 option. | 171 | * CF 3.0 spec table 35 also giving the D8-D15 option. |
170 | */ | 172 | */ |
171 | if (!(io->flags & (MAP_16BIT|MAP_AUTOSZ))) { | 173 | if (!(io->flags & (MAP_16BIT | MAP_AUTOSZ))) { |
172 | csr |= AT91_SMC_DBW_8; | 174 | csr |= AT91_SMC_DBW_8; |
173 | pr_debug("%s: 8bit i/o bus\n", driver_name); | 175 | pr_debug("%s: 8bit i/o bus\n", driver_name); |
174 | } else { | 176 | } else { |
175 | csr |= AT91_SMC_DBW_16; | 177 | csr |= AT91_SMC_DBW_16; |
176 | pr_debug("%s: 16bit i/o bus\n", driver_name); | 178 | pr_debug("%s: 16bit i/o bus\n", driver_name); |
177 | } | 179 | } |
178 | at91_sys_write(AT91_SMC_CSR(4), csr); | 180 | at91_sys_write(AT91_SMC_CSR(cf->board->chipselect), csr); |
179 | 181 | ||
180 | io->start = cf->socket.io_offset; | 182 | io->start = cf->socket.io_offset; |
181 | io->stop = io->start + SZ_2K - 1; | 183 | io->stop = io->start + SZ_2K - 1; |
@@ -194,11 +196,11 @@ at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map) | |||
194 | 196 | ||
195 | cf = container_of(s, struct at91_cf_socket, socket); | 197 | cf = container_of(s, struct at91_cf_socket, socket); |
196 | 198 | ||
197 | map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT; | 199 | map->flags &= (MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT); |
198 | if (map->flags & MAP_ATTRIB) | 200 | if (map->flags & MAP_ATTRIB) |
199 | map->static_start = CF_ATTR_PHYS; | 201 | map->static_start = cf->phys_baseaddr + CF_ATTR_PHYS; |
200 | else | 202 | else |
201 | map->static_start = CF_MEM_PHYS; | 203 | map->static_start = cf->phys_baseaddr + CF_MEM_PHYS; |
202 | 204 | ||
203 | return 0; | 205 | return 0; |
204 | } | 206 | } |
@@ -219,7 +221,6 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
219 | struct at91_cf_socket *cf; | 221 | struct at91_cf_socket *cf; |
220 | struct at91_cf_data *board = pdev->dev.platform_data; | 222 | struct at91_cf_data *board = pdev->dev.platform_data; |
221 | struct resource *io; | 223 | struct resource *io; |
222 | unsigned int csa; | ||
223 | int status; | 224 | int status; |
224 | 225 | ||
225 | if (!board || !board->det_pin || !board->rst_pin) | 226 | if (!board || !board->det_pin || !board->rst_pin) |
@@ -235,33 +236,11 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
235 | 236 | ||
236 | cf->board = board; | 237 | cf->board = board; |
237 | cf->pdev = pdev; | 238 | cf->pdev = pdev; |
239 | cf->phys_baseaddr = io->start; | ||
238 | platform_set_drvdata(pdev, cf); | 240 | platform_set_drvdata(pdev, cf); |
239 | 241 | ||
240 | /* CF takes over CS4, CS5, CS6 */ | ||
241 | csa = at91_sys_read(AT91_EBI_CSA); | ||
242 | at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH); | ||
243 | |||
244 | /* nWAIT is _not_ a default setting */ | ||
245 | (void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */ | ||
246 | |||
247 | /* | ||
248 | * Static memory controller timing adjustments. | ||
249 | * REVISIT: these timings are in terms of MCK cycles, so | ||
250 | * when MCK changes (cpufreq etc) so must these values... | ||
251 | */ | ||
252 | at91_sys_write(AT91_SMC_CSR(4), | ||
253 | AT91_SMC_ACSS_STD | ||
254 | | AT91_SMC_DBW_16 | ||
255 | | AT91_SMC_BAT | ||
256 | | AT91_SMC_WSEN | ||
257 | | AT91_SMC_NWS_(32) /* wait states */ | ||
258 | | AT91_SMC_RWSETUP_(6) /* setup time */ | ||
259 | | AT91_SMC_RWHOLD_(4) /* hold time */ | ||
260 | ); | ||
261 | |||
262 | /* must be a GPIO; ergo must trigger on both edges */ | 242 | /* must be a GPIO; ergo must trigger on both edges */ |
263 | status = request_irq(board->det_pin, at91_cf_irq, | 243 | status = request_irq(board->det_pin, at91_cf_irq, 0, driver_name, cf); |
264 | IRQF_SAMPLE_RANDOM, driver_name, cf); | ||
265 | if (status < 0) | 244 | if (status < 0) |
266 | goto fail0; | 245 | goto fail0; |
267 | device_init_wakeup(&pdev->dev, 1); | 246 | device_init_wakeup(&pdev->dev, 1); |
@@ -282,14 +261,18 @@ static int __init at91_cf_probe(struct platform_device *pdev) | |||
282 | cf->socket.pci_irq = NR_IRQS + 1; | 261 | cf->socket.pci_irq = NR_IRQS + 1; |
283 | 262 | ||
284 | /* pcmcia layer only remaps "real" memory not iospace */ | 263 | /* pcmcia layer only remaps "real" memory not iospace */ |
285 | cf->socket.io_offset = (unsigned long) ioremap(CF_IO_PHYS, SZ_2K); | 264 | cf->socket.io_offset = (unsigned long) ioremap(cf->phys_baseaddr + CF_IO_PHYS, SZ_2K); |
286 | if (!cf->socket.io_offset) | 265 | if (!cf->socket.io_offset) { |
266 | status = -ENXIO; | ||
287 | goto fail1; | 267 | goto fail1; |
268 | } | ||
288 | 269 | ||
289 | /* reserve CS4, CS5, and CS6 regions; but use just CS4 */ | 270 | /* reserve chip-select regions */ |
290 | if (!request_mem_region(io->start, io->end + 1 - io->start, | 271 | if (!request_mem_region(io->start, io->end + 1 - io->start, |
291 | driver_name)) | 272 | driver_name)) { |
273 | status = -ENXIO; | ||
292 | goto fail1; | 274 | goto fail1; |
275 | } | ||
293 | 276 | ||
294 | pr_info("%s: irqs det #%d, io #%d\n", driver_name, | 277 | pr_info("%s: irqs det #%d, io #%d\n", driver_name, |
295 | board->det_pin, board->irq_pin); | 278 | board->det_pin, board->irq_pin); |
@@ -319,9 +302,7 @@ fail1: | |||
319 | fail0a: | 302 | fail0a: |
320 | device_init_wakeup(&pdev->dev, 0); | 303 | device_init_wakeup(&pdev->dev, 0); |
321 | free_irq(board->det_pin, cf); | 304 | free_irq(board->det_pin, cf); |
322 | device_init_wakeup(&pdev->dev, 0); | ||
323 | fail0: | 305 | fail0: |
324 | at91_sys_write(AT91_EBI_CSA, csa); | ||
325 | kfree(cf); | 306 | kfree(cf); |
326 | return status; | 307 | return status; |
327 | } | 308 | } |
@@ -331,19 +312,15 @@ static int __exit at91_cf_remove(struct platform_device *pdev) | |||
331 | struct at91_cf_socket *cf = platform_get_drvdata(pdev); | 312 | struct at91_cf_socket *cf = platform_get_drvdata(pdev); |
332 | struct at91_cf_data *board = cf->board; | 313 | struct at91_cf_data *board = cf->board; |
333 | struct resource *io = cf->socket.io[0].res; | 314 | struct resource *io = cf->socket.io[0].res; |
334 | unsigned int csa; | ||
335 | 315 | ||
336 | pcmcia_unregister_socket(&cf->socket); | 316 | pcmcia_unregister_socket(&cf->socket); |
337 | if (board->irq_pin) | 317 | if (board->irq_pin) |
338 | free_irq(board->irq_pin, cf); | 318 | free_irq(board->irq_pin, cf); |
339 | free_irq(board->det_pin, cf); | ||
340 | device_init_wakeup(&pdev->dev, 0); | 319 | device_init_wakeup(&pdev->dev, 0); |
320 | free_irq(board->det_pin, cf); | ||
341 | iounmap((void __iomem *) cf->socket.io_offset); | 321 | iounmap((void __iomem *) cf->socket.io_offset); |
342 | release_mem_region(io->start, io->end + 1 - io->start); | 322 | release_mem_region(io->start, io->end + 1 - io->start); |
343 | 323 | ||
344 | csa = at91_sys_read(AT91_EBI_CSA); | ||
345 | at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A); | ||
346 | |||
347 | kfree(cf); | 324 | kfree(cf); |
348 | return 0; | 325 | return 0; |
349 | } | 326 | } |
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index d6164cd583fd..f573ea04db6f 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h | |||
@@ -135,7 +135,7 @@ int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_s | |||
135 | struct pcmcia_callback{ | 135 | struct pcmcia_callback{ |
136 | struct module *owner; | 136 | struct module *owner; |
137 | int (*event) (struct pcmcia_socket *s, event_t event, int priority); | 137 | int (*event) (struct pcmcia_socket *s, event_t event, int priority); |
138 | void (*requery) (struct pcmcia_socket *s); | 138 | void (*requery) (struct pcmcia_socket *s, int new_cis); |
139 | int (*suspend) (struct pcmcia_socket *s); | 139 | int (*suspend) (struct pcmcia_socket *s); |
140 | int (*resume) (struct pcmcia_socket *s); | 140 | int (*resume) (struct pcmcia_socket *s); |
141 | }; | 141 | }; |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 21d83a895b21..7355eb455a88 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -231,65 +231,6 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) | |||
231 | } | 231 | } |
232 | 232 | ||
233 | 233 | ||
234 | #ifdef CONFIG_PCMCIA_LOAD_CIS | ||
235 | |||
236 | /** | ||
237 | * pcmcia_load_firmware - load CIS from userspace if device-provided is broken | ||
238 | * @dev - the pcmcia device which needs a CIS override | ||
239 | * @filename - requested filename in /lib/firmware/ | ||
240 | * | ||
241 | * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if | ||
242 | * the one provided by the card is broken. The firmware files reside in | ||
243 | * /lib/firmware/ in userspace. | ||
244 | */ | ||
245 | static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | ||
246 | { | ||
247 | struct pcmcia_socket *s = dev->socket; | ||
248 | const struct firmware *fw; | ||
249 | char path[20]; | ||
250 | int ret=-ENOMEM; | ||
251 | cisdump_t *cis; | ||
252 | |||
253 | if (!filename) | ||
254 | return -EINVAL; | ||
255 | |||
256 | ds_dbg(1, "trying to load firmware %s\n", filename); | ||
257 | |||
258 | if (strlen(filename) > 14) | ||
259 | return -EINVAL; | ||
260 | |||
261 | snprintf(path, 20, "%s", filename); | ||
262 | |||
263 | if (request_firmware(&fw, path, &dev->dev) == 0) { | ||
264 | if (fw->size >= CISTPL_MAX_CIS_SIZE) | ||
265 | goto release; | ||
266 | |||
267 | cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); | ||
268 | if (!cis) | ||
269 | goto release; | ||
270 | |||
271 | cis->Length = fw->size + 1; | ||
272 | memcpy(cis->Data, fw->data, fw->size); | ||
273 | |||
274 | if (!pcmcia_replace_cis(s, cis)) | ||
275 | ret = 0; | ||
276 | } | ||
277 | release: | ||
278 | release_firmware(fw); | ||
279 | |||
280 | return (ret); | ||
281 | } | ||
282 | |||
283 | #else /* !CONFIG_PCMCIA_LOAD_CIS */ | ||
284 | |||
285 | static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | ||
286 | { | ||
287 | return -ENODEV; | ||
288 | } | ||
289 | |||
290 | #endif | ||
291 | |||
292 | |||
293 | /*======================================================================*/ | 234 | /*======================================================================*/ |
294 | 235 | ||
295 | 236 | ||
@@ -309,6 +250,8 @@ int pcmcia_register_driver(struct pcmcia_driver *driver) | |||
309 | driver->drv.bus = &pcmcia_bus_type; | 250 | driver->drv.bus = &pcmcia_bus_type; |
310 | driver->drv.owner = driver->owner; | 251 | driver->drv.owner = driver->owner; |
311 | 252 | ||
253 | ds_dbg(3, "registering driver %s\n", driver->drv.name); | ||
254 | |||
312 | return driver_register(&driver->drv); | 255 | return driver_register(&driver->drv); |
313 | } | 256 | } |
314 | EXPORT_SYMBOL(pcmcia_register_driver); | 257 | EXPORT_SYMBOL(pcmcia_register_driver); |
@@ -318,6 +261,7 @@ EXPORT_SYMBOL(pcmcia_register_driver); | |||
318 | */ | 261 | */ |
319 | void pcmcia_unregister_driver(struct pcmcia_driver *driver) | 262 | void pcmcia_unregister_driver(struct pcmcia_driver *driver) |
320 | { | 263 | { |
264 | ds_dbg(3, "unregistering driver %s\n", driver->drv.name); | ||
321 | driver_unregister(&driver->drv); | 265 | driver_unregister(&driver->drv); |
322 | } | 266 | } |
323 | EXPORT_SYMBOL(pcmcia_unregister_driver); | 267 | EXPORT_SYMBOL(pcmcia_unregister_driver); |
@@ -343,23 +287,27 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev) | |||
343 | static void pcmcia_release_function(struct kref *ref) | 287 | static void pcmcia_release_function(struct kref *ref) |
344 | { | 288 | { |
345 | struct config_t *c = container_of(ref, struct config_t, ref); | 289 | struct config_t *c = container_of(ref, struct config_t, ref); |
290 | ds_dbg(1, "releasing config_t\n"); | ||
346 | kfree(c); | 291 | kfree(c); |
347 | } | 292 | } |
348 | 293 | ||
349 | static void pcmcia_release_dev(struct device *dev) | 294 | static void pcmcia_release_dev(struct device *dev) |
350 | { | 295 | { |
351 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 296 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
352 | ds_dbg(1, "releasing dev %p\n", p_dev); | 297 | ds_dbg(1, "releasing device %s\n", p_dev->dev.bus_id); |
353 | pcmcia_put_socket(p_dev->socket); | 298 | pcmcia_put_socket(p_dev->socket); |
354 | kfree(p_dev->devname); | 299 | kfree(p_dev->devname); |
355 | kref_put(&p_dev->function_config->ref, pcmcia_release_function); | 300 | kref_put(&p_dev->function_config->ref, pcmcia_release_function); |
356 | kfree(p_dev); | 301 | kfree(p_dev); |
357 | } | 302 | } |
358 | 303 | ||
359 | static void pcmcia_add_pseudo_device(struct pcmcia_socket *s) | 304 | static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc) |
360 | { | 305 | { |
361 | if (!s->pcmcia_state.device_add_pending) { | 306 | if (!s->pcmcia_state.device_add_pending) { |
307 | ds_dbg(1, "scheduling to add %s secondary" | ||
308 | " device to %d\n", mfc ? "mfc" : "pfc", s->sock); | ||
362 | s->pcmcia_state.device_add_pending = 1; | 309 | s->pcmcia_state.device_add_pending = 1; |
310 | s->pcmcia_state.mfc_pfc = mfc; | ||
363 | schedule_work(&s->device_add); | 311 | schedule_work(&s->device_add); |
364 | } | 312 | } |
365 | return; | 313 | return; |
@@ -371,6 +319,7 @@ static int pcmcia_device_probe(struct device * dev) | |||
371 | struct pcmcia_driver *p_drv; | 319 | struct pcmcia_driver *p_drv; |
372 | struct pcmcia_device_id *did; | 320 | struct pcmcia_device_id *did; |
373 | struct pcmcia_socket *s; | 321 | struct pcmcia_socket *s; |
322 | cistpl_config_t cis_config; | ||
374 | int ret = 0; | 323 | int ret = 0; |
375 | 324 | ||
376 | dev = get_device(dev); | 325 | dev = get_device(dev); |
@@ -381,15 +330,33 @@ static int pcmcia_device_probe(struct device * dev) | |||
381 | p_drv = to_pcmcia_drv(dev->driver); | 330 | p_drv = to_pcmcia_drv(dev->driver); |
382 | s = p_dev->socket; | 331 | s = p_dev->socket; |
383 | 332 | ||
333 | ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id, | ||
334 | p_drv->drv.name); | ||
335 | |||
384 | if ((!p_drv->probe) || (!p_dev->function_config) || | 336 | if ((!p_drv->probe) || (!p_dev->function_config) || |
385 | (!try_module_get(p_drv->owner))) { | 337 | (!try_module_get(p_drv->owner))) { |
386 | ret = -EINVAL; | 338 | ret = -EINVAL; |
387 | goto put_dev; | 339 | goto put_dev; |
388 | } | 340 | } |
389 | 341 | ||
342 | /* set up some more device information */ | ||
343 | ret = pccard_read_tuple(p_dev->socket, p_dev->func, CISTPL_CONFIG, | ||
344 | &cis_config); | ||
345 | if (!ret) { | ||
346 | p_dev->conf.ConfigBase = cis_config.base; | ||
347 | p_dev->conf.Present = cis_config.rmask[0]; | ||
348 | } else { | ||
349 | printk(KERN_INFO "pcmcia: could not parse base and rmask0 of CIS\n"); | ||
350 | p_dev->conf.ConfigBase = 0; | ||
351 | p_dev->conf.Present = 0; | ||
352 | } | ||
353 | |||
390 | ret = p_drv->probe(p_dev); | 354 | ret = p_drv->probe(p_dev); |
391 | if (ret) | 355 | if (ret) { |
356 | ds_dbg(1, "binding %s to %s failed with %d\n", | ||
357 | p_dev->dev.bus_id, p_drv->drv.name, ret); | ||
392 | goto put_module; | 358 | goto put_module; |
359 | } | ||
393 | 360 | ||
394 | /* handle pseudo multifunction devices: | 361 | /* handle pseudo multifunction devices: |
395 | * there are at most two pseudo multifunction devices. | 362 | * there are at most two pseudo multifunction devices. |
@@ -400,7 +367,7 @@ static int pcmcia_device_probe(struct device * dev) | |||
400 | did = p_dev->dev.driver_data; | 367 | did = p_dev->dev.driver_data; |
401 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && | 368 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && |
402 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) | 369 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) |
403 | pcmcia_add_pseudo_device(p_dev->socket); | 370 | pcmcia_add_device_later(p_dev->socket, 0); |
404 | 371 | ||
405 | put_module: | 372 | put_module: |
406 | if (ret) | 373 | if (ret) |
@@ -421,8 +388,8 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le | |||
421 | struct pcmcia_device *tmp; | 388 | struct pcmcia_device *tmp; |
422 | unsigned long flags; | 389 | unsigned long flags; |
423 | 390 | ||
424 | ds_dbg(2, "unbind_request(%d)\n", s->sock); | 391 | ds_dbg(2, "pcmcia_card_remove(%d) %s\n", s->sock, |
425 | 392 | leftover ? leftover->devname : ""); | |
426 | 393 | ||
427 | if (!leftover) | 394 | if (!leftover) |
428 | s->device_count = 0; | 395 | s->device_count = 0; |
@@ -439,6 +406,7 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le | |||
439 | p_dev->_removed=1; | 406 | p_dev->_removed=1; |
440 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 407 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); |
441 | 408 | ||
409 | ds_dbg(2, "unregistering device %s\n", p_dev->dev.bus_id); | ||
442 | device_unregister(&p_dev->dev); | 410 | device_unregister(&p_dev->dev); |
443 | } | 411 | } |
444 | 412 | ||
@@ -455,6 +423,8 @@ static int pcmcia_device_remove(struct device * dev) | |||
455 | p_dev = to_pcmcia_dev(dev); | 423 | p_dev = to_pcmcia_dev(dev); |
456 | p_drv = to_pcmcia_drv(dev->driver); | 424 | p_drv = to_pcmcia_drv(dev->driver); |
457 | 425 | ||
426 | ds_dbg(1, "removing device %s\n", p_dev->dev.bus_id); | ||
427 | |||
458 | /* If we're removing the primary module driving a | 428 | /* If we're removing the primary module driving a |
459 | * pseudo multi-function card, we need to unbind | 429 | * pseudo multi-function card, we need to unbind |
460 | * all devices | 430 | * all devices |
@@ -587,8 +557,10 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
587 | 557 | ||
588 | mutex_lock(&device_add_lock); | 558 | mutex_lock(&device_add_lock); |
589 | 559 | ||
590 | /* max of 2 devices per card */ | 560 | ds_dbg(3, "adding device to %d, function %d\n", s->sock, function); |
591 | if (s->device_count == 2) | 561 | |
562 | /* max of 4 devices per card */ | ||
563 | if (s->device_count == 4) | ||
592 | goto err_put; | 564 | goto err_put; |
593 | 565 | ||
594 | p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); | 566 | p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); |
@@ -598,8 +570,6 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
598 | p_dev->socket = s; | 570 | p_dev->socket = s; |
599 | p_dev->device_no = (s->device_count++); | 571 | p_dev->device_no = (s->device_count++); |
600 | p_dev->func = function; | 572 | p_dev->func = function; |
601 | if (s->functions <= function) | ||
602 | s->functions = function + 1; | ||
603 | 573 | ||
604 | p_dev->dev.bus = &pcmcia_bus_type; | 574 | p_dev->dev.bus = &pcmcia_bus_type; |
605 | p_dev->dev.parent = s->dev.dev; | 575 | p_dev->dev.parent = s->dev.dev; |
@@ -610,8 +580,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
610 | if (!p_dev->devname) | 580 | if (!p_dev->devname) |
611 | goto err_free; | 581 | goto err_free; |
612 | sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id); | 582 | sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id); |
583 | ds_dbg(3, "devname is %s\n", p_dev->devname); | ||
613 | 584 | ||
614 | /* compat */ | ||
615 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 585 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); |
616 | 586 | ||
617 | /* | 587 | /* |
@@ -631,6 +601,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
631 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 601 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); |
632 | 602 | ||
633 | if (!p_dev->function_config) { | 603 | if (!p_dev->function_config) { |
604 | ds_dbg(3, "creating config_t for %s\n", p_dev->dev.bus_id); | ||
634 | p_dev->function_config = kzalloc(sizeof(struct config_t), | 605 | p_dev->function_config = kzalloc(sizeof(struct config_t), |
635 | GFP_KERNEL); | 606 | GFP_KERNEL); |
636 | if (!p_dev->function_config) | 607 | if (!p_dev->function_config) |
@@ -674,11 +645,16 @@ static int pcmcia_card_add(struct pcmcia_socket *s) | |||
674 | unsigned int no_funcs, i; | 645 | unsigned int no_funcs, i; |
675 | int ret = 0; | 646 | int ret = 0; |
676 | 647 | ||
677 | if (!(s->resource_setup_done)) | 648 | if (!(s->resource_setup_done)) { |
649 | ds_dbg(3, "no resources available, delaying card_add\n"); | ||
678 | return -EAGAIN; /* try again, but later... */ | 650 | return -EAGAIN; /* try again, but later... */ |
651 | } | ||
679 | 652 | ||
680 | if (pcmcia_validate_mem(s)) | 653 | if (pcmcia_validate_mem(s)) { |
654 | ds_dbg(3, "validating mem resources failed, " | ||
655 | "delaying card_add\n"); | ||
681 | return -EAGAIN; /* try again, but later... */ | 656 | return -EAGAIN; /* try again, but later... */ |
657 | } | ||
682 | 658 | ||
683 | ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo); | 659 | ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo); |
684 | if (ret || !cisinfo.Chains) { | 660 | if (ret || !cisinfo.Chains) { |
@@ -690,6 +666,7 @@ static int pcmcia_card_add(struct pcmcia_socket *s) | |||
690 | no_funcs = mfc.nfn; | 666 | no_funcs = mfc.nfn; |
691 | else | 667 | else |
692 | no_funcs = 1; | 668 | no_funcs = 1; |
669 | s->functions = no_funcs; | ||
693 | 670 | ||
694 | for (i=0; i < no_funcs; i++) | 671 | for (i=0; i < no_funcs; i++) |
695 | pcmcia_device_add(s, i); | 672 | pcmcia_device_add(s, i); |
@@ -698,38 +675,50 @@ static int pcmcia_card_add(struct pcmcia_socket *s) | |||
698 | } | 675 | } |
699 | 676 | ||
700 | 677 | ||
701 | static void pcmcia_delayed_add_pseudo_device(void *data) | 678 | static void pcmcia_delayed_add_device(struct work_struct *work) |
702 | { | 679 | { |
703 | struct pcmcia_socket *s = data; | 680 | struct pcmcia_socket *s = |
704 | pcmcia_device_add(s, 0); | 681 | container_of(work, struct pcmcia_socket, device_add); |
682 | ds_dbg(1, "adding additional device to %d\n", s->sock); | ||
683 | pcmcia_device_add(s, s->pcmcia_state.mfc_pfc); | ||
705 | s->pcmcia_state.device_add_pending = 0; | 684 | s->pcmcia_state.device_add_pending = 0; |
685 | s->pcmcia_state.mfc_pfc = 0; | ||
706 | } | 686 | } |
707 | 687 | ||
708 | static int pcmcia_requery(struct device *dev, void * _data) | 688 | static int pcmcia_requery(struct device *dev, void * _data) |
709 | { | 689 | { |
710 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 690 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
711 | if (!p_dev->dev.driver) | 691 | if (!p_dev->dev.driver) { |
692 | ds_dbg(1, "update device information for %s\n", | ||
693 | p_dev->dev.bus_id); | ||
712 | pcmcia_device_query(p_dev); | 694 | pcmcia_device_query(p_dev); |
695 | } | ||
713 | 696 | ||
714 | return 0; | 697 | return 0; |
715 | } | 698 | } |
716 | 699 | ||
717 | static void pcmcia_bus_rescan(struct pcmcia_socket *skt) | 700 | static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis) |
718 | { | 701 | { |
719 | int no_devices=0; | 702 | int no_devices = 0; |
720 | int ret = 0; | 703 | int ret = 0; |
721 | unsigned long flags; | 704 | unsigned long flags; |
722 | 705 | ||
723 | /* must be called with skt_mutex held */ | 706 | /* must be called with skt_mutex held */ |
707 | ds_dbg(0, "re-scanning socket %d\n", skt->sock); | ||
708 | |||
724 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 709 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); |
725 | if (list_empty(&skt->devices_list)) | 710 | if (list_empty(&skt->devices_list)) |
726 | no_devices=1; | 711 | no_devices = 1; |
727 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 712 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); |
728 | 713 | ||
714 | /* If this is because of a CIS override, start over */ | ||
715 | if (new_cis && !no_devices) | ||
716 | pcmcia_card_remove(skt, NULL); | ||
717 | |||
729 | /* if no devices were added for this socket yet because of | 718 | /* if no devices were added for this socket yet because of |
730 | * missing resource information or other trouble, we need to | 719 | * missing resource information or other trouble, we need to |
731 | * do this now. */ | 720 | * do this now. */ |
732 | if (no_devices) { | 721 | if (no_devices || new_cis) { |
733 | ret = pcmcia_card_add(skt); | 722 | ret = pcmcia_card_add(skt); |
734 | if (ret) | 723 | if (ret) |
735 | return; | 724 | return; |
@@ -747,6 +736,97 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt) | |||
747 | printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n"); | 736 | printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n"); |
748 | } | 737 | } |
749 | 738 | ||
739 | #ifdef CONFIG_PCMCIA_LOAD_CIS | ||
740 | |||
741 | /** | ||
742 | * pcmcia_load_firmware - load CIS from userspace if device-provided is broken | ||
743 | * @dev - the pcmcia device which needs a CIS override | ||
744 | * @filename - requested filename in /lib/firmware/ | ||
745 | * | ||
746 | * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if | ||
747 | * the one provided by the card is broken. The firmware files reside in | ||
748 | * /lib/firmware/ in userspace. | ||
749 | */ | ||
750 | static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | ||
751 | { | ||
752 | struct pcmcia_socket *s = dev->socket; | ||
753 | const struct firmware *fw; | ||
754 | char path[20]; | ||
755 | int ret = -ENOMEM; | ||
756 | int no_funcs; | ||
757 | int old_funcs; | ||
758 | cisdump_t *cis; | ||
759 | cistpl_longlink_mfc_t mfc; | ||
760 | |||
761 | if (!filename) | ||
762 | return -EINVAL; | ||
763 | |||
764 | ds_dbg(1, "trying to load CIS file %s\n", filename); | ||
765 | |||
766 | if (strlen(filename) > 14) { | ||
767 | printk(KERN_WARNING "pcmcia: CIS filename is too long\n"); | ||
768 | return -EINVAL; | ||
769 | } | ||
770 | |||
771 | snprintf(path, 20, "%s", filename); | ||
772 | |||
773 | if (request_firmware(&fw, path, &dev->dev) == 0) { | ||
774 | if (fw->size >= CISTPL_MAX_CIS_SIZE) { | ||
775 | ret = -EINVAL; | ||
776 | printk(KERN_ERR "pcmcia: CIS override is too big\n"); | ||
777 | goto release; | ||
778 | } | ||
779 | |||
780 | cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL); | ||
781 | if (!cis) { | ||
782 | ret = -ENOMEM; | ||
783 | goto release; | ||
784 | } | ||
785 | |||
786 | cis->Length = fw->size + 1; | ||
787 | memcpy(cis->Data, fw->data, fw->size); | ||
788 | |||
789 | if (!pcmcia_replace_cis(s, cis)) | ||
790 | ret = 0; | ||
791 | else { | ||
792 | printk(KERN_ERR "pcmcia: CIS override failed\n"); | ||
793 | goto release; | ||
794 | } | ||
795 | |||
796 | |||
797 | /* update information */ | ||
798 | pcmcia_device_query(dev); | ||
799 | |||
800 | /* does this cis override add or remove functions? */ | ||
801 | old_funcs = s->functions; | ||
802 | |||
803 | if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, &mfc)) | ||
804 | no_funcs = mfc.nfn; | ||
805 | else | ||
806 | no_funcs = 1; | ||
807 | s->functions = no_funcs; | ||
808 | |||
809 | if (old_funcs > no_funcs) | ||
810 | pcmcia_card_remove(s, dev); | ||
811 | else if (no_funcs > old_funcs) | ||
812 | pcmcia_add_device_later(s, 1); | ||
813 | } | ||
814 | release: | ||
815 | release_firmware(fw); | ||
816 | |||
817 | return (ret); | ||
818 | } | ||
819 | |||
820 | #else /* !CONFIG_PCMCIA_LOAD_CIS */ | ||
821 | |||
822 | static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | ||
823 | { | ||
824 | return -ENODEV; | ||
825 | } | ||
826 | |||
827 | #endif | ||
828 | |||
829 | |||
750 | static inline int pcmcia_devmatch(struct pcmcia_device *dev, | 830 | static inline int pcmcia_devmatch(struct pcmcia_device *dev, |
751 | struct pcmcia_device_id *did) | 831 | struct pcmcia_device_id *did) |
752 | { | 832 | { |
@@ -813,11 +893,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
813 | * after it has re-checked that there is no possible module | 893 | * after it has re-checked that there is no possible module |
814 | * with a prod_id/manf_id/card_id match. | 894 | * with a prod_id/manf_id/card_id match. |
815 | */ | 895 | */ |
896 | ds_dbg(0, "skipping FUNC_ID match for %s until userspace " | ||
897 | "interaction\n", dev->dev.bus_id); | ||
816 | if (!dev->allow_func_id_match) | 898 | if (!dev->allow_func_id_match) |
817 | return 0; | 899 | return 0; |
818 | } | 900 | } |
819 | 901 | ||
820 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { | 902 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { |
903 | ds_dbg(0, "device %s needs a fake CIS\n", dev->dev.bus_id); | ||
821 | if (!dev->socket->fake_cis) | 904 | if (!dev->socket->fake_cis) |
822 | pcmcia_load_firmware(dev, did->cisfile); | 905 | pcmcia_load_firmware(dev, did->cisfile); |
823 | 906 | ||
@@ -847,13 +930,21 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) { | |||
847 | 930 | ||
848 | #ifdef CONFIG_PCMCIA_IOCTL | 931 | #ifdef CONFIG_PCMCIA_IOCTL |
849 | /* matching by cardmgr */ | 932 | /* matching by cardmgr */ |
850 | if (p_dev->cardmgr == p_drv) | 933 | if (p_dev->cardmgr == p_drv) { |
934 | ds_dbg(0, "cardmgr matched %s to %s\n", dev->bus_id, | ||
935 | drv->name); | ||
851 | return 1; | 936 | return 1; |
937 | } | ||
852 | #endif | 938 | #endif |
853 | 939 | ||
854 | while (did && did->match_flags) { | 940 | while (did && did->match_flags) { |
855 | if (pcmcia_devmatch(p_dev, did)) | 941 | ds_dbg(3, "trying to match %s to %s\n", dev->bus_id, |
942 | drv->name); | ||
943 | if (pcmcia_devmatch(p_dev, did)) { | ||
944 | ds_dbg(0, "matched %s to %s\n", dev->bus_id, | ||
945 | drv->name); | ||
856 | return 1; | 946 | return 1; |
947 | } | ||
857 | did++; | 948 | did++; |
858 | } | 949 | } |
859 | 950 | ||
@@ -1044,6 +1135,8 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) | |||
1044 | struct pcmcia_driver *p_drv = NULL; | 1135 | struct pcmcia_driver *p_drv = NULL; |
1045 | int ret = 0; | 1136 | int ret = 0; |
1046 | 1137 | ||
1138 | ds_dbg(2, "suspending %s\n", dev->bus_id); | ||
1139 | |||
1047 | if (dev->driver) | 1140 | if (dev->driver) |
1048 | p_drv = to_pcmcia_drv(dev->driver); | 1141 | p_drv = to_pcmcia_drv(dev->driver); |
1049 | 1142 | ||
@@ -1052,12 +1145,18 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) | |||
1052 | 1145 | ||
1053 | if (p_drv->suspend) { | 1146 | if (p_drv->suspend) { |
1054 | ret = p_drv->suspend(p_dev); | 1147 | ret = p_drv->suspend(p_dev); |
1055 | if (ret) | 1148 | if (ret) { |
1149 | printk(KERN_ERR "pcmcia: device %s (driver %s) did " | ||
1150 | "not want to go to sleep (%d)\n", | ||
1151 | p_dev->devname, p_drv->drv.name, ret); | ||
1056 | goto out; | 1152 | goto out; |
1153 | } | ||
1057 | } | 1154 | } |
1058 | 1155 | ||
1059 | if (p_dev->device_no == p_dev->func) | 1156 | if (p_dev->device_no == p_dev->func) { |
1157 | ds_dbg(2, "releasing configuration for %s\n", dev->bus_id); | ||
1060 | pcmcia_release_configuration(p_dev); | 1158 | pcmcia_release_configuration(p_dev); |
1159 | } | ||
1061 | 1160 | ||
1062 | out: | 1161 | out: |
1063 | if (!ret) | 1162 | if (!ret) |
@@ -1072,6 +1171,8 @@ static int pcmcia_dev_resume(struct device * dev) | |||
1072 | struct pcmcia_driver *p_drv = NULL; | 1171 | struct pcmcia_driver *p_drv = NULL; |
1073 | int ret = 0; | 1172 | int ret = 0; |
1074 | 1173 | ||
1174 | ds_dbg(2, "resuming %s\n", dev->bus_id); | ||
1175 | |||
1075 | if (dev->driver) | 1176 | if (dev->driver) |
1076 | p_drv = to_pcmcia_drv(dev->driver); | 1177 | p_drv = to_pcmcia_drv(dev->driver); |
1077 | 1178 | ||
@@ -1079,6 +1180,7 @@ static int pcmcia_dev_resume(struct device * dev) | |||
1079 | goto out; | 1180 | goto out; |
1080 | 1181 | ||
1081 | if (p_dev->device_no == p_dev->func) { | 1182 | if (p_dev->device_no == p_dev->func) { |
1183 | ds_dbg(2, "requesting configuration for %s\n", dev->bus_id); | ||
1082 | ret = pcmcia_request_configuration(p_dev, &p_dev->conf); | 1184 | ret = pcmcia_request_configuration(p_dev, &p_dev->conf); |
1083 | if (ret) | 1185 | if (ret) |
1084 | goto out; | 1186 | goto out; |
@@ -1120,12 +1222,14 @@ static int pcmcia_bus_resume_callback(struct device *dev, void * _data) | |||
1120 | 1222 | ||
1121 | static int pcmcia_bus_resume(struct pcmcia_socket *skt) | 1223 | static int pcmcia_bus_resume(struct pcmcia_socket *skt) |
1122 | { | 1224 | { |
1225 | ds_dbg(2, "resuming socket %d\n", skt->sock); | ||
1123 | bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback); | 1226 | bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback); |
1124 | return 0; | 1227 | return 0; |
1125 | } | 1228 | } |
1126 | 1229 | ||
1127 | static int pcmcia_bus_suspend(struct pcmcia_socket *skt) | 1230 | static int pcmcia_bus_suspend(struct pcmcia_socket *skt) |
1128 | { | 1231 | { |
1232 | ds_dbg(2, "suspending socket %d\n", skt->sock); | ||
1129 | if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt, | 1233 | if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt, |
1130 | pcmcia_bus_suspend_callback)) { | 1234 | pcmcia_bus_suspend_callback)) { |
1131 | pcmcia_bus_resume(skt); | 1235 | pcmcia_bus_resume(skt); |
@@ -1246,7 +1350,7 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev, | |||
1246 | init_waitqueue_head(&socket->queue); | 1350 | init_waitqueue_head(&socket->queue); |
1247 | #endif | 1351 | #endif |
1248 | INIT_LIST_HEAD(&socket->devices_list); | 1352 | INIT_LIST_HEAD(&socket->devices_list); |
1249 | INIT_WORK(&socket->device_add, pcmcia_delayed_add_pseudo_device, socket); | 1353 | INIT_WORK(&socket->device_add, pcmcia_delayed_add_device); |
1250 | memset(&socket->pcmcia_state, 0, sizeof(u8)); | 1354 | memset(&socket->pcmcia_state, 0, sizeof(u8)); |
1251 | socket->device_count = 0; | 1355 | socket->device_count = 0; |
1252 | 1356 | ||
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 36fdaa58458c..3c22ac4625c2 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c | |||
@@ -398,7 +398,7 @@ static irqreturn_t pcc_interrupt(int irq, void *dev) | |||
398 | static void pcc_interrupt_wrapper(u_long data) | 398 | static void pcc_interrupt_wrapper(u_long data) |
399 | { | 399 | { |
400 | debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n"); | 400 | debug(3, "m32r_cfc: pcc_interrupt_wrapper:\n"); |
401 | pcc_interrupt(0, NULL, NULL); | 401 | pcc_interrupt(0, NULL); |
402 | init_timer(&poll_timer); | 402 | init_timer(&poll_timer); |
403 | poll_timer.expires = jiffies + poll_interval; | 403 | poll_timer.expires = jiffies + poll_interval; |
404 | add_timer(&poll_timer); | 404 | add_timer(&poll_timer); |
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 310ede575caa..d077870c6731 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
@@ -594,7 +594,12 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
594 | 594 | ||
595 | err = ret = 0; | 595 | err = ret = 0; |
596 | 596 | ||
597 | if (cmd & IOC_IN) __copy_from_user((char *)buf, uarg, size); | 597 | if (cmd & IOC_IN) { |
598 | if (__copy_from_user((char *)buf, uarg, size)) { | ||
599 | err = -EFAULT; | ||
600 | goto free_out; | ||
601 | } | ||
602 | } | ||
598 | 603 | ||
599 | switch (cmd) { | 604 | switch (cmd) { |
600 | case DS_ADJUST_RESOURCE_INFO: | 605 | case DS_ADJUST_RESOURCE_INFO: |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index a70f97fdbbdd..360c24896548 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -581,10 +581,10 @@ static irqreturn_t pd6729_test(int irq, void *dev) | |||
581 | return IRQ_HANDLED; | 581 | return IRQ_HANDLED; |
582 | } | 582 | } |
583 | 583 | ||
584 | static int pd6729_check_irq(int irq, int flags) | 584 | static int pd6729_check_irq(int irq) |
585 | { | 585 | { |
586 | if (request_irq(irq, pd6729_test, flags, "x", pd6729_test) != 0) | 586 | if (request_irq(irq, pd6729_test, IRQF_PROBE_SHARED, "x", pd6729_test) |
587 | return -1; | 587 | != 0) return -1; |
588 | free_irq(irq, pd6729_test); | 588 | free_irq(irq, pd6729_test); |
589 | return 0; | 589 | return 0; |
590 | } | 590 | } |
@@ -610,7 +610,7 @@ static u_int __devinit pd6729_isa_scan(void) | |||
610 | 610 | ||
611 | /* just find interrupts that aren't in use */ | 611 | /* just find interrupts that aren't in use */ |
612 | for (i = 0; i < 16; i++) | 612 | for (i = 0; i < 16; i++) |
613 | if ((mask0 & (1 << i)) && (pd6729_check_irq(i, 0) == 0)) | 613 | if ((mask0 & (1 << i)) && (pd6729_check_irq(i) == 0)) |
614 | mask |= (1 << i); | 614 | mask |= (1 << i); |
615 | 615 | ||
616 | printk(KERN_INFO "pd6729: ISA irqs = "); | 616 | printk(KERN_INFO "pd6729: ISA irqs = "); |
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 933cd864a5c9..b005602d6b53 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c | |||
@@ -188,7 +188,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf, | |||
188 | (s->state & SOCKET_PRESENT) && | 188 | (s->state & SOCKET_PRESENT) && |
189 | !(s->state & SOCKET_CARDBUS)) { | 189 | !(s->state & SOCKET_CARDBUS)) { |
190 | if (try_module_get(s->callback->owner)) { | 190 | if (try_module_get(s->callback->owner)) { |
191 | s->callback->requery(s); | 191 | s->callback->requery(s, 0); |
192 | module_put(s->callback->owner); | 192 | module_put(s->callback->owner); |
193 | } | 193 | } |
194 | } | 194 | } |
@@ -325,7 +325,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz | |||
325 | if ((s->callback) && (s->state & SOCKET_PRESENT) && | 325 | if ((s->callback) && (s->state & SOCKET_PRESENT) && |
326 | !(s->state & SOCKET_CARDBUS)) { | 326 | !(s->state & SOCKET_CARDBUS)) { |
327 | if (try_module_get(s->callback->owner)) { | 327 | if (try_module_get(s->callback->owner)) { |
328 | s->callback->requery(s); | 328 | s->callback->requery(s, 1); |
329 | module_put(s->callback->owner); | 329 | module_put(s->callback->owner); |
330 | } | 330 | } |
331 | } | 331 | } |
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile new file mode 100644 index 000000000000..b52d547b7a78 --- /dev/null +++ b/drivers/ps3/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-y += system-bus.o | |||
diff --git a/drivers/ps3/system-bus.c b/drivers/ps3/system-bus.c new file mode 100644 index 000000000000..d79f949bcb2a --- /dev/null +++ b/drivers/ps3/system-bus.c | |||
@@ -0,0 +1,362 @@ | |||
1 | /* | ||
2 | * PS3 system bus driver. | ||
3 | * | ||
4 | * Copyright (C) 2006 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2006 Sony Corp. | ||
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; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/err.h> | ||
26 | |||
27 | #include <asm/udbg.h> | ||
28 | #include <asm/ps3.h> | ||
29 | #include <asm/lv1call.h> | ||
30 | #include <asm/firmware.h> | ||
31 | |||
32 | #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__) | ||
33 | static void _dump_mmio_region(const struct ps3_mmio_region* r, | ||
34 | const char* func, int line) | ||
35 | { | ||
36 | pr_debug("%s:%d: dev %u:%u\n", func, line, r->did.bus_id, | ||
37 | r->did.dev_id); | ||
38 | pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); | ||
39 | pr_debug("%s:%d: len %lxh\n", func, line, r->len); | ||
40 | pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr); | ||
41 | } | ||
42 | |||
43 | int ps3_mmio_region_create(struct ps3_mmio_region *r) | ||
44 | { | ||
45 | int result; | ||
46 | |||
47 | result = lv1_map_device_mmio_region(r->did.bus_id, r->did.dev_id, | ||
48 | r->bus_addr, r->len, r->page_size, &r->lpar_addr); | ||
49 | |||
50 | if (result) { | ||
51 | pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n", | ||
52 | __func__, __LINE__, ps3_result(result)); | ||
53 | r->lpar_addr = r->len = r->bus_addr = 0; | ||
54 | } | ||
55 | |||
56 | dump_mmio_region(r); | ||
57 | return result; | ||
58 | } | ||
59 | |||
60 | int ps3_free_mmio_region(struct ps3_mmio_region *r) | ||
61 | { | ||
62 | int result; | ||
63 | |||
64 | result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id, | ||
65 | r->bus_addr); | ||
66 | |||
67 | if (result) | ||
68 | pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n", | ||
69 | __func__, __LINE__, ps3_result(result)); | ||
70 | |||
71 | r->lpar_addr = r->len = r->bus_addr = 0; | ||
72 | return result; | ||
73 | } | ||
74 | |||
75 | static int ps3_system_bus_match(struct device *_dev, | ||
76 | struct device_driver *_drv) | ||
77 | { | ||
78 | int result; | ||
79 | struct ps3_system_bus_driver *drv = to_ps3_system_bus_driver(_drv); | ||
80 | struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); | ||
81 | |||
82 | result = dev->match_id == drv->match_id; | ||
83 | |||
84 | pr_info("%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, __LINE__, | ||
85 | dev->match_id, dev->core.bus_id, drv->match_id, drv->core.name, | ||
86 | (result ? "match" : "miss")); | ||
87 | return result; | ||
88 | } | ||
89 | |||
90 | static int ps3_system_bus_probe(struct device *_dev) | ||
91 | { | ||
92 | int result; | ||
93 | struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); | ||
94 | struct ps3_system_bus_driver *drv = | ||
95 | to_ps3_system_bus_driver(_dev->driver); | ||
96 | |||
97 | result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0); | ||
98 | |||
99 | if (result) { | ||
100 | pr_debug("%s:%d: lv1_open_device failed (%d)\n", | ||
101 | __func__, __LINE__, result); | ||
102 | result = -EACCES; | ||
103 | goto clean_none; | ||
104 | } | ||
105 | |||
106 | if (dev->d_region->did.bus_id) { | ||
107 | result = ps3_dma_region_create(dev->d_region); | ||
108 | |||
109 | if (result) { | ||
110 | pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n", | ||
111 | __func__, __LINE__, result); | ||
112 | BUG_ON("check region type"); | ||
113 | result = -EINVAL; | ||
114 | goto clean_device; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | BUG_ON(!drv); | ||
119 | |||
120 | if (drv->probe) | ||
121 | result = drv->probe(dev); | ||
122 | else | ||
123 | pr_info("%s:%d: %s no probe method\n", __func__, __LINE__, | ||
124 | dev->core.bus_id); | ||
125 | |||
126 | if (result) { | ||
127 | pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__); | ||
128 | goto clean_dma; | ||
129 | } | ||
130 | |||
131 | return result; | ||
132 | |||
133 | clean_dma: | ||
134 | ps3_dma_region_free(dev->d_region); | ||
135 | clean_device: | ||
136 | lv1_close_device(dev->did.bus_id, dev->did.dev_id); | ||
137 | clean_none: | ||
138 | return result; | ||
139 | } | ||
140 | |||
141 | static int ps3_system_bus_remove(struct device *_dev) | ||
142 | { | ||
143 | struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); | ||
144 | struct ps3_system_bus_driver *drv = | ||
145 | to_ps3_system_bus_driver(_dev->driver); | ||
146 | |||
147 | if (drv->remove) | ||
148 | drv->remove(dev); | ||
149 | else | ||
150 | pr_info("%s:%d: %s no remove method\n", __func__, __LINE__, | ||
151 | dev->core.bus_id); | ||
152 | |||
153 | ps3_dma_region_free(dev->d_region); | ||
154 | ps3_free_mmio_region(dev->m_region); | ||
155 | lv1_close_device(dev->did.bus_id, dev->did.dev_id); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | struct bus_type ps3_system_bus_type = { | ||
161 | .name = "ps3_system_bus", | ||
162 | .match = ps3_system_bus_match, | ||
163 | .probe = ps3_system_bus_probe, | ||
164 | .remove = ps3_system_bus_remove, | ||
165 | }; | ||
166 | |||
167 | int __init ps3_system_bus_init(void) | ||
168 | { | ||
169 | int result; | ||
170 | |||
171 | if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) | ||
172 | return 0; | ||
173 | |||
174 | result = bus_register(&ps3_system_bus_type); | ||
175 | BUG_ON(result); | ||
176 | return result; | ||
177 | } | ||
178 | |||
179 | core_initcall(ps3_system_bus_init); | ||
180 | |||
181 | /* Allocates a contiguous real buffer and creates mappings over it. | ||
182 | * Returns the virtual address of the buffer and sets dma_handle | ||
183 | * to the dma address (mapping) of the first page. | ||
184 | */ | ||
185 | |||
186 | static void * ps3_alloc_coherent(struct device *_dev, size_t size, | ||
187 | dma_addr_t *dma_handle, gfp_t flag) | ||
188 | { | ||
189 | int result; | ||
190 | struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); | ||
191 | unsigned long virt_addr; | ||
192 | |||
193 | BUG_ON(!dev->d_region->bus_addr); | ||
194 | |||
195 | flag &= ~(__GFP_DMA | __GFP_HIGHMEM); | ||
196 | flag |= __GFP_ZERO; | ||
197 | |||
198 | virt_addr = __get_free_pages(flag, get_order(size)); | ||
199 | |||
200 | if (!virt_addr) { | ||
201 | pr_debug("%s:%d: get_free_pages failed\n", __func__, __LINE__); | ||
202 | goto clean_none; | ||
203 | } | ||
204 | |||
205 | result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle); | ||
206 | |||
207 | if (result) { | ||
208 | pr_debug("%s:%d: ps3_dma_map failed (%d)\n", | ||
209 | __func__, __LINE__, result); | ||
210 | BUG_ON("check region type"); | ||
211 | goto clean_alloc; | ||
212 | } | ||
213 | |||
214 | return (void*)virt_addr; | ||
215 | |||
216 | clean_alloc: | ||
217 | free_pages(virt_addr, get_order(size)); | ||
218 | clean_none: | ||
219 | dma_handle = NULL; | ||
220 | return NULL; | ||
221 | } | ||
222 | |||
223 | static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr, | ||
224 | dma_addr_t dma_handle) | ||
225 | { | ||
226 | struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); | ||
227 | |||
228 | ps3_dma_unmap(dev->d_region, dma_handle, size); | ||
229 | free_pages((unsigned long)vaddr, get_order(size)); | ||
230 | } | ||
231 | |||
232 | /* Creates TCEs for a user provided buffer. The user buffer must be | ||
233 | * contiguous real kernel storage (not vmalloc). The address of the buffer | ||
234 | * passed here is the kernel (virtual) address of the buffer. The buffer | ||
235 | * need not be page aligned, the dma_addr_t returned will point to the same | ||
236 | * byte within the page as vaddr. | ||
237 | */ | ||
238 | |||
239 | static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size, | ||
240 | enum dma_data_direction direction) | ||
241 | { | ||
242 | struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); | ||
243 | int result; | ||
244 | unsigned long bus_addr; | ||
245 | |||
246 | result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size, | ||
247 | &bus_addr); | ||
248 | |||
249 | if (result) { | ||
250 | pr_debug("%s:%d: ps3_dma_map failed (%d)\n", | ||
251 | __func__, __LINE__, result); | ||
252 | } | ||
253 | |||
254 | return bus_addr; | ||
255 | } | ||
256 | |||
257 | static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr, | ||
258 | size_t size, enum dma_data_direction direction) | ||
259 | { | ||
260 | struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); | ||
261 | int result; | ||
262 | |||
263 | result = ps3_dma_unmap(dev->d_region, dma_addr, size); | ||
264 | |||
265 | if (result) { | ||
266 | pr_debug("%s:%d: ps3_dma_unmap failed (%d)\n", | ||
267 | __func__, __LINE__, result); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents, | ||
272 | enum dma_data_direction direction) | ||
273 | { | ||
274 | #if defined(CONFIG_PS3_DYNAMIC_DMA) | ||
275 | BUG_ON("do"); | ||
276 | #endif | ||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg, | ||
281 | int nents, enum dma_data_direction direction) | ||
282 | { | ||
283 | #if defined(CONFIG_PS3_DYNAMIC_DMA) | ||
284 | BUG_ON("do"); | ||
285 | #endif | ||
286 | } | ||
287 | |||
288 | static int ps3_dma_supported(struct device *_dev, u64 mask) | ||
289 | { | ||
290 | return 1; | ||
291 | } | ||
292 | |||
293 | static struct dma_mapping_ops ps3_dma_ops = { | ||
294 | .alloc_coherent = ps3_alloc_coherent, | ||
295 | .free_coherent = ps3_free_coherent, | ||
296 | .map_single = ps3_map_single, | ||
297 | .unmap_single = ps3_unmap_single, | ||
298 | .map_sg = ps3_map_sg, | ||
299 | .unmap_sg = ps3_unmap_sg, | ||
300 | .dma_supported = ps3_dma_supported | ||
301 | }; | ||
302 | |||
303 | /** | ||
304 | * ps3_system_bus_release_device - remove a device from the system bus | ||
305 | */ | ||
306 | |||
307 | static void ps3_system_bus_release_device(struct device *_dev) | ||
308 | { | ||
309 | struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev); | ||
310 | kfree(dev); | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * ps3_system_bus_device_register - add a device to the system bus | ||
315 | * | ||
316 | * ps3_system_bus_device_register() expects the dev object to be allocated | ||
317 | * dynamically by the caller. The system bus takes ownership of the dev | ||
318 | * object and frees the object in ps3_system_bus_release_device(). | ||
319 | */ | ||
320 | |||
321 | int ps3_system_bus_device_register(struct ps3_system_bus_device *dev) | ||
322 | { | ||
323 | int result; | ||
324 | static unsigned int dev_count = 1; | ||
325 | |||
326 | dev->core.parent = NULL; | ||
327 | dev->core.bus = &ps3_system_bus_type; | ||
328 | dev->core.release = ps3_system_bus_release_device; | ||
329 | |||
330 | dev->core.archdata.of_node = NULL; | ||
331 | dev->core.archdata.dma_ops = &ps3_dma_ops; | ||
332 | dev->core.archdata.numa_node = 0; | ||
333 | |||
334 | snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x", | ||
335 | dev_count++); | ||
336 | |||
337 | pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id); | ||
338 | |||
339 | result = device_register(&dev->core); | ||
340 | return result; | ||
341 | } | ||
342 | |||
343 | EXPORT_SYMBOL_GPL(ps3_system_bus_device_register); | ||
344 | |||
345 | int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv) | ||
346 | { | ||
347 | int result; | ||
348 | |||
349 | drv->core.bus = &ps3_system_bus_type; | ||
350 | |||
351 | result = driver_register(&drv->core); | ||
352 | return result; | ||
353 | } | ||
354 | |||
355 | EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register); | ||
356 | |||
357 | void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv) | ||
358 | { | ||
359 | driver_unregister(&drv->core); | ||
360 | } | ||
361 | |||
362 | EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister); | ||
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 814b9e1873f5..828b329e08e0 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -53,9 +53,10 @@ static int rtc_dev_open(struct inode *inode, struct file *file) | |||
53 | * Routine to poll RTC seconds field for change as often as possible, | 53 | * Routine to poll RTC seconds field for change as often as possible, |
54 | * after first RTC_UIE use timer to reduce polling | 54 | * after first RTC_UIE use timer to reduce polling |
55 | */ | 55 | */ |
56 | static void rtc_uie_task(void *data) | 56 | static void rtc_uie_task(struct work_struct *work) |
57 | { | 57 | { |
58 | struct rtc_device *rtc = data; | 58 | struct rtc_device *rtc = |
59 | container_of(work, struct rtc_device, uie_task); | ||
59 | struct rtc_time tm; | 60 | struct rtc_time tm; |
60 | int num = 0; | 61 | int num = 0; |
61 | int err; | 62 | int err; |
@@ -411,7 +412,7 @@ static int rtc_dev_add_device(struct class_device *class_dev, | |||
411 | spin_lock_init(&rtc->irq_lock); | 412 | spin_lock_init(&rtc->irq_lock); |
412 | init_waitqueue_head(&rtc->irq_queue); | 413 | init_waitqueue_head(&rtc->irq_queue); |
413 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL | 414 | #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL |
414 | INIT_WORK(&rtc->uie_task, rtc_uie_task, rtc); | 415 | INIT_WORK(&rtc->uie_task, rtc_uie_task); |
415 | setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); | 416 | setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); |
416 | #endif | 417 | #endif |
417 | 418 | ||
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index a2cef57d7bcb..2af2d9b53d18 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -54,7 +54,7 @@ static void dasd_flush_request_queue(struct dasd_device *); | |||
54 | static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *); | 54 | static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *); |
55 | static int dasd_flush_ccw_queue(struct dasd_device *, int); | 55 | static int dasd_flush_ccw_queue(struct dasd_device *, int); |
56 | static void dasd_tasklet(struct dasd_device *); | 56 | static void dasd_tasklet(struct dasd_device *); |
57 | static void do_kick_device(void *data); | 57 | static void do_kick_device(struct work_struct *); |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * SECTION: Operations on the device structure. | 60 | * SECTION: Operations on the device structure. |
@@ -100,7 +100,7 @@ dasd_alloc_device(void) | |||
100 | (unsigned long) device); | 100 | (unsigned long) device); |
101 | INIT_LIST_HEAD(&device->ccw_queue); | 101 | INIT_LIST_HEAD(&device->ccw_queue); |
102 | init_timer(&device->timer); | 102 | init_timer(&device->timer); |
103 | INIT_WORK(&device->kick_work, do_kick_device, device); | 103 | INIT_WORK(&device->kick_work, do_kick_device); |
104 | device->state = DASD_STATE_NEW; | 104 | device->state = DASD_STATE_NEW; |
105 | device->target = DASD_STATE_NEW; | 105 | device->target = DASD_STATE_NEW; |
106 | 106 | ||
@@ -407,11 +407,9 @@ dasd_change_state(struct dasd_device *device) | |||
407 | * event daemon. | 407 | * event daemon. |
408 | */ | 408 | */ |
409 | static void | 409 | static void |
410 | do_kick_device(void *data) | 410 | do_kick_device(struct work_struct *work) |
411 | { | 411 | { |
412 | struct dasd_device *device; | 412 | struct dasd_device *device = container_of(work, struct dasd_device, kick_work); |
413 | |||
414 | device = (struct dasd_device *) data; | ||
415 | dasd_change_state(device); | 413 | dasd_change_state(device); |
416 | dasd_schedule_bh(device); | 414 | dasd_schedule_bh(device); |
417 | dasd_put_device(device); | 415 | dasd_put_device(device); |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index ad7f7e1c0163..26cf2f5ae2e7 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -334,7 +334,7 @@ static LIST_HEAD(slow_subchannels_head); | |||
334 | static DEFINE_SPINLOCK(slow_subchannel_lock); | 334 | static DEFINE_SPINLOCK(slow_subchannel_lock); |
335 | 335 | ||
336 | static void | 336 | static void |
337 | css_trigger_slow_path(void) | 337 | css_trigger_slow_path(struct work_struct *unused) |
338 | { | 338 | { |
339 | CIO_TRACE_EVENT(4, "slowpath"); | 339 | CIO_TRACE_EVENT(4, "slowpath"); |
340 | 340 | ||
@@ -359,8 +359,7 @@ css_trigger_slow_path(void) | |||
359 | spin_unlock_irq(&slow_subchannel_lock); | 359 | spin_unlock_irq(&slow_subchannel_lock); |
360 | } | 360 | } |
361 | 361 | ||
362 | typedef void (*workfunc)(void *); | 362 | DECLARE_WORK(slow_path_work, css_trigger_slow_path); |
363 | DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL); | ||
364 | struct workqueue_struct *slow_path_wq; | 363 | struct workqueue_struct *slow_path_wq; |
365 | 364 | ||
366 | /* Reprobe subchannel if unregistered. */ | 365 | /* Reprobe subchannel if unregistered. */ |
@@ -397,7 +396,7 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data) | |||
397 | } | 396 | } |
398 | 397 | ||
399 | /* Work function used to reprobe all unregistered subchannels. */ | 398 | /* Work function used to reprobe all unregistered subchannels. */ |
400 | static void reprobe_all(void *data) | 399 | static void reprobe_all(struct work_struct *unused) |
401 | { | 400 | { |
402 | int ret; | 401 | int ret; |
403 | 402 | ||
@@ -413,7 +412,7 @@ static void reprobe_all(void *data) | |||
413 | need_reprobe); | 412 | need_reprobe); |
414 | } | 413 | } |
415 | 414 | ||
416 | DECLARE_WORK(css_reprobe_work, reprobe_all, NULL); | 415 | DECLARE_WORK(css_reprobe_work, reprobe_all); |
417 | 416 | ||
418 | /* Schedule reprobing of all unregistered subchannels. */ | 417 | /* Schedule reprobing of all unregistered subchannels. */ |
419 | void css_schedule_reprobe(void) | 418 | void css_schedule_reprobe(void) |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 6a54334ffe09..e4dc947e74e9 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include "ap_bus.h" | 37 | #include "ap_bus.h" |
38 | 38 | ||
39 | /* Some prototypes. */ | 39 | /* Some prototypes. */ |
40 | static void ap_scan_bus(void *); | 40 | static void ap_scan_bus(struct work_struct *); |
41 | static void ap_poll_all(unsigned long); | 41 | static void ap_poll_all(unsigned long); |
42 | static void ap_poll_timeout(unsigned long); | 42 | static void ap_poll_timeout(unsigned long); |
43 | static int ap_poll_thread_start(void); | 43 | static int ap_poll_thread_start(void); |
@@ -71,7 +71,7 @@ static struct device *ap_root_device = NULL; | |||
71 | static struct workqueue_struct *ap_work_queue; | 71 | static struct workqueue_struct *ap_work_queue; |
72 | static struct timer_list ap_config_timer; | 72 | static struct timer_list ap_config_timer; |
73 | static int ap_config_time = AP_CONFIG_TIME; | 73 | static int ap_config_time = AP_CONFIG_TIME; |
74 | static DECLARE_WORK(ap_config_work, ap_scan_bus, NULL); | 74 | static DECLARE_WORK(ap_config_work, ap_scan_bus); |
75 | 75 | ||
76 | /** | 76 | /** |
77 | * Tasklet & timer for AP request polling. | 77 | * Tasklet & timer for AP request polling. |
@@ -732,7 +732,7 @@ static void ap_device_release(struct device *dev) | |||
732 | kfree(ap_dev); | 732 | kfree(ap_dev); |
733 | } | 733 | } |
734 | 734 | ||
735 | static void ap_scan_bus(void *data) | 735 | static void ap_scan_bus(struct work_struct *unused) |
736 | { | 736 | { |
737 | struct ap_device *ap_dev; | 737 | struct ap_device *ap_dev; |
738 | struct device *dev; | 738 | struct device *dev; |
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 08d4e47070bd..e5665b6743a1 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c | |||
@@ -67,7 +67,7 @@ static char debug_buffer[255]; | |||
67 | * Some prototypes. | 67 | * Some prototypes. |
68 | */ | 68 | */ |
69 | static void lcs_tasklet(unsigned long); | 69 | static void lcs_tasklet(unsigned long); |
70 | static void lcs_start_kernel_thread(struct lcs_card *card); | 70 | static void lcs_start_kernel_thread(struct work_struct *); |
71 | static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *); | 71 | static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *); |
72 | static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *); | 72 | static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *); |
73 | static int lcs_recovery(void *ptr); | 73 | static int lcs_recovery(void *ptr); |
@@ -1724,8 +1724,9 @@ lcs_stopcard(struct lcs_card *card) | |||
1724 | * Kernel Thread helper functions for LGW initiated commands | 1724 | * Kernel Thread helper functions for LGW initiated commands |
1725 | */ | 1725 | */ |
1726 | static void | 1726 | static void |
1727 | lcs_start_kernel_thread(struct lcs_card *card) | 1727 | lcs_start_kernel_thread(struct work_struct *work) |
1728 | { | 1728 | { |
1729 | struct lcs_card *card = container_of(work, struct lcs_card, kernel_thread_starter); | ||
1729 | LCS_DBF_TEXT(5, trace, "krnthrd"); | 1730 | LCS_DBF_TEXT(5, trace, "krnthrd"); |
1730 | if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD)) | 1731 | if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD)) |
1731 | kernel_thread(lcs_recovery, (void *) card, SIGCHLD); | 1732 | kernel_thread(lcs_recovery, (void *) card, SIGCHLD); |
@@ -2053,8 +2054,7 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev) | |||
2053 | ccwgdev->cdev[0]->handler = lcs_irq; | 2054 | ccwgdev->cdev[0]->handler = lcs_irq; |
2054 | ccwgdev->cdev[1]->handler = lcs_irq; | 2055 | ccwgdev->cdev[1]->handler = lcs_irq; |
2055 | card->gdev = ccwgdev; | 2056 | card->gdev = ccwgdev; |
2056 | INIT_WORK(&card->kernel_thread_starter, | 2057 | INIT_WORK(&card->kernel_thread_starter, lcs_start_kernel_thread); |
2057 | (void *) lcs_start_kernel_thread, card); | ||
2058 | card->thread_start_mask = 0; | 2058 | card->thread_start_mask = 0; |
2059 | card->thread_allowed_mask = 0; | 2059 | card->thread_allowed_mask = 0; |
2060 | card->thread_running_mask = 0; | 2060 | card->thread_running_mask = 0; |
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 7fdc5272c446..2bde4f1fb9c2 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -1039,8 +1039,9 @@ qeth_do_start_thread(struct qeth_card *card, unsigned long thread) | |||
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | static void | 1041 | static void |
1042 | qeth_start_kernel_thread(struct qeth_card *card) | 1042 | qeth_start_kernel_thread(struct work_struct *work) |
1043 | { | 1043 | { |
1044 | struct qeth_card *card = container_of(work, struct qeth_card, kernel_thread_starter); | ||
1044 | QETH_DBF_TEXT(trace , 2, "strthrd"); | 1045 | QETH_DBF_TEXT(trace , 2, "strthrd"); |
1045 | 1046 | ||
1046 | if (card->read.state != CH_STATE_UP && | 1047 | if (card->read.state != CH_STATE_UP && |
@@ -1103,8 +1104,7 @@ qeth_setup_card(struct qeth_card *card) | |||
1103 | card->thread_start_mask = 0; | 1104 | card->thread_start_mask = 0; |
1104 | card->thread_allowed_mask = 0; | 1105 | card->thread_allowed_mask = 0; |
1105 | card->thread_running_mask = 0; | 1106 | card->thread_running_mask = 0; |
1106 | INIT_WORK(&card->kernel_thread_starter, | 1107 | INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread); |
1107 | (void *)qeth_start_kernel_thread,card); | ||
1108 | INIT_LIST_HEAD(&card->ip_list); | 1108 | INIT_LIST_HEAD(&card->ip_list); |
1109 | card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL); | 1109 | card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL); |
1110 | if (!card->ip_tbd_list) { | 1110 | if (!card->ip_tbd_list) { |
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 562432d017b0..335a25540c08 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c | |||
@@ -622,8 +622,10 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata, | |||
622 | dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); | 622 | dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); |
623 | /* restore the old result if the request sense was | 623 | /* restore the old result if the request sense was |
624 | * successful */ | 624 | * successful */ |
625 | if(result == 0) | 625 | if (result == 0) |
626 | result = cmnd[7]; | 626 | result = cmnd[7]; |
627 | /* restore the original length */ | ||
628 | SCp->cmd_len = cmnd[8]; | ||
627 | } else | 629 | } else |
628 | NCR_700_unmap(hostdata, SCp, slot); | 630 | NCR_700_unmap(hostdata, SCp, slot); |
629 | 631 | ||
@@ -1007,6 +1009,9 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, | |||
1007 | * of the command */ | 1009 | * of the command */ |
1008 | cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; | 1010 | cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC; |
1009 | cmnd[7] = hostdata->status[0]; | 1011 | cmnd[7] = hostdata->status[0]; |
1012 | cmnd[8] = SCp->cmd_len; | ||
1013 | SCp->cmd_len = 6; /* command length for | ||
1014 | * REQUEST_SENSE */ | ||
1010 | slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE); | 1015 | slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE); |
1011 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); | 1016 | slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); |
1012 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); | 1017 | slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer)); |
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index cdd033724786..3075204915c8 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c | |||
@@ -2186,21 +2186,21 @@ static int __init BusLogic_init(void) | |||
2186 | 2186 | ||
2187 | if (BusLogic_ProbeOptions.NoProbe) | 2187 | if (BusLogic_ProbeOptions.NoProbe) |
2188 | return -ENODEV; | 2188 | return -ENODEV; |
2189 | BusLogic_ProbeInfoList = (struct BusLogic_ProbeInfo *) | 2189 | BusLogic_ProbeInfoList = |
2190 | kmalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_ATOMIC); | 2190 | kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL); |
2191 | if (BusLogic_ProbeInfoList == NULL) { | 2191 | if (BusLogic_ProbeInfoList == NULL) { |
2192 | BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL); | 2192 | BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL); |
2193 | return -ENOMEM; | 2193 | return -ENOMEM; |
2194 | } | 2194 | } |
2195 | memset(BusLogic_ProbeInfoList, 0, BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo)); | 2195 | |
2196 | PrototypeHostAdapter = (struct BusLogic_HostAdapter *) | 2196 | PrototypeHostAdapter = |
2197 | kmalloc(sizeof(struct BusLogic_HostAdapter), GFP_ATOMIC); | 2197 | kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL); |
2198 | if (PrototypeHostAdapter == NULL) { | 2198 | if (PrototypeHostAdapter == NULL) { |
2199 | kfree(BusLogic_ProbeInfoList); | 2199 | kfree(BusLogic_ProbeInfoList); |
2200 | BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL); | 2200 | BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL); |
2201 | return -ENOMEM; | 2201 | return -ENOMEM; |
2202 | } | 2202 | } |
2203 | memset(PrototypeHostAdapter, 0, sizeof(struct BusLogic_HostAdapter)); | 2203 | |
2204 | #ifdef MODULE | 2204 | #ifdef MODULE |
2205 | if (BusLogic != NULL) | 2205 | if (BusLogic != NULL) |
2206 | BusLogic_Setup(BusLogic); | 2206 | BusLogic_Setup(BusLogic); |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 9540eb8efdcb..69569096dae5 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -29,6 +29,13 @@ config SCSI | |||
29 | However, do not compile this as a module if your root file system | 29 | However, do not compile this as a module if your root file system |
30 | (the one containing the directory /) is located on a SCSI device. | 30 | (the one containing the directory /) is located on a SCSI device. |
31 | 31 | ||
32 | config SCSI_TGT | ||
33 | tristate "SCSI target support" | ||
34 | depends on SCSI && EXPERIMENTAL | ||
35 | ---help--- | ||
36 | If you want to use SCSI target mode drivers enable this option. | ||
37 | If you choose M, the module will be called scsi_tgt. | ||
38 | |||
32 | config SCSI_NETLINK | 39 | config SCSI_NETLINK |
33 | bool | 40 | bool |
34 | default n | 41 | default n |
@@ -216,6 +223,23 @@ config SCSI_LOGGING | |||
216 | there should be no noticeable performance impact as long as you have | 223 | there should be no noticeable performance impact as long as you have |
217 | logging turned off. | 224 | logging turned off. |
218 | 225 | ||
226 | config SCSI_SCAN_ASYNC | ||
227 | bool "Asynchronous SCSI scanning" | ||
228 | depends on SCSI | ||
229 | help | ||
230 | The SCSI subsystem can probe for devices while the rest of the | ||
231 | system continues booting, and even probe devices on different | ||
232 | busses in parallel, leading to a significant speed-up. | ||
233 | If you have built SCSI as modules, enabling this option can | ||
234 | be a problem as the devices may not have been found by the | ||
235 | time your system expects them to have been. You can load the | ||
236 | scsi_wait_scan module to ensure that all scans have completed. | ||
237 | If you build your SCSI drivers into the kernel, then everything | ||
238 | will work fine if you say Y here. | ||
239 | |||
240 | You can override this choice by specifying scsi_mod.scan="sync" | ||
241 | or "async" on the kernel's command line. | ||
242 | |||
219 | menu "SCSI Transports" | 243 | menu "SCSI Transports" |
220 | depends on SCSI | 244 | depends on SCSI |
221 | 245 | ||
@@ -797,6 +821,20 @@ config SCSI_IBMVSCSI | |||
797 | To compile this driver as a module, choose M here: the | 821 | To compile this driver as a module, choose M here: the |
798 | module will be called ibmvscsic. | 822 | module will be called ibmvscsic. |
799 | 823 | ||
824 | config SCSI_IBMVSCSIS | ||
825 | tristate "IBM Virtual SCSI Server support" | ||
826 | depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP | ||
827 | help | ||
828 | This is the SRP target driver for IBM pSeries virtual environments. | ||
829 | |||
830 | The userspace component needed to initialize the driver and | ||
831 | documentation can be found: | ||
832 | |||
833 | http://stgt.berlios.de/ | ||
834 | |||
835 | To compile this driver as a module, choose M here: the | ||
836 | module will be called ibmvstgt. | ||
837 | |||
800 | config SCSI_INITIO | 838 | config SCSI_INITIO |
801 | tristate "Initio 9100U(W) support" | 839 | tristate "Initio 9100U(W) support" |
802 | depends on PCI && SCSI | 840 | depends on PCI && SCSI |
@@ -944,8 +982,13 @@ config SCSI_STEX | |||
944 | tristate "Promise SuperTrak EX Series support" | 982 | tristate "Promise SuperTrak EX Series support" |
945 | depends on PCI && SCSI | 983 | depends on PCI && SCSI |
946 | ---help--- | 984 | ---help--- |
947 | This driver supports Promise SuperTrak EX8350/8300/16350/16300 | 985 | This driver supports Promise SuperTrak EX series storage controllers. |
948 | Storage controllers. | 986 | |
987 | Promise provides Linux RAID configuration utility for these | ||
988 | controllers. Please visit <http://www.promise.com> to download. | ||
989 | |||
990 | To compile this driver as a module, choose M here: the | ||
991 | module will be called stex. | ||
949 | 992 | ||
950 | config SCSI_SYM53C8XX_2 | 993 | config SCSI_SYM53C8XX_2 |
951 | tristate "SYM53C8XX Version 2 SCSI support" | 994 | tristate "SYM53C8XX Version 2 SCSI support" |
@@ -1026,6 +1069,7 @@ config SCSI_IPR | |||
1026 | config SCSI_IPR_TRACE | 1069 | config SCSI_IPR_TRACE |
1027 | bool "enable driver internal trace" | 1070 | bool "enable driver internal trace" |
1028 | depends on SCSI_IPR | 1071 | depends on SCSI_IPR |
1072 | default y | ||
1029 | help | 1073 | help |
1030 | If you say Y here, the driver will trace all commands issued | 1074 | If you say Y here, the driver will trace all commands issued |
1031 | to the adapter. Performance impact is minimal. Trace can be | 1075 | to the adapter. Performance impact is minimal. Trace can be |
@@ -1034,6 +1078,7 @@ config SCSI_IPR_TRACE | |||
1034 | config SCSI_IPR_DUMP | 1078 | config SCSI_IPR_DUMP |
1035 | bool "enable adapter dump support" | 1079 | bool "enable adapter dump support" |
1036 | depends on SCSI_IPR | 1080 | depends on SCSI_IPR |
1081 | default y | ||
1037 | help | 1082 | help |
1038 | If you say Y here, the driver will support adapter crash dump. | 1083 | If you say Y here, the driver will support adapter crash dump. |
1039 | If you enable this support, the iprdump daemon can be used | 1084 | If you enable this support, the iprdump daemon can be used |
@@ -1734,6 +1779,16 @@ config ZFCP | |||
1734 | called zfcp. If you want to compile it as a module, say M here | 1779 | called zfcp. If you want to compile it as a module, say M here |
1735 | and read <file:Documentation/modules.txt>. | 1780 | and read <file:Documentation/modules.txt>. |
1736 | 1781 | ||
1782 | config SCSI_SRP | ||
1783 | tristate "SCSI RDMA Protocol helper library" | ||
1784 | depends on SCSI && PCI | ||
1785 | select SCSI_TGT | ||
1786 | help | ||
1787 | If you wish to use SRP target drivers, say Y. | ||
1788 | |||
1789 | To compile this driver as a module, choose M here: the | ||
1790 | module will be called libsrp. | ||
1791 | |||
1737 | endmenu | 1792 | endmenu |
1738 | 1793 | ||
1739 | source "drivers/scsi/pcmcia/Kconfig" | 1794 | source "drivers/scsi/pcmcia/Kconfig" |
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index bcca39c3bcbf..bd7c9888f7f4 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -21,6 +21,7 @@ CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM | |||
21 | subdir-$(CONFIG_PCMCIA) += pcmcia | 21 | subdir-$(CONFIG_PCMCIA) += pcmcia |
22 | 22 | ||
23 | obj-$(CONFIG_SCSI) += scsi_mod.o | 23 | obj-$(CONFIG_SCSI) += scsi_mod.o |
24 | obj-$(CONFIG_SCSI_TGT) += scsi_tgt.o | ||
24 | 25 | ||
25 | obj-$(CONFIG_RAID_ATTRS) += raid_class.o | 26 | obj-$(CONFIG_RAID_ATTRS) += raid_class.o |
26 | 27 | ||
@@ -125,7 +126,9 @@ obj-$(CONFIG_SCSI_FCAL) += fcal.o | |||
125 | obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o | 126 | obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o |
126 | obj-$(CONFIG_SCSI_NSP32) += nsp32.o | 127 | obj-$(CONFIG_SCSI_NSP32) += nsp32.o |
127 | obj-$(CONFIG_SCSI_IPR) += ipr.o | 128 | obj-$(CONFIG_SCSI_IPR) += ipr.o |
129 | obj-$(CONFIG_SCSI_SRP) += libsrp.o | ||
128 | obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/ | 130 | obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/ |
131 | obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/ | ||
129 | obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o | 132 | obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o |
130 | obj-$(CONFIG_SCSI_STEX) += stex.o | 133 | obj-$(CONFIG_SCSI_STEX) += stex.o |
131 | 134 | ||
@@ -141,6 +144,8 @@ obj-$(CONFIG_CHR_DEV_SCH) += ch.o | |||
141 | # This goes last, so that "real" scsi devices probe earlier | 144 | # This goes last, so that "real" scsi devices probe earlier |
142 | obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o | 145 | obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o |
143 | 146 | ||
147 | obj-$(CONFIG_SCSI) += scsi_wait_scan.o | ||
148 | |||
144 | scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ | 149 | scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ |
145 | scsicam.o scsi_error.o scsi_lib.o \ | 150 | scsicam.o scsi_error.o scsi_lib.o \ |
146 | scsi_scan.o scsi_sysfs.o \ | 151 | scsi_scan.o scsi_sysfs.o \ |
@@ -149,6 +154,8 @@ scsi_mod-$(CONFIG_SCSI_NETLINK) += scsi_netlink.o | |||
149 | scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o | 154 | scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o |
150 | scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o | 155 | scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o |
151 | 156 | ||
157 | scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o | ||
158 | |||
152 | sd_mod-objs := sd.o | 159 | sd_mod-objs := sd.o |
153 | sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o | 160 | sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o |
154 | ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ | 161 | ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ |
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index a6aa91072880..bb3cb3360541 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c | |||
@@ -849,7 +849,7 @@ static int __devinit NCR5380_init(struct Scsi_Host *instance, int flags) | |||
849 | hostdata->issue_queue = NULL; | 849 | hostdata->issue_queue = NULL; |
850 | hostdata->disconnected_queue = NULL; | 850 | hostdata->disconnected_queue = NULL; |
851 | 851 | ||
852 | INIT_WORK(&hostdata->coroutine, NCR5380_main, hostdata); | 852 | INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main); |
853 | 853 | ||
854 | #ifdef NCR5380_STATS | 854 | #ifdef NCR5380_STATS |
855 | for (i = 0; i < 8; ++i) { | 855 | for (i = 0; i < 8; ++i) { |
@@ -1016,7 +1016,7 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
1016 | 1016 | ||
1017 | /* Run the coroutine if it isn't already running. */ | 1017 | /* Run the coroutine if it isn't already running. */ |
1018 | /* Kick off command processing */ | 1018 | /* Kick off command processing */ |
1019 | schedule_work(&hostdata->coroutine); | 1019 | schedule_delayed_work(&hostdata->coroutine, 0); |
1020 | return 0; | 1020 | return 0; |
1021 | } | 1021 | } |
1022 | 1022 | ||
@@ -1033,9 +1033,10 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
1033 | * host lock and called routines may take the isa dma lock. | 1033 | * host lock and called routines may take the isa dma lock. |
1034 | */ | 1034 | */ |
1035 | 1035 | ||
1036 | static void NCR5380_main(void *p) | 1036 | static void NCR5380_main(struct work_struct *work) |
1037 | { | 1037 | { |
1038 | struct NCR5380_hostdata *hostdata = p; | 1038 | struct NCR5380_hostdata *hostdata = |
1039 | container_of(work, struct NCR5380_hostdata, coroutine.work); | ||
1039 | struct Scsi_Host *instance = hostdata->host; | 1040 | struct Scsi_Host *instance = hostdata->host; |
1040 | Scsi_Cmnd *tmp, *prev; | 1041 | Scsi_Cmnd *tmp, *prev; |
1041 | int done; | 1042 | int done; |
@@ -1221,7 +1222,7 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id) | |||
1221 | } /* if BASR_IRQ */ | 1222 | } /* if BASR_IRQ */ |
1222 | spin_unlock_irqrestore(instance->host_lock, flags); | 1223 | spin_unlock_irqrestore(instance->host_lock, flags); |
1223 | if(!done) | 1224 | if(!done) |
1224 | schedule_work(&hostdata->coroutine); | 1225 | schedule_delayed_work(&hostdata->coroutine, 0); |
1225 | } while (!done); | 1226 | } while (!done); |
1226 | return IRQ_HANDLED; | 1227 | return IRQ_HANDLED; |
1227 | } | 1228 | } |
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index 1bc73de496b0..713a108c02ef 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h | |||
@@ -271,7 +271,7 @@ struct NCR5380_hostdata { | |||
271 | unsigned long time_expires; /* in jiffies, set prior to sleeping */ | 271 | unsigned long time_expires; /* in jiffies, set prior to sleeping */ |
272 | int select_time; /* timer in select for target response */ | 272 | int select_time; /* timer in select for target response */ |
273 | volatile Scsi_Cmnd *selecting; | 273 | volatile Scsi_Cmnd *selecting; |
274 | struct work_struct coroutine; /* our co-routine */ | 274 | struct delayed_work coroutine; /* our co-routine */ |
275 | #ifdef NCR5380_STATS | 275 | #ifdef NCR5380_STATS |
276 | unsigned timebase; /* Base for time calcs */ | 276 | unsigned timebase; /* Base for time calcs */ |
277 | long time_read[8]; /* time to do reads */ | 277 | long time_read[8]; /* time to do reads */ |
@@ -298,7 +298,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance); | |||
298 | #ifndef DONT_USE_INTR | 298 | #ifndef DONT_USE_INTR |
299 | static irqreturn_t NCR5380_intr(int irq, void *dev_id); | 299 | static irqreturn_t NCR5380_intr(int irq, void *dev_id); |
300 | #endif | 300 | #endif |
301 | static void NCR5380_main(void *ptr); | 301 | static void NCR5380_main(struct work_struct *work); |
302 | static void NCR5380_print_options(struct Scsi_Host *instance); | 302 | static void NCR5380_print_options(struct Scsi_Host *instance); |
303 | #ifdef NDEBUG | 303 | #ifdef NDEBUG |
304 | static void NCR5380_print_phase(struct Scsi_Host *instance); | 304 | static void NCR5380_print_phase(struct Scsi_Host *instance); |
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c index d4613815f685..8578555d58fd 100644 --- a/drivers/scsi/NCR53c406a.c +++ b/drivers/scsi/NCR53c406a.c | |||
@@ -220,9 +220,11 @@ static void *addresses[] = { | |||
220 | static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 }; | 220 | static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 }; |
221 | #define PORT_COUNT ARRAY_SIZE(ports) | 221 | #define PORT_COUNT ARRAY_SIZE(ports) |
222 | 222 | ||
223 | #ifndef MODULE | ||
223 | /* possible interrupt channels */ | 224 | /* possible interrupt channels */ |
224 | static unsigned short intrs[] = { 10, 11, 12, 15 }; | 225 | static unsigned short intrs[] = { 10, 11, 12, 15 }; |
225 | #define INTR_COUNT ARRAY_SIZE(intrs) | 226 | #define INTR_COUNT ARRAY_SIZE(intrs) |
227 | #endif /* !MODULE */ | ||
226 | 228 | ||
227 | /* signatures for NCR 53c406a based controllers */ | 229 | /* signatures for NCR 53c406a based controllers */ |
228 | #if USE_BIOS | 230 | #if USE_BIOS |
@@ -605,6 +607,7 @@ static int NCR53c406a_release(struct Scsi_Host *shost) | |||
605 | return 0; | 607 | return 0; |
606 | } | 608 | } |
607 | 609 | ||
610 | #ifndef MODULE | ||
608 | /* called from init/main.c */ | 611 | /* called from init/main.c */ |
609 | static int __init NCR53c406a_setup(char *str) | 612 | static int __init NCR53c406a_setup(char *str) |
610 | { | 613 | { |
@@ -661,6 +664,8 @@ static int __init NCR53c406a_setup(char *str) | |||
661 | 664 | ||
662 | __setup("ncr53c406a=", NCR53c406a_setup); | 665 | __setup("ncr53c406a=", NCR53c406a_setup); |
663 | 666 | ||
667 | #endif /* !MODULE */ | ||
668 | |||
664 | static const char *NCR53c406a_info(struct Scsi_Host *SChost) | 669 | static const char *NCR53c406a_info(struct Scsi_Host *SChost) |
665 | { | 670 | { |
666 | DEB(printk("NCR53c406a_info called\n")); | 671 | DEB(printk("NCR53c406a_info called\n")); |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index eb3ed91bac79..4f8b4c53d435 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -11,8 +11,8 @@ | |||
11 | *----------------------------------------------------------------------------*/ | 11 | *----------------------------------------------------------------------------*/ |
12 | 12 | ||
13 | #ifndef AAC_DRIVER_BUILD | 13 | #ifndef AAC_DRIVER_BUILD |
14 | # define AAC_DRIVER_BUILD 2409 | 14 | # define AAC_DRIVER_BUILD 2423 |
15 | # define AAC_DRIVER_BRANCH "-mh2" | 15 | # define AAC_DRIVER_BRANCH "-mh3" |
16 | #endif | 16 | #endif |
17 | #define MAXIMUM_NUM_CONTAINERS 32 | 17 | #define MAXIMUM_NUM_CONTAINERS 32 |
18 | 18 | ||
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 19e42ac07cb2..4893a6d06a33 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -518,6 +518,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
518 | */ | 518 | */ |
519 | unsigned long count = 36000000L; /* 3 minutes */ | 519 | unsigned long count = 36000000L; /* 3 minutes */ |
520 | while (down_trylock(&fibptr->event_wait)) { | 520 | while (down_trylock(&fibptr->event_wait)) { |
521 | int blink; | ||
521 | if (--count == 0) { | 522 | if (--count == 0) { |
522 | spin_lock_irqsave(q->lock, qflags); | 523 | spin_lock_irqsave(q->lock, qflags); |
523 | q->numpending--; | 524 | q->numpending--; |
@@ -530,6 +531,14 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, | |||
530 | } | 531 | } |
531 | return -ETIMEDOUT; | 532 | return -ETIMEDOUT; |
532 | } | 533 | } |
534 | if ((blink = aac_adapter_check_health(dev)) > 0) { | ||
535 | if (wait == -1) { | ||
536 | printk(KERN_ERR "aacraid: aac_fib_send: adapter blinkLED 0x%x.\n" | ||
537 | "Usually a result of a serious unrecoverable hardware problem\n", | ||
538 | blink); | ||
539 | } | ||
540 | return -EFAULT; | ||
541 | } | ||
533 | udelay(5); | 542 | udelay(5); |
534 | } | 543 | } |
535 | } else if (down_interruptible(&fibptr->event_wait)) { | 544 | } else if (down_interruptible(&fibptr->event_wait)) { |
@@ -1093,6 +1102,20 @@ static int _aac_reset_adapter(struct aac_dev *aac) | |||
1093 | goto out; | 1102 | goto out; |
1094 | } | 1103 | } |
1095 | 1104 | ||
1105 | /* | ||
1106 | * Loop through the fibs, close the synchronous FIBS | ||
1107 | */ | ||
1108 | for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) { | ||
1109 | struct fib *fib = &aac->fibs[index]; | ||
1110 | if (!(fib->hw_fib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && | ||
1111 | (fib->hw_fib->header.XferState & cpu_to_le32(ResponseExpected))) { | ||
1112 | unsigned long flagv; | ||
1113 | spin_lock_irqsave(&fib->event_lock, flagv); | ||
1114 | up(&fib->event_wait); | ||
1115 | spin_unlock_irqrestore(&fib->event_lock, flagv); | ||
1116 | schedule(); | ||
1117 | } | ||
1118 | } | ||
1096 | index = aac->cardtype; | 1119 | index = aac->cardtype; |
1097 | 1120 | ||
1098 | /* | 1121 | /* |
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 306f46b85a55..0cec742d12e9 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c | |||
@@ -1443,7 +1443,7 @@ static struct work_struct aha152x_tq; | |||
1443 | * Run service completions on the card with interrupts enabled. | 1443 | * Run service completions on the card with interrupts enabled. |
1444 | * | 1444 | * |
1445 | */ | 1445 | */ |
1446 | static void run(void) | 1446 | static void run(struct work_struct *work) |
1447 | { | 1447 | { |
1448 | struct aha152x_hostdata *hd; | 1448 | struct aha152x_hostdata *hd; |
1449 | 1449 | ||
@@ -1499,7 +1499,7 @@ static irqreturn_t intr(int irqno, void *dev_id) | |||
1499 | HOSTDATA(shpnt)->service=1; | 1499 | HOSTDATA(shpnt)->service=1; |
1500 | 1500 | ||
1501 | /* Poke the BH handler */ | 1501 | /* Poke the BH handler */ |
1502 | INIT_WORK(&aha152x_tq, (void *) run, NULL); | 1502 | INIT_WORK(&aha152x_tq, run); |
1503 | schedule_work(&aha152x_tq); | 1503 | schedule_work(&aha152x_tq); |
1504 | } | 1504 | } |
1505 | DO_UNLOCK(flags); | 1505 | DO_UNLOCK(flags); |
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index c3c38a7e8d32..d7af9c63a04d 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c | |||
@@ -586,7 +586,7 @@ static struct scsi_host_template aha1740_template = { | |||
586 | 586 | ||
587 | static int aha1740_probe (struct device *dev) | 587 | static int aha1740_probe (struct device *dev) |
588 | { | 588 | { |
589 | int slotbase; | 589 | int slotbase, rc; |
590 | unsigned int irq_level, irq_type, translation; | 590 | unsigned int irq_level, irq_type, translation; |
591 | struct Scsi_Host *shpnt; | 591 | struct Scsi_Host *shpnt; |
592 | struct aha1740_hostdata *host; | 592 | struct aha1740_hostdata *host; |
@@ -641,10 +641,16 @@ static int aha1740_probe (struct device *dev) | |||
641 | } | 641 | } |
642 | 642 | ||
643 | eisa_set_drvdata (edev, shpnt); | 643 | eisa_set_drvdata (edev, shpnt); |
644 | scsi_add_host (shpnt, dev); /* XXX handle failure */ | 644 | |
645 | rc = scsi_add_host (shpnt, dev); | ||
646 | if (rc) | ||
647 | goto err_irq; | ||
648 | |||
645 | scsi_scan_host (shpnt); | 649 | scsi_scan_host (shpnt); |
646 | return 0; | 650 | return 0; |
647 | 651 | ||
652 | err_irq: | ||
653 | free_irq(irq_level, shpnt); | ||
648 | err_unmap: | 654 | err_unmap: |
649 | dma_unmap_single (&edev->dev, host->ecb_dma_addr, | 655 | dma_unmap_single (&edev->dev, host->ecb_dma_addr, |
650 | sizeof (host->ecb), DMA_BIDIRECTIONAL); | 656 | sizeof (host->ecb), DMA_BIDIRECTIONAL); |
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index 2001fe890e71..1a3ab6aa856b 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c | |||
@@ -62,6 +62,7 @@ static struct pci_device_id ahd_linux_pci_id_table[] = { | |||
62 | /* aic7901 based controllers */ | 62 | /* aic7901 based controllers */ |
63 | ID(ID_AHA_29320A), | 63 | ID(ID_AHA_29320A), |
64 | ID(ID_AHA_29320ALP), | 64 | ID(ID_AHA_29320ALP), |
65 | ID(ID_AHA_29320LPE), | ||
65 | /* aic7902 based controllers */ | 66 | /* aic7902 based controllers */ |
66 | ID(ID_AHA_29320), | 67 | ID(ID_AHA_29320), |
67 | ID(ID_AHA_29320B), | 68 | ID(ID_AHA_29320B), |
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c index c07735819cd1..2cf7bb3123f0 100644 --- a/drivers/scsi/aic7xxx/aic79xx_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_pci.c | |||
@@ -109,7 +109,13 @@ static struct ahd_pci_identity ahd_pci_ident_table [] = | |||
109 | { | 109 | { |
110 | ID_AHA_29320ALP, | 110 | ID_AHA_29320ALP, |
111 | ID_ALL_MASK, | 111 | ID_ALL_MASK, |
112 | "Adaptec 29320ALP Ultra320 SCSI adapter", | 112 | "Adaptec 29320ALP PCIx Ultra320 SCSI adapter", |
113 | ahd_aic7901_setup | ||
114 | }, | ||
115 | { | ||
116 | ID_AHA_29320LPE, | ||
117 | ID_ALL_MASK, | ||
118 | "Adaptec 29320LPE PCIe Ultra320 SCSI adapter", | ||
113 | ahd_aic7901_setup | 119 | ahd_aic7901_setup |
114 | }, | 120 | }, |
115 | /* aic7901A based controllers */ | 121 | /* aic7901A based controllers */ |
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.h b/drivers/scsi/aic7xxx/aic79xx_pci.h index da45153668c7..16b7c70a673c 100644 --- a/drivers/scsi/aic7xxx/aic79xx_pci.h +++ b/drivers/scsi/aic7xxx/aic79xx_pci.h | |||
@@ -51,6 +51,7 @@ | |||
51 | #define ID_AIC7901 0x800F9005FFFF9005ull | 51 | #define ID_AIC7901 0x800F9005FFFF9005ull |
52 | #define ID_AHA_29320A 0x8000900500609005ull | 52 | #define ID_AHA_29320A 0x8000900500609005ull |
53 | #define ID_AHA_29320ALP 0x8017900500449005ull | 53 | #define ID_AHA_29320ALP 0x8017900500449005ull |
54 | #define ID_AHA_29320LPE 0x8017900500459005ull | ||
54 | 55 | ||
55 | #define ID_AIC7901A 0x801E9005FFFF9005ull | 56 | #define ID_AIC7901A 0x801E9005FFFF9005ull |
56 | #define ID_AHA_29320LP 0x8014900500449005ull | 57 | #define ID_AHA_29320LP 0x8014900500449005ull |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 57c5ba4043f2..42302ef05ee5 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -724,6 +724,15 @@ static void asd_free_queues(struct asd_ha_struct *asd_ha) | |||
724 | 724 | ||
725 | list_for_each_safe(pos, n, &pending) { | 725 | list_for_each_safe(pos, n, &pending) { |
726 | struct asd_ascb *ascb = list_entry(pos, struct asd_ascb, list); | 726 | struct asd_ascb *ascb = list_entry(pos, struct asd_ascb, list); |
727 | /* | ||
728 | * Delete unexpired ascb timers. This may happen if we issue | ||
729 | * a CONTROL PHY scb to an adapter and rmmod before the scb | ||
730 | * times out. Apparently we don't wait for the CONTROL PHY | ||
731 | * to complete, so it doesn't matter if we kill the timer. | ||
732 | */ | ||
733 | del_timer_sync(&ascb->timer); | ||
734 | WARN_ON(ascb->scb->header.opcode != CONTROL_PHY); | ||
735 | |||
727 | list_del_init(pos); | 736 | list_del_init(pos); |
728 | ASD_DPRINTK("freeing from pending\n"); | 737 | ASD_DPRINTK("freeing from pending\n"); |
729 | asd_ascb_free(ascb); | 738 | asd_ascb_free(ascb); |
diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index b15caf1c8fa2..75ed6b0569d1 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c | |||
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
28 | #include <scsi/scsi_host.h> | ||
28 | 29 | ||
29 | #include "aic94xx.h" | 30 | #include "aic94xx.h" |
30 | #include "aic94xx_reg.h" | 31 | #include "aic94xx_reg.h" |
@@ -412,6 +413,40 @@ void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id) | |||
412 | } | 413 | } |
413 | } | 414 | } |
414 | 415 | ||
416 | /* hard reset a phy later */ | ||
417 | static void do_phy_reset_later(struct work_struct *work) | ||
418 | { | ||
419 | struct sas_phy *sas_phy = | ||
420 | container_of(work, struct sas_phy, reset_work); | ||
421 | int error; | ||
422 | |||
423 | ASD_DPRINTK("%s: About to hard reset phy %d\n", __FUNCTION__, | ||
424 | sas_phy->identify.phy_identifier); | ||
425 | /* Reset device port */ | ||
426 | error = sas_phy_reset(sas_phy, 1); | ||
427 | if (error) | ||
428 | ASD_DPRINTK("%s: Hard reset of phy %d failed (%d).\n", | ||
429 | __FUNCTION__, sas_phy->identify.phy_identifier, error); | ||
430 | } | ||
431 | |||
432 | static void phy_reset_later(struct sas_phy *sas_phy, struct Scsi_Host *shost) | ||
433 | { | ||
434 | INIT_WORK(&sas_phy->reset_work, do_phy_reset_later); | ||
435 | queue_work(shost->work_q, &sas_phy->reset_work); | ||
436 | } | ||
437 | |||
438 | /* start up the ABORT TASK tmf... */ | ||
439 | static void task_kill_later(struct asd_ascb *ascb) | ||
440 | { | ||
441 | struct asd_ha_struct *asd_ha = ascb->ha; | ||
442 | struct sas_ha_struct *sas_ha = &asd_ha->sas_ha; | ||
443 | struct Scsi_Host *shost = sas_ha->core.shost; | ||
444 | struct sas_task *task = ascb->uldd_task; | ||
445 | |||
446 | INIT_WORK(&task->abort_work, sas_task_abort); | ||
447 | queue_work(shost->work_q, &task->abort_work); | ||
448 | } | ||
449 | |||
415 | static void escb_tasklet_complete(struct asd_ascb *ascb, | 450 | static void escb_tasklet_complete(struct asd_ascb *ascb, |
416 | struct done_list_struct *dl) | 451 | struct done_list_struct *dl) |
417 | { | 452 | { |
@@ -439,6 +474,74 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
439 | ascb->scb->header.opcode); | 474 | ascb->scb->header.opcode); |
440 | } | 475 | } |
441 | 476 | ||
477 | /* Catch these before we mask off the sb_opcode bits */ | ||
478 | switch (sb_opcode) { | ||
479 | case REQ_TASK_ABORT: { | ||
480 | struct asd_ascb *a, *b; | ||
481 | u16 tc_abort; | ||
482 | |||
483 | tc_abort = *((u16*)(&dl->status_block[1])); | ||
484 | tc_abort = le16_to_cpu(tc_abort); | ||
485 | |||
486 | ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n", | ||
487 | __FUNCTION__, dl->status_block[3]); | ||
488 | |||
489 | /* Find the pending task and abort it. */ | ||
490 | list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list) | ||
491 | if (a->tc_index == tc_abort) { | ||
492 | task_kill_later(a); | ||
493 | break; | ||
494 | } | ||
495 | goto out; | ||
496 | } | ||
497 | case REQ_DEVICE_RESET: { | ||
498 | struct Scsi_Host *shost = sas_ha->core.shost; | ||
499 | struct sas_phy *dev_phy; | ||
500 | struct asd_ascb *a; | ||
501 | u16 conn_handle; | ||
502 | |||
503 | conn_handle = *((u16*)(&dl->status_block[1])); | ||
504 | conn_handle = le16_to_cpu(conn_handle); | ||
505 | |||
506 | ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__, | ||
507 | dl->status_block[3]); | ||
508 | |||
509 | /* Kill all pending tasks and reset the device */ | ||
510 | dev_phy = NULL; | ||
511 | list_for_each_entry(a, &asd_ha->seq.pend_q, list) { | ||
512 | struct sas_task *task; | ||
513 | struct domain_device *dev; | ||
514 | u16 x; | ||
515 | |||
516 | task = a->uldd_task; | ||
517 | if (!task) | ||
518 | continue; | ||
519 | dev = task->dev; | ||
520 | |||
521 | x = (unsigned long)dev->lldd_dev; | ||
522 | if (x == conn_handle) { | ||
523 | dev_phy = dev->port->phy; | ||
524 | task_kill_later(a); | ||
525 | } | ||
526 | } | ||
527 | |||
528 | /* Reset device port */ | ||
529 | if (!dev_phy) { | ||
530 | ASD_DPRINTK("%s: No pending commands; can't reset.\n", | ||
531 | __FUNCTION__); | ||
532 | goto out; | ||
533 | } | ||
534 | phy_reset_later(dev_phy, shost); | ||
535 | goto out; | ||
536 | } | ||
537 | case SIGNAL_NCQ_ERROR: | ||
538 | ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __FUNCTION__); | ||
539 | goto out; | ||
540 | case CLEAR_NCQ_ERROR: | ||
541 | ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __FUNCTION__); | ||
542 | goto out; | ||
543 | } | ||
544 | |||
442 | sb_opcode &= ~DL_PHY_MASK; | 545 | sb_opcode &= ~DL_PHY_MASK; |
443 | 546 | ||
444 | switch (sb_opcode) { | 547 | switch (sb_opcode) { |
@@ -469,22 +572,6 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
469 | asd_deform_port(asd_ha, phy); | 572 | asd_deform_port(asd_ha, phy); |
470 | sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); | 573 | sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT); |
471 | break; | 574 | break; |
472 | case REQ_TASK_ABORT: | ||
473 | ASD_DPRINTK("%s: phy%d: REQ_TASK_ABORT\n", __FUNCTION__, | ||
474 | phy_id); | ||
475 | break; | ||
476 | case REQ_DEVICE_RESET: | ||
477 | ASD_DPRINTK("%s: phy%d: REQ_DEVICE_RESET\n", __FUNCTION__, | ||
478 | phy_id); | ||
479 | break; | ||
480 | case SIGNAL_NCQ_ERROR: | ||
481 | ASD_DPRINTK("%s: phy%d: SIGNAL_NCQ_ERROR\n", __FUNCTION__, | ||
482 | phy_id); | ||
483 | break; | ||
484 | case CLEAR_NCQ_ERROR: | ||
485 | ASD_DPRINTK("%s: phy%d: CLEAR_NCQ_ERROR\n", __FUNCTION__, | ||
486 | phy_id); | ||
487 | break; | ||
488 | default: | 575 | default: |
489 | ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__, | 576 | ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__, |
490 | phy_id, sb_opcode); | 577 | phy_id, sb_opcode); |
@@ -504,7 +591,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb, | |||
504 | 591 | ||
505 | break; | 592 | break; |
506 | } | 593 | } |
507 | 594 | out: | |
508 | asd_invalidate_edb(ascb, edb); | 595 | asd_invalidate_edb(ascb, edb); |
509 | } | 596 | } |
510 | 597 | ||
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c index ef8285c326e4..668569e8856b 100644 --- a/drivers/scsi/fd_mcs.c +++ b/drivers/scsi/fd_mcs.c | |||
@@ -294,6 +294,7 @@ static struct Scsi_Host *hosts[FD_MAX_HOSTS + 1] = { NULL }; | |||
294 | static int user_fifo_count = 0; | 294 | static int user_fifo_count = 0; |
295 | static int user_fifo_size = 0; | 295 | static int user_fifo_size = 0; |
296 | 296 | ||
297 | #ifndef MODULE | ||
297 | static int __init fd_mcs_setup(char *str) | 298 | static int __init fd_mcs_setup(char *str) |
298 | { | 299 | { |
299 | static int done_setup = 0; | 300 | static int done_setup = 0; |
@@ -311,6 +312,7 @@ static int __init fd_mcs_setup(char *str) | |||
311 | } | 312 | } |
312 | 313 | ||
313 | __setup("fd_mcs=", fd_mcs_setup); | 314 | __setup("fd_mcs=", fd_mcs_setup); |
315 | #endif /* !MODULE */ | ||
314 | 316 | ||
315 | static void print_banner(struct Scsi_Host *shpnt) | 317 | static void print_banner(struct Scsi_Host *shpnt) |
316 | { | 318 | { |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 68ef1636678d..38c3a291efac 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -263,6 +263,10 @@ static void scsi_host_dev_release(struct device *dev) | |||
263 | kthread_stop(shost->ehandler); | 263 | kthread_stop(shost->ehandler); |
264 | if (shost->work_q) | 264 | if (shost->work_q) |
265 | destroy_workqueue(shost->work_q); | 265 | destroy_workqueue(shost->work_q); |
266 | if (shost->uspace_req_q) { | ||
267 | kfree(shost->uspace_req_q->queuedata); | ||
268 | scsi_free_queue(shost->uspace_req_q); | ||
269 | } | ||
266 | 270 | ||
267 | scsi_destroy_command_freelist(shost); | 271 | scsi_destroy_command_freelist(shost); |
268 | if (shost->bqt) | 272 | if (shost->bqt) |
@@ -301,8 +305,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
301 | if (!shost) | 305 | if (!shost) |
302 | return NULL; | 306 | return NULL; |
303 | 307 | ||
304 | spin_lock_init(&shost->default_lock); | 308 | shost->host_lock = &shost->default_lock; |
305 | scsi_assign_lock(shost, &shost->default_lock); | 309 | spin_lock_init(shost->host_lock); |
306 | shost->shost_state = SHOST_CREATED; | 310 | shost->shost_state = SHOST_CREATED; |
307 | INIT_LIST_HEAD(&shost->__devices); | 311 | INIT_LIST_HEAD(&shost->__devices); |
308 | INIT_LIST_HEAD(&shost->__targets); | 312 | INIT_LIST_HEAD(&shost->__targets); |
diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile index 4e247b6b8700..6ac0633d5452 100644 --- a/drivers/scsi/ibmvscsi/Makefile +++ b/drivers/scsi/ibmvscsi/Makefile | |||
@@ -3,3 +3,5 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o | |||
3 | ibmvscsic-y += ibmvscsi.o | 3 | ibmvscsic-y += ibmvscsi.o |
4 | ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o | 4 | ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o |
5 | ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o | 5 | ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o |
6 | |||
7 | obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o | ||
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c new file mode 100644 index 000000000000..e28260f05d6b --- /dev/null +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c | |||
@@ -0,0 +1,960 @@ | |||
1 | /* | ||
2 | * IBM eServer i/pSeries Virtual SCSI Target Driver | ||
3 | * Copyright (C) 2003-2005 Dave Boutcher (boutcher@us.ibm.com) IBM Corp. | ||
4 | * Santiago Leon (santil@us.ibm.com) IBM Corp. | ||
5 | * Linda Xie (lxie@us.ibm.com) IBM Corp. | ||
6 | * | ||
7 | * Copyright (C) 2005-2006 FUJITA Tomonori <tomof@acm.org> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
22 | * USA | ||
23 | */ | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <scsi/scsi.h> | ||
27 | #include <scsi/scsi_host.h> | ||
28 | #include <scsi/scsi_tgt.h> | ||
29 | #include <scsi/libsrp.h> | ||
30 | #include <asm/hvcall.h> | ||
31 | #include <asm/iommu.h> | ||
32 | #include <asm/prom.h> | ||
33 | #include <asm/vio.h> | ||
34 | |||
35 | #include "ibmvscsi.h" | ||
36 | |||
37 | #define INITIAL_SRP_LIMIT 16 | ||
38 | #define DEFAULT_MAX_SECTORS 512 | ||
39 | |||
40 | #define TGT_NAME "ibmvstgt" | ||
41 | |||
42 | /* | ||
43 | * Hypervisor calls. | ||
44 | */ | ||
45 | #define h_copy_rdma(l, sa, sb, da, db) \ | ||
46 | plpar_hcall_norets(H_COPY_RDMA, l, sa, sb, da, db) | ||
47 | #define h_send_crq(ua, l, h) \ | ||
48 | plpar_hcall_norets(H_SEND_CRQ, ua, l, h) | ||
49 | #define h_reg_crq(ua, tok, sz)\ | ||
50 | plpar_hcall_norets(H_REG_CRQ, ua, tok, sz); | ||
51 | #define h_free_crq(ua) \ | ||
52 | plpar_hcall_norets(H_FREE_CRQ, ua); | ||
53 | |||
54 | /* tmp - will replace with SCSI logging stuff */ | ||
55 | #define eprintk(fmt, args...) \ | ||
56 | do { \ | ||
57 | printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ | ||
58 | } while (0) | ||
59 | /* #define dprintk eprintk */ | ||
60 | #define dprintk(fmt, args...) | ||
61 | |||
62 | struct vio_port { | ||
63 | struct vio_dev *dma_dev; | ||
64 | |||
65 | struct crq_queue crq_queue; | ||
66 | struct work_struct crq_work; | ||
67 | |||
68 | unsigned long liobn; | ||
69 | unsigned long riobn; | ||
70 | struct srp_target *target; | ||
71 | }; | ||
72 | |||
73 | static struct workqueue_struct *vtgtd; | ||
74 | |||
75 | /* | ||
76 | * These are fixed for the system and come from the Open Firmware device tree. | ||
77 | * We just store them here to save getting them every time. | ||
78 | */ | ||
79 | static char system_id[64] = ""; | ||
80 | static char partition_name[97] = "UNKNOWN"; | ||
81 | static unsigned int partition_number = -1; | ||
82 | |||
83 | static struct vio_port *target_to_port(struct srp_target *target) | ||
84 | { | ||
85 | return (struct vio_port *) target->ldata; | ||
86 | } | ||
87 | |||
88 | static inline union viosrp_iu *vio_iu(struct iu_entry *iue) | ||
89 | { | ||
90 | return (union viosrp_iu *) (iue->sbuf->buf); | ||
91 | } | ||
92 | |||
93 | static int send_iu(struct iu_entry *iue, uint64_t length, uint8_t format) | ||
94 | { | ||
95 | struct srp_target *target = iue->target; | ||
96 | struct vio_port *vport = target_to_port(target); | ||
97 | long rc, rc1; | ||
98 | union { | ||
99 | struct viosrp_crq cooked; | ||
100 | uint64_t raw[2]; | ||
101 | } crq; | ||
102 | |||
103 | /* First copy the SRP */ | ||
104 | rc = h_copy_rdma(length, vport->liobn, iue->sbuf->dma, | ||
105 | vport->riobn, iue->remote_token); | ||
106 | |||
107 | if (rc) | ||
108 | eprintk("Error %ld transferring data\n", rc); | ||
109 | |||
110 | crq.cooked.valid = 0x80; | ||
111 | crq.cooked.format = format; | ||
112 | crq.cooked.reserved = 0x00; | ||
113 | crq.cooked.timeout = 0x00; | ||
114 | crq.cooked.IU_length = length; | ||
115 | crq.cooked.IU_data_ptr = vio_iu(iue)->srp.rsp.tag; | ||
116 | |||
117 | if (rc == 0) | ||
118 | crq.cooked.status = 0x99; /* Just needs to be non-zero */ | ||
119 | else | ||
120 | crq.cooked.status = 0x00; | ||
121 | |||
122 | rc1 = h_send_crq(vport->dma_dev->unit_address, crq.raw[0], crq.raw[1]); | ||
123 | |||
124 | if (rc1) { | ||
125 | eprintk("%ld sending response\n", rc1); | ||
126 | return rc1; | ||
127 | } | ||
128 | |||
129 | return rc; | ||
130 | } | ||
131 | |||
132 | #define SRP_RSP_SENSE_DATA_LEN 18 | ||
133 | |||
134 | static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc, | ||
135 | unsigned char status, unsigned char asc) | ||
136 | { | ||
137 | union viosrp_iu *iu = vio_iu(iue); | ||
138 | uint64_t tag = iu->srp.rsp.tag; | ||
139 | |||
140 | /* If the linked bit is on and status is good */ | ||
141 | if (test_bit(V_LINKED, &iue->flags) && (status == NO_SENSE)) | ||
142 | status = 0x10; | ||
143 | |||
144 | memset(iu, 0, sizeof(struct srp_rsp)); | ||
145 | iu->srp.rsp.opcode = SRP_RSP; | ||
146 | iu->srp.rsp.req_lim_delta = 1; | ||
147 | iu->srp.rsp.tag = tag; | ||
148 | |||
149 | if (test_bit(V_DIOVER, &iue->flags)) | ||
150 | iu->srp.rsp.flags |= SRP_RSP_FLAG_DIOVER; | ||
151 | |||
152 | iu->srp.rsp.data_in_res_cnt = 0; | ||
153 | iu->srp.rsp.data_out_res_cnt = 0; | ||
154 | |||
155 | iu->srp.rsp.flags &= ~SRP_RSP_FLAG_RSPVALID; | ||
156 | |||
157 | iu->srp.rsp.resp_data_len = 0; | ||
158 | iu->srp.rsp.status = status; | ||
159 | if (status) { | ||
160 | uint8_t *sense = iu->srp.rsp.data; | ||
161 | |||
162 | if (sc) { | ||
163 | iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; | ||
164 | iu->srp.rsp.sense_data_len = SCSI_SENSE_BUFFERSIZE; | ||
165 | memcpy(sense, sc->sense_buffer, SCSI_SENSE_BUFFERSIZE); | ||
166 | } else { | ||
167 | iu->srp.rsp.status = SAM_STAT_CHECK_CONDITION; | ||
168 | iu->srp.rsp.flags |= SRP_RSP_FLAG_SNSVALID; | ||
169 | iu->srp.rsp.sense_data_len = SRP_RSP_SENSE_DATA_LEN; | ||
170 | |||
171 | /* Valid bit and 'current errors' */ | ||
172 | sense[0] = (0x1 << 7 | 0x70); | ||
173 | /* Sense key */ | ||
174 | sense[2] = status; | ||
175 | /* Additional sense length */ | ||
176 | sense[7] = 0xa; /* 10 bytes */ | ||
177 | /* Additional sense code */ | ||
178 | sense[12] = asc; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | send_iu(iue, sizeof(iu->srp.rsp) + SRP_RSP_SENSE_DATA_LEN, | ||
183 | VIOSRP_SRP_FORMAT); | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static void handle_cmd_queue(struct srp_target *target) | ||
189 | { | ||
190 | struct Scsi_Host *shost = target->shost; | ||
191 | struct iu_entry *iue; | ||
192 | struct srp_cmd *cmd; | ||
193 | unsigned long flags; | ||
194 | int err; | ||
195 | |||
196 | retry: | ||
197 | spin_lock_irqsave(&target->lock, flags); | ||
198 | |||
199 | list_for_each_entry(iue, &target->cmd_queue, ilist) { | ||
200 | if (!test_and_set_bit(V_FLYING, &iue->flags)) { | ||
201 | spin_unlock_irqrestore(&target->lock, flags); | ||
202 | cmd = iue->sbuf->buf; | ||
203 | err = srp_cmd_queue(shost, cmd, iue, 0); | ||
204 | if (err) { | ||
205 | eprintk("cannot queue cmd %p %d\n", cmd, err); | ||
206 | srp_iu_put(iue); | ||
207 | } | ||
208 | goto retry; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | spin_unlock_irqrestore(&target->lock, flags); | ||
213 | } | ||
214 | |||
215 | static int ibmvstgt_rdma(struct scsi_cmnd *sc, struct scatterlist *sg, int nsg, | ||
216 | struct srp_direct_buf *md, int nmd, | ||
217 | enum dma_data_direction dir, unsigned int rest) | ||
218 | { | ||
219 | struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; | ||
220 | struct srp_target *target = iue->target; | ||
221 | struct vio_port *vport = target_to_port(target); | ||
222 | dma_addr_t token; | ||
223 | long err; | ||
224 | unsigned int done = 0; | ||
225 | int i, sidx, soff; | ||
226 | |||
227 | sidx = soff = 0; | ||
228 | token = sg_dma_address(sg + sidx); | ||
229 | |||
230 | for (i = 0; i < nmd && rest; i++) { | ||
231 | unsigned int mdone, mlen; | ||
232 | |||
233 | mlen = min(rest, md[i].len); | ||
234 | for (mdone = 0; mlen;) { | ||
235 | int slen = min(sg_dma_len(sg + sidx) - soff, mlen); | ||
236 | |||
237 | if (dir == DMA_TO_DEVICE) | ||
238 | err = h_copy_rdma(slen, | ||
239 | vport->riobn, | ||
240 | md[i].va + mdone, | ||
241 | vport->liobn, | ||
242 | token + soff); | ||
243 | else | ||
244 | err = h_copy_rdma(slen, | ||
245 | vport->liobn, | ||
246 | token + soff, | ||
247 | vport->riobn, | ||
248 | md[i].va + mdone); | ||
249 | |||
250 | if (err != H_SUCCESS) { | ||
251 | eprintk("rdma error %d %d\n", dir, slen); | ||
252 | goto out; | ||
253 | } | ||
254 | |||
255 | mlen -= slen; | ||
256 | mdone += slen; | ||
257 | soff += slen; | ||
258 | done += slen; | ||
259 | |||
260 | if (soff == sg_dma_len(sg + sidx)) { | ||
261 | sidx++; | ||
262 | soff = 0; | ||
263 | token = sg_dma_address(sg + sidx); | ||
264 | |||
265 | if (sidx > nsg) { | ||
266 | eprintk("out of sg %p %d %d\n", | ||
267 | iue, sidx, nsg); | ||
268 | goto out; | ||
269 | } | ||
270 | } | ||
271 | }; | ||
272 | |||
273 | rest -= mlen; | ||
274 | } | ||
275 | out: | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | static int ibmvstgt_transfer_data(struct scsi_cmnd *sc, | ||
281 | void (*done)(struct scsi_cmnd *)) | ||
282 | { | ||
283 | struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; | ||
284 | int err; | ||
285 | |||
286 | err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); | ||
287 | |||
288 | done(sc); | ||
289 | |||
290 | return err; | ||
291 | } | ||
292 | |||
293 | static int ibmvstgt_cmd_done(struct scsi_cmnd *sc, | ||
294 | void (*done)(struct scsi_cmnd *)) | ||
295 | { | ||
296 | unsigned long flags; | ||
297 | struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; | ||
298 | struct srp_target *target = iue->target; | ||
299 | |||
300 | dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]); | ||
301 | |||
302 | spin_lock_irqsave(&target->lock, flags); | ||
303 | list_del(&iue->ilist); | ||
304 | spin_unlock_irqrestore(&target->lock, flags); | ||
305 | |||
306 | if (sc->result != SAM_STAT_GOOD) { | ||
307 | eprintk("operation failed %p %d %x\n", | ||
308 | iue, sc->result, vio_iu(iue)->srp.cmd.cdb[0]); | ||
309 | send_rsp(iue, sc, HARDWARE_ERROR, 0x00); | ||
310 | } else | ||
311 | send_rsp(iue, sc, NO_SENSE, 0x00); | ||
312 | |||
313 | done(sc); | ||
314 | srp_iu_put(iue); | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | int send_adapter_info(struct iu_entry *iue, | ||
319 | dma_addr_t remote_buffer, uint16_t length) | ||
320 | { | ||
321 | struct srp_target *target = iue->target; | ||
322 | struct vio_port *vport = target_to_port(target); | ||
323 | struct Scsi_Host *shost = target->shost; | ||
324 | dma_addr_t data_token; | ||
325 | struct mad_adapter_info_data *info; | ||
326 | int err; | ||
327 | |||
328 | info = dma_alloc_coherent(target->dev, sizeof(*info), &data_token, | ||
329 | GFP_KERNEL); | ||
330 | if (!info) { | ||
331 | eprintk("bad dma_alloc_coherent %p\n", target); | ||
332 | return 1; | ||
333 | } | ||
334 | |||
335 | /* Get remote info */ | ||
336 | err = h_copy_rdma(sizeof(*info), vport->riobn, remote_buffer, | ||
337 | vport->liobn, data_token); | ||
338 | if (err == H_SUCCESS) { | ||
339 | dprintk("Client connect: %s (%d)\n", | ||
340 | info->partition_name, info->partition_number); | ||
341 | } | ||
342 | |||
343 | memset(info, 0, sizeof(*info)); | ||
344 | |||
345 | strcpy(info->srp_version, "16.a"); | ||
346 | strncpy(info->partition_name, partition_name, | ||
347 | sizeof(info->partition_name)); | ||
348 | info->partition_number = partition_number; | ||
349 | info->mad_version = 1; | ||
350 | info->os_type = 2; | ||
351 | info->port_max_txu[0] = shost->hostt->max_sectors << 9; | ||
352 | |||
353 | /* Send our info to remote */ | ||
354 | err = h_copy_rdma(sizeof(*info), vport->liobn, data_token, | ||
355 | vport->riobn, remote_buffer); | ||
356 | |||
357 | dma_free_coherent(target->dev, sizeof(*info), info, data_token); | ||
358 | |||
359 | if (err != H_SUCCESS) { | ||
360 | eprintk("Error sending adapter info %d\n", err); | ||
361 | return 1; | ||
362 | } | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | static void process_login(struct iu_entry *iue) | ||
368 | { | ||
369 | union viosrp_iu *iu = vio_iu(iue); | ||
370 | struct srp_login_rsp *rsp = &iu->srp.login_rsp; | ||
371 | uint64_t tag = iu->srp.rsp.tag; | ||
372 | |||
373 | /* TODO handle case that requested size is wrong and | ||
374 | * buffer format is wrong | ||
375 | */ | ||
376 | memset(iu, 0, sizeof(struct srp_login_rsp)); | ||
377 | rsp->opcode = SRP_LOGIN_RSP; | ||
378 | rsp->req_lim_delta = INITIAL_SRP_LIMIT; | ||
379 | rsp->tag = tag; | ||
380 | rsp->max_it_iu_len = sizeof(union srp_iu); | ||
381 | rsp->max_ti_iu_len = sizeof(union srp_iu); | ||
382 | /* direct and indirect */ | ||
383 | rsp->buf_fmt = SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT; | ||
384 | |||
385 | send_iu(iue, sizeof(*rsp), VIOSRP_SRP_FORMAT); | ||
386 | } | ||
387 | |||
388 | static inline void queue_cmd(struct iu_entry *iue) | ||
389 | { | ||
390 | struct srp_target *target = iue->target; | ||
391 | unsigned long flags; | ||
392 | |||
393 | spin_lock_irqsave(&target->lock, flags); | ||
394 | list_add_tail(&iue->ilist, &target->cmd_queue); | ||
395 | spin_unlock_irqrestore(&target->lock, flags); | ||
396 | } | ||
397 | |||
398 | static int process_tsk_mgmt(struct iu_entry *iue) | ||
399 | { | ||
400 | union viosrp_iu *iu = vio_iu(iue); | ||
401 | int fn; | ||
402 | |||
403 | dprintk("%p %u\n", iue, iu->srp.tsk_mgmt.tsk_mgmt_func); | ||
404 | |||
405 | switch (iu->srp.tsk_mgmt.tsk_mgmt_func) { | ||
406 | case SRP_TSK_ABORT_TASK: | ||
407 | fn = ABORT_TASK; | ||
408 | break; | ||
409 | case SRP_TSK_ABORT_TASK_SET: | ||
410 | fn = ABORT_TASK_SET; | ||
411 | break; | ||
412 | case SRP_TSK_CLEAR_TASK_SET: | ||
413 | fn = CLEAR_TASK_SET; | ||
414 | break; | ||
415 | case SRP_TSK_LUN_RESET: | ||
416 | fn = LOGICAL_UNIT_RESET; | ||
417 | break; | ||
418 | case SRP_TSK_CLEAR_ACA: | ||
419 | fn = CLEAR_ACA; | ||
420 | break; | ||
421 | default: | ||
422 | fn = 0; | ||
423 | } | ||
424 | if (fn) | ||
425 | scsi_tgt_tsk_mgmt_request(iue->target->shost, fn, | ||
426 | iu->srp.tsk_mgmt.task_tag, | ||
427 | (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, | ||
428 | iue); | ||
429 | else | ||
430 | send_rsp(iue, NULL, ILLEGAL_REQUEST, 0x20); | ||
431 | |||
432 | return !fn; | ||
433 | } | ||
434 | |||
435 | static int process_mad_iu(struct iu_entry *iue) | ||
436 | { | ||
437 | union viosrp_iu *iu = vio_iu(iue); | ||
438 | struct viosrp_adapter_info *info; | ||
439 | struct viosrp_host_config *conf; | ||
440 | |||
441 | switch (iu->mad.empty_iu.common.type) { | ||
442 | case VIOSRP_EMPTY_IU_TYPE: | ||
443 | eprintk("%s\n", "Unsupported EMPTY MAD IU"); | ||
444 | break; | ||
445 | case VIOSRP_ERROR_LOG_TYPE: | ||
446 | eprintk("%s\n", "Unsupported ERROR LOG MAD IU"); | ||
447 | iu->mad.error_log.common.status = 1; | ||
448 | send_iu(iue, sizeof(iu->mad.error_log), VIOSRP_MAD_FORMAT); | ||
449 | break; | ||
450 | case VIOSRP_ADAPTER_INFO_TYPE: | ||
451 | info = &iu->mad.adapter_info; | ||
452 | info->common.status = send_adapter_info(iue, info->buffer, | ||
453 | info->common.length); | ||
454 | send_iu(iue, sizeof(*info), VIOSRP_MAD_FORMAT); | ||
455 | break; | ||
456 | case VIOSRP_HOST_CONFIG_TYPE: | ||
457 | conf = &iu->mad.host_config; | ||
458 | conf->common.status = 1; | ||
459 | send_iu(iue, sizeof(*conf), VIOSRP_MAD_FORMAT); | ||
460 | break; | ||
461 | default: | ||
462 | eprintk("Unknown type %u\n", iu->srp.rsp.opcode); | ||
463 | } | ||
464 | |||
465 | return 1; | ||
466 | } | ||
467 | |||
468 | static int process_srp_iu(struct iu_entry *iue) | ||
469 | { | ||
470 | union viosrp_iu *iu = vio_iu(iue); | ||
471 | int done = 1; | ||
472 | u8 opcode = iu->srp.rsp.opcode; | ||
473 | |||
474 | switch (opcode) { | ||
475 | case SRP_LOGIN_REQ: | ||
476 | process_login(iue); | ||
477 | break; | ||
478 | case SRP_TSK_MGMT: | ||
479 | done = process_tsk_mgmt(iue); | ||
480 | break; | ||
481 | case SRP_CMD: | ||
482 | queue_cmd(iue); | ||
483 | done = 0; | ||
484 | break; | ||
485 | case SRP_LOGIN_RSP: | ||
486 | case SRP_I_LOGOUT: | ||
487 | case SRP_T_LOGOUT: | ||
488 | case SRP_RSP: | ||
489 | case SRP_CRED_REQ: | ||
490 | case SRP_CRED_RSP: | ||
491 | case SRP_AER_REQ: | ||
492 | case SRP_AER_RSP: | ||
493 | eprintk("Unsupported type %u\n", opcode); | ||
494 | break; | ||
495 | default: | ||
496 | eprintk("Unknown type %u\n", opcode); | ||
497 | } | ||
498 | |||
499 | return done; | ||
500 | } | ||
501 | |||
502 | static void process_iu(struct viosrp_crq *crq, struct srp_target *target) | ||
503 | { | ||
504 | struct vio_port *vport = target_to_port(target); | ||
505 | struct iu_entry *iue; | ||
506 | long err, done; | ||
507 | |||
508 | iue = srp_iu_get(target); | ||
509 | if (!iue) { | ||
510 | eprintk("Error getting IU from pool, %p\n", target); | ||
511 | return; | ||
512 | } | ||
513 | |||
514 | iue->remote_token = crq->IU_data_ptr; | ||
515 | |||
516 | err = h_copy_rdma(crq->IU_length, vport->riobn, | ||
517 | iue->remote_token, vport->liobn, iue->sbuf->dma); | ||
518 | |||
519 | if (err != H_SUCCESS) { | ||
520 | eprintk("%ld transferring data error %p\n", err, iue); | ||
521 | done = 1; | ||
522 | goto out; | ||
523 | } | ||
524 | |||
525 | if (crq->format == VIOSRP_MAD_FORMAT) | ||
526 | done = process_mad_iu(iue); | ||
527 | else | ||
528 | done = process_srp_iu(iue); | ||
529 | out: | ||
530 | if (done) | ||
531 | srp_iu_put(iue); | ||
532 | } | ||
533 | |||
534 | static irqreturn_t ibmvstgt_interrupt(int irq, void *data) | ||
535 | { | ||
536 | struct srp_target *target = (struct srp_target *) data; | ||
537 | struct vio_port *vport = target_to_port(target); | ||
538 | |||
539 | vio_disable_interrupts(vport->dma_dev); | ||
540 | queue_work(vtgtd, &vport->crq_work); | ||
541 | |||
542 | return IRQ_HANDLED; | ||
543 | } | ||
544 | |||
545 | static int crq_queue_create(struct crq_queue *queue, struct srp_target *target) | ||
546 | { | ||
547 | int err; | ||
548 | struct vio_port *vport = target_to_port(target); | ||
549 | |||
550 | queue->msgs = (struct viosrp_crq *) get_zeroed_page(GFP_KERNEL); | ||
551 | if (!queue->msgs) | ||
552 | goto malloc_failed; | ||
553 | queue->size = PAGE_SIZE / sizeof(*queue->msgs); | ||
554 | |||
555 | queue->msg_token = dma_map_single(target->dev, queue->msgs, | ||
556 | queue->size * sizeof(*queue->msgs), | ||
557 | DMA_BIDIRECTIONAL); | ||
558 | |||
559 | if (dma_mapping_error(queue->msg_token)) | ||
560 | goto map_failed; | ||
561 | |||
562 | err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token, | ||
563 | PAGE_SIZE); | ||
564 | |||
565 | /* If the adapter was left active for some reason (like kexec) | ||
566 | * try freeing and re-registering | ||
567 | */ | ||
568 | if (err == H_RESOURCE) { | ||
569 | do { | ||
570 | err = h_free_crq(vport->dma_dev->unit_address); | ||
571 | } while (err == H_BUSY || H_IS_LONG_BUSY(err)); | ||
572 | |||
573 | err = h_reg_crq(vport->dma_dev->unit_address, queue->msg_token, | ||
574 | PAGE_SIZE); | ||
575 | } | ||
576 | |||
577 | if (err != H_SUCCESS && err != 2) { | ||
578 | eprintk("Error 0x%x opening virtual adapter\n", err); | ||
579 | goto reg_crq_failed; | ||
580 | } | ||
581 | |||
582 | err = request_irq(vport->dma_dev->irq, &ibmvstgt_interrupt, | ||
583 | SA_INTERRUPT, "ibmvstgt", target); | ||
584 | if (err) | ||
585 | goto req_irq_failed; | ||
586 | |||
587 | vio_enable_interrupts(vport->dma_dev); | ||
588 | |||
589 | h_send_crq(vport->dma_dev->unit_address, 0xC001000000000000, 0); | ||
590 | |||
591 | queue->cur = 0; | ||
592 | spin_lock_init(&queue->lock); | ||
593 | |||
594 | return 0; | ||
595 | |||
596 | req_irq_failed: | ||
597 | do { | ||
598 | err = h_free_crq(vport->dma_dev->unit_address); | ||
599 | } while (err == H_BUSY || H_IS_LONG_BUSY(err)); | ||
600 | |||
601 | reg_crq_failed: | ||
602 | dma_unmap_single(target->dev, queue->msg_token, | ||
603 | queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); | ||
604 | map_failed: | ||
605 | free_page((unsigned long) queue->msgs); | ||
606 | |||
607 | malloc_failed: | ||
608 | return -ENOMEM; | ||
609 | } | ||
610 | |||
611 | static void crq_queue_destroy(struct srp_target *target) | ||
612 | { | ||
613 | struct vio_port *vport = target_to_port(target); | ||
614 | struct crq_queue *queue = &vport->crq_queue; | ||
615 | int err; | ||
616 | |||
617 | free_irq(vport->dma_dev->irq, target); | ||
618 | do { | ||
619 | err = h_free_crq(vport->dma_dev->unit_address); | ||
620 | } while (err == H_BUSY || H_IS_LONG_BUSY(err)); | ||
621 | |||
622 | dma_unmap_single(target->dev, queue->msg_token, | ||
623 | queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); | ||
624 | |||
625 | free_page((unsigned long) queue->msgs); | ||
626 | } | ||
627 | |||
628 | static void process_crq(struct viosrp_crq *crq, struct srp_target *target) | ||
629 | { | ||
630 | struct vio_port *vport = target_to_port(target); | ||
631 | dprintk("%x %x\n", crq->valid, crq->format); | ||
632 | |||
633 | switch (crq->valid) { | ||
634 | case 0xC0: | ||
635 | /* initialization */ | ||
636 | switch (crq->format) { | ||
637 | case 0x01: | ||
638 | h_send_crq(vport->dma_dev->unit_address, | ||
639 | 0xC002000000000000, 0); | ||
640 | break; | ||
641 | case 0x02: | ||
642 | break; | ||
643 | default: | ||
644 | eprintk("Unknown format %u\n", crq->format); | ||
645 | } | ||
646 | break; | ||
647 | case 0xFF: | ||
648 | /* transport event */ | ||
649 | break; | ||
650 | case 0x80: | ||
651 | /* real payload */ | ||
652 | switch (crq->format) { | ||
653 | case VIOSRP_SRP_FORMAT: | ||
654 | case VIOSRP_MAD_FORMAT: | ||
655 | process_iu(crq, target); | ||
656 | break; | ||
657 | case VIOSRP_OS400_FORMAT: | ||
658 | case VIOSRP_AIX_FORMAT: | ||
659 | case VIOSRP_LINUX_FORMAT: | ||
660 | case VIOSRP_INLINE_FORMAT: | ||
661 | eprintk("Unsupported format %u\n", crq->format); | ||
662 | break; | ||
663 | default: | ||
664 | eprintk("Unknown format %u\n", crq->format); | ||
665 | } | ||
666 | break; | ||
667 | default: | ||
668 | eprintk("unknown message type 0x%02x!?\n", crq->valid); | ||
669 | } | ||
670 | } | ||
671 | |||
672 | static inline struct viosrp_crq *next_crq(struct crq_queue *queue) | ||
673 | { | ||
674 | struct viosrp_crq *crq; | ||
675 | unsigned long flags; | ||
676 | |||
677 | spin_lock_irqsave(&queue->lock, flags); | ||
678 | crq = &queue->msgs[queue->cur]; | ||
679 | if (crq->valid & 0x80) { | ||
680 | if (++queue->cur == queue->size) | ||
681 | queue->cur = 0; | ||
682 | } else | ||
683 | crq = NULL; | ||
684 | spin_unlock_irqrestore(&queue->lock, flags); | ||
685 | |||
686 | return crq; | ||
687 | } | ||
688 | |||
689 | static void handle_crq(struct work_struct *work) | ||
690 | { | ||
691 | struct vio_port *vport = container_of(work, struct vio_port, crq_work); | ||
692 | struct srp_target *target = vport->target; | ||
693 | struct viosrp_crq *crq; | ||
694 | int done = 0; | ||
695 | |||
696 | while (!done) { | ||
697 | while ((crq = next_crq(&vport->crq_queue)) != NULL) { | ||
698 | process_crq(crq, target); | ||
699 | crq->valid = 0x00; | ||
700 | } | ||
701 | |||
702 | vio_enable_interrupts(vport->dma_dev); | ||
703 | |||
704 | crq = next_crq(&vport->crq_queue); | ||
705 | if (crq) { | ||
706 | vio_disable_interrupts(vport->dma_dev); | ||
707 | process_crq(crq, target); | ||
708 | crq->valid = 0x00; | ||
709 | } else | ||
710 | done = 1; | ||
711 | } | ||
712 | |||
713 | handle_cmd_queue(target); | ||
714 | } | ||
715 | |||
716 | |||
717 | static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc) | ||
718 | { | ||
719 | unsigned long flags; | ||
720 | struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; | ||
721 | struct srp_target *target = iue->target; | ||
722 | |||
723 | dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]); | ||
724 | |||
725 | spin_lock_irqsave(&target->lock, flags); | ||
726 | list_del(&iue->ilist); | ||
727 | spin_unlock_irqrestore(&target->lock, flags); | ||
728 | |||
729 | srp_iu_put(iue); | ||
730 | |||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) | ||
735 | { | ||
736 | struct iu_entry *iue = (struct iu_entry *) ((void *) mid); | ||
737 | union viosrp_iu *iu = vio_iu(iue); | ||
738 | unsigned char status, asc; | ||
739 | |||
740 | eprintk("%p %d\n", iue, result); | ||
741 | status = NO_SENSE; | ||
742 | asc = 0; | ||
743 | |||
744 | switch (iu->srp.tsk_mgmt.tsk_mgmt_func) { | ||
745 | case SRP_TSK_ABORT_TASK: | ||
746 | asc = 0x14; | ||
747 | if (result) | ||
748 | status = ABORTED_COMMAND; | ||
749 | break; | ||
750 | default: | ||
751 | break; | ||
752 | } | ||
753 | |||
754 | send_rsp(iue, NULL, status, asc); | ||
755 | srp_iu_put(iue); | ||
756 | |||
757 | return 0; | ||
758 | } | ||
759 | |||
760 | static ssize_t system_id_show(struct class_device *cdev, char *buf) | ||
761 | { | ||
762 | return snprintf(buf, PAGE_SIZE, "%s\n", system_id); | ||
763 | } | ||
764 | |||
765 | static ssize_t partition_number_show(struct class_device *cdev, char *buf) | ||
766 | { | ||
767 | return snprintf(buf, PAGE_SIZE, "%x\n", partition_number); | ||
768 | } | ||
769 | |||
770 | static ssize_t unit_address_show(struct class_device *cdev, char *buf) | ||
771 | { | ||
772 | struct Scsi_Host *shost = class_to_shost(cdev); | ||
773 | struct srp_target *target = host_to_srp_target(shost); | ||
774 | struct vio_port *vport = target_to_port(target); | ||
775 | return snprintf(buf, PAGE_SIZE, "%x\n", vport->dma_dev->unit_address); | ||
776 | } | ||
777 | |||
778 | static CLASS_DEVICE_ATTR(system_id, S_IRUGO, system_id_show, NULL); | ||
779 | static CLASS_DEVICE_ATTR(partition_number, S_IRUGO, partition_number_show, NULL); | ||
780 | static CLASS_DEVICE_ATTR(unit_address, S_IRUGO, unit_address_show, NULL); | ||
781 | |||
782 | static struct class_device_attribute *ibmvstgt_attrs[] = { | ||
783 | &class_device_attr_system_id, | ||
784 | &class_device_attr_partition_number, | ||
785 | &class_device_attr_unit_address, | ||
786 | NULL, | ||
787 | }; | ||
788 | |||
789 | static struct scsi_host_template ibmvstgt_sht = { | ||
790 | .name = TGT_NAME, | ||
791 | .module = THIS_MODULE, | ||
792 | .can_queue = INITIAL_SRP_LIMIT, | ||
793 | .sg_tablesize = SG_ALL, | ||
794 | .use_clustering = DISABLE_CLUSTERING, | ||
795 | .max_sectors = DEFAULT_MAX_SECTORS, | ||
796 | .transfer_response = ibmvstgt_cmd_done, | ||
797 | .transfer_data = ibmvstgt_transfer_data, | ||
798 | .eh_abort_handler = ibmvstgt_eh_abort_handler, | ||
799 | .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, | ||
800 | .shost_attrs = ibmvstgt_attrs, | ||
801 | .proc_name = TGT_NAME, | ||
802 | }; | ||
803 | |||
804 | static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) | ||
805 | { | ||
806 | struct Scsi_Host *shost; | ||
807 | struct srp_target *target; | ||
808 | struct vio_port *vport; | ||
809 | unsigned int *dma, dma_size; | ||
810 | int err = -ENOMEM; | ||
811 | |||
812 | vport = kzalloc(sizeof(struct vio_port), GFP_KERNEL); | ||
813 | if (!vport) | ||
814 | return err; | ||
815 | shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); | ||
816 | if (!shost) | ||
817 | goto free_vport; | ||
818 | err = scsi_tgt_alloc_queue(shost); | ||
819 | if (err) | ||
820 | goto put_host; | ||
821 | |||
822 | target = host_to_srp_target(shost); | ||
823 | target->shost = shost; | ||
824 | vport->dma_dev = dev; | ||
825 | target->ldata = vport; | ||
826 | vport->target = target; | ||
827 | err = srp_target_alloc(target, &dev->dev, INITIAL_SRP_LIMIT, | ||
828 | SRP_MAX_IU_LEN); | ||
829 | if (err) | ||
830 | goto put_host; | ||
831 | |||
832 | dma = (unsigned int *) vio_get_attribute(dev, "ibm,my-dma-window", | ||
833 | &dma_size); | ||
834 | if (!dma || dma_size != 40) { | ||
835 | eprintk("Couldn't get window property %d\n", dma_size); | ||
836 | err = -EIO; | ||
837 | goto free_srp_target; | ||
838 | } | ||
839 | vport->liobn = dma[0]; | ||
840 | vport->riobn = dma[5]; | ||
841 | |||
842 | INIT_WORK(&vport->crq_work, handle_crq); | ||
843 | |||
844 | err = crq_queue_create(&vport->crq_queue, target); | ||
845 | if (err) | ||
846 | goto free_srp_target; | ||
847 | |||
848 | err = scsi_add_host(shost, target->dev); | ||
849 | if (err) | ||
850 | goto destroy_queue; | ||
851 | return 0; | ||
852 | |||
853 | destroy_queue: | ||
854 | crq_queue_destroy(target); | ||
855 | free_srp_target: | ||
856 | srp_target_free(target); | ||
857 | put_host: | ||
858 | scsi_host_put(shost); | ||
859 | free_vport: | ||
860 | kfree(vport); | ||
861 | return err; | ||
862 | } | ||
863 | |||
864 | static int ibmvstgt_remove(struct vio_dev *dev) | ||
865 | { | ||
866 | struct srp_target *target = (struct srp_target *) dev->dev.driver_data; | ||
867 | struct Scsi_Host *shost = target->shost; | ||
868 | struct vio_port *vport = target->ldata; | ||
869 | |||
870 | crq_queue_destroy(target); | ||
871 | scsi_remove_host(shost); | ||
872 | scsi_tgt_free_queue(shost); | ||
873 | srp_target_free(target); | ||
874 | kfree(vport); | ||
875 | scsi_host_put(shost); | ||
876 | return 0; | ||
877 | } | ||
878 | |||
879 | static struct vio_device_id ibmvstgt_device_table[] __devinitdata = { | ||
880 | {"v-scsi-host", "IBM,v-scsi-host"}, | ||
881 | {"",""} | ||
882 | }; | ||
883 | |||
884 | MODULE_DEVICE_TABLE(vio, ibmvstgt_device_table); | ||
885 | |||
886 | static struct vio_driver ibmvstgt_driver = { | ||
887 | .id_table = ibmvstgt_device_table, | ||
888 | .probe = ibmvstgt_probe, | ||
889 | .remove = ibmvstgt_remove, | ||
890 | .driver = { | ||
891 | .name = "ibmvscsis", | ||
892 | .owner = THIS_MODULE, | ||
893 | } | ||
894 | }; | ||
895 | |||
896 | static int get_system_info(void) | ||
897 | { | ||
898 | struct device_node *rootdn; | ||
899 | const char *id, *model, *name; | ||
900 | unsigned int *num; | ||
901 | |||
902 | rootdn = find_path_device("/"); | ||
903 | if (!rootdn) | ||
904 | return -ENOENT; | ||
905 | |||
906 | model = get_property(rootdn, "model", NULL); | ||
907 | id = get_property(rootdn, "system-id", NULL); | ||
908 | if (model && id) | ||
909 | snprintf(system_id, sizeof(system_id), "%s-%s", model, id); | ||
910 | |||
911 | name = get_property(rootdn, "ibm,partition-name", NULL); | ||
912 | if (name) | ||
913 | strncpy(partition_name, name, sizeof(partition_name)); | ||
914 | |||
915 | num = (unsigned int *) get_property(rootdn, "ibm,partition-no", NULL); | ||
916 | if (num) | ||
917 | partition_number = *num; | ||
918 | |||
919 | return 0; | ||
920 | } | ||
921 | |||
922 | static int ibmvstgt_init(void) | ||
923 | { | ||
924 | int err = -ENOMEM; | ||
925 | |||
926 | printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); | ||
927 | |||
928 | vtgtd = create_workqueue("ibmvtgtd"); | ||
929 | if (!vtgtd) | ||
930 | return err; | ||
931 | |||
932 | err = get_system_info(); | ||
933 | if (err) | ||
934 | goto destroy_wq; | ||
935 | |||
936 | err = vio_register_driver(&ibmvstgt_driver); | ||
937 | if (err) | ||
938 | goto destroy_wq; | ||
939 | |||
940 | return 0; | ||
941 | |||
942 | destroy_wq: | ||
943 | destroy_workqueue(vtgtd); | ||
944 | return err; | ||
945 | } | ||
946 | |||
947 | static void ibmvstgt_exit(void) | ||
948 | { | ||
949 | printk("Unregister IBM virtual SCSI driver\n"); | ||
950 | |||
951 | destroy_workqueue(vtgtd); | ||
952 | vio_unregister_driver(&ibmvstgt_driver); | ||
953 | } | ||
954 | |||
955 | MODULE_DESCRIPTION("IBM Virtual SCSI Target"); | ||
956 | MODULE_AUTHOR("Santiago Leon"); | ||
957 | MODULE_LICENSE("GPL"); | ||
958 | |||
959 | module_init(ibmvstgt_init); | ||
960 | module_exit(ibmvstgt_exit); | ||
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index e31f6122106f..0464c182c577 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c | |||
@@ -36,7 +36,7 @@ typedef struct { | |||
36 | int base_hi; /* Hi Base address for ECP-ISA chipset */ | 36 | int base_hi; /* Hi Base address for ECP-ISA chipset */ |
37 | int mode; /* Transfer mode */ | 37 | int mode; /* Transfer mode */ |
38 | struct scsi_cmnd *cur_cmd; /* Current queued command */ | 38 | struct scsi_cmnd *cur_cmd; /* Current queued command */ |
39 | struct work_struct imm_tq; /* Polling interrupt stuff */ | 39 | struct delayed_work imm_tq; /* Polling interrupt stuff */ |
40 | unsigned long jstart; /* Jiffies at start */ | 40 | unsigned long jstart; /* Jiffies at start */ |
41 | unsigned failed:1; /* Failure flag */ | 41 | unsigned failed:1; /* Failure flag */ |
42 | unsigned dp:1; /* Data phase present */ | 42 | unsigned dp:1; /* Data phase present */ |
@@ -733,9 +733,9 @@ static int imm_completion(struct scsi_cmnd *cmd) | |||
733 | * the scheduler's task queue to generate a stream of call-backs and | 733 | * the scheduler's task queue to generate a stream of call-backs and |
734 | * complete the request when the drive is ready. | 734 | * complete the request when the drive is ready. |
735 | */ | 735 | */ |
736 | static void imm_interrupt(void *data) | 736 | static void imm_interrupt(struct work_struct *work) |
737 | { | 737 | { |
738 | imm_struct *dev = (imm_struct *) data; | 738 | imm_struct *dev = container_of(work, imm_struct, imm_tq.work); |
739 | struct scsi_cmnd *cmd = dev->cur_cmd; | 739 | struct scsi_cmnd *cmd = dev->cur_cmd; |
740 | struct Scsi_Host *host = cmd->device->host; | 740 | struct Scsi_Host *host = cmd->device->host; |
741 | unsigned long flags; | 741 | unsigned long flags; |
@@ -745,7 +745,6 @@ static void imm_interrupt(void *data) | |||
745 | return; | 745 | return; |
746 | } | 746 | } |
747 | if (imm_engine(dev, cmd)) { | 747 | if (imm_engine(dev, cmd)) { |
748 | INIT_WORK(&dev->imm_tq, imm_interrupt, (void *) dev); | ||
749 | schedule_delayed_work(&dev->imm_tq, 1); | 748 | schedule_delayed_work(&dev->imm_tq, 1); |
750 | return; | 749 | return; |
751 | } | 750 | } |
@@ -953,8 +952,7 @@ static int imm_queuecommand(struct scsi_cmnd *cmd, | |||
953 | cmd->result = DID_ERROR << 16; /* default return code */ | 952 | cmd->result = DID_ERROR << 16; /* default return code */ |
954 | cmd->SCp.phase = 0; /* bus free */ | 953 | cmd->SCp.phase = 0; /* bus free */ |
955 | 954 | ||
956 | INIT_WORK(&dev->imm_tq, imm_interrupt, dev); | 955 | schedule_delayed_work(&dev->imm_tq, 0); |
957 | schedule_work(&dev->imm_tq); | ||
958 | 956 | ||
959 | imm_pb_claim(dev); | 957 | imm_pb_claim(dev); |
960 | 958 | ||
@@ -1225,7 +1223,7 @@ static int __imm_attach(struct parport *pb) | |||
1225 | else | 1223 | else |
1226 | ports = 8; | 1224 | ports = 8; |
1227 | 1225 | ||
1228 | INIT_WORK(&dev->imm_tq, imm_interrupt, dev); | 1226 | INIT_DELAYED_WORK(&dev->imm_tq, imm_interrupt); |
1229 | 1227 | ||
1230 | err = -ENOMEM; | 1228 | err = -ENOMEM; |
1231 | host = scsi_host_alloc(&imm_template, sizeof(imm_struct *)); | 1229 | host = scsi_host_alloc(&imm_template, sizeof(imm_struct *)); |
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index afed293dd7b9..f160357e37a6 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c | |||
@@ -170,7 +170,7 @@ static int setup_debug = 0; | |||
170 | static void i91uSCBPost(BYTE * pHcb, BYTE * pScb); | 170 | static void i91uSCBPost(BYTE * pHcb, BYTE * pScb); |
171 | 171 | ||
172 | /* PCI Devices supported by this driver */ | 172 | /* PCI Devices supported by this driver */ |
173 | static struct pci_device_id i91u_pci_devices[] __devinitdata = { | 173 | static struct pci_device_id i91u_pci_devices[] = { |
174 | { PCI_VENDOR_ID_INIT, I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 174 | { PCI_VENDOR_ID_INIT, I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
175 | { PCI_VENDOR_ID_INIT, I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 175 | { PCI_VENDOR_ID_INIT, I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
176 | { PCI_VENDOR_ID_INIT, I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 176 | { PCI_VENDOR_ID_INIT, I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 2dde821025f3..ccd4dafce8e2 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -79,7 +79,6 @@ | |||
79 | #include <scsi/scsi_tcq.h> | 79 | #include <scsi/scsi_tcq.h> |
80 | #include <scsi/scsi_eh.h> | 80 | #include <scsi/scsi_eh.h> |
81 | #include <scsi/scsi_cmnd.h> | 81 | #include <scsi/scsi_cmnd.h> |
82 | #include <scsi/scsi_transport.h> | ||
83 | #include "ipr.h" | 82 | #include "ipr.h" |
84 | 83 | ||
85 | /* | 84 | /* |
@@ -98,7 +97,7 @@ static DEFINE_SPINLOCK(ipr_driver_lock); | |||
98 | 97 | ||
99 | /* This table describes the differences between DMA controller chips */ | 98 | /* This table describes the differences between DMA controller chips */ |
100 | static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { | 99 | static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { |
101 | { /* Gemstone, Citrine, and Obsidian */ | 100 | { /* Gemstone, Citrine, Obsidian, and Obsidian-E */ |
102 | .mailbox = 0x0042C, | 101 | .mailbox = 0x0042C, |
103 | .cache_line_size = 0x20, | 102 | .cache_line_size = 0x20, |
104 | { | 103 | { |
@@ -135,6 +134,7 @@ static const struct ipr_chip_t ipr_chip[] = { | |||
135 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, &ipr_chip_cfg[0] }, | 134 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, &ipr_chip_cfg[0] }, |
136 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, &ipr_chip_cfg[0] }, | 135 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, &ipr_chip_cfg[0] }, |
137 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, &ipr_chip_cfg[0] }, | 136 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, &ipr_chip_cfg[0] }, |
137 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, &ipr_chip_cfg[0] }, | ||
138 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, &ipr_chip_cfg[1] }, | 138 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, &ipr_chip_cfg[1] }, |
139 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, &ipr_chip_cfg[1] } | 139 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, &ipr_chip_cfg[1] } |
140 | }; | 140 | }; |
@@ -1249,19 +1249,23 @@ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1249 | 1249 | ||
1250 | /** | 1250 | /** |
1251 | * ipr_log_hex_data - Log additional hex IOA error data. | 1251 | * ipr_log_hex_data - Log additional hex IOA error data. |
1252 | * @ioa_cfg: ioa config struct | ||
1252 | * @data: IOA error data | 1253 | * @data: IOA error data |
1253 | * @len: data length | 1254 | * @len: data length |
1254 | * | 1255 | * |
1255 | * Return value: | 1256 | * Return value: |
1256 | * none | 1257 | * none |
1257 | **/ | 1258 | **/ |
1258 | static void ipr_log_hex_data(u32 *data, int len) | 1259 | static void ipr_log_hex_data(struct ipr_ioa_cfg *ioa_cfg, u32 *data, int len) |
1259 | { | 1260 | { |
1260 | int i; | 1261 | int i; |
1261 | 1262 | ||
1262 | if (len == 0) | 1263 | if (len == 0) |
1263 | return; | 1264 | return; |
1264 | 1265 | ||
1266 | if (ioa_cfg->log_level <= IPR_DEFAULT_LOG_LEVEL) | ||
1267 | len = min_t(int, len, IPR_DEFAULT_MAX_ERROR_DUMP); | ||
1268 | |||
1265 | for (i = 0; i < len / 4; i += 4) { | 1269 | for (i = 0; i < len / 4; i += 4) { |
1266 | ipr_err("%08X: %08X %08X %08X %08X\n", i*4, | 1270 | ipr_err("%08X: %08X %08X %08X %08X\n", i*4, |
1267 | be32_to_cpu(data[i]), | 1271 | be32_to_cpu(data[i]), |
@@ -1290,7 +1294,7 @@ static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1290 | ipr_err("%s\n", error->failure_reason); | 1294 | ipr_err("%s\n", error->failure_reason); |
1291 | ipr_err("Remote Adapter VPD:\n"); | 1295 | ipr_err("Remote Adapter VPD:\n"); |
1292 | ipr_log_ext_vpd(&error->vpd); | 1296 | ipr_log_ext_vpd(&error->vpd); |
1293 | ipr_log_hex_data(error->data, | 1297 | ipr_log_hex_data(ioa_cfg, error->data, |
1294 | be32_to_cpu(hostrcb->hcam.length) - | 1298 | be32_to_cpu(hostrcb->hcam.length) - |
1295 | (offsetof(struct ipr_hostrcb_error, u) + | 1299 | (offsetof(struct ipr_hostrcb_error, u) + |
1296 | offsetof(struct ipr_hostrcb_type_17_error, data))); | 1300 | offsetof(struct ipr_hostrcb_type_17_error, data))); |
@@ -1315,12 +1319,225 @@ static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1315 | ipr_err("%s\n", error->failure_reason); | 1319 | ipr_err("%s\n", error->failure_reason); |
1316 | ipr_err("Remote Adapter VPD:\n"); | 1320 | ipr_err("Remote Adapter VPD:\n"); |
1317 | ipr_log_vpd(&error->vpd); | 1321 | ipr_log_vpd(&error->vpd); |
1318 | ipr_log_hex_data(error->data, | 1322 | ipr_log_hex_data(ioa_cfg, error->data, |
1319 | be32_to_cpu(hostrcb->hcam.length) - | 1323 | be32_to_cpu(hostrcb->hcam.length) - |
1320 | (offsetof(struct ipr_hostrcb_error, u) + | 1324 | (offsetof(struct ipr_hostrcb_error, u) + |
1321 | offsetof(struct ipr_hostrcb_type_07_error, data))); | 1325 | offsetof(struct ipr_hostrcb_type_07_error, data))); |
1322 | } | 1326 | } |
1323 | 1327 | ||
1328 | static const struct { | ||
1329 | u8 active; | ||
1330 | char *desc; | ||
1331 | } path_active_desc[] = { | ||
1332 | { IPR_PATH_NO_INFO, "Path" }, | ||
1333 | { IPR_PATH_ACTIVE, "Active path" }, | ||
1334 | { IPR_PATH_NOT_ACTIVE, "Inactive path" } | ||
1335 | }; | ||
1336 | |||
1337 | static const struct { | ||
1338 | u8 state; | ||
1339 | char *desc; | ||
1340 | } path_state_desc[] = { | ||
1341 | { IPR_PATH_STATE_NO_INFO, "has no path state information available" }, | ||
1342 | { IPR_PATH_HEALTHY, "is healthy" }, | ||
1343 | { IPR_PATH_DEGRADED, "is degraded" }, | ||
1344 | { IPR_PATH_FAILED, "is failed" } | ||
1345 | }; | ||
1346 | |||
1347 | /** | ||
1348 | * ipr_log_fabric_path - Log a fabric path error | ||
1349 | * @hostrcb: hostrcb struct | ||
1350 | * @fabric: fabric descriptor | ||
1351 | * | ||
1352 | * Return value: | ||
1353 | * none | ||
1354 | **/ | ||
1355 | static void ipr_log_fabric_path(struct ipr_hostrcb *hostrcb, | ||
1356 | struct ipr_hostrcb_fabric_desc *fabric) | ||
1357 | { | ||
1358 | int i, j; | ||
1359 | u8 path_state = fabric->path_state; | ||
1360 | u8 active = path_state & IPR_PATH_ACTIVE_MASK; | ||
1361 | u8 state = path_state & IPR_PATH_STATE_MASK; | ||
1362 | |||
1363 | for (i = 0; i < ARRAY_SIZE(path_active_desc); i++) { | ||
1364 | if (path_active_desc[i].active != active) | ||
1365 | continue; | ||
1366 | |||
1367 | for (j = 0; j < ARRAY_SIZE(path_state_desc); j++) { | ||
1368 | if (path_state_desc[j].state != state) | ||
1369 | continue; | ||
1370 | |||
1371 | if (fabric->cascaded_expander == 0xff && fabric->phy == 0xff) { | ||
1372 | ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d\n", | ||
1373 | path_active_desc[i].desc, path_state_desc[j].desc, | ||
1374 | fabric->ioa_port); | ||
1375 | } else if (fabric->cascaded_expander == 0xff) { | ||
1376 | ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Phy=%d\n", | ||
1377 | path_active_desc[i].desc, path_state_desc[j].desc, | ||
1378 | fabric->ioa_port, fabric->phy); | ||
1379 | } else if (fabric->phy == 0xff) { | ||
1380 | ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Cascade=%d\n", | ||
1381 | path_active_desc[i].desc, path_state_desc[j].desc, | ||
1382 | fabric->ioa_port, fabric->cascaded_expander); | ||
1383 | } else { | ||
1384 | ipr_hcam_err(hostrcb, "%s %s: IOA Port=%d, Cascade=%d, Phy=%d\n", | ||
1385 | path_active_desc[i].desc, path_state_desc[j].desc, | ||
1386 | fabric->ioa_port, fabric->cascaded_expander, fabric->phy); | ||
1387 | } | ||
1388 | return; | ||
1389 | } | ||
1390 | } | ||
1391 | |||
1392 | ipr_err("Path state=%02X IOA Port=%d Cascade=%d Phy=%d\n", path_state, | ||
1393 | fabric->ioa_port, fabric->cascaded_expander, fabric->phy); | ||
1394 | } | ||
1395 | |||
1396 | static const struct { | ||
1397 | u8 type; | ||
1398 | char *desc; | ||
1399 | } path_type_desc[] = { | ||
1400 | { IPR_PATH_CFG_IOA_PORT, "IOA port" }, | ||
1401 | { IPR_PATH_CFG_EXP_PORT, "Expander port" }, | ||
1402 | { IPR_PATH_CFG_DEVICE_PORT, "Device port" }, | ||
1403 | { IPR_PATH_CFG_DEVICE_LUN, "Device LUN" } | ||
1404 | }; | ||
1405 | |||
1406 | static const struct { | ||
1407 | u8 status; | ||
1408 | char *desc; | ||
1409 | } path_status_desc[] = { | ||
1410 | { IPR_PATH_CFG_NO_PROB, "Functional" }, | ||
1411 | { IPR_PATH_CFG_DEGRADED, "Degraded" }, | ||
1412 | { IPR_PATH_CFG_FAILED, "Failed" }, | ||
1413 | { IPR_PATH_CFG_SUSPECT, "Suspect" }, | ||
1414 | { IPR_PATH_NOT_DETECTED, "Missing" }, | ||
1415 | { IPR_PATH_INCORRECT_CONN, "Incorrectly connected" } | ||
1416 | }; | ||
1417 | |||
1418 | static const char *link_rate[] = { | ||
1419 | "unknown", | ||
1420 | "disabled", | ||
1421 | "phy reset problem", | ||
1422 | "spinup hold", | ||
1423 | "port selector", | ||
1424 | "unknown", | ||
1425 | "unknown", | ||
1426 | "unknown", | ||
1427 | "1.5Gbps", | ||
1428 | "3.0Gbps", | ||
1429 | "unknown", | ||
1430 | "unknown", | ||
1431 | "unknown", | ||
1432 | "unknown", | ||
1433 | "unknown", | ||
1434 | "unknown" | ||
1435 | }; | ||
1436 | |||
1437 | /** | ||
1438 | * ipr_log_path_elem - Log a fabric path element. | ||
1439 | * @hostrcb: hostrcb struct | ||
1440 | * @cfg: fabric path element struct | ||
1441 | * | ||
1442 | * Return value: | ||
1443 | * none | ||
1444 | **/ | ||
1445 | static void ipr_log_path_elem(struct ipr_hostrcb *hostrcb, | ||
1446 | struct ipr_hostrcb_config_element *cfg) | ||
1447 | { | ||
1448 | int i, j; | ||
1449 | u8 type = cfg->type_status & IPR_PATH_CFG_TYPE_MASK; | ||
1450 | u8 status = cfg->type_status & IPR_PATH_CFG_STATUS_MASK; | ||
1451 | |||
1452 | if (type == IPR_PATH_CFG_NOT_EXIST) | ||
1453 | return; | ||
1454 | |||
1455 | for (i = 0; i < ARRAY_SIZE(path_type_desc); i++) { | ||
1456 | if (path_type_desc[i].type != type) | ||
1457 | continue; | ||
1458 | |||
1459 | for (j = 0; j < ARRAY_SIZE(path_status_desc); j++) { | ||
1460 | if (path_status_desc[j].status != status) | ||
1461 | continue; | ||
1462 | |||
1463 | if (type == IPR_PATH_CFG_IOA_PORT) { | ||
1464 | ipr_hcam_err(hostrcb, "%s %s: Phy=%d, Link rate=%s, WWN=%08X%08X\n", | ||
1465 | path_status_desc[j].desc, path_type_desc[i].desc, | ||
1466 | cfg->phy, link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], | ||
1467 | be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); | ||
1468 | } else { | ||
1469 | if (cfg->cascaded_expander == 0xff && cfg->phy == 0xff) { | ||
1470 | ipr_hcam_err(hostrcb, "%s %s: Link rate=%s, WWN=%08X%08X\n", | ||
1471 | path_status_desc[j].desc, path_type_desc[i].desc, | ||
1472 | link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], | ||
1473 | be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); | ||
1474 | } else if (cfg->cascaded_expander == 0xff) { | ||
1475 | ipr_hcam_err(hostrcb, "%s %s: Phy=%d, Link rate=%s, " | ||
1476 | "WWN=%08X%08X\n", path_status_desc[j].desc, | ||
1477 | path_type_desc[i].desc, cfg->phy, | ||
1478 | link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], | ||
1479 | be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); | ||
1480 | } else if (cfg->phy == 0xff) { | ||
1481 | ipr_hcam_err(hostrcb, "%s %s: Cascade=%d, Link rate=%s, " | ||
1482 | "WWN=%08X%08X\n", path_status_desc[j].desc, | ||
1483 | path_type_desc[i].desc, cfg->cascaded_expander, | ||
1484 | link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], | ||
1485 | be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); | ||
1486 | } else { | ||
1487 | ipr_hcam_err(hostrcb, "%s %s: Cascade=%d, Phy=%d, Link rate=%s " | ||
1488 | "WWN=%08X%08X\n", path_status_desc[j].desc, | ||
1489 | path_type_desc[i].desc, cfg->cascaded_expander, cfg->phy, | ||
1490 | link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], | ||
1491 | be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); | ||
1492 | } | ||
1493 | } | ||
1494 | return; | ||
1495 | } | ||
1496 | } | ||
1497 | |||
1498 | ipr_hcam_err(hostrcb, "Path element=%02X: Cascade=%d Phy=%d Link rate=%s " | ||
1499 | "WWN=%08X%08X\n", cfg->type_status, cfg->cascaded_expander, cfg->phy, | ||
1500 | link_rate[cfg->link_rate & IPR_PHY_LINK_RATE_MASK], | ||
1501 | be32_to_cpu(cfg->wwid[0]), be32_to_cpu(cfg->wwid[1])); | ||
1502 | } | ||
1503 | |||
1504 | /** | ||
1505 | * ipr_log_fabric_error - Log a fabric error. | ||
1506 | * @ioa_cfg: ioa config struct | ||
1507 | * @hostrcb: hostrcb struct | ||
1508 | * | ||
1509 | * Return value: | ||
1510 | * none | ||
1511 | **/ | ||
1512 | static void ipr_log_fabric_error(struct ipr_ioa_cfg *ioa_cfg, | ||
1513 | struct ipr_hostrcb *hostrcb) | ||
1514 | { | ||
1515 | struct ipr_hostrcb_type_20_error *error; | ||
1516 | struct ipr_hostrcb_fabric_desc *fabric; | ||
1517 | struct ipr_hostrcb_config_element *cfg; | ||
1518 | int i, add_len; | ||
1519 | |||
1520 | error = &hostrcb->hcam.u.error.u.type_20_error; | ||
1521 | error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; | ||
1522 | ipr_hcam_err(hostrcb, "%s\n", error->failure_reason); | ||
1523 | |||
1524 | add_len = be32_to_cpu(hostrcb->hcam.length) - | ||
1525 | (offsetof(struct ipr_hostrcb_error, u) + | ||
1526 | offsetof(struct ipr_hostrcb_type_20_error, desc)); | ||
1527 | |||
1528 | for (i = 0, fabric = error->desc; i < error->num_entries; i++) { | ||
1529 | ipr_log_fabric_path(hostrcb, fabric); | ||
1530 | for_each_fabric_cfg(fabric, cfg) | ||
1531 | ipr_log_path_elem(hostrcb, cfg); | ||
1532 | |||
1533 | add_len -= be16_to_cpu(fabric->length); | ||
1534 | fabric = (struct ipr_hostrcb_fabric_desc *) | ||
1535 | ((unsigned long)fabric + be16_to_cpu(fabric->length)); | ||
1536 | } | ||
1537 | |||
1538 | ipr_log_hex_data(ioa_cfg, (u32 *)fabric, add_len); | ||
1539 | } | ||
1540 | |||
1324 | /** | 1541 | /** |
1325 | * ipr_log_generic_error - Log an adapter error. | 1542 | * ipr_log_generic_error - Log an adapter error. |
1326 | * @ioa_cfg: ioa config struct | 1543 | * @ioa_cfg: ioa config struct |
@@ -1332,7 +1549,7 @@ static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, | |||
1332 | static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg, | 1549 | static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg, |
1333 | struct ipr_hostrcb *hostrcb) | 1550 | struct ipr_hostrcb *hostrcb) |
1334 | { | 1551 | { |
1335 | ipr_log_hex_data(hostrcb->hcam.u.raw.data, | 1552 | ipr_log_hex_data(ioa_cfg, hostrcb->hcam.u.raw.data, |
1336 | be32_to_cpu(hostrcb->hcam.length)); | 1553 | be32_to_cpu(hostrcb->hcam.length)); |
1337 | } | 1554 | } |
1338 | 1555 | ||
@@ -1394,13 +1611,7 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, | |||
1394 | if (!ipr_error_table[error_index].log_hcam) | 1611 | if (!ipr_error_table[error_index].log_hcam) |
1395 | return; | 1612 | return; |
1396 | 1613 | ||
1397 | if (ipr_is_device(&hostrcb->hcam.u.error.failing_dev_res_addr)) { | 1614 | ipr_hcam_err(hostrcb, "%s\n", ipr_error_table[error_index].error); |
1398 | ipr_ra_err(ioa_cfg, hostrcb->hcam.u.error.failing_dev_res_addr, | ||
1399 | "%s\n", ipr_error_table[error_index].error); | ||
1400 | } else { | ||
1401 | dev_err(&ioa_cfg->pdev->dev, "%s\n", | ||
1402 | ipr_error_table[error_index].error); | ||
1403 | } | ||
1404 | 1615 | ||
1405 | /* Set indication we have logged an error */ | 1616 | /* Set indication we have logged an error */ |
1406 | ioa_cfg->errors_logged++; | 1617 | ioa_cfg->errors_logged++; |
@@ -1437,6 +1648,9 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, | |||
1437 | case IPR_HOST_RCB_OVERLAY_ID_17: | 1648 | case IPR_HOST_RCB_OVERLAY_ID_17: |
1438 | ipr_log_enhanced_dual_ioa_error(ioa_cfg, hostrcb); | 1649 | ipr_log_enhanced_dual_ioa_error(ioa_cfg, hostrcb); |
1439 | break; | 1650 | break; |
1651 | case IPR_HOST_RCB_OVERLAY_ID_20: | ||
1652 | ipr_log_fabric_error(ioa_cfg, hostrcb); | ||
1653 | break; | ||
1440 | case IPR_HOST_RCB_OVERLAY_ID_1: | 1654 | case IPR_HOST_RCB_OVERLAY_ID_1: |
1441 | case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: | 1655 | case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: |
1442 | default: | 1656 | default: |
@@ -2093,7 +2307,7 @@ static void ipr_release_dump(struct kref *kref) | |||
2093 | 2307 | ||
2094 | /** | 2308 | /** |
2095 | * ipr_worker_thread - Worker thread | 2309 | * ipr_worker_thread - Worker thread |
2096 | * @data: ioa config struct | 2310 | * @work: ioa config struct |
2097 | * | 2311 | * |
2098 | * Called at task level from a work thread. This function takes care | 2312 | * Called at task level from a work thread. This function takes care |
2099 | * of adding and removing device from the mid-layer as configuration | 2313 | * of adding and removing device from the mid-layer as configuration |
@@ -2102,13 +2316,14 @@ static void ipr_release_dump(struct kref *kref) | |||
2102 | * Return value: | 2316 | * Return value: |
2103 | * nothing | 2317 | * nothing |
2104 | **/ | 2318 | **/ |
2105 | static void ipr_worker_thread(void *data) | 2319 | static void ipr_worker_thread(struct work_struct *work) |
2106 | { | 2320 | { |
2107 | unsigned long lock_flags; | 2321 | unsigned long lock_flags; |
2108 | struct ipr_resource_entry *res; | 2322 | struct ipr_resource_entry *res; |
2109 | struct scsi_device *sdev; | 2323 | struct scsi_device *sdev; |
2110 | struct ipr_dump *dump; | 2324 | struct ipr_dump *dump; |
2111 | struct ipr_ioa_cfg *ioa_cfg = data; | 2325 | struct ipr_ioa_cfg *ioa_cfg = |
2326 | container_of(work, struct ipr_ioa_cfg, work_q); | ||
2112 | u8 bus, target, lun; | 2327 | u8 bus, target, lun; |
2113 | int did_work; | 2328 | int did_work; |
2114 | 2329 | ||
@@ -2969,7 +3184,6 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg) | |||
2969 | struct ipr_dump *dump; | 3184 | struct ipr_dump *dump; |
2970 | unsigned long lock_flags = 0; | 3185 | unsigned long lock_flags = 0; |
2971 | 3186 | ||
2972 | ENTER; | ||
2973 | dump = kzalloc(sizeof(struct ipr_dump), GFP_KERNEL); | 3187 | dump = kzalloc(sizeof(struct ipr_dump), GFP_KERNEL); |
2974 | 3188 | ||
2975 | if (!dump) { | 3189 | if (!dump) { |
@@ -2996,7 +3210,6 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg) | |||
2996 | } | 3210 | } |
2997 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | 3211 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); |
2998 | 3212 | ||
2999 | LEAVE; | ||
3000 | return 0; | 3213 | return 0; |
3001 | } | 3214 | } |
3002 | 3215 | ||
@@ -3573,6 +3786,12 @@ static int ipr_sata_reset(struct ata_port *ap, unsigned int *classes) | |||
3573 | 3786 | ||
3574 | ENTER; | 3787 | ENTER; |
3575 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | 3788 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); |
3789 | while(ioa_cfg->in_reset_reload) { | ||
3790 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
3791 | wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); | ||
3792 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
3793 | } | ||
3794 | |||
3576 | res = sata_port->res; | 3795 | res = sata_port->res; |
3577 | if (res) { | 3796 | if (res) { |
3578 | rc = ipr_device_reset(ioa_cfg, res); | 3797 | rc = ipr_device_reset(ioa_cfg, res); |
@@ -3636,6 +3855,10 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) | |||
3636 | if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { | 3855 | if (ipr_cmd->ioarcb.res_handle == res->cfgte.res_handle) { |
3637 | if (ipr_cmd->scsi_cmd) | 3856 | if (ipr_cmd->scsi_cmd) |
3638 | ipr_cmd->done = ipr_scsi_eh_done; | 3857 | ipr_cmd->done = ipr_scsi_eh_done; |
3858 | if (ipr_cmd->qc && !(ipr_cmd->qc->flags & ATA_QCFLAG_FAILED)) { | ||
3859 | ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT; | ||
3860 | ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED; | ||
3861 | } | ||
3639 | } | 3862 | } |
3640 | } | 3863 | } |
3641 | 3864 | ||
@@ -3770,7 +3993,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd) | |||
3770 | */ | 3993 | */ |
3771 | if (ioa_cfg->in_reset_reload || ioa_cfg->ioa_is_dead) | 3994 | if (ioa_cfg->in_reset_reload || ioa_cfg->ioa_is_dead) |
3772 | return FAILED; | 3995 | return FAILED; |
3773 | if (!res || (!ipr_is_gscsi(res) && !ipr_is_vset_device(res))) | 3996 | if (!res || !ipr_is_gscsi(res)) |
3774 | return FAILED; | 3997 | return FAILED; |
3775 | 3998 | ||
3776 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { | 3999 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { |
@@ -4615,7 +4838,7 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd, | |||
4615 | * Return value: | 4838 | * Return value: |
4616 | * 0 on success / other on failure | 4839 | * 0 on success / other on failure |
4617 | **/ | 4840 | **/ |
4618 | int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) | 4841 | static int ipr_ioctl(struct scsi_device *sdev, int cmd, void __user *arg) |
4619 | { | 4842 | { |
4620 | struct ipr_resource_entry *res; | 4843 | struct ipr_resource_entry *res; |
4621 | 4844 | ||
@@ -4648,40 +4871,6 @@ static const char * ipr_ioa_info(struct Scsi_Host *host) | |||
4648 | return buffer; | 4871 | return buffer; |
4649 | } | 4872 | } |
4650 | 4873 | ||
4651 | /** | ||
4652 | * ipr_scsi_timed_out - Handle scsi command timeout | ||
4653 | * @scsi_cmd: scsi command struct | ||
4654 | * | ||
4655 | * Return value: | ||
4656 | * EH_NOT_HANDLED | ||
4657 | **/ | ||
4658 | enum scsi_eh_timer_return ipr_scsi_timed_out(struct scsi_cmnd *scsi_cmd) | ||
4659 | { | ||
4660 | struct ipr_ioa_cfg *ioa_cfg; | ||
4661 | struct ipr_cmnd *ipr_cmd; | ||
4662 | unsigned long flags; | ||
4663 | |||
4664 | ENTER; | ||
4665 | spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); | ||
4666 | ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata; | ||
4667 | |||
4668 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { | ||
4669 | if (ipr_cmd->qc && ipr_cmd->qc->scsicmd == scsi_cmd) { | ||
4670 | ipr_cmd->qc->err_mask |= AC_ERR_TIMEOUT; | ||
4671 | ipr_cmd->qc->flags |= ATA_QCFLAG_FAILED; | ||
4672 | break; | ||
4673 | } | ||
4674 | } | ||
4675 | |||
4676 | spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); | ||
4677 | LEAVE; | ||
4678 | return EH_NOT_HANDLED; | ||
4679 | } | ||
4680 | |||
4681 | static struct scsi_transport_template ipr_transport_template = { | ||
4682 | .eh_timed_out = ipr_scsi_timed_out | ||
4683 | }; | ||
4684 | |||
4685 | static struct scsi_host_template driver_template = { | 4874 | static struct scsi_host_template driver_template = { |
4686 | .module = THIS_MODULE, | 4875 | .module = THIS_MODULE, |
4687 | .name = "IPR", | 4876 | .name = "IPR", |
@@ -4776,6 +4965,12 @@ static void ipr_ata_post_internal(struct ata_queued_cmd *qc) | |||
4776 | unsigned long flags; | 4965 | unsigned long flags; |
4777 | 4966 | ||
4778 | spin_lock_irqsave(ioa_cfg->host->host_lock, flags); | 4967 | spin_lock_irqsave(ioa_cfg->host->host_lock, flags); |
4968 | while(ioa_cfg->in_reset_reload) { | ||
4969 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); | ||
4970 | wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); | ||
4971 | spin_lock_irqsave(ioa_cfg->host->host_lock, flags); | ||
4972 | } | ||
4973 | |||
4779 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { | 4974 | list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) { |
4780 | if (ipr_cmd->qc == qc) { | 4975 | if (ipr_cmd->qc == qc) { |
4781 | ipr_device_reset(ioa_cfg, sata_port->res); | 4976 | ipr_device_reset(ioa_cfg, sata_port->res); |
@@ -6832,6 +7027,7 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) | |||
6832 | 7027 | ||
6833 | ioa_cfg->hostrcb[i]->hostrcb_dma = | 7028 | ioa_cfg->hostrcb[i]->hostrcb_dma = |
6834 | ioa_cfg->hostrcb_dma[i] + offsetof(struct ipr_hostrcb, hcam); | 7029 | ioa_cfg->hostrcb_dma[i] + offsetof(struct ipr_hostrcb, hcam); |
7030 | ioa_cfg->hostrcb[i]->ioa_cfg = ioa_cfg; | ||
6835 | list_add_tail(&ioa_cfg->hostrcb[i]->queue, &ioa_cfg->hostrcb_free_q); | 7031 | list_add_tail(&ioa_cfg->hostrcb[i]->queue, &ioa_cfg->hostrcb_free_q); |
6836 | } | 7032 | } |
6837 | 7033 | ||
@@ -6926,7 +7122,7 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, | |||
6926 | INIT_LIST_HEAD(&ioa_cfg->hostrcb_pending_q); | 7122 | INIT_LIST_HEAD(&ioa_cfg->hostrcb_pending_q); |
6927 | INIT_LIST_HEAD(&ioa_cfg->free_res_q); | 7123 | INIT_LIST_HEAD(&ioa_cfg->free_res_q); |
6928 | INIT_LIST_HEAD(&ioa_cfg->used_res_q); | 7124 | INIT_LIST_HEAD(&ioa_cfg->used_res_q); |
6929 | INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread, ioa_cfg); | 7125 | INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread); |
6930 | init_waitqueue_head(&ioa_cfg->reset_wait_q); | 7126 | init_waitqueue_head(&ioa_cfg->reset_wait_q); |
6931 | ioa_cfg->sdt_state = INACTIVE; | 7127 | ioa_cfg->sdt_state = INACTIVE; |
6932 | if (ipr_enable_cache) | 7128 | if (ipr_enable_cache) |
@@ -7017,7 +7213,6 @@ static int __devinit ipr_probe_ioa(struct pci_dev *pdev, | |||
7017 | 7213 | ||
7018 | ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata; | 7214 | ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata; |
7019 | memset(ioa_cfg, 0, sizeof(struct ipr_ioa_cfg)); | 7215 | memset(ioa_cfg, 0, sizeof(struct ipr_ioa_cfg)); |
7020 | host->transportt = &ipr_transport_template; | ||
7021 | ata_host_init(&ioa_cfg->ata_host, &pdev->dev, | 7216 | ata_host_init(&ioa_cfg->ata_host, &pdev->dev, |
7022 | sata_port_info.flags, &ipr_sata_ops); | 7217 | sata_port_info.flags, &ipr_sata_ops); |
7023 | 7218 | ||
@@ -7351,12 +7546,24 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { | |||
7351 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, | 7546 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, |
7352 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, | 7547 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, |
7353 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | 7548 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, |
7549 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, | ||
7550 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, | ||
7551 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7354 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, | 7552 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, |
7355 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, | 7553 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, |
7356 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | 7554 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, |
7357 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, | 7555 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, |
7358 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, | 7556 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, |
7359 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | 7557 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, |
7558 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, | ||
7559 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, | ||
7560 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7561 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, | ||
7562 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B8, | ||
7563 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7564 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, | ||
7565 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, | ||
7566 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, | ||
7360 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, | 7567 | { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, |
7361 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780, | 7568 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780, |
7362 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, | 7569 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, |
@@ -7366,6 +7573,9 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { | |||
7366 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, | 7573 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, |
7367 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, | 7574 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, |
7368 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, | 7575 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, |
7576 | { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, | ||
7577 | PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572F, | ||
7578 | 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, | ||
7369 | { } | 7579 | { } |
7370 | }; | 7580 | }; |
7371 | MODULE_DEVICE_TABLE(pci, ipr_pci_table); | 7581 | MODULE_DEVICE_TABLE(pci, ipr_pci_table); |
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 6d035283af08..9f62a1d4d511 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
@@ -37,8 +37,8 @@ | |||
37 | /* | 37 | /* |
38 | * Literals | 38 | * Literals |
39 | */ | 39 | */ |
40 | #define IPR_DRIVER_VERSION "2.2.0" | 40 | #define IPR_DRIVER_VERSION "2.3.0" |
41 | #define IPR_DRIVER_DATE "(September 25, 2006)" | 41 | #define IPR_DRIVER_DATE "(November 8, 2006)" |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding | 44 | * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding |
@@ -54,6 +54,8 @@ | |||
54 | */ | 54 | */ |
55 | #define IPR_NUM_BASE_CMD_BLKS 100 | 55 | #define IPR_NUM_BASE_CMD_BLKS 100 |
56 | 56 | ||
57 | #define PCI_DEVICE_ID_IBM_OBSIDIAN_E 0x0339 | ||
58 | |||
57 | #define IPR_SUBS_DEV_ID_2780 0x0264 | 59 | #define IPR_SUBS_DEV_ID_2780 0x0264 |
58 | #define IPR_SUBS_DEV_ID_5702 0x0266 | 60 | #define IPR_SUBS_DEV_ID_5702 0x0266 |
59 | #define IPR_SUBS_DEV_ID_5703 0x0278 | 61 | #define IPR_SUBS_DEV_ID_5703 0x0278 |
@@ -66,7 +68,11 @@ | |||
66 | #define IPR_SUBS_DEV_ID_571F 0x02D5 | 68 | #define IPR_SUBS_DEV_ID_571F 0x02D5 |
67 | #define IPR_SUBS_DEV_ID_572A 0x02C1 | 69 | #define IPR_SUBS_DEV_ID_572A 0x02C1 |
68 | #define IPR_SUBS_DEV_ID_572B 0x02C2 | 70 | #define IPR_SUBS_DEV_ID_572B 0x02C2 |
71 | #define IPR_SUBS_DEV_ID_572F 0x02C3 | ||
69 | #define IPR_SUBS_DEV_ID_575B 0x030D | 72 | #define IPR_SUBS_DEV_ID_575B 0x030D |
73 | #define IPR_SUBS_DEV_ID_575C 0x0338 | ||
74 | #define IPR_SUBS_DEV_ID_57B7 0x0360 | ||
75 | #define IPR_SUBS_DEV_ID_57B8 0x02C2 | ||
70 | 76 | ||
71 | #define IPR_NAME "ipr" | 77 | #define IPR_NAME "ipr" |
72 | 78 | ||
@@ -98,6 +104,7 @@ | |||
98 | #define IPR_IOASC_IOA_WAS_RESET 0x10000001 | 104 | #define IPR_IOASC_IOA_WAS_RESET 0x10000001 |
99 | #define IPR_IOASC_PCI_ACCESS_ERROR 0x10000002 | 105 | #define IPR_IOASC_PCI_ACCESS_ERROR 0x10000002 |
100 | 106 | ||
107 | #define IPR_DEFAULT_MAX_ERROR_DUMP 984 | ||
101 | #define IPR_NUM_LOG_HCAMS 2 | 108 | #define IPR_NUM_LOG_HCAMS 2 |
102 | #define IPR_NUM_CFG_CHG_HCAMS 2 | 109 | #define IPR_NUM_CFG_CHG_HCAMS 2 |
103 | #define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS) | 110 | #define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS) |
@@ -731,6 +738,64 @@ struct ipr_hostrcb_type_17_error { | |||
731 | u32 data[476]; | 738 | u32 data[476]; |
732 | }__attribute__((packed, aligned (4))); | 739 | }__attribute__((packed, aligned (4))); |
733 | 740 | ||
741 | struct ipr_hostrcb_config_element { | ||
742 | u8 type_status; | ||
743 | #define IPR_PATH_CFG_TYPE_MASK 0xF0 | ||
744 | #define IPR_PATH_CFG_NOT_EXIST 0x00 | ||
745 | #define IPR_PATH_CFG_IOA_PORT 0x10 | ||
746 | #define IPR_PATH_CFG_EXP_PORT 0x20 | ||
747 | #define IPR_PATH_CFG_DEVICE_PORT 0x30 | ||
748 | #define IPR_PATH_CFG_DEVICE_LUN 0x40 | ||
749 | |||
750 | #define IPR_PATH_CFG_STATUS_MASK 0x0F | ||
751 | #define IPR_PATH_CFG_NO_PROB 0x00 | ||
752 | #define IPR_PATH_CFG_DEGRADED 0x01 | ||
753 | #define IPR_PATH_CFG_FAILED 0x02 | ||
754 | #define IPR_PATH_CFG_SUSPECT 0x03 | ||
755 | #define IPR_PATH_NOT_DETECTED 0x04 | ||
756 | #define IPR_PATH_INCORRECT_CONN 0x05 | ||
757 | |||
758 | u8 cascaded_expander; | ||
759 | u8 phy; | ||
760 | u8 link_rate; | ||
761 | #define IPR_PHY_LINK_RATE_MASK 0x0F | ||
762 | |||
763 | __be32 wwid[2]; | ||
764 | }__attribute__((packed, aligned (4))); | ||
765 | |||
766 | struct ipr_hostrcb_fabric_desc { | ||
767 | __be16 length; | ||
768 | u8 ioa_port; | ||
769 | u8 cascaded_expander; | ||
770 | u8 phy; | ||
771 | u8 path_state; | ||
772 | #define IPR_PATH_ACTIVE_MASK 0xC0 | ||
773 | #define IPR_PATH_NO_INFO 0x00 | ||
774 | #define IPR_PATH_ACTIVE 0x40 | ||
775 | #define IPR_PATH_NOT_ACTIVE 0x80 | ||
776 | |||
777 | #define IPR_PATH_STATE_MASK 0x0F | ||
778 | #define IPR_PATH_STATE_NO_INFO 0x00 | ||
779 | #define IPR_PATH_HEALTHY 0x01 | ||
780 | #define IPR_PATH_DEGRADED 0x02 | ||
781 | #define IPR_PATH_FAILED 0x03 | ||
782 | |||
783 | __be16 num_entries; | ||
784 | struct ipr_hostrcb_config_element elem[1]; | ||
785 | }__attribute__((packed, aligned (4))); | ||
786 | |||
787 | #define for_each_fabric_cfg(fabric, cfg) \ | ||
788 | for (cfg = (fabric)->elem; \ | ||
789 | cfg < ((fabric)->elem + be16_to_cpu((fabric)->num_entries)); \ | ||
790 | cfg++) | ||
791 | |||
792 | struct ipr_hostrcb_type_20_error { | ||
793 | u8 failure_reason[64]; | ||
794 | u8 reserved[3]; | ||
795 | u8 num_entries; | ||
796 | struct ipr_hostrcb_fabric_desc desc[1]; | ||
797 | }__attribute__((packed, aligned (4))); | ||
798 | |||
734 | struct ipr_hostrcb_error { | 799 | struct ipr_hostrcb_error { |
735 | __be32 failing_dev_ioasc; | 800 | __be32 failing_dev_ioasc; |
736 | struct ipr_res_addr failing_dev_res_addr; | 801 | struct ipr_res_addr failing_dev_res_addr; |
@@ -747,6 +812,7 @@ struct ipr_hostrcb_error { | |||
747 | struct ipr_hostrcb_type_13_error type_13_error; | 812 | struct ipr_hostrcb_type_13_error type_13_error; |
748 | struct ipr_hostrcb_type_14_error type_14_error; | 813 | struct ipr_hostrcb_type_14_error type_14_error; |
749 | struct ipr_hostrcb_type_17_error type_17_error; | 814 | struct ipr_hostrcb_type_17_error type_17_error; |
815 | struct ipr_hostrcb_type_20_error type_20_error; | ||
750 | } u; | 816 | } u; |
751 | }__attribute__((packed, aligned (4))); | 817 | }__attribute__((packed, aligned (4))); |
752 | 818 | ||
@@ -786,6 +852,7 @@ struct ipr_hcam { | |||
786 | #define IPR_HOST_RCB_OVERLAY_ID_14 0x14 | 852 | #define IPR_HOST_RCB_OVERLAY_ID_14 0x14 |
787 | #define IPR_HOST_RCB_OVERLAY_ID_16 0x16 | 853 | #define IPR_HOST_RCB_OVERLAY_ID_16 0x16 |
788 | #define IPR_HOST_RCB_OVERLAY_ID_17 0x17 | 854 | #define IPR_HOST_RCB_OVERLAY_ID_17 0x17 |
855 | #define IPR_HOST_RCB_OVERLAY_ID_20 0x20 | ||
789 | #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF | 856 | #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF |
790 | 857 | ||
791 | u8 reserved1[3]; | 858 | u8 reserved1[3]; |
@@ -805,6 +872,7 @@ struct ipr_hostrcb { | |||
805 | struct ipr_hcam hcam; | 872 | struct ipr_hcam hcam; |
806 | dma_addr_t hostrcb_dma; | 873 | dma_addr_t hostrcb_dma; |
807 | struct list_head queue; | 874 | struct list_head queue; |
875 | struct ipr_ioa_cfg *ioa_cfg; | ||
808 | }; | 876 | }; |
809 | 877 | ||
810 | /* IPR smart dump table structures */ | 878 | /* IPR smart dump table structures */ |
@@ -1283,6 +1351,17 @@ struct ipr_ucode_image_header { | |||
1283 | } \ | 1351 | } \ |
1284 | } | 1352 | } |
1285 | 1353 | ||
1354 | #define ipr_hcam_err(hostrcb, fmt, ...) \ | ||
1355 | { \ | ||
1356 | if (ipr_is_device(&(hostrcb)->hcam.u.error.failing_dev_res_addr)) { \ | ||
1357 | ipr_ra_err((hostrcb)->ioa_cfg, \ | ||
1358 | (hostrcb)->hcam.u.error.failing_dev_res_addr, \ | ||
1359 | fmt, ##__VA_ARGS__); \ | ||
1360 | } else { \ | ||
1361 | dev_err(&(hostrcb)->ioa_cfg->pdev->dev, fmt, ##__VA_ARGS__); \ | ||
1362 | } \ | ||
1363 | } | ||
1364 | |||
1286 | #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ | 1365 | #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ |
1287 | __FILE__, __FUNCTION__, __LINE__) | 1366 | __FILE__, __FUNCTION__, __LINE__) |
1288 | 1367 | ||
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index f06a06ae6092..8b704f73055a 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c | |||
@@ -5001,7 +5001,7 @@ ips_init_copperhead(ips_ha_t * ha) | |||
5001 | break; | 5001 | break; |
5002 | 5002 | ||
5003 | /* Delay for 1 Second */ | 5003 | /* Delay for 1 Second */ |
5004 | msleep(IPS_ONE_SEC); | 5004 | MDELAY(IPS_ONE_SEC); |
5005 | } | 5005 | } |
5006 | 5006 | ||
5007 | if (j >= 45) | 5007 | if (j >= 45) |
@@ -5027,7 +5027,7 @@ ips_init_copperhead(ips_ha_t * ha) | |||
5027 | break; | 5027 | break; |
5028 | 5028 | ||
5029 | /* Delay for 1 Second */ | 5029 | /* Delay for 1 Second */ |
5030 | msleep(IPS_ONE_SEC); | 5030 | MDELAY(IPS_ONE_SEC); |
5031 | } | 5031 | } |
5032 | 5032 | ||
5033 | if (j >= 240) | 5033 | if (j >= 240) |
@@ -5045,7 +5045,7 @@ ips_init_copperhead(ips_ha_t * ha) | |||
5045 | break; | 5045 | break; |
5046 | 5046 | ||
5047 | /* Delay for 1 Second */ | 5047 | /* Delay for 1 Second */ |
5048 | msleep(IPS_ONE_SEC); | 5048 | MDELAY(IPS_ONE_SEC); |
5049 | } | 5049 | } |
5050 | 5050 | ||
5051 | if (i >= 240) | 5051 | if (i >= 240) |
@@ -5095,7 +5095,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) | |||
5095 | break; | 5095 | break; |
5096 | 5096 | ||
5097 | /* Delay for 1 Second */ | 5097 | /* Delay for 1 Second */ |
5098 | msleep(IPS_ONE_SEC); | 5098 | MDELAY(IPS_ONE_SEC); |
5099 | } | 5099 | } |
5100 | 5100 | ||
5101 | if (j >= 45) | 5101 | if (j >= 45) |
@@ -5121,7 +5121,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) | |||
5121 | break; | 5121 | break; |
5122 | 5122 | ||
5123 | /* Delay for 1 Second */ | 5123 | /* Delay for 1 Second */ |
5124 | msleep(IPS_ONE_SEC); | 5124 | MDELAY(IPS_ONE_SEC); |
5125 | } | 5125 | } |
5126 | 5126 | ||
5127 | if (j >= 240) | 5127 | if (j >= 240) |
@@ -5139,7 +5139,7 @@ ips_init_copperhead_memio(ips_ha_t * ha) | |||
5139 | break; | 5139 | break; |
5140 | 5140 | ||
5141 | /* Delay for 1 Second */ | 5141 | /* Delay for 1 Second */ |
5142 | msleep(IPS_ONE_SEC); | 5142 | MDELAY(IPS_ONE_SEC); |
5143 | } | 5143 | } |
5144 | 5144 | ||
5145 | if (i >= 240) | 5145 | if (i >= 240) |
@@ -5191,7 +5191,7 @@ ips_init_morpheus(ips_ha_t * ha) | |||
5191 | break; | 5191 | break; |
5192 | 5192 | ||
5193 | /* Delay for 1 Second */ | 5193 | /* Delay for 1 Second */ |
5194 | msleep(IPS_ONE_SEC); | 5194 | MDELAY(IPS_ONE_SEC); |
5195 | } | 5195 | } |
5196 | 5196 | ||
5197 | if (i >= 45) { | 5197 | if (i >= 45) { |
@@ -5217,7 +5217,7 @@ ips_init_morpheus(ips_ha_t * ha) | |||
5217 | if (Post != 0x4F00) | 5217 | if (Post != 0x4F00) |
5218 | break; | 5218 | break; |
5219 | /* Delay for 1 Second */ | 5219 | /* Delay for 1 Second */ |
5220 | msleep(IPS_ONE_SEC); | 5220 | MDELAY(IPS_ONE_SEC); |
5221 | } | 5221 | } |
5222 | 5222 | ||
5223 | if (i >= 120) { | 5223 | if (i >= 120) { |
@@ -5247,7 +5247,7 @@ ips_init_morpheus(ips_ha_t * ha) | |||
5247 | break; | 5247 | break; |
5248 | 5248 | ||
5249 | /* Delay for 1 Second */ | 5249 | /* Delay for 1 Second */ |
5250 | msleep(IPS_ONE_SEC); | 5250 | MDELAY(IPS_ONE_SEC); |
5251 | } | 5251 | } |
5252 | 5252 | ||
5253 | if (i >= 240) { | 5253 | if (i >= 240) { |
@@ -5307,12 +5307,12 @@ ips_reset_copperhead(ips_ha_t * ha) | |||
5307 | outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR); | 5307 | outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR); |
5308 | 5308 | ||
5309 | /* Delay for 1 Second */ | 5309 | /* Delay for 1 Second */ |
5310 | msleep(IPS_ONE_SEC); | 5310 | MDELAY(IPS_ONE_SEC); |
5311 | 5311 | ||
5312 | outb(0, ha->io_addr + IPS_REG_SCPR); | 5312 | outb(0, ha->io_addr + IPS_REG_SCPR); |
5313 | 5313 | ||
5314 | /* Delay for 1 Second */ | 5314 | /* Delay for 1 Second */ |
5315 | msleep(IPS_ONE_SEC); | 5315 | MDELAY(IPS_ONE_SEC); |
5316 | 5316 | ||
5317 | if ((*ha->func.init) (ha)) | 5317 | if ((*ha->func.init) (ha)) |
5318 | break; | 5318 | break; |
@@ -5352,12 +5352,12 @@ ips_reset_copperhead_memio(ips_ha_t * ha) | |||
5352 | writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR); | 5352 | writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR); |
5353 | 5353 | ||
5354 | /* Delay for 1 Second */ | 5354 | /* Delay for 1 Second */ |
5355 | msleep(IPS_ONE_SEC); | 5355 | MDELAY(IPS_ONE_SEC); |
5356 | 5356 | ||
5357 | writeb(0, ha->mem_ptr + IPS_REG_SCPR); | 5357 | writeb(0, ha->mem_ptr + IPS_REG_SCPR); |
5358 | 5358 | ||
5359 | /* Delay for 1 Second */ | 5359 | /* Delay for 1 Second */ |
5360 | msleep(IPS_ONE_SEC); | 5360 | MDELAY(IPS_ONE_SEC); |
5361 | 5361 | ||
5362 | if ((*ha->func.init) (ha)) | 5362 | if ((*ha->func.init) (ha)) |
5363 | break; | 5363 | break; |
@@ -5398,7 +5398,7 @@ ips_reset_morpheus(ips_ha_t * ha) | |||
5398 | writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); | 5398 | writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR); |
5399 | 5399 | ||
5400 | /* Delay for 5 Seconds */ | 5400 | /* Delay for 5 Seconds */ |
5401 | msleep(5 * IPS_ONE_SEC); | 5401 | MDELAY(5 * IPS_ONE_SEC); |
5402 | 5402 | ||
5403 | /* Do a PCI config read to wait for adapter */ | 5403 | /* Do a PCI config read to wait for adapter */ |
5404 | pci_read_config_byte(ha->pcidev, 4, &junk); | 5404 | pci_read_config_byte(ha->pcidev, 4, &junk); |
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index 34680f3dd452..b726dcc424b1 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h | |||
@@ -51,6 +51,7 @@ | |||
51 | #define _IPS_H_ | 51 | #define _IPS_H_ |
52 | 52 | ||
53 | #include <linux/version.h> | 53 | #include <linux/version.h> |
54 | #include <linux/nmi.h> | ||
54 | #include <asm/uaccess.h> | 55 | #include <asm/uaccess.h> |
55 | #include <asm/io.h> | 56 | #include <asm/io.h> |
56 | 57 | ||
@@ -116,9 +117,11 @@ | |||
116 | dev_printk(level , &((pcidev)->dev) , format , ## arg) | 117 | dev_printk(level , &((pcidev)->dev) , format , ## arg) |
117 | #endif | 118 | #endif |
118 | 119 | ||
119 | #ifndef MDELAY | 120 | #define MDELAY(n) \ |
120 | #define MDELAY mdelay | 121 | do { \ |
121 | #endif | 122 | mdelay(n); \ |
123 | touch_nmi_watchdog(); \ | ||
124 | } while (0) | ||
122 | 125 | ||
123 | #ifndef min | 126 | #ifndef min |
124 | #define min(x,y) ((x) < (y) ? x : y) | 127 | #define min(x,y) ((x) < (y) ? x : y) |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 5d8862189485..e11b23c641e2 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -719,9 +719,10 @@ again: | |||
719 | return rc; | 719 | return rc; |
720 | } | 720 | } |
721 | 721 | ||
722 | static void iscsi_xmitworker(void *data) | 722 | static void iscsi_xmitworker(struct work_struct *work) |
723 | { | 723 | { |
724 | struct iscsi_conn *conn = data; | 724 | struct iscsi_conn *conn = |
725 | container_of(work, struct iscsi_conn, xmitwork); | ||
725 | int rc; | 726 | int rc; |
726 | /* | 727 | /* |
727 | * serialize Xmit worker on a per-connection basis. | 728 | * serialize Xmit worker on a per-connection basis. |
@@ -1512,7 +1513,7 @@ iscsi_conn_setup(struct iscsi_cls_session *cls_session, uint32_t conn_idx) | |||
1512 | if (conn->mgmtqueue == ERR_PTR(-ENOMEM)) | 1513 | if (conn->mgmtqueue == ERR_PTR(-ENOMEM)) |
1513 | goto mgmtqueue_alloc_fail; | 1514 | goto mgmtqueue_alloc_fail; |
1514 | 1515 | ||
1515 | INIT_WORK(&conn->xmitwork, iscsi_xmitworker, conn); | 1516 | INIT_WORK(&conn->xmitwork, iscsi_xmitworker); |
1516 | 1517 | ||
1517 | /* allocate login_mtask used for the login/text sequences */ | 1518 | /* allocate login_mtask used for the login/text sequences */ |
1518 | spin_lock_bh(&session->lock); | 1519 | spin_lock_bh(&session->lock); |
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index d977bd492d8d..fb7df7b75811 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c | |||
@@ -647,10 +647,12 @@ void sas_unregister_domain_devices(struct asd_sas_port *port) | |||
647 | * Discover process only interrogates devices in order to discover the | 647 | * Discover process only interrogates devices in order to discover the |
648 | * domain. | 648 | * domain. |
649 | */ | 649 | */ |
650 | static void sas_discover_domain(void *data) | 650 | static void sas_discover_domain(struct work_struct *work) |
651 | { | 651 | { |
652 | int error = 0; | 652 | int error = 0; |
653 | struct asd_sas_port *port = data; | 653 | struct sas_discovery_event *ev = |
654 | container_of(work, struct sas_discovery_event, work); | ||
655 | struct asd_sas_port *port = ev->port; | ||
654 | 656 | ||
655 | sas_begin_event(DISCE_DISCOVER_DOMAIN, &port->disc.disc_event_lock, | 657 | sas_begin_event(DISCE_DISCOVER_DOMAIN, &port->disc.disc_event_lock, |
656 | &port->disc.pending); | 658 | &port->disc.pending); |
@@ -692,10 +694,12 @@ static void sas_discover_domain(void *data) | |||
692 | current->pid, error); | 694 | current->pid, error); |
693 | } | 695 | } |
694 | 696 | ||
695 | static void sas_revalidate_domain(void *data) | 697 | static void sas_revalidate_domain(struct work_struct *work) |
696 | { | 698 | { |
697 | int res = 0; | 699 | int res = 0; |
698 | struct asd_sas_port *port = data; | 700 | struct sas_discovery_event *ev = |
701 | container_of(work, struct sas_discovery_event, work); | ||
702 | struct asd_sas_port *port = ev->port; | ||
699 | 703 | ||
700 | sas_begin_event(DISCE_REVALIDATE_DOMAIN, &port->disc.disc_event_lock, | 704 | sas_begin_event(DISCE_REVALIDATE_DOMAIN, &port->disc.disc_event_lock, |
701 | &port->disc.pending); | 705 | &port->disc.pending); |
@@ -722,7 +726,7 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev) | |||
722 | BUG_ON(ev >= DISC_NUM_EVENTS); | 726 | BUG_ON(ev >= DISC_NUM_EVENTS); |
723 | 727 | ||
724 | sas_queue_event(ev, &disc->disc_event_lock, &disc->pending, | 728 | sas_queue_event(ev, &disc->disc_event_lock, &disc->pending, |
725 | &disc->disc_work[ev], port->ha->core.shost); | 729 | &disc->disc_work[ev].work, port->ha->core.shost); |
726 | 730 | ||
727 | return 0; | 731 | return 0; |
728 | } | 732 | } |
@@ -737,13 +741,15 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port) | |||
737 | { | 741 | { |
738 | int i; | 742 | int i; |
739 | 743 | ||
740 | static void (*sas_event_fns[DISC_NUM_EVENTS])(void *) = { | 744 | static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = { |
741 | [DISCE_DISCOVER_DOMAIN] = sas_discover_domain, | 745 | [DISCE_DISCOVER_DOMAIN] = sas_discover_domain, |
742 | [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain, | 746 | [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain, |
743 | }; | 747 | }; |
744 | 748 | ||
745 | spin_lock_init(&disc->disc_event_lock); | 749 | spin_lock_init(&disc->disc_event_lock); |
746 | disc->pending = 0; | 750 | disc->pending = 0; |
747 | for (i = 0; i < DISC_NUM_EVENTS; i++) | 751 | for (i = 0; i < DISC_NUM_EVENTS; i++) { |
748 | INIT_WORK(&disc->disc_work[i], sas_event_fns[i], port); | 752 | INIT_WORK(&disc->disc_work[i].work, sas_event_fns[i]); |
753 | disc->disc_work[i].port = port; | ||
754 | } | ||
749 | } | 755 | } |
diff --git a/drivers/scsi/libsas/sas_event.c b/drivers/scsi/libsas/sas_event.c index 19110ed1c89c..d83392ee6823 100644 --- a/drivers/scsi/libsas/sas_event.c +++ b/drivers/scsi/libsas/sas_event.c | |||
@@ -31,7 +31,7 @@ static void notify_ha_event(struct sas_ha_struct *sas_ha, enum ha_event event) | |||
31 | BUG_ON(event >= HA_NUM_EVENTS); | 31 | BUG_ON(event >= HA_NUM_EVENTS); |
32 | 32 | ||
33 | sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending, | 33 | sas_queue_event(event, &sas_ha->event_lock, &sas_ha->pending, |
34 | &sas_ha->ha_events[event], sas_ha->core.shost); | 34 | &sas_ha->ha_events[event].work, sas_ha->core.shost); |
35 | } | 35 | } |
36 | 36 | ||
37 | static void notify_port_event(struct asd_sas_phy *phy, enum port_event event) | 37 | static void notify_port_event(struct asd_sas_phy *phy, enum port_event event) |
@@ -41,7 +41,7 @@ static void notify_port_event(struct asd_sas_phy *phy, enum port_event event) | |||
41 | BUG_ON(event >= PORT_NUM_EVENTS); | 41 | BUG_ON(event >= PORT_NUM_EVENTS); |
42 | 42 | ||
43 | sas_queue_event(event, &ha->event_lock, &phy->port_events_pending, | 43 | sas_queue_event(event, &ha->event_lock, &phy->port_events_pending, |
44 | &phy->port_events[event], ha->core.shost); | 44 | &phy->port_events[event].work, ha->core.shost); |
45 | } | 45 | } |
46 | 46 | ||
47 | static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) | 47 | static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) |
@@ -51,12 +51,12 @@ static void notify_phy_event(struct asd_sas_phy *phy, enum phy_event event) | |||
51 | BUG_ON(event >= PHY_NUM_EVENTS); | 51 | BUG_ON(event >= PHY_NUM_EVENTS); |
52 | 52 | ||
53 | sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending, | 53 | sas_queue_event(event, &ha->event_lock, &phy->phy_events_pending, |
54 | &phy->phy_events[event], ha->core.shost); | 54 | &phy->phy_events[event].work, ha->core.shost); |
55 | } | 55 | } |
56 | 56 | ||
57 | int sas_init_events(struct sas_ha_struct *sas_ha) | 57 | int sas_init_events(struct sas_ha_struct *sas_ha) |
58 | { | 58 | { |
59 | static void (*sas_ha_event_fns[HA_NUM_EVENTS])(void *) = { | 59 | static const work_func_t sas_ha_event_fns[HA_NUM_EVENTS] = { |
60 | [HAE_RESET] = sas_hae_reset, | 60 | [HAE_RESET] = sas_hae_reset, |
61 | }; | 61 | }; |
62 | 62 | ||
@@ -64,8 +64,10 @@ int sas_init_events(struct sas_ha_struct *sas_ha) | |||
64 | 64 | ||
65 | spin_lock_init(&sas_ha->event_lock); | 65 | spin_lock_init(&sas_ha->event_lock); |
66 | 66 | ||
67 | for (i = 0; i < HA_NUM_EVENTS; i++) | 67 | for (i = 0; i < HA_NUM_EVENTS; i++) { |
68 | INIT_WORK(&sas_ha->ha_events[i], sas_ha_event_fns[i], sas_ha); | 68 | INIT_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]); |
69 | sas_ha->ha_events[i].ha = sas_ha; | ||
70 | } | ||
69 | 71 | ||
70 | sas_ha->notify_ha_event = notify_ha_event; | 72 | sas_ha->notify_ha_event = notify_ha_event; |
71 | sas_ha->notify_port_event = notify_port_event; | 73 | sas_ha->notify_port_event = notify_port_event; |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index e34a93435497..d31e6fa466f7 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
@@ -597,10 +597,15 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
597 | child->iproto = phy->attached_iproto; | 597 | child->iproto = phy->attached_iproto; |
598 | memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); | 598 | memcpy(child->sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); |
599 | sas_hash_addr(child->hashed_sas_addr, child->sas_addr); | 599 | sas_hash_addr(child->hashed_sas_addr, child->sas_addr); |
600 | phy->port = sas_port_alloc(&parent->rphy->dev, phy_id); | 600 | if (!phy->port) { |
601 | BUG_ON(!phy->port); | 601 | phy->port = sas_port_alloc(&parent->rphy->dev, phy_id); |
602 | /* FIXME: better error handling*/ | 602 | if (unlikely(!phy->port)) |
603 | BUG_ON(sas_port_add(phy->port) != 0); | 603 | goto out_err; |
604 | if (unlikely(sas_port_add(phy->port) != 0)) { | ||
605 | sas_port_free(phy->port); | ||
606 | goto out_err; | ||
607 | } | ||
608 | } | ||
604 | sas_ex_get_linkrate(parent, child, phy); | 609 | sas_ex_get_linkrate(parent, child, phy); |
605 | 610 | ||
606 | if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) { | 611 | if ((phy->attached_tproto & SAS_PROTO_STP) || phy->attached_sata_dev) { |
@@ -615,8 +620,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
615 | SAS_DPRINTK("report phy sata to %016llx:0x%x returned " | 620 | SAS_DPRINTK("report phy sata to %016llx:0x%x returned " |
616 | "0x%x\n", SAS_ADDR(parent->sas_addr), | 621 | "0x%x\n", SAS_ADDR(parent->sas_addr), |
617 | phy_id, res); | 622 | phy_id, res); |
618 | kfree(child); | 623 | goto out_free; |
619 | return NULL; | ||
620 | } | 624 | } |
621 | memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis, | 625 | memcpy(child->frame_rcvd, &child->sata_dev.rps_resp.rps.fis, |
622 | sizeof(struct dev_to_host_fis)); | 626 | sizeof(struct dev_to_host_fis)); |
@@ -627,14 +631,14 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
627 | "%016llx:0x%x returned 0x%x\n", | 631 | "%016llx:0x%x returned 0x%x\n", |
628 | SAS_ADDR(child->sas_addr), | 632 | SAS_ADDR(child->sas_addr), |
629 | SAS_ADDR(parent->sas_addr), phy_id, res); | 633 | SAS_ADDR(parent->sas_addr), phy_id, res); |
630 | kfree(child); | 634 | goto out_free; |
631 | return NULL; | ||
632 | } | 635 | } |
633 | } else if (phy->attached_tproto & SAS_PROTO_SSP) { | 636 | } else if (phy->attached_tproto & SAS_PROTO_SSP) { |
634 | child->dev_type = SAS_END_DEV; | 637 | child->dev_type = SAS_END_DEV; |
635 | rphy = sas_end_device_alloc(phy->port); | 638 | rphy = sas_end_device_alloc(phy->port); |
636 | /* FIXME: error handling */ | 639 | /* FIXME: error handling */ |
637 | BUG_ON(!rphy); | 640 | if (unlikely(!rphy)) |
641 | goto out_free; | ||
638 | child->tproto = phy->attached_tproto; | 642 | child->tproto = phy->attached_tproto; |
639 | sas_init_dev(child); | 643 | sas_init_dev(child); |
640 | 644 | ||
@@ -651,9 +655,7 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
651 | "at %016llx:0x%x returned 0x%x\n", | 655 | "at %016llx:0x%x returned 0x%x\n", |
652 | SAS_ADDR(child->sas_addr), | 656 | SAS_ADDR(child->sas_addr), |
653 | SAS_ADDR(parent->sas_addr), phy_id, res); | 657 | SAS_ADDR(parent->sas_addr), phy_id, res); |
654 | /* FIXME: this kfrees list elements without removing them */ | 658 | goto out_list_del; |
655 | //kfree(child); | ||
656 | return NULL; | ||
657 | } | 659 | } |
658 | } else { | 660 | } else { |
659 | SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n", | 661 | SAS_DPRINTK("target proto 0x%x at %016llx:0x%x not handled\n", |
@@ -663,6 +665,16 @@ static struct domain_device *sas_ex_discover_end_dev( | |||
663 | 665 | ||
664 | list_add_tail(&child->siblings, &parent_ex->children); | 666 | list_add_tail(&child->siblings, &parent_ex->children); |
665 | return child; | 667 | return child; |
668 | |||
669 | out_list_del: | ||
670 | list_del(&child->dev_list_node); | ||
671 | sas_rphy_free(rphy); | ||
672 | out_free: | ||
673 | sas_port_delete(phy->port); | ||
674 | out_err: | ||
675 | phy->port = NULL; | ||
676 | kfree(child); | ||
677 | return NULL; | ||
666 | } | 678 | } |
667 | 679 | ||
668 | static struct domain_device *sas_ex_discover_expander( | 680 | static struct domain_device *sas_ex_discover_expander( |
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index c836a237fb79..d65bc4e0f214 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c | |||
@@ -65,9 +65,11 @@ void sas_hash_addr(u8 *hashed, const u8 *sas_addr) | |||
65 | 65 | ||
66 | /* ---------- HA events ---------- */ | 66 | /* ---------- HA events ---------- */ |
67 | 67 | ||
68 | void sas_hae_reset(void *data) | 68 | void sas_hae_reset(struct work_struct *work) |
69 | { | 69 | { |
70 | struct sas_ha_struct *ha = data; | 70 | struct sas_ha_event *ev = |
71 | container_of(work, struct sas_ha_event, work); | ||
72 | struct sas_ha_struct *ha = ev->ha; | ||
71 | 73 | ||
72 | sas_begin_event(HAE_RESET, &ha->event_lock, | 74 | sas_begin_event(HAE_RESET, &ha->event_lock, |
73 | &ha->pending); | 75 | &ha->pending); |
@@ -112,6 +114,8 @@ int sas_register_ha(struct sas_ha_struct *sas_ha) | |||
112 | } | 114 | } |
113 | } | 115 | } |
114 | 116 | ||
117 | INIT_LIST_HEAD(&sas_ha->eh_done_q); | ||
118 | |||
115 | return 0; | 119 | return 0; |
116 | 120 | ||
117 | Undo_ports: | 121 | Undo_ports: |
@@ -142,7 +146,7 @@ static int sas_get_linkerrors(struct sas_phy *phy) | |||
142 | return sas_smp_get_phy_events(phy); | 146 | return sas_smp_get_phy_events(phy); |
143 | } | 147 | } |
144 | 148 | ||
145 | static int sas_phy_reset(struct sas_phy *phy, int hard_reset) | 149 | int sas_phy_reset(struct sas_phy *phy, int hard_reset) |
146 | { | 150 | { |
147 | int ret; | 151 | int ret; |
148 | enum phy_func reset_type; | 152 | enum phy_func reset_type; |
diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index bffcee474921..137d7e496b6d 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h | |||
@@ -60,11 +60,11 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha); | |||
60 | 60 | ||
61 | void sas_deform_port(struct asd_sas_phy *phy); | 61 | void sas_deform_port(struct asd_sas_phy *phy); |
62 | 62 | ||
63 | void sas_porte_bytes_dmaed(void *); | 63 | void sas_porte_bytes_dmaed(struct work_struct *work); |
64 | void sas_porte_broadcast_rcvd(void *); | 64 | void sas_porte_broadcast_rcvd(struct work_struct *work); |
65 | void sas_porte_link_reset_err(void *); | 65 | void sas_porte_link_reset_err(struct work_struct *work); |
66 | void sas_porte_timer_event(void *); | 66 | void sas_porte_timer_event(struct work_struct *work); |
67 | void sas_porte_hard_reset(void *); | 67 | void sas_porte_hard_reset(struct work_struct *work); |
68 | 68 | ||
69 | int sas_notify_lldd_dev_found(struct domain_device *); | 69 | int sas_notify_lldd_dev_found(struct domain_device *); |
70 | void sas_notify_lldd_dev_gone(struct domain_device *); | 70 | void sas_notify_lldd_dev_gone(struct domain_device *); |
@@ -75,7 +75,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy); | |||
75 | 75 | ||
76 | struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy); | 76 | struct domain_device *sas_find_dev_by_rphy(struct sas_rphy *rphy); |
77 | 77 | ||
78 | void sas_hae_reset(void *); | 78 | void sas_hae_reset(struct work_struct *work); |
79 | 79 | ||
80 | static inline void sas_queue_event(int event, spinlock_t *lock, | 80 | static inline void sas_queue_event(int event, spinlock_t *lock, |
81 | unsigned long *pending, | 81 | unsigned long *pending, |
diff --git a/drivers/scsi/libsas/sas_phy.c b/drivers/scsi/libsas/sas_phy.c index 9340cdbae4a3..b459c4b635b1 100644 --- a/drivers/scsi/libsas/sas_phy.c +++ b/drivers/scsi/libsas/sas_phy.c | |||
@@ -30,9 +30,11 @@ | |||
30 | 30 | ||
31 | /* ---------- Phy events ---------- */ | 31 | /* ---------- Phy events ---------- */ |
32 | 32 | ||
33 | static void sas_phye_loss_of_signal(void *data) | 33 | static void sas_phye_loss_of_signal(struct work_struct *work) |
34 | { | 34 | { |
35 | struct asd_sas_phy *phy = data; | 35 | struct asd_sas_event *ev = |
36 | container_of(work, struct asd_sas_event, work); | ||
37 | struct asd_sas_phy *phy = ev->phy; | ||
36 | 38 | ||
37 | sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock, | 39 | sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock, |
38 | &phy->phy_events_pending); | 40 | &phy->phy_events_pending); |
@@ -40,18 +42,22 @@ static void sas_phye_loss_of_signal(void *data) | |||
40 | sas_deform_port(phy); | 42 | sas_deform_port(phy); |
41 | } | 43 | } |
42 | 44 | ||
43 | static void sas_phye_oob_done(void *data) | 45 | static void sas_phye_oob_done(struct work_struct *work) |
44 | { | 46 | { |
45 | struct asd_sas_phy *phy = data; | 47 | struct asd_sas_event *ev = |
48 | container_of(work, struct asd_sas_event, work); | ||
49 | struct asd_sas_phy *phy = ev->phy; | ||
46 | 50 | ||
47 | sas_begin_event(PHYE_OOB_DONE, &phy->ha->event_lock, | 51 | sas_begin_event(PHYE_OOB_DONE, &phy->ha->event_lock, |
48 | &phy->phy_events_pending); | 52 | &phy->phy_events_pending); |
49 | phy->error = 0; | 53 | phy->error = 0; |
50 | } | 54 | } |
51 | 55 | ||
52 | static void sas_phye_oob_error(void *data) | 56 | static void sas_phye_oob_error(struct work_struct *work) |
53 | { | 57 | { |
54 | struct asd_sas_phy *phy = data; | 58 | struct asd_sas_event *ev = |
59 | container_of(work, struct asd_sas_event, work); | ||
60 | struct asd_sas_phy *phy = ev->phy; | ||
55 | struct sas_ha_struct *sas_ha = phy->ha; | 61 | struct sas_ha_struct *sas_ha = phy->ha; |
56 | struct asd_sas_port *port = phy->port; | 62 | struct asd_sas_port *port = phy->port; |
57 | struct sas_internal *i = | 63 | struct sas_internal *i = |
@@ -80,9 +86,11 @@ static void sas_phye_oob_error(void *data) | |||
80 | } | 86 | } |
81 | } | 87 | } |
82 | 88 | ||
83 | static void sas_phye_spinup_hold(void *data) | 89 | static void sas_phye_spinup_hold(struct work_struct *work) |
84 | { | 90 | { |
85 | struct asd_sas_phy *phy = data; | 91 | struct asd_sas_event *ev = |
92 | container_of(work, struct asd_sas_event, work); | ||
93 | struct asd_sas_phy *phy = ev->phy; | ||
86 | struct sas_ha_struct *sas_ha = phy->ha; | 94 | struct sas_ha_struct *sas_ha = phy->ha; |
87 | struct sas_internal *i = | 95 | struct sas_internal *i = |
88 | to_sas_internal(sas_ha->core.shost->transportt); | 96 | to_sas_internal(sas_ha->core.shost->transportt); |
@@ -100,14 +108,14 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) | |||
100 | { | 108 | { |
101 | int i; | 109 | int i; |
102 | 110 | ||
103 | static void (*sas_phy_event_fns[PHY_NUM_EVENTS])(void *) = { | 111 | static const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS] = { |
104 | [PHYE_LOSS_OF_SIGNAL] = sas_phye_loss_of_signal, | 112 | [PHYE_LOSS_OF_SIGNAL] = sas_phye_loss_of_signal, |
105 | [PHYE_OOB_DONE] = sas_phye_oob_done, | 113 | [PHYE_OOB_DONE] = sas_phye_oob_done, |
106 | [PHYE_OOB_ERROR] = sas_phye_oob_error, | 114 | [PHYE_OOB_ERROR] = sas_phye_oob_error, |
107 | [PHYE_SPINUP_HOLD] = sas_phye_spinup_hold, | 115 | [PHYE_SPINUP_HOLD] = sas_phye_spinup_hold, |
108 | }; | 116 | }; |
109 | 117 | ||
110 | static void (*sas_port_event_fns[PORT_NUM_EVENTS])(void *) = { | 118 | static const work_func_t sas_port_event_fns[PORT_NUM_EVENTS] = { |
111 | [PORTE_BYTES_DMAED] = sas_porte_bytes_dmaed, | 119 | [PORTE_BYTES_DMAED] = sas_porte_bytes_dmaed, |
112 | [PORTE_BROADCAST_RCVD] = sas_porte_broadcast_rcvd, | 120 | [PORTE_BROADCAST_RCVD] = sas_porte_broadcast_rcvd, |
113 | [PORTE_LINK_RESET_ERR] = sas_porte_link_reset_err, | 121 | [PORTE_LINK_RESET_ERR] = sas_porte_link_reset_err, |
@@ -122,13 +130,18 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) | |||
122 | 130 | ||
123 | phy->error = 0; | 131 | phy->error = 0; |
124 | INIT_LIST_HEAD(&phy->port_phy_el); | 132 | INIT_LIST_HEAD(&phy->port_phy_el); |
125 | for (k = 0; k < PORT_NUM_EVENTS; k++) | 133 | for (k = 0; k < PORT_NUM_EVENTS; k++) { |
126 | INIT_WORK(&phy->port_events[k], sas_port_event_fns[k], | 134 | INIT_WORK(&phy->port_events[k].work, |
127 | phy); | 135 | sas_port_event_fns[k]); |
136 | phy->port_events[k].phy = phy; | ||
137 | } | ||
138 | |||
139 | for (k = 0; k < PHY_NUM_EVENTS; k++) { | ||
140 | INIT_WORK(&phy->phy_events[k].work, | ||
141 | sas_phy_event_fns[k]); | ||
142 | phy->phy_events[k].phy = phy; | ||
143 | } | ||
128 | 144 | ||
129 | for (k = 0; k < PHY_NUM_EVENTS; k++) | ||
130 | INIT_WORK(&phy->phy_events[k], sas_phy_event_fns[k], | ||
131 | phy); | ||
132 | phy->port = NULL; | 145 | phy->port = NULL; |
133 | phy->ha = sas_ha; | 146 | phy->ha = sas_ha; |
134 | spin_lock_init(&phy->frame_rcvd_lock); | 147 | spin_lock_init(&phy->frame_rcvd_lock); |
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index 253cdcf306a2..971c37ceecb4 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c | |||
@@ -181,9 +181,11 @@ void sas_deform_port(struct asd_sas_phy *phy) | |||
181 | 181 | ||
182 | /* ---------- SAS port events ---------- */ | 182 | /* ---------- SAS port events ---------- */ |
183 | 183 | ||
184 | void sas_porte_bytes_dmaed(void *data) | 184 | void sas_porte_bytes_dmaed(struct work_struct *work) |
185 | { | 185 | { |
186 | struct asd_sas_phy *phy = data; | 186 | struct asd_sas_event *ev = |
187 | container_of(work, struct asd_sas_event, work); | ||
188 | struct asd_sas_phy *phy = ev->phy; | ||
187 | 189 | ||
188 | sas_begin_event(PORTE_BYTES_DMAED, &phy->ha->event_lock, | 190 | sas_begin_event(PORTE_BYTES_DMAED, &phy->ha->event_lock, |
189 | &phy->port_events_pending); | 191 | &phy->port_events_pending); |
@@ -191,11 +193,13 @@ void sas_porte_bytes_dmaed(void *data) | |||
191 | sas_form_port(phy); | 193 | sas_form_port(phy); |
192 | } | 194 | } |
193 | 195 | ||
194 | void sas_porte_broadcast_rcvd(void *data) | 196 | void sas_porte_broadcast_rcvd(struct work_struct *work) |
195 | { | 197 | { |
198 | struct asd_sas_event *ev = | ||
199 | container_of(work, struct asd_sas_event, work); | ||
200 | struct asd_sas_phy *phy = ev->phy; | ||
196 | unsigned long flags; | 201 | unsigned long flags; |
197 | u32 prim; | 202 | u32 prim; |
198 | struct asd_sas_phy *phy = data; | ||
199 | 203 | ||
200 | sas_begin_event(PORTE_BROADCAST_RCVD, &phy->ha->event_lock, | 204 | sas_begin_event(PORTE_BROADCAST_RCVD, &phy->ha->event_lock, |
201 | &phy->port_events_pending); | 205 | &phy->port_events_pending); |
@@ -208,9 +212,11 @@ void sas_porte_broadcast_rcvd(void *data) | |||
208 | sas_discover_event(phy->port, DISCE_REVALIDATE_DOMAIN); | 212 | sas_discover_event(phy->port, DISCE_REVALIDATE_DOMAIN); |
209 | } | 213 | } |
210 | 214 | ||
211 | void sas_porte_link_reset_err(void *data) | 215 | void sas_porte_link_reset_err(struct work_struct *work) |
212 | { | 216 | { |
213 | struct asd_sas_phy *phy = data; | 217 | struct asd_sas_event *ev = |
218 | container_of(work, struct asd_sas_event, work); | ||
219 | struct asd_sas_phy *phy = ev->phy; | ||
214 | 220 | ||
215 | sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock, | 221 | sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock, |
216 | &phy->port_events_pending); | 222 | &phy->port_events_pending); |
@@ -218,9 +224,11 @@ void sas_porte_link_reset_err(void *data) | |||
218 | sas_deform_port(phy); | 224 | sas_deform_port(phy); |
219 | } | 225 | } |
220 | 226 | ||
221 | void sas_porte_timer_event(void *data) | 227 | void sas_porte_timer_event(struct work_struct *work) |
222 | { | 228 | { |
223 | struct asd_sas_phy *phy = data; | 229 | struct asd_sas_event *ev = |
230 | container_of(work, struct asd_sas_event, work); | ||
231 | struct asd_sas_phy *phy = ev->phy; | ||
224 | 232 | ||
225 | sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock, | 233 | sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock, |
226 | &phy->port_events_pending); | 234 | &phy->port_events_pending); |
@@ -228,9 +236,11 @@ void sas_porte_timer_event(void *data) | |||
228 | sas_deform_port(phy); | 236 | sas_deform_port(phy); |
229 | } | 237 | } |
230 | 238 | ||
231 | void sas_porte_hard_reset(void *data) | 239 | void sas_porte_hard_reset(struct work_struct *work) |
232 | { | 240 | { |
233 | struct asd_sas_phy *phy = data; | 241 | struct asd_sas_event *ev = |
242 | container_of(work, struct asd_sas_event, work); | ||
243 | struct asd_sas_phy *phy = ev->phy; | ||
234 | 244 | ||
235 | sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock, | 245 | sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock, |
236 | &phy->port_events_pending); | 246 | &phy->port_events_pending); |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index e46e79355b77..22672d54aa27 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -29,9 +29,11 @@ | |||
29 | #include <scsi/scsi_device.h> | 29 | #include <scsi/scsi_device.h> |
30 | #include <scsi/scsi_tcq.h> | 30 | #include <scsi/scsi_tcq.h> |
31 | #include <scsi/scsi.h> | 31 | #include <scsi/scsi.h> |
32 | #include <scsi/scsi_eh.h> | ||
32 | #include <scsi/scsi_transport.h> | 33 | #include <scsi/scsi_transport.h> |
33 | #include <scsi/scsi_transport_sas.h> | 34 | #include <scsi/scsi_transport_sas.h> |
34 | #include "../scsi_sas_internal.h" | 35 | #include "../scsi_sas_internal.h" |
36 | #include "../scsi_transport_api.h" | ||
35 | 37 | ||
36 | #include <linux/err.h> | 38 | #include <linux/err.h> |
37 | #include <linux/blkdev.h> | 39 | #include <linux/blkdev.h> |
@@ -46,6 +48,7 @@ static void sas_scsi_task_done(struct sas_task *task) | |||
46 | { | 48 | { |
47 | struct task_status_struct *ts = &task->task_status; | 49 | struct task_status_struct *ts = &task->task_status; |
48 | struct scsi_cmnd *sc = task->uldd_task; | 50 | struct scsi_cmnd *sc = task->uldd_task; |
51 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(sc->device->host); | ||
49 | unsigned ts_flags = task->task_state_flags; | 52 | unsigned ts_flags = task->task_state_flags; |
50 | int hs = 0, stat = 0; | 53 | int hs = 0, stat = 0; |
51 | 54 | ||
@@ -116,7 +119,7 @@ static void sas_scsi_task_done(struct sas_task *task) | |||
116 | sas_free_task(task); | 119 | sas_free_task(task); |
117 | /* This is very ugly but this is how SCSI Core works. */ | 120 | /* This is very ugly but this is how SCSI Core works. */ |
118 | if (ts_flags & SAS_TASK_STATE_ABORTED) | 121 | if (ts_flags & SAS_TASK_STATE_ABORTED) |
119 | scsi_finish_command(sc); | 122 | scsi_eh_finish_cmd(sc, &sas_ha->eh_done_q); |
120 | else | 123 | else |
121 | sc->scsi_done(sc); | 124 | sc->scsi_done(sc); |
122 | } | 125 | } |
@@ -307,6 +310,15 @@ static enum task_disposition sas_scsi_find_task(struct sas_task *task) | |||
307 | spin_unlock_irqrestore(&core->task_queue_lock, flags); | 310 | spin_unlock_irqrestore(&core->task_queue_lock, flags); |
308 | } | 311 | } |
309 | 312 | ||
313 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
314 | if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) { | ||
315 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
316 | SAS_DPRINTK("%s: task 0x%p already aborted\n", | ||
317 | __FUNCTION__, task); | ||
318 | return TASK_IS_ABORTED; | ||
319 | } | ||
320 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
321 | |||
310 | for (i = 0; i < 5; i++) { | 322 | for (i = 0; i < 5; i++) { |
311 | SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); | 323 | SAS_DPRINTK("%s: aborting task 0x%p\n", __FUNCTION__, task); |
312 | res = si->dft->lldd_abort_task(task); | 324 | res = si->dft->lldd_abort_task(task); |
@@ -409,13 +421,16 @@ Again: | |||
409 | SAS_DPRINTK("going over list...\n"); | 421 | SAS_DPRINTK("going over list...\n"); |
410 | list_for_each_entry_safe(cmd, n, &error_q, eh_entry) { | 422 | list_for_each_entry_safe(cmd, n, &error_q, eh_entry) { |
411 | struct sas_task *task = TO_SAS_TASK(cmd); | 423 | struct sas_task *task = TO_SAS_TASK(cmd); |
424 | list_del_init(&cmd->eh_entry); | ||
412 | 425 | ||
426 | if (!task) { | ||
427 | SAS_DPRINTK("%s: taskless cmd?!\n", __FUNCTION__); | ||
428 | continue; | ||
429 | } | ||
413 | SAS_DPRINTK("trying to find task 0x%p\n", task); | 430 | SAS_DPRINTK("trying to find task 0x%p\n", task); |
414 | list_del_init(&cmd->eh_entry); | ||
415 | res = sas_scsi_find_task(task); | 431 | res = sas_scsi_find_task(task); |
416 | 432 | ||
417 | cmd->eh_eflags = 0; | 433 | cmd->eh_eflags = 0; |
418 | shost->host_failed--; | ||
419 | 434 | ||
420 | switch (res) { | 435 | switch (res) { |
421 | case TASK_IS_DONE: | 436 | case TASK_IS_DONE: |
@@ -491,6 +506,7 @@ Again: | |||
491 | } | 506 | } |
492 | } | 507 | } |
493 | out: | 508 | out: |
509 | scsi_eh_flush_done_q(&ha->eh_done_q); | ||
494 | SAS_DPRINTK("--- Exit %s\n", __FUNCTION__); | 510 | SAS_DPRINTK("--- Exit %s\n", __FUNCTION__); |
495 | return; | 511 | return; |
496 | clear_q: | 512 | clear_q: |
@@ -508,12 +524,18 @@ enum scsi_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) | |||
508 | unsigned long flags; | 524 | unsigned long flags; |
509 | 525 | ||
510 | if (!task) { | 526 | if (!task) { |
511 | SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", | 527 | SAS_DPRINTK("command 0x%p, task 0x%p, gone: EH_HANDLED\n", |
512 | cmd, task); | 528 | cmd, task); |
513 | return EH_HANDLED; | 529 | return EH_HANDLED; |
514 | } | 530 | } |
515 | 531 | ||
516 | spin_lock_irqsave(&task->task_state_lock, flags); | 532 | spin_lock_irqsave(&task->task_state_lock, flags); |
533 | if (task->task_state_flags & SAS_TASK_INITIATOR_ABORTED) { | ||
534 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
535 | SAS_DPRINTK("command 0x%p, task 0x%p, aborted by initiator: " | ||
536 | "EH_NOT_HANDLED\n", cmd, task); | ||
537 | return EH_NOT_HANDLED; | ||
538 | } | ||
517 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { | 539 | if (task->task_state_flags & SAS_TASK_STATE_DONE) { |
518 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 540 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
519 | SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", | 541 | SAS_DPRINTK("command 0x%p, task 0x%p, timed out: EH_HANDLED\n", |
@@ -777,6 +799,66 @@ void sas_shutdown_queue(struct sas_ha_struct *sas_ha) | |||
777 | spin_unlock_irqrestore(&core->task_queue_lock, flags); | 799 | spin_unlock_irqrestore(&core->task_queue_lock, flags); |
778 | } | 800 | } |
779 | 801 | ||
802 | static int do_sas_task_abort(struct sas_task *task) | ||
803 | { | ||
804 | struct scsi_cmnd *sc = task->uldd_task; | ||
805 | struct sas_internal *si = | ||
806 | to_sas_internal(task->dev->port->ha->core.shost->transportt); | ||
807 | unsigned long flags; | ||
808 | int res; | ||
809 | |||
810 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
811 | if (task->task_state_flags & SAS_TASK_STATE_ABORTED) { | ||
812 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
813 | SAS_DPRINTK("%s: Task %p already aborted.\n", __FUNCTION__, | ||
814 | task); | ||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | task->task_state_flags |= SAS_TASK_INITIATOR_ABORTED; | ||
819 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) | ||
820 | task->task_state_flags |= SAS_TASK_STATE_ABORTED; | ||
821 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
822 | |||
823 | if (!si->dft->lldd_abort_task) | ||
824 | return -ENODEV; | ||
825 | |||
826 | res = si->dft->lldd_abort_task(task); | ||
827 | if ((task->task_state_flags & SAS_TASK_STATE_DONE) || | ||
828 | (res == TMF_RESP_FUNC_COMPLETE)) | ||
829 | { | ||
830 | /* SMP commands don't have scsi_cmds(?) */ | ||
831 | if (!sc) { | ||
832 | task->task_done(task); | ||
833 | return 0; | ||
834 | } | ||
835 | scsi_req_abort_cmd(sc); | ||
836 | scsi_schedule_eh(sc->device->host); | ||
837 | return 0; | ||
838 | } | ||
839 | |||
840 | spin_lock_irqsave(&task->task_state_lock, flags); | ||
841 | task->task_state_flags &= ~SAS_TASK_INITIATOR_ABORTED; | ||
842 | if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) | ||
843 | task->task_state_flags &= ~SAS_TASK_STATE_ABORTED; | ||
844 | spin_unlock_irqrestore(&task->task_state_lock, flags); | ||
845 | |||
846 | return -EAGAIN; | ||
847 | } | ||
848 | |||
849 | void sas_task_abort(struct work_struct *work) | ||
850 | { | ||
851 | struct sas_task *task = | ||
852 | container_of(work, struct sas_task, abort_work); | ||
853 | int i; | ||
854 | |||
855 | for (i = 0; i < 5; i++) | ||
856 | if (!do_sas_task_abort(task)) | ||
857 | return; | ||
858 | |||
859 | SAS_DPRINTK("%s: Could not kill task!\n", __FUNCTION__); | ||
860 | } | ||
861 | |||
780 | EXPORT_SYMBOL_GPL(sas_queuecommand); | 862 | EXPORT_SYMBOL_GPL(sas_queuecommand); |
781 | EXPORT_SYMBOL_GPL(sas_target_alloc); | 863 | EXPORT_SYMBOL_GPL(sas_target_alloc); |
782 | EXPORT_SYMBOL_GPL(sas_slave_configure); | 864 | EXPORT_SYMBOL_GPL(sas_slave_configure); |
@@ -784,3 +866,5 @@ EXPORT_SYMBOL_GPL(sas_slave_destroy); | |||
784 | EXPORT_SYMBOL_GPL(sas_change_queue_depth); | 866 | EXPORT_SYMBOL_GPL(sas_change_queue_depth); |
785 | EXPORT_SYMBOL_GPL(sas_change_queue_type); | 867 | EXPORT_SYMBOL_GPL(sas_change_queue_type); |
786 | EXPORT_SYMBOL_GPL(sas_bios_param); | 868 | EXPORT_SYMBOL_GPL(sas_bios_param); |
869 | EXPORT_SYMBOL_GPL(sas_task_abort); | ||
870 | EXPORT_SYMBOL_GPL(sas_phy_reset); | ||
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c new file mode 100644 index 000000000000..89403b00e042 --- /dev/null +++ b/drivers/scsi/libsrp.c | |||
@@ -0,0 +1,441 @@ | |||
1 | /* | ||
2 | * SCSI RDAM Protocol lib functions | ||
3 | * | ||
4 | * Copyright (C) 2006 FUJITA Tomonori <tomof@acm.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation; either version 2 of the | ||
9 | * License, or (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
19 | * 02110-1301 USA | ||
20 | */ | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/kfifo.h> | ||
23 | #include <linux/scatterlist.h> | ||
24 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/pci.h> | ||
26 | #include <scsi/scsi.h> | ||
27 | #include <scsi/scsi_cmnd.h> | ||
28 | #include <scsi/scsi_tcq.h> | ||
29 | #include <scsi/scsi_tgt.h> | ||
30 | #include <scsi/srp.h> | ||
31 | #include <scsi/libsrp.h> | ||
32 | |||
33 | enum srp_task_attributes { | ||
34 | SRP_SIMPLE_TASK = 0, | ||
35 | SRP_HEAD_TASK = 1, | ||
36 | SRP_ORDERED_TASK = 2, | ||
37 | SRP_ACA_TASK = 4 | ||
38 | }; | ||
39 | |||
40 | /* tmp - will replace with SCSI logging stuff */ | ||
41 | #define eprintk(fmt, args...) \ | ||
42 | do { \ | ||
43 | printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ | ||
44 | } while (0) | ||
45 | /* #define dprintk eprintk */ | ||
46 | #define dprintk(fmt, args...) | ||
47 | |||
48 | static int srp_iu_pool_alloc(struct srp_queue *q, size_t max, | ||
49 | struct srp_buf **ring) | ||
50 | { | ||
51 | int i; | ||
52 | struct iu_entry *iue; | ||
53 | |||
54 | q->pool = kcalloc(max, sizeof(struct iu_entry *), GFP_KERNEL); | ||
55 | if (!q->pool) | ||
56 | return -ENOMEM; | ||
57 | q->items = kcalloc(max, sizeof(struct iu_entry), GFP_KERNEL); | ||
58 | if (!q->items) | ||
59 | goto free_pool; | ||
60 | |||
61 | spin_lock_init(&q->lock); | ||
62 | q->queue = kfifo_init((void *) q->pool, max * sizeof(void *), | ||
63 | GFP_KERNEL, &q->lock); | ||
64 | if (IS_ERR(q->queue)) | ||
65 | goto free_item; | ||
66 | |||
67 | for (i = 0, iue = q->items; i < max; i++) { | ||
68 | __kfifo_put(q->queue, (void *) &iue, sizeof(void *)); | ||
69 | iue->sbuf = ring[i]; | ||
70 | iue++; | ||
71 | } | ||
72 | return 0; | ||
73 | |||
74 | free_item: | ||
75 | kfree(q->items); | ||
76 | free_pool: | ||
77 | kfree(q->pool); | ||
78 | return -ENOMEM; | ||
79 | } | ||
80 | |||
81 | static void srp_iu_pool_free(struct srp_queue *q) | ||
82 | { | ||
83 | kfree(q->items); | ||
84 | kfree(q->pool); | ||
85 | } | ||
86 | |||
87 | static struct srp_buf **srp_ring_alloc(struct device *dev, | ||
88 | size_t max, size_t size) | ||
89 | { | ||
90 | int i; | ||
91 | struct srp_buf **ring; | ||
92 | |||
93 | ring = kcalloc(max, sizeof(struct srp_buf *), GFP_KERNEL); | ||
94 | if (!ring) | ||
95 | return NULL; | ||
96 | |||
97 | for (i = 0; i < max; i++) { | ||
98 | ring[i] = kzalloc(sizeof(struct srp_buf), GFP_KERNEL); | ||
99 | if (!ring[i]) | ||
100 | goto out; | ||
101 | ring[i]->buf = dma_alloc_coherent(dev, size, &ring[i]->dma, | ||
102 | GFP_KERNEL); | ||
103 | if (!ring[i]->buf) | ||
104 | goto out; | ||
105 | } | ||
106 | return ring; | ||
107 | |||
108 | out: | ||
109 | for (i = 0; i < max && ring[i]; i++) { | ||
110 | if (ring[i]->buf) | ||
111 | dma_free_coherent(dev, size, ring[i]->buf, ring[i]->dma); | ||
112 | kfree(ring[i]); | ||
113 | } | ||
114 | kfree(ring); | ||
115 | |||
116 | return NULL; | ||
117 | } | ||
118 | |||
119 | static void srp_ring_free(struct device *dev, struct srp_buf **ring, size_t max, | ||
120 | size_t size) | ||
121 | { | ||
122 | int i; | ||
123 | |||
124 | for (i = 0; i < max; i++) { | ||
125 | dma_free_coherent(dev, size, ring[i]->buf, ring[i]->dma); | ||
126 | kfree(ring[i]); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | int srp_target_alloc(struct srp_target *target, struct device *dev, | ||
131 | size_t nr, size_t iu_size) | ||
132 | { | ||
133 | int err; | ||
134 | |||
135 | spin_lock_init(&target->lock); | ||
136 | INIT_LIST_HEAD(&target->cmd_queue); | ||
137 | |||
138 | target->dev = dev; | ||
139 | target->dev->driver_data = target; | ||
140 | |||
141 | target->srp_iu_size = iu_size; | ||
142 | target->rx_ring_size = nr; | ||
143 | target->rx_ring = srp_ring_alloc(target->dev, nr, iu_size); | ||
144 | if (!target->rx_ring) | ||
145 | return -ENOMEM; | ||
146 | err = srp_iu_pool_alloc(&target->iu_queue, nr, target->rx_ring); | ||
147 | if (err) | ||
148 | goto free_ring; | ||
149 | |||
150 | return 0; | ||
151 | |||
152 | free_ring: | ||
153 | srp_ring_free(target->dev, target->rx_ring, nr, iu_size); | ||
154 | return -ENOMEM; | ||
155 | } | ||
156 | EXPORT_SYMBOL_GPL(srp_target_alloc); | ||
157 | |||
158 | void srp_target_free(struct srp_target *target) | ||
159 | { | ||
160 | srp_ring_free(target->dev, target->rx_ring, target->rx_ring_size, | ||
161 | target->srp_iu_size); | ||
162 | srp_iu_pool_free(&target->iu_queue); | ||
163 | } | ||
164 | EXPORT_SYMBOL_GPL(srp_target_free); | ||
165 | |||
166 | struct iu_entry *srp_iu_get(struct srp_target *target) | ||
167 | { | ||
168 | struct iu_entry *iue = NULL; | ||
169 | |||
170 | kfifo_get(target->iu_queue.queue, (void *) &iue, sizeof(void *)); | ||
171 | if (!iue) | ||
172 | return iue; | ||
173 | iue->target = target; | ||
174 | INIT_LIST_HEAD(&iue->ilist); | ||
175 | iue->flags = 0; | ||
176 | return iue; | ||
177 | } | ||
178 | EXPORT_SYMBOL_GPL(srp_iu_get); | ||
179 | |||
180 | void srp_iu_put(struct iu_entry *iue) | ||
181 | { | ||
182 | kfifo_put(iue->target->iu_queue.queue, (void *) &iue, sizeof(void *)); | ||
183 | } | ||
184 | EXPORT_SYMBOL_GPL(srp_iu_put); | ||
185 | |||
186 | static int srp_direct_data(struct scsi_cmnd *sc, struct srp_direct_buf *md, | ||
187 | enum dma_data_direction dir, srp_rdma_t rdma_io, | ||
188 | int dma_map, int ext_desc) | ||
189 | { | ||
190 | struct iu_entry *iue = NULL; | ||
191 | struct scatterlist *sg = NULL; | ||
192 | int err, nsg = 0, len; | ||
193 | |||
194 | if (dma_map) { | ||
195 | iue = (struct iu_entry *) sc->SCp.ptr; | ||
196 | sg = sc->request_buffer; | ||
197 | |||
198 | dprintk("%p %u %u %d\n", iue, sc->request_bufflen, | ||
199 | md->len, sc->use_sg); | ||
200 | |||
201 | nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg, | ||
202 | DMA_BIDIRECTIONAL); | ||
203 | if (!nsg) { | ||
204 | printk("fail to map %p %d\n", iue, sc->use_sg); | ||
205 | return 0; | ||
206 | } | ||
207 | len = min(sc->request_bufflen, md->len); | ||
208 | } else | ||
209 | len = md->len; | ||
210 | |||
211 | err = rdma_io(sc, sg, nsg, md, 1, dir, len); | ||
212 | |||
213 | if (dma_map) | ||
214 | dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL); | ||
215 | |||
216 | return err; | ||
217 | } | ||
218 | |||
219 | static int srp_indirect_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, | ||
220 | struct srp_indirect_buf *id, | ||
221 | enum dma_data_direction dir, srp_rdma_t rdma_io, | ||
222 | int dma_map, int ext_desc) | ||
223 | { | ||
224 | struct iu_entry *iue = NULL; | ||
225 | struct srp_direct_buf *md = NULL; | ||
226 | struct scatterlist dummy, *sg = NULL; | ||
227 | dma_addr_t token = 0; | ||
228 | long err; | ||
229 | unsigned int done = 0; | ||
230 | int nmd, nsg = 0, len; | ||
231 | |||
232 | if (dma_map || ext_desc) { | ||
233 | iue = (struct iu_entry *) sc->SCp.ptr; | ||
234 | sg = sc->request_buffer; | ||
235 | |||
236 | dprintk("%p %u %u %d %d\n", | ||
237 | iue, sc->request_bufflen, id->len, | ||
238 | cmd->data_in_desc_cnt, cmd->data_out_desc_cnt); | ||
239 | } | ||
240 | |||
241 | nmd = id->table_desc.len / sizeof(struct srp_direct_buf); | ||
242 | |||
243 | if ((dir == DMA_FROM_DEVICE && nmd == cmd->data_in_desc_cnt) || | ||
244 | (dir == DMA_TO_DEVICE && nmd == cmd->data_out_desc_cnt)) { | ||
245 | md = &id->desc_list[0]; | ||
246 | goto rdma; | ||
247 | } | ||
248 | |||
249 | if (ext_desc && dma_map) { | ||
250 | md = dma_alloc_coherent(iue->target->dev, id->table_desc.len, | ||
251 | &token, GFP_KERNEL); | ||
252 | if (!md) { | ||
253 | eprintk("Can't get dma memory %u\n", id->table_desc.len); | ||
254 | return -ENOMEM; | ||
255 | } | ||
256 | |||
257 | sg_init_one(&dummy, md, id->table_desc.len); | ||
258 | sg_dma_address(&dummy) = token; | ||
259 | err = rdma_io(sc, &dummy, 1, &id->table_desc, 1, DMA_TO_DEVICE, | ||
260 | id->table_desc.len); | ||
261 | if (err < 0) { | ||
262 | eprintk("Error copying indirect table %ld\n", err); | ||
263 | goto free_mem; | ||
264 | } | ||
265 | } else { | ||
266 | eprintk("This command uses external indirect buffer\n"); | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | |||
270 | rdma: | ||
271 | if (dma_map) { | ||
272 | nsg = dma_map_sg(iue->target->dev, sg, sc->use_sg, DMA_BIDIRECTIONAL); | ||
273 | if (!nsg) { | ||
274 | eprintk("fail to map %p %d\n", iue, sc->use_sg); | ||
275 | goto free_mem; | ||
276 | } | ||
277 | len = min(sc->request_bufflen, id->len); | ||
278 | } else | ||
279 | len = id->len; | ||
280 | |||
281 | err = rdma_io(sc, sg, nsg, md, nmd, dir, len); | ||
282 | |||
283 | if (dma_map) | ||
284 | dma_unmap_sg(iue->target->dev, sg, nsg, DMA_BIDIRECTIONAL); | ||
285 | |||
286 | free_mem: | ||
287 | if (token && dma_map) | ||
288 | dma_free_coherent(iue->target->dev, id->table_desc.len, md, token); | ||
289 | |||
290 | return done; | ||
291 | } | ||
292 | |||
293 | static int data_out_desc_size(struct srp_cmd *cmd) | ||
294 | { | ||
295 | int size = 0; | ||
296 | u8 fmt = cmd->buf_fmt >> 4; | ||
297 | |||
298 | switch (fmt) { | ||
299 | case SRP_NO_DATA_DESC: | ||
300 | break; | ||
301 | case SRP_DATA_DESC_DIRECT: | ||
302 | size = sizeof(struct srp_direct_buf); | ||
303 | break; | ||
304 | case SRP_DATA_DESC_INDIRECT: | ||
305 | size = sizeof(struct srp_indirect_buf) + | ||
306 | sizeof(struct srp_direct_buf) * cmd->data_out_desc_cnt; | ||
307 | break; | ||
308 | default: | ||
309 | eprintk("client error. Invalid data_out_format %x\n", fmt); | ||
310 | break; | ||
311 | } | ||
312 | return size; | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * TODO: this can be called multiple times for a single command if it | ||
317 | * has very long data. | ||
318 | */ | ||
319 | int srp_transfer_data(struct scsi_cmnd *sc, struct srp_cmd *cmd, | ||
320 | srp_rdma_t rdma_io, int dma_map, int ext_desc) | ||
321 | { | ||
322 | struct srp_direct_buf *md; | ||
323 | struct srp_indirect_buf *id; | ||
324 | enum dma_data_direction dir; | ||
325 | int offset, err = 0; | ||
326 | u8 format; | ||
327 | |||
328 | offset = cmd->add_cdb_len * 4; | ||
329 | |||
330 | dir = srp_cmd_direction(cmd); | ||
331 | if (dir == DMA_FROM_DEVICE) | ||
332 | offset += data_out_desc_size(cmd); | ||
333 | |||
334 | if (dir == DMA_TO_DEVICE) | ||
335 | format = cmd->buf_fmt >> 4; | ||
336 | else | ||
337 | format = cmd->buf_fmt & ((1U << 4) - 1); | ||
338 | |||
339 | switch (format) { | ||
340 | case SRP_NO_DATA_DESC: | ||
341 | break; | ||
342 | case SRP_DATA_DESC_DIRECT: | ||
343 | md = (struct srp_direct_buf *) | ||
344 | (cmd->add_data + offset); | ||
345 | err = srp_direct_data(sc, md, dir, rdma_io, dma_map, ext_desc); | ||
346 | break; | ||
347 | case SRP_DATA_DESC_INDIRECT: | ||
348 | id = (struct srp_indirect_buf *) | ||
349 | (cmd->add_data + offset); | ||
350 | err = srp_indirect_data(sc, cmd, id, dir, rdma_io, dma_map, | ||
351 | ext_desc); | ||
352 | break; | ||
353 | default: | ||
354 | eprintk("Unknown format %d %x\n", dir, format); | ||
355 | break; | ||
356 | } | ||
357 | |||
358 | return err; | ||
359 | } | ||
360 | EXPORT_SYMBOL_GPL(srp_transfer_data); | ||
361 | |||
362 | static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir) | ||
363 | { | ||
364 | struct srp_direct_buf *md; | ||
365 | struct srp_indirect_buf *id; | ||
366 | int len = 0, offset = cmd->add_cdb_len * 4; | ||
367 | u8 fmt; | ||
368 | |||
369 | if (dir == DMA_TO_DEVICE) | ||
370 | fmt = cmd->buf_fmt >> 4; | ||
371 | else { | ||
372 | fmt = cmd->buf_fmt & ((1U << 4) - 1); | ||
373 | offset += data_out_desc_size(cmd); | ||
374 | } | ||
375 | |||
376 | switch (fmt) { | ||
377 | case SRP_NO_DATA_DESC: | ||
378 | break; | ||
379 | case SRP_DATA_DESC_DIRECT: | ||
380 | md = (struct srp_direct_buf *) (cmd->add_data + offset); | ||
381 | len = md->len; | ||
382 | break; | ||
383 | case SRP_DATA_DESC_INDIRECT: | ||
384 | id = (struct srp_indirect_buf *) (cmd->add_data + offset); | ||
385 | len = id->len; | ||
386 | break; | ||
387 | default: | ||
388 | eprintk("invalid data format %x\n", fmt); | ||
389 | break; | ||
390 | } | ||
391 | return len; | ||
392 | } | ||
393 | |||
394 | int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, | ||
395 | u64 addr) | ||
396 | { | ||
397 | enum dma_data_direction dir; | ||
398 | struct scsi_cmnd *sc; | ||
399 | int tag, len, err; | ||
400 | |||
401 | switch (cmd->task_attr) { | ||
402 | case SRP_SIMPLE_TASK: | ||
403 | tag = MSG_SIMPLE_TAG; | ||
404 | break; | ||
405 | case SRP_ORDERED_TASK: | ||
406 | tag = MSG_ORDERED_TAG; | ||
407 | break; | ||
408 | case SRP_HEAD_TASK: | ||
409 | tag = MSG_HEAD_TAG; | ||
410 | break; | ||
411 | default: | ||
412 | eprintk("Task attribute %d not supported\n", cmd->task_attr); | ||
413 | tag = MSG_ORDERED_TAG; | ||
414 | } | ||
415 | |||
416 | dir = srp_cmd_direction(cmd); | ||
417 | len = vscsis_data_length(cmd, dir); | ||
418 | |||
419 | dprintk("%p %x %lx %d %d %d %llx\n", info, cmd->cdb[0], | ||
420 | cmd->lun, dir, len, tag, (unsigned long long) cmd->tag); | ||
421 | |||
422 | sc = scsi_host_get_command(shost, dir, GFP_KERNEL); | ||
423 | if (!sc) | ||
424 | return -ENOMEM; | ||
425 | |||
426 | sc->SCp.ptr = info; | ||
427 | memcpy(sc->cmnd, cmd->cdb, MAX_COMMAND_SIZE); | ||
428 | sc->request_bufflen = len; | ||
429 | sc->request_buffer = (void *) (unsigned long) addr; | ||
430 | sc->tag = tag; | ||
431 | err = scsi_tgt_queue_command(sc, (struct scsi_lun *) &cmd->lun, cmd->tag); | ||
432 | if (err) | ||
433 | scsi_host_put_command(shost, sc); | ||
434 | |||
435 | return err; | ||
436 | } | ||
437 | EXPORT_SYMBOL_GPL(srp_cmd_queue); | ||
438 | |||
439 | MODULE_DESCRIPTION("SCSI RDAM Protocol lib functions"); | ||
440 | MODULE_AUTHOR("FUJITA Tomonori"); | ||
441 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 3f7f5f8abd75..a7de0bca5bdd 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
@@ -296,13 +296,17 @@ struct lpfc_hba { | |||
296 | uint32_t cfg_cr_delay; | 296 | uint32_t cfg_cr_delay; |
297 | uint32_t cfg_cr_count; | 297 | uint32_t cfg_cr_count; |
298 | uint32_t cfg_multi_ring_support; | 298 | uint32_t cfg_multi_ring_support; |
299 | uint32_t cfg_multi_ring_rctl; | ||
300 | uint32_t cfg_multi_ring_type; | ||
299 | uint32_t cfg_fdmi_on; | 301 | uint32_t cfg_fdmi_on; |
300 | uint32_t cfg_discovery_threads; | 302 | uint32_t cfg_discovery_threads; |
301 | uint32_t cfg_max_luns; | 303 | uint32_t cfg_max_luns; |
302 | uint32_t cfg_poll; | 304 | uint32_t cfg_poll; |
303 | uint32_t cfg_poll_tmo; | 305 | uint32_t cfg_poll_tmo; |
306 | uint32_t cfg_use_msi; | ||
304 | uint32_t cfg_sg_seg_cnt; | 307 | uint32_t cfg_sg_seg_cnt; |
305 | uint32_t cfg_sg_dma_buf_size; | 308 | uint32_t cfg_sg_dma_buf_size; |
309 | uint64_t cfg_soft_wwnn; | ||
306 | uint64_t cfg_soft_wwpn; | 310 | uint64_t cfg_soft_wwpn; |
307 | 311 | ||
308 | uint32_t dev_loss_tmo_changed; | 312 | uint32_t dev_loss_tmo_changed; |
@@ -355,7 +359,7 @@ struct lpfc_hba { | |||
355 | #define VPD_PORT 0x8 /* valid vpd port data */ | 359 | #define VPD_PORT 0x8 /* valid vpd port data */ |
356 | #define VPD_MASK 0xf /* mask for any vpd data */ | 360 | #define VPD_MASK 0xf /* mask for any vpd data */ |
357 | 361 | ||
358 | uint8_t soft_wwpn_enable; | 362 | uint8_t soft_wwn_enable; |
359 | 363 | ||
360 | struct timer_list fcp_poll_timer; | 364 | struct timer_list fcp_poll_timer; |
361 | struct timer_list els_tmofunc; | 365 | struct timer_list els_tmofunc; |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 2a4e02e7a392..f247e786af99 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -552,10 +552,10 @@ static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, | |||
552 | static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); | 552 | static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); |
553 | 553 | ||
554 | 554 | ||
555 | static char *lpfc_soft_wwpn_key = "C99G71SL8032A"; | 555 | static char *lpfc_soft_wwn_key = "C99G71SL8032A"; |
556 | 556 | ||
557 | static ssize_t | 557 | static ssize_t |
558 | lpfc_soft_wwpn_enable_store(struct class_device *cdev, const char *buf, | 558 | lpfc_soft_wwn_enable_store(struct class_device *cdev, const char *buf, |
559 | size_t count) | 559 | size_t count) |
560 | { | 560 | { |
561 | struct Scsi_Host *host = class_to_shost(cdev); | 561 | struct Scsi_Host *host = class_to_shost(cdev); |
@@ -579,15 +579,15 @@ lpfc_soft_wwpn_enable_store(struct class_device *cdev, const char *buf, | |||
579 | if (buf[cnt-1] == '\n') | 579 | if (buf[cnt-1] == '\n') |
580 | cnt--; | 580 | cnt--; |
581 | 581 | ||
582 | if ((cnt != strlen(lpfc_soft_wwpn_key)) || | 582 | if ((cnt != strlen(lpfc_soft_wwn_key)) || |
583 | (strncmp(buf, lpfc_soft_wwpn_key, strlen(lpfc_soft_wwpn_key)) != 0)) | 583 | (strncmp(buf, lpfc_soft_wwn_key, strlen(lpfc_soft_wwn_key)) != 0)) |
584 | return -EINVAL; | 584 | return -EINVAL; |
585 | 585 | ||
586 | phba->soft_wwpn_enable = 1; | 586 | phba->soft_wwn_enable = 1; |
587 | return count; | 587 | return count; |
588 | } | 588 | } |
589 | static CLASS_DEVICE_ATTR(lpfc_soft_wwpn_enable, S_IWUSR, NULL, | 589 | static CLASS_DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL, |
590 | lpfc_soft_wwpn_enable_store); | 590 | lpfc_soft_wwn_enable_store); |
591 | 591 | ||
592 | static ssize_t | 592 | static ssize_t |
593 | lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) | 593 | lpfc_soft_wwpn_show(struct class_device *cdev, char *buf) |
@@ -613,12 +613,12 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) | |||
613 | if (buf[cnt-1] == '\n') | 613 | if (buf[cnt-1] == '\n') |
614 | cnt--; | 614 | cnt--; |
615 | 615 | ||
616 | if (!phba->soft_wwpn_enable || (cnt < 16) || (cnt > 18) || | 616 | if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) || |
617 | ((cnt == 17) && (*buf++ != 'x')) || | 617 | ((cnt == 17) && (*buf++ != 'x')) || |
618 | ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x')))) | 618 | ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x')))) |
619 | return -EINVAL; | 619 | return -EINVAL; |
620 | 620 | ||
621 | phba->soft_wwpn_enable = 0; | 621 | phba->soft_wwn_enable = 0; |
622 | 622 | ||
623 | memset(wwpn, 0, sizeof(wwpn)); | 623 | memset(wwpn, 0, sizeof(wwpn)); |
624 | 624 | ||
@@ -639,6 +639,8 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) | |||
639 | } | 639 | } |
640 | phba->cfg_soft_wwpn = wwn_to_u64(wwpn); | 640 | phba->cfg_soft_wwpn = wwn_to_u64(wwpn); |
641 | fc_host_port_name(host) = phba->cfg_soft_wwpn; | 641 | fc_host_port_name(host) = phba->cfg_soft_wwpn; |
642 | if (phba->cfg_soft_wwnn) | ||
643 | fc_host_node_name(host) = phba->cfg_soft_wwnn; | ||
642 | 644 | ||
643 | dev_printk(KERN_NOTICE, &phba->pcidev->dev, | 645 | dev_printk(KERN_NOTICE, &phba->pcidev->dev, |
644 | "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); | 646 | "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); |
@@ -664,6 +666,66 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) | |||
664 | static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ | 666 | static CLASS_DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\ |
665 | lpfc_soft_wwpn_show, lpfc_soft_wwpn_store); | 667 | lpfc_soft_wwpn_show, lpfc_soft_wwpn_store); |
666 | 668 | ||
669 | static ssize_t | ||
670 | lpfc_soft_wwnn_show(struct class_device *cdev, char *buf) | ||
671 | { | ||
672 | struct Scsi_Host *host = class_to_shost(cdev); | ||
673 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | ||
674 | return snprintf(buf, PAGE_SIZE, "0x%llx\n", | ||
675 | (unsigned long long)phba->cfg_soft_wwnn); | ||
676 | } | ||
677 | |||
678 | |||
679 | static ssize_t | ||
680 | lpfc_soft_wwnn_store(struct class_device *cdev, const char *buf, size_t count) | ||
681 | { | ||
682 | struct Scsi_Host *host = class_to_shost(cdev); | ||
683 | struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; | ||
684 | unsigned int i, j, cnt=count; | ||
685 | u8 wwnn[8]; | ||
686 | |||
687 | /* count may include a LF at end of string */ | ||
688 | if (buf[cnt-1] == '\n') | ||
689 | cnt--; | ||
690 | |||
691 | if (!phba->soft_wwn_enable || (cnt < 16) || (cnt > 18) || | ||
692 | ((cnt == 17) && (*buf++ != 'x')) || | ||
693 | ((cnt == 18) && ((*buf++ != '0') || (*buf++ != 'x')))) | ||
694 | return -EINVAL; | ||
695 | |||
696 | /* | ||
697 | * Allow wwnn to be set many times, as long as the enable is set. | ||
698 | * However, once the wwpn is set, everything locks. | ||
699 | */ | ||
700 | |||
701 | memset(wwnn, 0, sizeof(wwnn)); | ||
702 | |||
703 | /* Validate and store the new name */ | ||
704 | for (i=0, j=0; i < 16; i++) { | ||
705 | if ((*buf >= 'a') && (*buf <= 'f')) | ||
706 | j = ((j << 4) | ((*buf++ -'a') + 10)); | ||
707 | else if ((*buf >= 'A') && (*buf <= 'F')) | ||
708 | j = ((j << 4) | ((*buf++ -'A') + 10)); | ||
709 | else if ((*buf >= '0') && (*buf <= '9')) | ||
710 | j = ((j << 4) | (*buf++ -'0')); | ||
711 | else | ||
712 | return -EINVAL; | ||
713 | if (i % 2) { | ||
714 | wwnn[i/2] = j & 0xff; | ||
715 | j = 0; | ||
716 | } | ||
717 | } | ||
718 | phba->cfg_soft_wwnn = wwn_to_u64(wwnn); | ||
719 | |||
720 | dev_printk(KERN_NOTICE, &phba->pcidev->dev, | ||
721 | "lpfc%d: soft_wwnn set. Value will take effect upon " | ||
722 | "setting of the soft_wwpn\n", phba->brd_no); | ||
723 | |||
724 | return count; | ||
725 | } | ||
726 | static CLASS_DEVICE_ATTR(lpfc_soft_wwnn, S_IRUGO | S_IWUSR,\ | ||
727 | lpfc_soft_wwnn_show, lpfc_soft_wwnn_store); | ||
728 | |||
667 | 729 | ||
668 | static int lpfc_poll = 0; | 730 | static int lpfc_poll = 0; |
669 | module_param(lpfc_poll, int, 0); | 731 | module_param(lpfc_poll, int, 0); |
@@ -802,12 +864,11 @@ static CLASS_DEVICE_ATTR(lpfc_devloss_tmo, S_IRUGO | S_IWUSR, | |||
802 | # LOG_MBOX 0x4 Mailbox events | 864 | # LOG_MBOX 0x4 Mailbox events |
803 | # LOG_INIT 0x8 Initialization events | 865 | # LOG_INIT 0x8 Initialization events |
804 | # LOG_LINK_EVENT 0x10 Link events | 866 | # LOG_LINK_EVENT 0x10 Link events |
805 | # LOG_IP 0x20 IP traffic history | ||
806 | # LOG_FCP 0x40 FCP traffic history | 867 | # LOG_FCP 0x40 FCP traffic history |
807 | # LOG_NODE 0x80 Node table events | 868 | # LOG_NODE 0x80 Node table events |
808 | # LOG_MISC 0x400 Miscellaneous events | 869 | # LOG_MISC 0x400 Miscellaneous events |
809 | # LOG_SLI 0x800 SLI events | 870 | # LOG_SLI 0x800 SLI events |
810 | # LOG_CHK_COND 0x1000 FCP Check condition flag | 871 | # LOG_FCP_ERROR 0x1000 Only log FCP errors |
811 | # LOG_LIBDFC 0x2000 LIBDFC events | 872 | # LOG_LIBDFC 0x2000 LIBDFC events |
812 | # LOG_ALL_MSG 0xffff LOG all messages | 873 | # LOG_ALL_MSG 0xffff LOG all messages |
813 | */ | 874 | */ |
@@ -916,6 +977,22 @@ LPFC_ATTR_R(multi_ring_support, 1, 1, 2, "Determines number of primary " | |||
916 | "SLI rings to spread IOCB entries across"); | 977 | "SLI rings to spread IOCB entries across"); |
917 | 978 | ||
918 | /* | 979 | /* |
980 | # lpfc_multi_ring_rctl: If lpfc_multi_ring_support is enabled, this | ||
981 | # identifies what rctl value to configure the additional ring for. | ||
982 | # Value range is [1,0xff]. Default value is 4 (Unsolicated Data). | ||
983 | */ | ||
984 | LPFC_ATTR_R(multi_ring_rctl, FC_UNSOL_DATA, 1, | ||
985 | 255, "Identifies RCTL for additional ring configuration"); | ||
986 | |||
987 | /* | ||
988 | # lpfc_multi_ring_type: If lpfc_multi_ring_support is enabled, this | ||
989 | # identifies what type value to configure the additional ring for. | ||
990 | # Value range is [1,0xff]. Default value is 5 (LLC/SNAP). | ||
991 | */ | ||
992 | LPFC_ATTR_R(multi_ring_type, FC_LLC_SNAP, 1, | ||
993 | 255, "Identifies TYPE for additional ring configuration"); | ||
994 | |||
995 | /* | ||
919 | # lpfc_fdmi_on: controls FDMI support. | 996 | # lpfc_fdmi_on: controls FDMI support. |
920 | # 0 = no FDMI support | 997 | # 0 = no FDMI support |
921 | # 1 = support FDMI without attribute of hostname | 998 | # 1 = support FDMI without attribute of hostname |
@@ -946,6 +1023,15 @@ LPFC_ATTR_R(max_luns, 255, 0, 65535, | |||
946 | LPFC_ATTR_RW(poll_tmo, 10, 1, 255, | 1023 | LPFC_ATTR_RW(poll_tmo, 10, 1, 255, |
947 | "Milliseconds driver will wait between polling FCP ring"); | 1024 | "Milliseconds driver will wait between polling FCP ring"); |
948 | 1025 | ||
1026 | /* | ||
1027 | # lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that | ||
1028 | # support this feature | ||
1029 | # 0 = MSI disabled (default) | ||
1030 | # 1 = MSI enabled | ||
1031 | # Value range is [0,1]. Default value is 0. | ||
1032 | */ | ||
1033 | LPFC_ATTR_R(use_msi, 0, 0, 1, "Use Message Signaled Interrupts, if possible"); | ||
1034 | |||
949 | 1035 | ||
950 | struct class_device_attribute *lpfc_host_attrs[] = { | 1036 | struct class_device_attribute *lpfc_host_attrs[] = { |
951 | &class_device_attr_info, | 1037 | &class_device_attr_info, |
@@ -974,6 +1060,8 @@ struct class_device_attribute *lpfc_host_attrs[] = { | |||
974 | &class_device_attr_lpfc_cr_delay, | 1060 | &class_device_attr_lpfc_cr_delay, |
975 | &class_device_attr_lpfc_cr_count, | 1061 | &class_device_attr_lpfc_cr_count, |
976 | &class_device_attr_lpfc_multi_ring_support, | 1062 | &class_device_attr_lpfc_multi_ring_support, |
1063 | &class_device_attr_lpfc_multi_ring_rctl, | ||
1064 | &class_device_attr_lpfc_multi_ring_type, | ||
977 | &class_device_attr_lpfc_fdmi_on, | 1065 | &class_device_attr_lpfc_fdmi_on, |
978 | &class_device_attr_lpfc_max_luns, | 1066 | &class_device_attr_lpfc_max_luns, |
979 | &class_device_attr_nport_evt_cnt, | 1067 | &class_device_attr_nport_evt_cnt, |
@@ -982,8 +1070,10 @@ struct class_device_attribute *lpfc_host_attrs[] = { | |||
982 | &class_device_attr_issue_reset, | 1070 | &class_device_attr_issue_reset, |
983 | &class_device_attr_lpfc_poll, | 1071 | &class_device_attr_lpfc_poll, |
984 | &class_device_attr_lpfc_poll_tmo, | 1072 | &class_device_attr_lpfc_poll_tmo, |
1073 | &class_device_attr_lpfc_use_msi, | ||
1074 | &class_device_attr_lpfc_soft_wwnn, | ||
985 | &class_device_attr_lpfc_soft_wwpn, | 1075 | &class_device_attr_lpfc_soft_wwpn, |
986 | &class_device_attr_lpfc_soft_wwpn_enable, | 1076 | &class_device_attr_lpfc_soft_wwn_enable, |
987 | NULL, | 1077 | NULL, |
988 | }; | 1078 | }; |
989 | 1079 | ||
@@ -1771,6 +1861,8 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
1771 | lpfc_cr_delay_init(phba, lpfc_cr_delay); | 1861 | lpfc_cr_delay_init(phba, lpfc_cr_delay); |
1772 | lpfc_cr_count_init(phba, lpfc_cr_count); | 1862 | lpfc_cr_count_init(phba, lpfc_cr_count); |
1773 | lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support); | 1863 | lpfc_multi_ring_support_init(phba, lpfc_multi_ring_support); |
1864 | lpfc_multi_ring_rctl_init(phba, lpfc_multi_ring_rctl); | ||
1865 | lpfc_multi_ring_type_init(phba, lpfc_multi_ring_type); | ||
1774 | lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth); | 1866 | lpfc_lun_queue_depth_init(phba, lpfc_lun_queue_depth); |
1775 | lpfc_fcp_class_init(phba, lpfc_fcp_class); | 1867 | lpfc_fcp_class_init(phba, lpfc_fcp_class); |
1776 | lpfc_use_adisc_init(phba, lpfc_use_adisc); | 1868 | lpfc_use_adisc_init(phba, lpfc_use_adisc); |
@@ -1782,9 +1874,11 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
1782 | lpfc_discovery_threads_init(phba, lpfc_discovery_threads); | 1874 | lpfc_discovery_threads_init(phba, lpfc_discovery_threads); |
1783 | lpfc_max_luns_init(phba, lpfc_max_luns); | 1875 | lpfc_max_luns_init(phba, lpfc_max_luns); |
1784 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); | 1876 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); |
1877 | lpfc_use_msi_init(phba, lpfc_use_msi); | ||
1785 | lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo); | 1878 | lpfc_devloss_tmo_init(phba, lpfc_devloss_tmo); |
1786 | lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo); | 1879 | lpfc_nodev_tmo_init(phba, lpfc_nodev_tmo); |
1787 | phba->cfg_poll = lpfc_poll; | 1880 | phba->cfg_poll = lpfc_poll; |
1881 | phba->cfg_soft_wwnn = 0L; | ||
1788 | phba->cfg_soft_wwpn = 0L; | 1882 | phba->cfg_soft_wwpn = 0L; |
1789 | 1883 | ||
1790 | /* | 1884 | /* |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 3add7c237859..a51a41b7f15d 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -558,6 +558,14 @@ lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
558 | return; | 558 | return; |
559 | } | 559 | } |
560 | 560 | ||
561 | static void | ||
562 | lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | ||
563 | struct lpfc_iocbq * rspiocb) | ||
564 | { | ||
565 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | ||
566 | return; | ||
567 | } | ||
568 | |||
561 | void | 569 | void |
562 | lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp) | 570 | lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp) |
563 | { | 571 | { |
@@ -629,6 +637,8 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
629 | bpl->tus.f.bdeSize = RNN_REQUEST_SZ; | 637 | bpl->tus.f.bdeSize = RNN_REQUEST_SZ; |
630 | else if (cmdcode == SLI_CTNS_RSNN_NN) | 638 | else if (cmdcode == SLI_CTNS_RSNN_NN) |
631 | bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; | 639 | bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; |
640 | else if (cmdcode == SLI_CTNS_RFF_ID) | ||
641 | bpl->tus.f.bdeSize = RFF_REQUEST_SZ; | ||
632 | else | 642 | else |
633 | bpl->tus.f.bdeSize = 0; | 643 | bpl->tus.f.bdeSize = 0; |
634 | bpl->tus.w = le32_to_cpu(bpl->tus.w); | 644 | bpl->tus.w = le32_to_cpu(bpl->tus.w); |
@@ -660,6 +670,17 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
660 | cmpl = lpfc_cmpl_ct_cmd_rft_id; | 670 | cmpl = lpfc_cmpl_ct_cmd_rft_id; |
661 | break; | 671 | break; |
662 | 672 | ||
673 | case SLI_CTNS_RFF_ID: | ||
674 | CtReq->CommandResponse.bits.CmdRsp = | ||
675 | be16_to_cpu(SLI_CTNS_RFF_ID); | ||
676 | CtReq->un.rff.PortId = be32_to_cpu(phba->fc_myDID); | ||
677 | CtReq->un.rff.feature_res = 0; | ||
678 | CtReq->un.rff.feature_tgt = 0; | ||
679 | CtReq->un.rff.type_code = FC_FCP_DATA; | ||
680 | CtReq->un.rff.feature_init = 1; | ||
681 | cmpl = lpfc_cmpl_ct_cmd_rff_id; | ||
682 | break; | ||
683 | |||
663 | case SLI_CTNS_RNN_ID: | 684 | case SLI_CTNS_RNN_ID: |
664 | CtReq->CommandResponse.bits.CmdRsp = | 685 | CtReq->CommandResponse.bits.CmdRsp = |
665 | be16_to_cpu(SLI_CTNS_RNN_ID); | 686 | be16_to_cpu(SLI_CTNS_RNN_ID); |
@@ -934,7 +955,8 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
934 | ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); | 955 | ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) rh + size); |
935 | ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION); | 956 | ae->ad.bits.AttrType = be16_to_cpu(OS_NAME_VERSION); |
936 | sprintf(ae->un.OsNameVersion, "%s %s %s", | 957 | sprintf(ae->un.OsNameVersion, "%s %s %s", |
937 | init_utsname()->sysname, init_utsname()->release, | 958 | init_utsname()->sysname, |
959 | init_utsname()->release, | ||
938 | init_utsname()->version); | 960 | init_utsname()->version); |
939 | len = strlen(ae->un.OsNameVersion); | 961 | len = strlen(ae->un.OsNameVersion); |
940 | len += (len & 3) ? (4 - (len & 3)) : 4; | 962 | len += (len & 3) ? (4 - (len & 3)) : 4; |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 71864cdc6c71..a5f33a0dd4e7 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -243,6 +243,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
243 | struct serv_parm *sp, IOCB_t *irsp) | 243 | struct serv_parm *sp, IOCB_t *irsp) |
244 | { | 244 | { |
245 | LPFC_MBOXQ_t *mbox; | 245 | LPFC_MBOXQ_t *mbox; |
246 | struct lpfc_dmabuf *mp; | ||
246 | int rc; | 247 | int rc; |
247 | 248 | ||
248 | spin_lock_irq(phba->host->host_lock); | 249 | spin_lock_irq(phba->host->host_lock); |
@@ -307,10 +308,14 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
307 | 308 | ||
308 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); | 309 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); |
309 | if (rc == MBX_NOT_FINISHED) | 310 | if (rc == MBX_NOT_FINISHED) |
310 | goto fail_free_mbox; | 311 | goto fail_issue_reg_login; |
311 | 312 | ||
312 | return 0; | 313 | return 0; |
313 | 314 | ||
315 | fail_issue_reg_login: | ||
316 | mp = (struct lpfc_dmabuf *) mbox->context1; | ||
317 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
318 | kfree(mp); | ||
314 | fail_free_mbox: | 319 | fail_free_mbox: |
315 | mempool_free(mbox, phba->mbox_mem_pool); | 320 | mempool_free(mbox, phba->mbox_mem_pool); |
316 | fail: | 321 | fail: |
@@ -657,6 +662,12 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, | |||
657 | uint8_t name[sizeof (struct lpfc_name)]; | 662 | uint8_t name[sizeof (struct lpfc_name)]; |
658 | uint32_t rc; | 663 | uint32_t rc; |
659 | 664 | ||
665 | /* Fabric nodes can have the same WWPN so we don't bother searching | ||
666 | * by WWPN. Just return the ndlp that was given to us. | ||
667 | */ | ||
668 | if (ndlp->nlp_type & NLP_FABRIC) | ||
669 | return ndlp; | ||
670 | |||
660 | lp = (uint32_t *) prsp->virt; | 671 | lp = (uint32_t *) prsp->virt; |
661 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 672 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
662 | memset(name, 0, sizeof (struct lpfc_name)); | 673 | memset(name, 0, sizeof (struct lpfc_name)); |
@@ -1122,7 +1133,7 @@ lpfc_cmpl_els_adisc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1122 | mempool_free(mbox, | 1133 | mempool_free(mbox, |
1123 | phba->mbox_mem_pool); | 1134 | phba->mbox_mem_pool); |
1124 | lpfc_disc_flush_list(phba); | 1135 | lpfc_disc_flush_list(phba); |
1125 | psli->ring[(psli->ip_ring)]. | 1136 | psli->ring[(psli->extra_ring)]. |
1126 | flag &= | 1137 | flag &= |
1127 | ~LPFC_STOP_IOCB_EVENT; | 1138 | ~LPFC_STOP_IOCB_EVENT; |
1128 | psli->ring[(psli->fcp_ring)]. | 1139 | psli->ring[(psli->fcp_ring)]. |
@@ -1851,6 +1862,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1851 | IOCB_t *irsp; | 1862 | IOCB_t *irsp; |
1852 | struct lpfc_nodelist *ndlp; | 1863 | struct lpfc_nodelist *ndlp; |
1853 | LPFC_MBOXQ_t *mbox = NULL; | 1864 | LPFC_MBOXQ_t *mbox = NULL; |
1865 | struct lpfc_dmabuf *mp; | ||
1854 | 1866 | ||
1855 | irsp = &rspiocb->iocb; | 1867 | irsp = &rspiocb->iocb; |
1856 | 1868 | ||
@@ -1862,6 +1874,11 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1862 | /* Check to see if link went down during discovery */ | 1874 | /* Check to see if link went down during discovery */ |
1863 | if ((lpfc_els_chk_latt(phba)) || !ndlp) { | 1875 | if ((lpfc_els_chk_latt(phba)) || !ndlp) { |
1864 | if (mbox) { | 1876 | if (mbox) { |
1877 | mp = (struct lpfc_dmabuf *) mbox->context1; | ||
1878 | if (mp) { | ||
1879 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
1880 | kfree(mp); | ||
1881 | } | ||
1865 | mempool_free( mbox, phba->mbox_mem_pool); | 1882 | mempool_free( mbox, phba->mbox_mem_pool); |
1866 | } | 1883 | } |
1867 | goto out; | 1884 | goto out; |
@@ -1893,9 +1910,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1893 | } | 1910 | } |
1894 | /* NOTE: we should have messages for unsuccessful | 1911 | /* NOTE: we should have messages for unsuccessful |
1895 | reglogin */ | 1912 | reglogin */ |
1896 | mempool_free( mbox, phba->mbox_mem_pool); | ||
1897 | } else { | 1913 | } else { |
1898 | mempool_free( mbox, phba->mbox_mem_pool); | ||
1899 | /* Do not call NO_LIST for lpfc_els_abort'ed ELS cmds */ | 1914 | /* Do not call NO_LIST for lpfc_els_abort'ed ELS cmds */ |
1900 | if (!((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && | 1915 | if (!((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && |
1901 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || | 1916 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || |
@@ -1907,6 +1922,12 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1907 | } | 1922 | } |
1908 | } | 1923 | } |
1909 | } | 1924 | } |
1925 | mp = (struct lpfc_dmabuf *) mbox->context1; | ||
1926 | if (mp) { | ||
1927 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
1928 | kfree(mp); | ||
1929 | } | ||
1930 | mempool_free(mbox, phba->mbox_mem_pool); | ||
1910 | } | 1931 | } |
1911 | out: | 1932 | out: |
1912 | if (ndlp) { | 1933 | if (ndlp) { |
@@ -2644,6 +2665,7 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) | |||
2644 | ndlp->nlp_type |= NLP_FABRIC; | 2665 | ndlp->nlp_type |= NLP_FABRIC; |
2645 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2666 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2646 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 2667 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
2668 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | ||
2647 | lpfc_issue_els_plogi(phba, NameServer_DID, 0); | 2669 | lpfc_issue_els_plogi(phba, NameServer_DID, 0); |
2648 | /* Wait for NameServer login cmpl before we can | 2670 | /* Wait for NameServer login cmpl before we can |
2649 | continue */ | 2671 | continue */ |
@@ -3039,7 +3061,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, | |||
3039 | /* FARP-REQ received from DID <did> */ | 3061 | /* FARP-REQ received from DID <did> */ |
3040 | lpfc_printf_log(phba, | 3062 | lpfc_printf_log(phba, |
3041 | KERN_INFO, | 3063 | KERN_INFO, |
3042 | LOG_IP, | 3064 | LOG_ELS, |
3043 | "%d:0601 FARP-REQ received from DID x%x\n", | 3065 | "%d:0601 FARP-REQ received from DID x%x\n", |
3044 | phba->brd_no, did); | 3066 | phba->brd_no, did); |
3045 | 3067 | ||
@@ -3101,7 +3123,7 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba, | |||
3101 | /* FARP-RSP received from DID <did> */ | 3123 | /* FARP-RSP received from DID <did> */ |
3102 | lpfc_printf_log(phba, | 3124 | lpfc_printf_log(phba, |
3103 | KERN_INFO, | 3125 | KERN_INFO, |
3104 | LOG_IP, | 3126 | LOG_ELS, |
3105 | "%d:0600 FARP-RSP received from DID x%x\n", | 3127 | "%d:0600 FARP-RSP received from DID x%x\n", |
3106 | phba->brd_no, did); | 3128 | phba->brd_no, did); |
3107 | 3129 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 19c79a0549a7..c39564e85e94 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -525,7 +525,7 @@ lpfc_mbx_cmpl_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
525 | psli = &phba->sli; | 525 | psli = &phba->sli; |
526 | mb = &pmb->mb; | 526 | mb = &pmb->mb; |
527 | /* Since we don't do discovery right now, turn these off here */ | 527 | /* Since we don't do discovery right now, turn these off here */ |
528 | psli->ring[psli->ip_ring].flag &= ~LPFC_STOP_IOCB_EVENT; | 528 | psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT; |
529 | psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT; | 529 | psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT; |
530 | psli->ring[psli->next_ring].flag &= ~LPFC_STOP_IOCB_EVENT; | 530 | psli->ring[psli->next_ring].flag &= ~LPFC_STOP_IOCB_EVENT; |
531 | 531 | ||
@@ -641,7 +641,7 @@ out: | |||
641 | if (rc == MBX_NOT_FINISHED) { | 641 | if (rc == MBX_NOT_FINISHED) { |
642 | mempool_free(pmb, phba->mbox_mem_pool); | 642 | mempool_free(pmb, phba->mbox_mem_pool); |
643 | lpfc_disc_flush_list(phba); | 643 | lpfc_disc_flush_list(phba); |
644 | psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 644 | psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
645 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 645 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
646 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 646 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
647 | phba->hba_state = LPFC_HBA_READY; | 647 | phba->hba_state = LPFC_HBA_READY; |
@@ -672,6 +672,8 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
672 | 672 | ||
673 | memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt, | 673 | memcpy((uint8_t *) & phba->fc_sparam, (uint8_t *) mp->virt, |
674 | sizeof (struct serv_parm)); | 674 | sizeof (struct serv_parm)); |
675 | if (phba->cfg_soft_wwnn) | ||
676 | u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn); | ||
675 | if (phba->cfg_soft_wwpn) | 677 | if (phba->cfg_soft_wwpn) |
676 | u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn); | 678 | u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn); |
677 | memcpy((uint8_t *) & phba->fc_nodename, | 679 | memcpy((uint8_t *) & phba->fc_nodename, |
@@ -696,7 +698,7 @@ out: | |||
696 | == MBX_NOT_FINISHED) { | 698 | == MBX_NOT_FINISHED) { |
697 | mempool_free( pmb, phba->mbox_mem_pool); | 699 | mempool_free( pmb, phba->mbox_mem_pool); |
698 | lpfc_disc_flush_list(phba); | 700 | lpfc_disc_flush_list(phba); |
699 | psli->ring[(psli->ip_ring)].flag &= | 701 | psli->ring[(psli->extra_ring)].flag &= |
700 | ~LPFC_STOP_IOCB_EVENT; | 702 | ~LPFC_STOP_IOCB_EVENT; |
701 | psli->ring[(psli->fcp_ring)].flag &= | 703 | psli->ring[(psli->fcp_ring)].flag &= |
702 | ~LPFC_STOP_IOCB_EVENT; | 704 | ~LPFC_STOP_IOCB_EVENT; |
@@ -715,6 +717,9 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
715 | { | 717 | { |
716 | int i; | 718 | int i; |
717 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox; | 719 | LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox; |
720 | struct lpfc_dmabuf *mp; | ||
721 | int rc; | ||
722 | |||
718 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 723 | sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
719 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 724 | cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
720 | 725 | ||
@@ -793,16 +798,27 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
793 | if (sparam_mbox) { | 798 | if (sparam_mbox) { |
794 | lpfc_read_sparam(phba, sparam_mbox); | 799 | lpfc_read_sparam(phba, sparam_mbox); |
795 | sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; | 800 | sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam; |
796 | lpfc_sli_issue_mbox(phba, sparam_mbox, | 801 | rc = lpfc_sli_issue_mbox(phba, sparam_mbox, |
797 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 802 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
803 | if (rc == MBX_NOT_FINISHED) { | ||
804 | mp = (struct lpfc_dmabuf *) sparam_mbox->context1; | ||
805 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
806 | kfree(mp); | ||
807 | mempool_free(sparam_mbox, phba->mbox_mem_pool); | ||
808 | if (cfglink_mbox) | ||
809 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); | ||
810 | return; | ||
811 | } | ||
798 | } | 812 | } |
799 | 813 | ||
800 | if (cfglink_mbox) { | 814 | if (cfglink_mbox) { |
801 | phba->hba_state = LPFC_LOCAL_CFG_LINK; | 815 | phba->hba_state = LPFC_LOCAL_CFG_LINK; |
802 | lpfc_config_link(phba, cfglink_mbox); | 816 | lpfc_config_link(phba, cfglink_mbox); |
803 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; | 817 | cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link; |
804 | lpfc_sli_issue_mbox(phba, cfglink_mbox, | 818 | rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, |
805 | (MBX_NOWAIT | MBX_STOP_IOCB)); | 819 | (MBX_NOWAIT | MBX_STOP_IOCB)); |
820 | if (rc == MBX_NOT_FINISHED) | ||
821 | mempool_free(cfglink_mbox, phba->mbox_mem_pool); | ||
806 | } | 822 | } |
807 | } | 823 | } |
808 | 824 | ||
@@ -1067,6 +1083,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) | |||
1067 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RNN_ID); | 1083 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RNN_ID); |
1068 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RSNN_NN); | 1084 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RSNN_NN); |
1069 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFT_ID); | 1085 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFT_ID); |
1086 | lpfc_ns_cmd(phba, ndlp, SLI_CTNS_RFF_ID); | ||
1070 | } | 1087 | } |
1071 | 1088 | ||
1072 | phba->fc_ns_retry = 0; | 1089 | phba->fc_ns_retry = 0; |
@@ -1423,7 +1440,7 @@ lpfc_check_sli_ndlp(struct lpfc_hba * phba, | |||
1423 | if (iocb->context1 == (uint8_t *) ndlp) | 1440 | if (iocb->context1 == (uint8_t *) ndlp) |
1424 | return 1; | 1441 | return 1; |
1425 | } | 1442 | } |
1426 | } else if (pring->ringno == psli->ip_ring) { | 1443 | } else if (pring->ringno == psli->extra_ring) { |
1427 | 1444 | ||
1428 | } else if (pring->ringno == psli->fcp_ring) { | 1445 | } else if (pring->ringno == psli->fcp_ring) { |
1429 | /* Skip match check if waiting to relogin to FCP target */ | 1446 | /* Skip match check if waiting to relogin to FCP target */ |
@@ -1680,112 +1697,38 @@ lpfc_matchdid(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) | |||
1680 | struct lpfc_nodelist * | 1697 | struct lpfc_nodelist * |
1681 | lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | 1698 | lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) |
1682 | { | 1699 | { |
1683 | struct lpfc_nodelist *ndlp, *next_ndlp; | 1700 | struct lpfc_nodelist *ndlp; |
1701 | struct list_head *lists[]={&phba->fc_nlpunmap_list, | ||
1702 | &phba->fc_nlpmap_list, | ||
1703 | &phba->fc_plogi_list, | ||
1704 | &phba->fc_adisc_list, | ||
1705 | &phba->fc_reglogin_list, | ||
1706 | &phba->fc_prli_list, | ||
1707 | &phba->fc_npr_list, | ||
1708 | &phba->fc_unused_list}; | ||
1709 | uint32_t search[]={NLP_SEARCH_UNMAPPED, | ||
1710 | NLP_SEARCH_MAPPED, | ||
1711 | NLP_SEARCH_PLOGI, | ||
1712 | NLP_SEARCH_ADISC, | ||
1713 | NLP_SEARCH_REGLOGIN, | ||
1714 | NLP_SEARCH_PRLI, | ||
1715 | NLP_SEARCH_NPR, | ||
1716 | NLP_SEARCH_UNUSED}; | ||
1717 | int i; | ||
1684 | uint32_t data1; | 1718 | uint32_t data1; |
1685 | 1719 | ||
1686 | spin_lock_irq(phba->host->host_lock); | 1720 | spin_lock_irq(phba->host->host_lock); |
1687 | if (order & NLP_SEARCH_UNMAPPED) { | 1721 | for (i = 0; i < ARRAY_SIZE(lists); i++ ) { |
1688 | list_for_each_entry_safe(ndlp, next_ndlp, | 1722 | if (!(order & search[i])) |
1689 | &phba->fc_nlpunmap_list, nlp_listp) { | 1723 | continue; |
1690 | if (lpfc_matchdid(phba, ndlp, did)) { | 1724 | list_for_each_entry(ndlp, lists[i], nlp_listp) { |
1691 | data1 = (((uint32_t) ndlp->nlp_state << 24) | | ||
1692 | ((uint32_t) ndlp->nlp_xri << 16) | | ||
1693 | ((uint32_t) ndlp->nlp_type << 8) | | ||
1694 | ((uint32_t) ndlp->nlp_rpi & 0xff)); | ||
1695 | /* FIND node DID unmapped */ | ||
1696 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | ||
1697 | "%d:0929 FIND node DID unmapped" | ||
1698 | " Data: x%p x%x x%x x%x\n", | ||
1699 | phba->brd_no, | ||
1700 | ndlp, ndlp->nlp_DID, | ||
1701 | ndlp->nlp_flag, data1); | ||
1702 | spin_unlock_irq(phba->host->host_lock); | ||
1703 | return ndlp; | ||
1704 | } | ||
1705 | } | ||
1706 | } | ||
1707 | |||
1708 | if (order & NLP_SEARCH_MAPPED) { | ||
1709 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list, | ||
1710 | nlp_listp) { | ||
1711 | if (lpfc_matchdid(phba, ndlp, did)) { | ||
1712 | |||
1713 | data1 = (((uint32_t) ndlp->nlp_state << 24) | | ||
1714 | ((uint32_t) ndlp->nlp_xri << 16) | | ||
1715 | ((uint32_t) ndlp->nlp_type << 8) | | ||
1716 | ((uint32_t) ndlp->nlp_rpi & 0xff)); | ||
1717 | /* FIND node DID mapped */ | ||
1718 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | ||
1719 | "%d:0930 FIND node DID mapped " | ||
1720 | "Data: x%p x%x x%x x%x\n", | ||
1721 | phba->brd_no, | ||
1722 | ndlp, ndlp->nlp_DID, | ||
1723 | ndlp->nlp_flag, data1); | ||
1724 | spin_unlock_irq(phba->host->host_lock); | ||
1725 | return ndlp; | ||
1726 | } | ||
1727 | } | ||
1728 | } | ||
1729 | |||
1730 | if (order & NLP_SEARCH_PLOGI) { | ||
1731 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, | ||
1732 | nlp_listp) { | ||
1733 | if (lpfc_matchdid(phba, ndlp, did)) { | ||
1734 | |||
1735 | data1 = (((uint32_t) ndlp->nlp_state << 24) | | ||
1736 | ((uint32_t) ndlp->nlp_xri << 16) | | ||
1737 | ((uint32_t) ndlp->nlp_type << 8) | | ||
1738 | ((uint32_t) ndlp->nlp_rpi & 0xff)); | ||
1739 | /* LOG change to PLOGI */ | ||
1740 | /* FIND node DID plogi */ | ||
1741 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | ||
1742 | "%d:0908 FIND node DID plogi " | ||
1743 | "Data: x%p x%x x%x x%x\n", | ||
1744 | phba->brd_no, | ||
1745 | ndlp, ndlp->nlp_DID, | ||
1746 | ndlp->nlp_flag, data1); | ||
1747 | spin_unlock_irq(phba->host->host_lock); | ||
1748 | return ndlp; | ||
1749 | } | ||
1750 | } | ||
1751 | } | ||
1752 | |||
1753 | if (order & NLP_SEARCH_ADISC) { | ||
1754 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, | ||
1755 | nlp_listp) { | ||
1756 | if (lpfc_matchdid(phba, ndlp, did)) { | ||
1757 | |||
1758 | data1 = (((uint32_t) ndlp->nlp_state << 24) | | ||
1759 | ((uint32_t) ndlp->nlp_xri << 16) | | ||
1760 | ((uint32_t) ndlp->nlp_type << 8) | | ||
1761 | ((uint32_t) ndlp->nlp_rpi & 0xff)); | ||
1762 | /* LOG change to ADISC */ | ||
1763 | /* FIND node DID adisc */ | ||
1764 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | ||
1765 | "%d:0931 FIND node DID adisc " | ||
1766 | "Data: x%p x%x x%x x%x\n", | ||
1767 | phba->brd_no, | ||
1768 | ndlp, ndlp->nlp_DID, | ||
1769 | ndlp->nlp_flag, data1); | ||
1770 | spin_unlock_irq(phba->host->host_lock); | ||
1771 | return ndlp; | ||
1772 | } | ||
1773 | } | ||
1774 | } | ||
1775 | |||
1776 | if (order & NLP_SEARCH_REGLOGIN) { | ||
1777 | list_for_each_entry_safe(ndlp, next_ndlp, | ||
1778 | &phba->fc_reglogin_list, nlp_listp) { | ||
1779 | if (lpfc_matchdid(phba, ndlp, did)) { | 1725 | if (lpfc_matchdid(phba, ndlp, did)) { |
1780 | |||
1781 | data1 = (((uint32_t) ndlp->nlp_state << 24) | | 1726 | data1 = (((uint32_t) ndlp->nlp_state << 24) | |
1782 | ((uint32_t) ndlp->nlp_xri << 16) | | 1727 | ((uint32_t) ndlp->nlp_xri << 16) | |
1783 | ((uint32_t) ndlp->nlp_type << 8) | | 1728 | ((uint32_t) ndlp->nlp_type << 8) | |
1784 | ((uint32_t) ndlp->nlp_rpi & 0xff)); | 1729 | ((uint32_t) ndlp->nlp_rpi & 0xff)); |
1785 | /* LOG change to REGLOGIN */ | ||
1786 | /* FIND node DID reglogin */ | ||
1787 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | 1730 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, |
1788 | "%d:0901 FIND node DID reglogin" | 1731 | "%d:0929 FIND node DID " |
1789 | " Data: x%p x%x x%x x%x\n", | 1732 | " Data: x%p x%x x%x x%x\n", |
1790 | phba->brd_no, | 1733 | phba->brd_no, |
1791 | ndlp, ndlp->nlp_DID, | 1734 | ndlp, ndlp->nlp_DID, |
@@ -1795,86 +1738,12 @@ lpfc_findnode_did(struct lpfc_hba * phba, uint32_t order, uint32_t did) | |||
1795 | } | 1738 | } |
1796 | } | 1739 | } |
1797 | } | 1740 | } |
1798 | |||
1799 | if (order & NLP_SEARCH_PRLI) { | ||
1800 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list, | ||
1801 | nlp_listp) { | ||
1802 | if (lpfc_matchdid(phba, ndlp, did)) { | ||
1803 | |||
1804 | data1 = (((uint32_t) ndlp->nlp_state << 24) | | ||
1805 | ((uint32_t) ndlp->nlp_xri << 16) | | ||
1806 | ((uint32_t) ndlp->nlp_type << 8) | | ||
1807 | ((uint32_t) ndlp->nlp_rpi & 0xff)); | ||
1808 | /* LOG change to PRLI */ | ||
1809 | /* FIND node DID prli */ | ||
1810 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | ||
1811 | "%d:0902 FIND node DID prli " | ||
1812 | "Data: x%p x%x x%x x%x\n", | ||
1813 | phba->brd_no, | ||
1814 | ndlp, ndlp->nlp_DID, | ||
1815 | ndlp->nlp_flag, data1); | ||
1816 | spin_unlock_irq(phba->host->host_lock); | ||
1817 | return ndlp; | ||
1818 | } | ||
1819 | } | ||
1820 | } | ||
1821 | |||
1822 | if (order & NLP_SEARCH_NPR) { | ||
1823 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, | ||
1824 | nlp_listp) { | ||
1825 | if (lpfc_matchdid(phba, ndlp, did)) { | ||
1826 | |||
1827 | data1 = (((uint32_t) ndlp->nlp_state << 24) | | ||
1828 | ((uint32_t) ndlp->nlp_xri << 16) | | ||
1829 | ((uint32_t) ndlp->nlp_type << 8) | | ||
1830 | ((uint32_t) ndlp->nlp_rpi & 0xff)); | ||
1831 | /* LOG change to NPR */ | ||
1832 | /* FIND node DID npr */ | ||
1833 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | ||
1834 | "%d:0903 FIND node DID npr " | ||
1835 | "Data: x%p x%x x%x x%x\n", | ||
1836 | phba->brd_no, | ||
1837 | ndlp, ndlp->nlp_DID, | ||
1838 | ndlp->nlp_flag, data1); | ||
1839 | spin_unlock_irq(phba->host->host_lock); | ||
1840 | return ndlp; | ||
1841 | } | ||
1842 | } | ||
1843 | } | ||
1844 | |||
1845 | if (order & NLP_SEARCH_UNUSED) { | ||
1846 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, | ||
1847 | nlp_listp) { | ||
1848 | if (lpfc_matchdid(phba, ndlp, did)) { | ||
1849 | |||
1850 | data1 = (((uint32_t) ndlp->nlp_state << 24) | | ||
1851 | ((uint32_t) ndlp->nlp_xri << 16) | | ||
1852 | ((uint32_t) ndlp->nlp_type << 8) | | ||
1853 | ((uint32_t) ndlp->nlp_rpi & 0xff)); | ||
1854 | /* LOG change to UNUSED */ | ||
1855 | /* FIND node DID unused */ | ||
1856 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, | ||
1857 | "%d:0905 FIND node DID unused " | ||
1858 | "Data: x%p x%x x%x x%x\n", | ||
1859 | phba->brd_no, | ||
1860 | ndlp, ndlp->nlp_DID, | ||
1861 | ndlp->nlp_flag, data1); | ||
1862 | spin_unlock_irq(phba->host->host_lock); | ||
1863 | return ndlp; | ||
1864 | } | ||
1865 | } | ||
1866 | } | ||
1867 | |||
1868 | spin_unlock_irq(phba->host->host_lock); | 1741 | spin_unlock_irq(phba->host->host_lock); |
1869 | 1742 | ||
1870 | /* FIND node did <did> NOT FOUND */ | 1743 | /* FIND node did <did> NOT FOUND */ |
1871 | lpfc_printf_log(phba, | 1744 | lpfc_printf_log(phba, KERN_INFO, LOG_NODE, |
1872 | KERN_INFO, | ||
1873 | LOG_NODE, | ||
1874 | "%d:0932 FIND node did x%x NOT FOUND Data: x%x\n", | 1745 | "%d:0932 FIND node did x%x NOT FOUND Data: x%x\n", |
1875 | phba->brd_no, did, order); | 1746 | phba->brd_no, did, order); |
1876 | |||
1877 | /* no match found */ | ||
1878 | return NULL; | 1747 | return NULL; |
1879 | } | 1748 | } |
1880 | 1749 | ||
@@ -2036,7 +1905,7 @@ lpfc_disc_start(struct lpfc_hba * phba) | |||
2036 | if (rc == MBX_NOT_FINISHED) { | 1905 | if (rc == MBX_NOT_FINISHED) { |
2037 | mempool_free( mbox, phba->mbox_mem_pool); | 1906 | mempool_free( mbox, phba->mbox_mem_pool); |
2038 | lpfc_disc_flush_list(phba); | 1907 | lpfc_disc_flush_list(phba); |
2039 | psli->ring[(psli->ip_ring)].flag &= | 1908 | psli->ring[(psli->extra_ring)].flag &= |
2040 | ~LPFC_STOP_IOCB_EVENT; | 1909 | ~LPFC_STOP_IOCB_EVENT; |
2041 | psli->ring[(psli->fcp_ring)].flag &= | 1910 | psli->ring[(psli->fcp_ring)].flag &= |
2042 | ~LPFC_STOP_IOCB_EVENT; | 1911 | ~LPFC_STOP_IOCB_EVENT; |
@@ -2415,7 +2284,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) | |||
2415 | 2284 | ||
2416 | if (clrlaerr) { | 2285 | if (clrlaerr) { |
2417 | lpfc_disc_flush_list(phba); | 2286 | lpfc_disc_flush_list(phba); |
2418 | psli->ring[(psli->ip_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 2287 | psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
2419 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 2288 | psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
2420 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; | 2289 | psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT; |
2421 | phba->hba_state = LPFC_HBA_READY; | 2290 | phba->hba_state = LPFC_HBA_READY; |
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index eedf98801366..f79cb6136906 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
@@ -42,14 +42,14 @@ | |||
42 | #define FCELSSIZE 1024 /* maximum ELS transfer size */ | 42 | #define FCELSSIZE 1024 /* maximum ELS transfer size */ |
43 | 43 | ||
44 | #define LPFC_FCP_RING 0 /* ring 0 for FCP initiator commands */ | 44 | #define LPFC_FCP_RING 0 /* ring 0 for FCP initiator commands */ |
45 | #define LPFC_IP_RING 1 /* ring 1 for IP commands */ | 45 | #define LPFC_EXTRA_RING 1 /* ring 1 for other protocols */ |
46 | #define LPFC_ELS_RING 2 /* ring 2 for ELS commands */ | 46 | #define LPFC_ELS_RING 2 /* ring 2 for ELS commands */ |
47 | #define LPFC_FCP_NEXT_RING 3 | 47 | #define LPFC_FCP_NEXT_RING 3 |
48 | 48 | ||
49 | #define SLI2_IOCB_CMD_R0_ENTRIES 172 /* SLI-2 FCP command ring entries */ | 49 | #define SLI2_IOCB_CMD_R0_ENTRIES 172 /* SLI-2 FCP command ring entries */ |
50 | #define SLI2_IOCB_RSP_R0_ENTRIES 134 /* SLI-2 FCP response ring entries */ | 50 | #define SLI2_IOCB_RSP_R0_ENTRIES 134 /* SLI-2 FCP response ring entries */ |
51 | #define SLI2_IOCB_CMD_R1_ENTRIES 4 /* SLI-2 IP command ring entries */ | 51 | #define SLI2_IOCB_CMD_R1_ENTRIES 4 /* SLI-2 extra command ring entries */ |
52 | #define SLI2_IOCB_RSP_R1_ENTRIES 4 /* SLI-2 IP response ring entries */ | 52 | #define SLI2_IOCB_RSP_R1_ENTRIES 4 /* SLI-2 extra response ring entries */ |
53 | #define SLI2_IOCB_CMD_R1XTRA_ENTRIES 36 /* SLI-2 extra FCP cmd ring entries */ | 53 | #define SLI2_IOCB_CMD_R1XTRA_ENTRIES 36 /* SLI-2 extra FCP cmd ring entries */ |
54 | #define SLI2_IOCB_RSP_R1XTRA_ENTRIES 52 /* SLI-2 extra FCP rsp ring entries */ | 54 | #define SLI2_IOCB_RSP_R1XTRA_ENTRIES 52 /* SLI-2 extra FCP rsp ring entries */ |
55 | #define SLI2_IOCB_CMD_R2_ENTRIES 20 /* SLI-2 ELS command ring entries */ | 55 | #define SLI2_IOCB_CMD_R2_ENTRIES 20 /* SLI-2 ELS command ring entries */ |
@@ -121,6 +121,20 @@ struct lpfc_sli_ct_request { | |||
121 | 121 | ||
122 | uint32_t rsvd[7]; | 122 | uint32_t rsvd[7]; |
123 | } rft; | 123 | } rft; |
124 | struct rff { | ||
125 | uint32_t PortId; | ||
126 | uint8_t reserved[2]; | ||
127 | #ifdef __BIG_ENDIAN_BITFIELD | ||
128 | uint8_t feature_res:6; | ||
129 | uint8_t feature_init:1; | ||
130 | uint8_t feature_tgt:1; | ||
131 | #else /* __LITTLE_ENDIAN_BITFIELD */ | ||
132 | uint8_t feature_tgt:1; | ||
133 | uint8_t feature_init:1; | ||
134 | uint8_t feature_res:6; | ||
135 | #endif | ||
136 | uint8_t type_code; /* type=8 for FCP */ | ||
137 | } rff; | ||
124 | struct rnn { | 138 | struct rnn { |
125 | uint32_t PortId; /* For RNN_ID requests */ | 139 | uint32_t PortId; /* For RNN_ID requests */ |
126 | uint8_t wwnn[8]; | 140 | uint8_t wwnn[8]; |
@@ -136,6 +150,7 @@ struct lpfc_sli_ct_request { | |||
136 | #define SLI_CT_REVISION 1 | 150 | #define SLI_CT_REVISION 1 |
137 | #define GID_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 260) | 151 | #define GID_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 260) |
138 | #define RFT_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 228) | 152 | #define RFT_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 228) |
153 | #define RFF_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 235) | ||
139 | #define RNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 252) | 154 | #define RNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request) - 252) |
140 | #define RSNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request)) | 155 | #define RSNN_REQUEST_SZ (sizeof(struct lpfc_sli_ct_request)) |
141 | 156 | ||
@@ -225,6 +240,7 @@ struct lpfc_sli_ct_request { | |||
225 | #define SLI_CTNS_RNN_ID 0x0213 | 240 | #define SLI_CTNS_RNN_ID 0x0213 |
226 | #define SLI_CTNS_RCS_ID 0x0214 | 241 | #define SLI_CTNS_RCS_ID 0x0214 |
227 | #define SLI_CTNS_RFT_ID 0x0217 | 242 | #define SLI_CTNS_RFT_ID 0x0217 |
243 | #define SLI_CTNS_RFF_ID 0x021F | ||
228 | #define SLI_CTNS_RSPN_ID 0x0218 | 244 | #define SLI_CTNS_RSPN_ID 0x0218 |
229 | #define SLI_CTNS_RPT_ID 0x021A | 245 | #define SLI_CTNS_RPT_ID 0x021A |
230 | #define SLI_CTNS_RIP_NN 0x0235 | 246 | #define SLI_CTNS_RIP_NN 0x0235 |
@@ -1089,12 +1105,6 @@ typedef struct { | |||
1089 | #define PCI_DEVICE_ID_ZEPHYR_SCSP 0xfe11 | 1105 | #define PCI_DEVICE_ID_ZEPHYR_SCSP 0xfe11 |
1090 | #define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12 | 1106 | #define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12 |
1091 | 1107 | ||
1092 | #define PCI_SUBSYSTEM_ID_LP11000S 0xfc11 | ||
1093 | #define PCI_SUBSYSTEM_ID_LP11002S 0xfc12 | ||
1094 | #define PCI_SUBSYSTEM_ID_LPE11000S 0xfc21 | ||
1095 | #define PCI_SUBSYSTEM_ID_LPE11002S 0xfc22 | ||
1096 | #define PCI_SUBSYSTEM_ID_LPE11010S 0xfc2A | ||
1097 | |||
1098 | #define JEDEC_ID_ADDRESS 0x0080001c | 1108 | #define JEDEC_ID_ADDRESS 0x0080001c |
1099 | #define FIREFLY_JEDEC_ID 0x1ACC | 1109 | #define FIREFLY_JEDEC_ID 0x1ACC |
1100 | #define SUPERFLY_JEDEC_ID 0x0020 | 1110 | #define SUPERFLY_JEDEC_ID 0x0020 |
@@ -1284,6 +1294,10 @@ typedef struct { /* FireFly BIU registers */ | |||
1284 | #define CMD_FCP_IREAD_CX 0x1B | 1294 | #define CMD_FCP_IREAD_CX 0x1B |
1285 | #define CMD_FCP_ICMND_CR 0x1C | 1295 | #define CMD_FCP_ICMND_CR 0x1C |
1286 | #define CMD_FCP_ICMND_CX 0x1D | 1296 | #define CMD_FCP_ICMND_CX 0x1D |
1297 | #define CMD_FCP_TSEND_CX 0x1F | ||
1298 | #define CMD_FCP_TRECEIVE_CX 0x21 | ||
1299 | #define CMD_FCP_TRSP_CX 0x23 | ||
1300 | #define CMD_FCP_AUTO_TRSP_CX 0x29 | ||
1287 | 1301 | ||
1288 | #define CMD_ADAPTER_MSG 0x20 | 1302 | #define CMD_ADAPTER_MSG 0x20 |
1289 | #define CMD_ADAPTER_DUMP 0x22 | 1303 | #define CMD_ADAPTER_DUMP 0x22 |
@@ -1310,6 +1324,9 @@ typedef struct { /* FireFly BIU registers */ | |||
1310 | #define CMD_FCP_IREAD64_CX 0x9B | 1324 | #define CMD_FCP_IREAD64_CX 0x9B |
1311 | #define CMD_FCP_ICMND64_CR 0x9C | 1325 | #define CMD_FCP_ICMND64_CR 0x9C |
1312 | #define CMD_FCP_ICMND64_CX 0x9D | 1326 | #define CMD_FCP_ICMND64_CX 0x9D |
1327 | #define CMD_FCP_TSEND64_CX 0x9F | ||
1328 | #define CMD_FCP_TRECEIVE64_CX 0xA1 | ||
1329 | #define CMD_FCP_TRSP64_CX 0xA3 | ||
1313 | 1330 | ||
1314 | #define CMD_GEN_REQUEST64_CR 0xC2 | 1331 | #define CMD_GEN_REQUEST64_CR 0xC2 |
1315 | #define CMD_GEN_REQUEST64_CX 0xC3 | 1332 | #define CMD_GEN_REQUEST64_CX 0xC3 |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index a5723ad0a099..afca45cdbcef 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -268,6 +268,8 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
268 | kfree(mp); | 268 | kfree(mp); |
269 | pmb->context1 = NULL; | 269 | pmb->context1 = NULL; |
270 | 270 | ||
271 | if (phba->cfg_soft_wwnn) | ||
272 | u64_to_wwn(phba->cfg_soft_wwnn, phba->fc_sparam.nodeName.u.wwn); | ||
271 | if (phba->cfg_soft_wwpn) | 273 | if (phba->cfg_soft_wwpn) |
272 | u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn); | 274 | u64_to_wwn(phba->cfg_soft_wwpn, phba->fc_sparam.portName.u.wwn); |
273 | memcpy(&phba->fc_nodename, &phba->fc_sparam.nodeName, | 275 | memcpy(&phba->fc_nodename, &phba->fc_sparam.nodeName, |
@@ -349,8 +351,8 @@ lpfc_config_port_post(struct lpfc_hba * phba) | |||
349 | phba->hba_state = LPFC_LINK_DOWN; | 351 | phba->hba_state = LPFC_LINK_DOWN; |
350 | 352 | ||
351 | /* Only process IOCBs on ring 0 till hba_state is READY */ | 353 | /* Only process IOCBs on ring 0 till hba_state is READY */ |
352 | if (psli->ring[psli->ip_ring].cmdringaddr) | 354 | if (psli->ring[psli->extra_ring].cmdringaddr) |
353 | psli->ring[psli->ip_ring].flag |= LPFC_STOP_IOCB_EVENT; | 355 | psli->ring[psli->extra_ring].flag |= LPFC_STOP_IOCB_EVENT; |
354 | if (psli->ring[psli->fcp_ring].cmdringaddr) | 356 | if (psli->ring[psli->fcp_ring].cmdringaddr) |
355 | psli->ring[psli->fcp_ring].flag |= LPFC_STOP_IOCB_EVENT; | 357 | psli->ring[psli->fcp_ring].flag |= LPFC_STOP_IOCB_EVENT; |
356 | if (psli->ring[psli->next_ring].cmdringaddr) | 358 | if (psli->ring[psli->next_ring].cmdringaddr) |
@@ -517,7 +519,8 @@ lpfc_handle_eratt(struct lpfc_hba * phba) | |||
517 | struct lpfc_sli_ring *pring; | 519 | struct lpfc_sli_ring *pring; |
518 | uint32_t event_data; | 520 | uint32_t event_data; |
519 | 521 | ||
520 | if (phba->work_hs & HS_FFER6) { | 522 | if (phba->work_hs & HS_FFER6 || |
523 | phba->work_hs & HS_FFER5) { | ||
521 | /* Re-establishing Link */ | 524 | /* Re-establishing Link */ |
522 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, | 525 | lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT, |
523 | "%d:1301 Re-establishing Link " | 526 | "%d:1301 Re-establishing Link " |
@@ -611,7 +614,7 @@ lpfc_handle_latt(struct lpfc_hba * phba) | |||
611 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; | 614 | pmb->mbox_cmpl = lpfc_mbx_cmpl_read_la; |
612 | rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); | 615 | rc = lpfc_sli_issue_mbox (phba, pmb, (MBX_NOWAIT | MBX_STOP_IOCB)); |
613 | if (rc == MBX_NOT_FINISHED) | 616 | if (rc == MBX_NOT_FINISHED) |
614 | goto lpfc_handle_latt_free_mp; | 617 | goto lpfc_handle_latt_free_mbuf; |
615 | 618 | ||
616 | /* Clear Link Attention in HA REG */ | 619 | /* Clear Link Attention in HA REG */ |
617 | spin_lock_irq(phba->host->host_lock); | 620 | spin_lock_irq(phba->host->host_lock); |
@@ -621,6 +624,8 @@ lpfc_handle_latt(struct lpfc_hba * phba) | |||
621 | 624 | ||
622 | return; | 625 | return; |
623 | 626 | ||
627 | lpfc_handle_latt_free_mbuf: | ||
628 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
624 | lpfc_handle_latt_free_mp: | 629 | lpfc_handle_latt_free_mp: |
625 | kfree(mp); | 630 | kfree(mp); |
626 | lpfc_handle_latt_free_pmb: | 631 | lpfc_handle_latt_free_pmb: |
@@ -802,19 +807,13 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | |||
802 | { | 807 | { |
803 | lpfc_vpd_t *vp; | 808 | lpfc_vpd_t *vp; |
804 | uint16_t dev_id = phba->pcidev->device; | 809 | uint16_t dev_id = phba->pcidev->device; |
805 | uint16_t dev_subid = phba->pcidev->subsystem_device; | ||
806 | uint8_t hdrtype; | ||
807 | int max_speed; | 810 | int max_speed; |
808 | char * ports; | ||
809 | struct { | 811 | struct { |
810 | char * name; | 812 | char * name; |
811 | int max_speed; | 813 | int max_speed; |
812 | char * ports; | ||
813 | char * bus; | 814 | char * bus; |
814 | } m = {"<Unknown>", 0, "", ""}; | 815 | } m = {"<Unknown>", 0, ""}; |
815 | 816 | ||
816 | pci_read_config_byte(phba->pcidev, PCI_HEADER_TYPE, &hdrtype); | ||
817 | ports = (hdrtype == 0x80) ? "2-port " : ""; | ||
818 | if (mdp && mdp[0] != '\0' | 817 | if (mdp && mdp[0] != '\0' |
819 | && descp && descp[0] != '\0') | 818 | && descp && descp[0] != '\0') |
820 | return; | 819 | return; |
@@ -834,130 +833,93 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | |||
834 | 833 | ||
835 | switch (dev_id) { | 834 | switch (dev_id) { |
836 | case PCI_DEVICE_ID_FIREFLY: | 835 | case PCI_DEVICE_ID_FIREFLY: |
837 | m = (typeof(m)){"LP6000", max_speed, "", "PCI"}; | 836 | m = (typeof(m)){"LP6000", max_speed, "PCI"}; |
838 | break; | 837 | break; |
839 | case PCI_DEVICE_ID_SUPERFLY: | 838 | case PCI_DEVICE_ID_SUPERFLY: |
840 | if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3) | 839 | if (vp->rev.biuRev >= 1 && vp->rev.biuRev <= 3) |
841 | m = (typeof(m)){"LP7000", max_speed, "", "PCI"}; | 840 | m = (typeof(m)){"LP7000", max_speed, "PCI"}; |
842 | else | 841 | else |
843 | m = (typeof(m)){"LP7000E", max_speed, "", "PCI"}; | 842 | m = (typeof(m)){"LP7000E", max_speed, "PCI"}; |
844 | break; | 843 | break; |
845 | case PCI_DEVICE_ID_DRAGONFLY: | 844 | case PCI_DEVICE_ID_DRAGONFLY: |
846 | m = (typeof(m)){"LP8000", max_speed, "", "PCI"}; | 845 | m = (typeof(m)){"LP8000", max_speed, "PCI"}; |
847 | break; | 846 | break; |
848 | case PCI_DEVICE_ID_CENTAUR: | 847 | case PCI_DEVICE_ID_CENTAUR: |
849 | if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) | 848 | if (FC_JEDEC_ID(vp->rev.biuRev) == CENTAUR_2G_JEDEC_ID) |
850 | m = (typeof(m)){"LP9002", max_speed, "", "PCI"}; | 849 | m = (typeof(m)){"LP9002", max_speed, "PCI"}; |
851 | else | 850 | else |
852 | m = (typeof(m)){"LP9000", max_speed, "", "PCI"}; | 851 | m = (typeof(m)){"LP9000", max_speed, "PCI"}; |
853 | break; | 852 | break; |
854 | case PCI_DEVICE_ID_RFLY: | 853 | case PCI_DEVICE_ID_RFLY: |
855 | m = (typeof(m)){"LP952", max_speed, "", "PCI"}; | 854 | m = (typeof(m)){"LP952", max_speed, "PCI"}; |
856 | break; | 855 | break; |
857 | case PCI_DEVICE_ID_PEGASUS: | 856 | case PCI_DEVICE_ID_PEGASUS: |
858 | m = (typeof(m)){"LP9802", max_speed, "", "PCI-X"}; | 857 | m = (typeof(m)){"LP9802", max_speed, "PCI-X"}; |
859 | break; | 858 | break; |
860 | case PCI_DEVICE_ID_THOR: | 859 | case PCI_DEVICE_ID_THOR: |
861 | if (hdrtype == 0x80) | 860 | m = (typeof(m)){"LP10000", max_speed, "PCI-X"}; |
862 | m = (typeof(m)){"LP10000DC", | ||
863 | max_speed, ports, "PCI-X"}; | ||
864 | else | ||
865 | m = (typeof(m)){"LP10000", | ||
866 | max_speed, ports, "PCI-X"}; | ||
867 | break; | 861 | break; |
868 | case PCI_DEVICE_ID_VIPER: | 862 | case PCI_DEVICE_ID_VIPER: |
869 | m = (typeof(m)){"LPX1000", max_speed, "", "PCI-X"}; | 863 | m = (typeof(m)){"LPX1000", max_speed, "PCI-X"}; |
870 | break; | 864 | break; |
871 | case PCI_DEVICE_ID_PFLY: | 865 | case PCI_DEVICE_ID_PFLY: |
872 | m = (typeof(m)){"LP982", max_speed, "", "PCI-X"}; | 866 | m = (typeof(m)){"LP982", max_speed, "PCI-X"}; |
873 | break; | 867 | break; |
874 | case PCI_DEVICE_ID_TFLY: | 868 | case PCI_DEVICE_ID_TFLY: |
875 | if (hdrtype == 0x80) | 869 | m = (typeof(m)){"LP1050", max_speed, "PCI-X"}; |
876 | m = (typeof(m)){"LP1050DC", max_speed, ports, "PCI-X"}; | ||
877 | else | ||
878 | m = (typeof(m)){"LP1050", max_speed, ports, "PCI-X"}; | ||
879 | break; | 870 | break; |
880 | case PCI_DEVICE_ID_HELIOS: | 871 | case PCI_DEVICE_ID_HELIOS: |
881 | if (hdrtype == 0x80) | 872 | m = (typeof(m)){"LP11000", max_speed, "PCI-X2"}; |
882 | m = (typeof(m)){"LP11002", max_speed, ports, "PCI-X2"}; | ||
883 | else | ||
884 | m = (typeof(m)){"LP11000", max_speed, ports, "PCI-X2"}; | ||
885 | break; | 873 | break; |
886 | case PCI_DEVICE_ID_HELIOS_SCSP: | 874 | case PCI_DEVICE_ID_HELIOS_SCSP: |
887 | m = (typeof(m)){"LP11000-SP", max_speed, ports, "PCI-X2"}; | 875 | m = (typeof(m)){"LP11000-SP", max_speed, "PCI-X2"}; |
888 | break; | 876 | break; |
889 | case PCI_DEVICE_ID_HELIOS_DCSP: | 877 | case PCI_DEVICE_ID_HELIOS_DCSP: |
890 | m = (typeof(m)){"LP11002-SP", max_speed, ports, "PCI-X2"}; | 878 | m = (typeof(m)){"LP11002-SP", max_speed, "PCI-X2"}; |
891 | break; | 879 | break; |
892 | case PCI_DEVICE_ID_NEPTUNE: | 880 | case PCI_DEVICE_ID_NEPTUNE: |
893 | if (hdrtype == 0x80) | 881 | m = (typeof(m)){"LPe1000", max_speed, "PCIe"}; |
894 | m = (typeof(m)){"LPe1002", max_speed, ports, "PCIe"}; | ||
895 | else | ||
896 | m = (typeof(m)){"LPe1000", max_speed, ports, "PCIe"}; | ||
897 | break; | 882 | break; |
898 | case PCI_DEVICE_ID_NEPTUNE_SCSP: | 883 | case PCI_DEVICE_ID_NEPTUNE_SCSP: |
899 | m = (typeof(m)){"LPe1000-SP", max_speed, ports, "PCIe"}; | 884 | m = (typeof(m)){"LPe1000-SP", max_speed, "PCIe"}; |
900 | break; | 885 | break; |
901 | case PCI_DEVICE_ID_NEPTUNE_DCSP: | 886 | case PCI_DEVICE_ID_NEPTUNE_DCSP: |
902 | m = (typeof(m)){"LPe1002-SP", max_speed, ports, "PCIe"}; | 887 | m = (typeof(m)){"LPe1002-SP", max_speed, "PCIe"}; |
903 | break; | 888 | break; |
904 | case PCI_DEVICE_ID_BMID: | 889 | case PCI_DEVICE_ID_BMID: |
905 | m = (typeof(m)){"LP1150", max_speed, ports, "PCI-X2"}; | 890 | m = (typeof(m)){"LP1150", max_speed, "PCI-X2"}; |
906 | break; | 891 | break; |
907 | case PCI_DEVICE_ID_BSMB: | 892 | case PCI_DEVICE_ID_BSMB: |
908 | m = (typeof(m)){"LP111", max_speed, ports, "PCI-X2"}; | 893 | m = (typeof(m)){"LP111", max_speed, "PCI-X2"}; |
909 | break; | 894 | break; |
910 | case PCI_DEVICE_ID_ZEPHYR: | 895 | case PCI_DEVICE_ID_ZEPHYR: |
911 | if (hdrtype == 0x80) | 896 | m = (typeof(m)){"LPe11000", max_speed, "PCIe"}; |
912 | m = (typeof(m)){"LPe11002", max_speed, ports, "PCIe"}; | ||
913 | else | ||
914 | m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"}; | ||
915 | break; | 897 | break; |
916 | case PCI_DEVICE_ID_ZEPHYR_SCSP: | 898 | case PCI_DEVICE_ID_ZEPHYR_SCSP: |
917 | m = (typeof(m)){"LPe11000", max_speed, ports, "PCIe"}; | 899 | m = (typeof(m)){"LPe11000", max_speed, "PCIe"}; |
918 | break; | 900 | break; |
919 | case PCI_DEVICE_ID_ZEPHYR_DCSP: | 901 | case PCI_DEVICE_ID_ZEPHYR_DCSP: |
920 | m = (typeof(m)){"LPe11002-SP", max_speed, ports, "PCIe"}; | 902 | m = (typeof(m)){"LPe11002-SP", max_speed, "PCIe"}; |
921 | break; | 903 | break; |
922 | case PCI_DEVICE_ID_ZMID: | 904 | case PCI_DEVICE_ID_ZMID: |
923 | m = (typeof(m)){"LPe1150", max_speed, ports, "PCIe"}; | 905 | m = (typeof(m)){"LPe1150", max_speed, "PCIe"}; |
924 | break; | 906 | break; |
925 | case PCI_DEVICE_ID_ZSMB: | 907 | case PCI_DEVICE_ID_ZSMB: |
926 | m = (typeof(m)){"LPe111", max_speed, ports, "PCIe"}; | 908 | m = (typeof(m)){"LPe111", max_speed, "PCIe"}; |
927 | break; | 909 | break; |
928 | case PCI_DEVICE_ID_LP101: | 910 | case PCI_DEVICE_ID_LP101: |
929 | m = (typeof(m)){"LP101", max_speed, ports, "PCI-X"}; | 911 | m = (typeof(m)){"LP101", max_speed, "PCI-X"}; |
930 | break; | 912 | break; |
931 | case PCI_DEVICE_ID_LP10000S: | 913 | case PCI_DEVICE_ID_LP10000S: |
932 | m = (typeof(m)){"LP10000-S", max_speed, ports, "PCI"}; | 914 | m = (typeof(m)){"LP10000-S", max_speed, "PCI"}; |
933 | break; | 915 | break; |
934 | case PCI_DEVICE_ID_LP11000S: | 916 | case PCI_DEVICE_ID_LP11000S: |
917 | m = (typeof(m)){"LP11000-S", max_speed, | ||
918 | "PCI-X2"}; | ||
919 | break; | ||
935 | case PCI_DEVICE_ID_LPE11000S: | 920 | case PCI_DEVICE_ID_LPE11000S: |
936 | switch (dev_subid) { | 921 | m = (typeof(m)){"LPe11000-S", max_speed, |
937 | case PCI_SUBSYSTEM_ID_LP11000S: | 922 | "PCIe"}; |
938 | m = (typeof(m)){"LP11000-S", max_speed, | ||
939 | ports, "PCI-X2"}; | ||
940 | break; | ||
941 | case PCI_SUBSYSTEM_ID_LP11002S: | ||
942 | m = (typeof(m)){"LP11002-S", max_speed, | ||
943 | ports, "PCI-X2"}; | ||
944 | break; | ||
945 | case PCI_SUBSYSTEM_ID_LPE11000S: | ||
946 | m = (typeof(m)){"LPe11000-S", max_speed, | ||
947 | ports, "PCIe"}; | ||
948 | break; | ||
949 | case PCI_SUBSYSTEM_ID_LPE11002S: | ||
950 | m = (typeof(m)){"LPe11002-S", max_speed, | ||
951 | ports, "PCIe"}; | ||
952 | break; | ||
953 | case PCI_SUBSYSTEM_ID_LPE11010S: | ||
954 | m = (typeof(m)){"LPe11010-S", max_speed, | ||
955 | "10-port ", "PCIe"}; | ||
956 | break; | ||
957 | default: | ||
958 | m = (typeof(m)){ NULL }; | ||
959 | break; | ||
960 | } | ||
961 | break; | 923 | break; |
962 | default: | 924 | default: |
963 | m = (typeof(m)){ NULL }; | 925 | m = (typeof(m)){ NULL }; |
@@ -968,8 +930,8 @@ lpfc_get_hba_model_desc(struct lpfc_hba * phba, uint8_t * mdp, uint8_t * descp) | |||
968 | snprintf(mdp, 79,"%s", m.name); | 930 | snprintf(mdp, 79,"%s", m.name); |
969 | if (descp && descp[0] == '\0') | 931 | if (descp && descp[0] == '\0') |
970 | snprintf(descp, 255, | 932 | snprintf(descp, 255, |
971 | "Emulex %s %dGb %s%s Fibre Channel Adapter", | 933 | "Emulex %s %dGb %s Fibre Channel Adapter", |
972 | m.name, m.max_speed, m.ports, m.bus); | 934 | m.name, m.max_speed, m.bus); |
973 | } | 935 | } |
974 | 936 | ||
975 | /**************************************************/ | 937 | /**************************************************/ |
@@ -1651,6 +1613,14 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |||
1651 | if (error) | 1613 | if (error) |
1652 | goto out_remove_host; | 1614 | goto out_remove_host; |
1653 | 1615 | ||
1616 | if (phba->cfg_use_msi) { | ||
1617 | error = pci_enable_msi(phba->pcidev); | ||
1618 | if (error) | ||
1619 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, "%d:0452 " | ||
1620 | "Enable MSI failed, continuing with " | ||
1621 | "IRQ\n", phba->brd_no); | ||
1622 | } | ||
1623 | |||
1654 | error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, | 1624 | error = request_irq(phba->pcidev->irq, lpfc_intr_handler, IRQF_SHARED, |
1655 | LPFC_DRIVER_NAME, phba); | 1625 | LPFC_DRIVER_NAME, phba); |
1656 | if (error) { | 1626 | if (error) { |
@@ -1730,6 +1700,7 @@ out_free_irq: | |||
1730 | lpfc_stop_timer(phba); | 1700 | lpfc_stop_timer(phba); |
1731 | phba->work_hba_events = 0; | 1701 | phba->work_hba_events = 0; |
1732 | free_irq(phba->pcidev->irq, phba); | 1702 | free_irq(phba->pcidev->irq, phba); |
1703 | pci_disable_msi(phba->pcidev); | ||
1733 | out_free_sysfs_attr: | 1704 | out_free_sysfs_attr: |
1734 | lpfc_free_sysfs_attr(phba); | 1705 | lpfc_free_sysfs_attr(phba); |
1735 | out_remove_host: | 1706 | out_remove_host: |
@@ -1796,6 +1767,7 @@ lpfc_pci_remove_one(struct pci_dev *pdev) | |||
1796 | 1767 | ||
1797 | /* Release the irq reservation */ | 1768 | /* Release the irq reservation */ |
1798 | free_irq(phba->pcidev->irq, phba); | 1769 | free_irq(phba->pcidev->irq, phba); |
1770 | pci_disable_msi(phba->pcidev); | ||
1799 | 1771 | ||
1800 | lpfc_cleanup(phba, 0); | 1772 | lpfc_cleanup(phba, 0); |
1801 | lpfc_stop_timer(phba); | 1773 | lpfc_stop_timer(phba); |
diff --git a/drivers/scsi/lpfc/lpfc_logmsg.h b/drivers/scsi/lpfc/lpfc_logmsg.h index 62c8ca862e9e..438cbcd9eb13 100644 --- a/drivers/scsi/lpfc/lpfc_logmsg.h +++ b/drivers/scsi/lpfc/lpfc_logmsg.h | |||
@@ -28,7 +28,7 @@ | |||
28 | #define LOG_NODE 0x80 /* Node table events */ | 28 | #define LOG_NODE 0x80 /* Node table events */ |
29 | #define LOG_MISC 0x400 /* Miscellaneous events */ | 29 | #define LOG_MISC 0x400 /* Miscellaneous events */ |
30 | #define LOG_SLI 0x800 /* SLI events */ | 30 | #define LOG_SLI 0x800 /* SLI events */ |
31 | #define LOG_CHK_COND 0x1000 /* FCP Check condition flag */ | 31 | #define LOG_FCP_ERROR 0x1000 /* log errors, not underruns */ |
32 | #define LOG_LIBDFC 0x2000 /* Libdfc events */ | 32 | #define LOG_LIBDFC 0x2000 /* Libdfc events */ |
33 | #define LOG_ALL_MSG 0xffff /* LOG all messages */ | 33 | #define LOG_ALL_MSG 0xffff /* LOG all messages */ |
34 | 34 | ||
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index d5f415007db2..0c7e731dc45a 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -739,7 +739,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
739 | uint32_t evt) | 739 | uint32_t evt) |
740 | { | 740 | { |
741 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 741 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
742 | struct lpfc_dmabuf *pcmd, *prsp; | 742 | struct lpfc_dmabuf *pcmd, *prsp, *mp; |
743 | uint32_t *lp; | 743 | uint32_t *lp; |
744 | IOCB_t *irsp; | 744 | IOCB_t *irsp; |
745 | struct serv_parm *sp; | 745 | struct serv_parm *sp; |
@@ -829,6 +829,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
829 | NLP_REGLOGIN_LIST); | 829 | NLP_REGLOGIN_LIST); |
830 | return ndlp->nlp_state; | 830 | return ndlp->nlp_state; |
831 | } | 831 | } |
832 | mp = (struct lpfc_dmabuf *)mbox->context1; | ||
833 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
834 | kfree(mp); | ||
832 | mempool_free(mbox, phba->mbox_mem_pool); | 835 | mempool_free(mbox, phba->mbox_mem_pool); |
833 | } else { | 836 | } else { |
834 | mempool_free(mbox, phba->mbox_mem_pool); | 837 | mempool_free(mbox, phba->mbox_mem_pool); |
@@ -1620,8 +1623,8 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, | |||
1620 | * or discovery in progress for this node. Starting discovery | 1623 | * or discovery in progress for this node. Starting discovery |
1621 | * here will affect the counting of discovery threads. | 1624 | * here will affect the counting of discovery threads. |
1622 | */ | 1625 | */ |
1623 | if ((!(ndlp->nlp_flag & NLP_DELAY_TMO)) && | 1626 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO) && |
1624 | (ndlp->nlp_flag & NLP_NPR_2B_DISC)){ | 1627 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC)){ |
1625 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1628 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
1626 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1629 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1627 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1630 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 97ae98dc95d0..c3e68e0d8f74 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -297,8 +297,10 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) | |||
297 | uint32_t fcpi_parm = lpfc_cmd->cur_iocbq.iocb.un.fcpi.fcpi_parm; | 297 | uint32_t fcpi_parm = lpfc_cmd->cur_iocbq.iocb.un.fcpi.fcpi_parm; |
298 | uint32_t resp_info = fcprsp->rspStatus2; | 298 | uint32_t resp_info = fcprsp->rspStatus2; |
299 | uint32_t scsi_status = fcprsp->rspStatus3; | 299 | uint32_t scsi_status = fcprsp->rspStatus3; |
300 | uint32_t *lp; | ||
300 | uint32_t host_status = DID_OK; | 301 | uint32_t host_status = DID_OK; |
301 | uint32_t rsplen = 0; | 302 | uint32_t rsplen = 0; |
303 | uint32_t logit = LOG_FCP | LOG_FCP_ERROR; | ||
302 | 304 | ||
303 | /* | 305 | /* |
304 | * If this is a task management command, there is no | 306 | * If this is a task management command, there is no |
@@ -310,10 +312,25 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) | |||
310 | goto out; | 312 | goto out; |
311 | } | 313 | } |
312 | 314 | ||
313 | lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, | 315 | if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) { |
314 | "%d:0730 FCP command failed: RSP " | 316 | uint32_t snslen = be32_to_cpu(fcprsp->rspSnsLen); |
315 | "Data: x%x x%x x%x x%x x%x x%x\n", | 317 | if (snslen > SCSI_SENSE_BUFFERSIZE) |
316 | phba->brd_no, resp_info, scsi_status, | 318 | snslen = SCSI_SENSE_BUFFERSIZE; |
319 | |||
320 | if (resp_info & RSP_LEN_VALID) | ||
321 | rsplen = be32_to_cpu(fcprsp->rspRspLen); | ||
322 | memcpy(cmnd->sense_buffer, &fcprsp->rspInfo0 + rsplen, snslen); | ||
323 | } | ||
324 | lp = (uint32_t *)cmnd->sense_buffer; | ||
325 | |||
326 | if (!scsi_status && (resp_info & RESID_UNDER)) | ||
327 | logit = LOG_FCP; | ||
328 | |||
329 | lpfc_printf_log(phba, KERN_WARNING, logit, | ||
330 | "%d:0730 FCP command x%x failed: x%x SNS x%x x%x " | ||
331 | "Data: x%x x%x x%x x%x x%x\n", | ||
332 | phba->brd_no, cmnd->cmnd[0], scsi_status, | ||
333 | be32_to_cpu(*lp), be32_to_cpu(*(lp + 3)), resp_info, | ||
317 | be32_to_cpu(fcprsp->rspResId), | 334 | be32_to_cpu(fcprsp->rspResId), |
318 | be32_to_cpu(fcprsp->rspSnsLen), | 335 | be32_to_cpu(fcprsp->rspSnsLen), |
319 | be32_to_cpu(fcprsp->rspRspLen), | 336 | be32_to_cpu(fcprsp->rspRspLen), |
@@ -328,14 +345,6 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) | |||
328 | } | 345 | } |
329 | } | 346 | } |
330 | 347 | ||
331 | if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen) { | ||
332 | uint32_t snslen = be32_to_cpu(fcprsp->rspSnsLen); | ||
333 | if (snslen > SCSI_SENSE_BUFFERSIZE) | ||
334 | snslen = SCSI_SENSE_BUFFERSIZE; | ||
335 | |||
336 | memcpy(cmnd->sense_buffer, &fcprsp->rspInfo0 + rsplen, snslen); | ||
337 | } | ||
338 | |||
339 | cmnd->resid = 0; | 348 | cmnd->resid = 0; |
340 | if (resp_info & RESID_UNDER) { | 349 | if (resp_info & RESID_UNDER) { |
341 | cmnd->resid = be32_to_cpu(fcprsp->rspResId); | 350 | cmnd->resid = be32_to_cpu(fcprsp->rspResId); |
@@ -378,7 +387,7 @@ lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) | |||
378 | */ | 387 | */ |
379 | } else if ((scsi_status == SAM_STAT_GOOD) && fcpi_parm && | 388 | } else if ((scsi_status == SAM_STAT_GOOD) && fcpi_parm && |
380 | (cmnd->sc_data_direction == DMA_FROM_DEVICE)) { | 389 | (cmnd->sc_data_direction == DMA_FROM_DEVICE)) { |
381 | lpfc_printf_log(phba, KERN_WARNING, LOG_FCP, | 390 | lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_FCP_ERROR, |
382 | "%d:0734 FCP Read Check Error Data: " | 391 | "%d:0734 FCP Read Check Error Data: " |
383 | "x%x x%x x%x x%x\n", phba->brd_no, | 392 | "x%x x%x x%x x%x\n", phba->brd_no, |
384 | be32_to_cpu(fcpcmd->fcpDl), | 393 | be32_to_cpu(fcpcmd->fcpDl), |
@@ -670,6 +679,9 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, | |||
670 | struct lpfc_iocbq *iocbqrsp; | 679 | struct lpfc_iocbq *iocbqrsp; |
671 | int ret; | 680 | int ret; |
672 | 681 | ||
682 | if (!rdata->pnode) | ||
683 | return FAILED; | ||
684 | |||
673 | lpfc_cmd->rdata = rdata; | 685 | lpfc_cmd->rdata = rdata; |
674 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, | 686 | ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, |
675 | FCP_TARGET_RESET); | 687 | FCP_TARGET_RESET); |
@@ -976,20 +988,34 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
976 | 988 | ||
977 | lpfc_block_error_handler(cmnd); | 989 | lpfc_block_error_handler(cmnd); |
978 | spin_lock_irq(shost->host_lock); | 990 | spin_lock_irq(shost->host_lock); |
991 | loopcnt = 0; | ||
979 | /* | 992 | /* |
980 | * If target is not in a MAPPED state, delay the reset until | 993 | * If target is not in a MAPPED state, delay the reset until |
981 | * target is rediscovered or devloss timeout expires. | 994 | * target is rediscovered or devloss timeout expires. |
982 | */ | 995 | */ |
983 | while ( 1 ) { | 996 | while ( 1 ) { |
984 | if (!pnode) | 997 | if (!pnode) |
985 | break; | 998 | return FAILED; |
986 | 999 | ||
987 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { | 1000 | if (pnode->nlp_state != NLP_STE_MAPPED_NODE) { |
988 | spin_unlock_irq(phba->host->host_lock); | 1001 | spin_unlock_irq(phba->host->host_lock); |
989 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); | 1002 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); |
990 | spin_lock_irq(phba->host->host_lock); | 1003 | spin_lock_irq(phba->host->host_lock); |
1004 | loopcnt++; | ||
1005 | rdata = cmnd->device->hostdata; | ||
1006 | if (!rdata || | ||
1007 | (loopcnt > ((phba->cfg_devloss_tmo * 2) + 1))) { | ||
1008 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | ||
1009 | "%d:0721 LUN Reset rport failure:" | ||
1010 | " cnt x%x rdata x%p\n", | ||
1011 | phba->brd_no, loopcnt, rdata); | ||
1012 | goto out; | ||
1013 | } | ||
1014 | pnode = rdata->pnode; | ||
1015 | if (!pnode) | ||
1016 | return FAILED; | ||
991 | } | 1017 | } |
992 | if ((pnode) && (pnode->nlp_state == NLP_STE_MAPPED_NODE)) | 1018 | if (pnode->nlp_state == NLP_STE_MAPPED_NODE) |
993 | break; | 1019 | break; |
994 | } | 1020 | } |
995 | 1021 | ||
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 582f5ea4e84e..a4128e19338a 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -117,6 +117,10 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) | |||
117 | case CMD_FCP_IREAD_CX: | 117 | case CMD_FCP_IREAD_CX: |
118 | case CMD_FCP_ICMND_CR: | 118 | case CMD_FCP_ICMND_CR: |
119 | case CMD_FCP_ICMND_CX: | 119 | case CMD_FCP_ICMND_CX: |
120 | case CMD_FCP_TSEND_CX: | ||
121 | case CMD_FCP_TRSP_CX: | ||
122 | case CMD_FCP_TRECEIVE_CX: | ||
123 | case CMD_FCP_AUTO_TRSP_CX: | ||
120 | case CMD_ADAPTER_MSG: | 124 | case CMD_ADAPTER_MSG: |
121 | case CMD_ADAPTER_DUMP: | 125 | case CMD_ADAPTER_DUMP: |
122 | case CMD_XMIT_SEQUENCE64_CR: | 126 | case CMD_XMIT_SEQUENCE64_CR: |
@@ -131,6 +135,9 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd) | |||
131 | case CMD_FCP_IREAD64_CX: | 135 | case CMD_FCP_IREAD64_CX: |
132 | case CMD_FCP_ICMND64_CR: | 136 | case CMD_FCP_ICMND64_CR: |
133 | case CMD_FCP_ICMND64_CX: | 137 | case CMD_FCP_ICMND64_CX: |
138 | case CMD_FCP_TSEND64_CX: | ||
139 | case CMD_FCP_TRSP64_CX: | ||
140 | case CMD_FCP_TRECEIVE64_CX: | ||
134 | case CMD_GEN_REQUEST64_CR: | 141 | case CMD_GEN_REQUEST64_CR: |
135 | case CMD_GEN_REQUEST64_CX: | 142 | case CMD_GEN_REQUEST64_CX: |
136 | case CMD_XMIT_ELS_RSP64_CX: | 143 | case CMD_XMIT_ELS_RSP64_CX: |
@@ -1098,6 +1105,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, | |||
1098 | lpfc_sli_pcimem_bcopy((uint32_t *) entry, | 1105 | lpfc_sli_pcimem_bcopy((uint32_t *) entry, |
1099 | (uint32_t *) &rspiocbq.iocb, | 1106 | (uint32_t *) &rspiocbq.iocb, |
1100 | sizeof (IOCB_t)); | 1107 | sizeof (IOCB_t)); |
1108 | INIT_LIST_HEAD(&(rspiocbq.list)); | ||
1101 | irsp = &rspiocbq.iocb; | 1109 | irsp = &rspiocbq.iocb; |
1102 | 1110 | ||
1103 | type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK); | 1111 | type = lpfc_sli_iocb_cmd_type(irsp->ulpCommand & CMD_IOCB_MASK); |
@@ -1149,6 +1157,11 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba * phba, | |||
1149 | } | 1157 | } |
1150 | } | 1158 | } |
1151 | break; | 1159 | break; |
1160 | case LPFC_UNSOL_IOCB: | ||
1161 | spin_unlock_irqrestore(phba->host->host_lock, iflag); | ||
1162 | lpfc_sli_process_unsol_iocb(phba, pring, &rspiocbq); | ||
1163 | spin_lock_irqsave(phba->host->host_lock, iflag); | ||
1164 | break; | ||
1152 | default: | 1165 | default: |
1153 | if (irsp->ulpCommand == CMD_ADAPTER_MSG) { | 1166 | if (irsp->ulpCommand == CMD_ADAPTER_MSG) { |
1154 | char adaptermsg[LPFC_MAX_ADPTMSG]; | 1167 | char adaptermsg[LPFC_MAX_ADPTMSG]; |
@@ -2472,13 +2485,17 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba) | |||
2472 | psli = &phba->sli; | 2485 | psli = &phba->sli; |
2473 | 2486 | ||
2474 | /* Adjust cmd/rsp ring iocb entries more evenly */ | 2487 | /* Adjust cmd/rsp ring iocb entries more evenly */ |
2488 | |||
2489 | /* Take some away from the FCP ring */ | ||
2475 | pring = &psli->ring[psli->fcp_ring]; | 2490 | pring = &psli->ring[psli->fcp_ring]; |
2476 | pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES; | 2491 | pring->numCiocb -= SLI2_IOCB_CMD_R1XTRA_ENTRIES; |
2477 | pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES; | 2492 | pring->numRiocb -= SLI2_IOCB_RSP_R1XTRA_ENTRIES; |
2478 | pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES; | 2493 | pring->numCiocb -= SLI2_IOCB_CMD_R3XTRA_ENTRIES; |
2479 | pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES; | 2494 | pring->numRiocb -= SLI2_IOCB_RSP_R3XTRA_ENTRIES; |
2480 | 2495 | ||
2481 | pring = &psli->ring[1]; | 2496 | /* and give them to the extra ring */ |
2497 | pring = &psli->ring[psli->extra_ring]; | ||
2498 | |||
2482 | pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES; | 2499 | pring->numCiocb += SLI2_IOCB_CMD_R1XTRA_ENTRIES; |
2483 | pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES; | 2500 | pring->numRiocb += SLI2_IOCB_RSP_R1XTRA_ENTRIES; |
2484 | pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES; | 2501 | pring->numCiocb += SLI2_IOCB_CMD_R3XTRA_ENTRIES; |
@@ -2488,8 +2505,8 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba) | |||
2488 | pring->iotag_max = 4096; | 2505 | pring->iotag_max = 4096; |
2489 | pring->num_mask = 1; | 2506 | pring->num_mask = 1; |
2490 | pring->prt[0].profile = 0; /* Mask 0 */ | 2507 | pring->prt[0].profile = 0; /* Mask 0 */ |
2491 | pring->prt[0].rctl = FC_UNSOL_DATA; | 2508 | pring->prt[0].rctl = phba->cfg_multi_ring_rctl; |
2492 | pring->prt[0].type = 5; | 2509 | pring->prt[0].type = phba->cfg_multi_ring_type; |
2493 | pring->prt[0].lpfc_sli_rcv_unsol_event = NULL; | 2510 | pring->prt[0].lpfc_sli_rcv_unsol_event = NULL; |
2494 | return 0; | 2511 | return 0; |
2495 | } | 2512 | } |
@@ -2505,7 +2522,7 @@ lpfc_sli_setup(struct lpfc_hba *phba) | |||
2505 | psli->sli_flag = 0; | 2522 | psli->sli_flag = 0; |
2506 | psli->fcp_ring = LPFC_FCP_RING; | 2523 | psli->fcp_ring = LPFC_FCP_RING; |
2507 | psli->next_ring = LPFC_FCP_NEXT_RING; | 2524 | psli->next_ring = LPFC_FCP_NEXT_RING; |
2508 | psli->ip_ring = LPFC_IP_RING; | 2525 | psli->extra_ring = LPFC_EXTRA_RING; |
2509 | 2526 | ||
2510 | psli->iocbq_lookup = NULL; | 2527 | psli->iocbq_lookup = NULL; |
2511 | psli->iocbq_lookup_len = 0; | 2528 | psli->iocbq_lookup_len = 0; |
@@ -2528,7 +2545,7 @@ lpfc_sli_setup(struct lpfc_hba *phba) | |||
2528 | pring->fast_iotag = pring->iotag_max; | 2545 | pring->fast_iotag = pring->iotag_max; |
2529 | pring->num_mask = 0; | 2546 | pring->num_mask = 0; |
2530 | break; | 2547 | break; |
2531 | case LPFC_IP_RING: /* ring 1 - IP */ | 2548 | case LPFC_EXTRA_RING: /* ring 1 - EXTRA */ |
2532 | /* numCiocb and numRiocb are used in config_port */ | 2549 | /* numCiocb and numRiocb are used in config_port */ |
2533 | pring->numCiocb = SLI2_IOCB_CMD_R1_ENTRIES; | 2550 | pring->numCiocb = SLI2_IOCB_CMD_R1_ENTRIES; |
2534 | pring->numRiocb = SLI2_IOCB_RSP_R1_ENTRIES; | 2551 | pring->numRiocb = SLI2_IOCB_RSP_R1_ENTRIES; |
@@ -3238,6 +3255,21 @@ lpfc_intr_handler(int irq, void *dev_id) | |||
3238 | lpfc_sli_handle_fast_ring_event(phba, | 3255 | lpfc_sli_handle_fast_ring_event(phba, |
3239 | &phba->sli.ring[LPFC_FCP_RING], | 3256 | &phba->sli.ring[LPFC_FCP_RING], |
3240 | status); | 3257 | status); |
3258 | |||
3259 | if (phba->cfg_multi_ring_support == 2) { | ||
3260 | /* | ||
3261 | * Process all events on extra ring. Take the optimized path | ||
3262 | * for extra ring IO. Any other IO is slow path and is handled | ||
3263 | * by the worker thread. | ||
3264 | */ | ||
3265 | status = (ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING))); | ||
3266 | status >>= (4*LPFC_EXTRA_RING); | ||
3267 | if (status & HA_RXATT) { | ||
3268 | lpfc_sli_handle_fast_ring_event(phba, | ||
3269 | &phba->sli.ring[LPFC_EXTRA_RING], | ||
3270 | status); | ||
3271 | } | ||
3272 | } | ||
3241 | return IRQ_HANDLED; | 3273 | return IRQ_HANDLED; |
3242 | 3274 | ||
3243 | } /* lpfc_intr_handler */ | 3275 | } /* lpfc_intr_handler */ |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index e26de6809358..a43549959dc7 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
@@ -198,7 +198,7 @@ struct lpfc_sli { | |||
198 | int fcp_ring; /* ring used for FCP initiator commands */ | 198 | int fcp_ring; /* ring used for FCP initiator commands */ |
199 | int next_ring; | 199 | int next_ring; |
200 | 200 | ||
201 | int ip_ring; /* ring used for IP network drv cmds */ | 201 | int extra_ring; /* extra ring used for other protocols */ |
202 | 202 | ||
203 | struct lpfc_sli_stat slistat; /* SLI statistical info */ | 203 | struct lpfc_sli_stat slistat; /* SLI statistical info */ |
204 | struct list_head mboxq; | 204 | struct list_head mboxq; |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index ac417908b407..a61ef3d1e7f1 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.1.10" | 21 | #define LPFC_DRIVER_VERSION "8.1.11" |
22 | 22 | ||
23 | #define LPFC_DRIVER_NAME "lpfc" | 23 | #define LPFC_DRIVER_NAME "lpfc" |
24 | 24 | ||
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 86099fde1b2a..77d9d3804ccf 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c | |||
@@ -73,10 +73,10 @@ static unsigned short int max_mbox_busy_wait = MBOX_BUSY_WAIT; | |||
73 | module_param(max_mbox_busy_wait, ushort, 0); | 73 | module_param(max_mbox_busy_wait, ushort, 0); |
74 | MODULE_PARM_DESC(max_mbox_busy_wait, "Maximum wait for mailbox in microseconds if busy (default=MBOX_BUSY_WAIT=10)"); | 74 | MODULE_PARM_DESC(max_mbox_busy_wait, "Maximum wait for mailbox in microseconds if busy (default=MBOX_BUSY_WAIT=10)"); |
75 | 75 | ||
76 | #define RDINDOOR(adapter) readl((adapter)->base + 0x20) | 76 | #define RDINDOOR(adapter) readl((adapter)->mmio_base + 0x20) |
77 | #define RDOUTDOOR(adapter) readl((adapter)->base + 0x2C) | 77 | #define RDOUTDOOR(adapter) readl((adapter)->mmio_base + 0x2C) |
78 | #define WRINDOOR(adapter,value) writel(value, (adapter)->base + 0x20) | 78 | #define WRINDOOR(adapter,value) writel(value, (adapter)->mmio_base + 0x20) |
79 | #define WROUTDOOR(adapter,value) writel(value, (adapter)->base + 0x2C) | 79 | #define WROUTDOOR(adapter,value) writel(value, (adapter)->mmio_base + 0x2C) |
80 | 80 | ||
81 | /* | 81 | /* |
82 | * Global variables | 82 | * Global variables |
@@ -1386,7 +1386,8 @@ megaraid_isr_memmapped(int irq, void *devp) | |||
1386 | 1386 | ||
1387 | handled = 1; | 1387 | handled = 1; |
1388 | 1388 | ||
1389 | while( RDINDOOR(adapter) & 0x02 ) cpu_relax(); | 1389 | while( RDINDOOR(adapter) & 0x02 ) |
1390 | cpu_relax(); | ||
1390 | 1391 | ||
1391 | mega_cmd_done(adapter, completed, nstatus, status); | 1392 | mega_cmd_done(adapter, completed, nstatus, status); |
1392 | 1393 | ||
@@ -4668,6 +4669,8 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4668 | host->host_no, mega_baseport, irq); | 4669 | host->host_no, mega_baseport, irq); |
4669 | 4670 | ||
4670 | adapter->base = mega_baseport; | 4671 | adapter->base = mega_baseport; |
4672 | if (flag & BOARD_MEMMAP) | ||
4673 | adapter->mmio_base = (void __iomem *) mega_baseport; | ||
4671 | 4674 | ||
4672 | INIT_LIST_HEAD(&adapter->free_list); | 4675 | INIT_LIST_HEAD(&adapter->free_list); |
4673 | INIT_LIST_HEAD(&adapter->pending_list); | 4676 | INIT_LIST_HEAD(&adapter->pending_list); |
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 66529f11d23c..c6e74643abe2 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h | |||
@@ -801,7 +801,8 @@ typedef struct { | |||
801 | clustering is available */ | 801 | clustering is available */ |
802 | u32 flag; | 802 | u32 flag; |
803 | 803 | ||
804 | unsigned long base; | 804 | unsigned long base; |
805 | void __iomem *mmio_base; | ||
805 | 806 | ||
806 | /* mbox64 with mbox not aligned on 16-byte boundry */ | 807 | /* mbox64 with mbox not aligned on 16-byte boundry */ |
807 | mbox64_t *una_mbox64; | 808 | mbox64_t *una_mbox64; |
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 7e4262f2af96..046223b4ae57 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -517,7 +517,7 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp, | |||
517 | * Returns the number of frames required for numnber of sge's (sge_count) | 517 | * Returns the number of frames required for numnber of sge's (sge_count) |
518 | */ | 518 | */ |
519 | 519 | ||
520 | u32 megasas_get_frame_count(u8 sge_count) | 520 | static u32 megasas_get_frame_count(u8 sge_count) |
521 | { | 521 | { |
522 | int num_cnt; | 522 | int num_cnt; |
523 | int sge_bytes; | 523 | int sge_bytes; |
@@ -1733,7 +1733,7 @@ megasas_get_ctrl_info(struct megasas_instance *instance, | |||
1733 | * | 1733 | * |
1734 | * Tasklet to complete cmds | 1734 | * Tasklet to complete cmds |
1735 | */ | 1735 | */ |
1736 | void megasas_complete_cmd_dpc(unsigned long instance_addr) | 1736 | static void megasas_complete_cmd_dpc(unsigned long instance_addr) |
1737 | { | 1737 | { |
1738 | u32 producer; | 1738 | u32 producer; |
1739 | u32 consumer; | 1739 | u32 consumer; |
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index adb8eb4f5fd1..bbf521cbc55d 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c | |||
@@ -589,10 +589,12 @@ static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd) | |||
589 | static struct ncr_driver_setup | 589 | static struct ncr_driver_setup |
590 | driver_setup = SCSI_NCR_DRIVER_SETUP; | 590 | driver_setup = SCSI_NCR_DRIVER_SETUP; |
591 | 591 | ||
592 | #ifndef MODULE | ||
592 | #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT | 593 | #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT |
593 | static struct ncr_driver_setup | 594 | static struct ncr_driver_setup |
594 | driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP; | 595 | driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP; |
595 | #endif | 596 | #endif |
597 | #endif /* !MODULE */ | ||
596 | 598 | ||
597 | #define initverbose (driver_setup.verbose) | 599 | #define initverbose (driver_setup.verbose) |
598 | #define bootverbose (np->verbose) | 600 | #define bootverbose (np->verbose) |
@@ -641,6 +643,13 @@ static struct ncr_driver_setup | |||
641 | #define OPT_IARB 26 | 643 | #define OPT_IARB 26 |
642 | #endif | 644 | #endif |
643 | 645 | ||
646 | #ifdef MODULE | ||
647 | #define ARG_SEP ' ' | ||
648 | #else | ||
649 | #define ARG_SEP ',' | ||
650 | #endif | ||
651 | |||
652 | #ifndef MODULE | ||
644 | static char setup_token[] __initdata = | 653 | static char setup_token[] __initdata = |
645 | "tags:" "mpar:" | 654 | "tags:" "mpar:" |
646 | "spar:" "disc:" | 655 | "spar:" "disc:" |
@@ -660,12 +669,6 @@ static char setup_token[] __initdata = | |||
660 | #endif | 669 | #endif |
661 | ; /* DONNOT REMOVE THIS ';' */ | 670 | ; /* DONNOT REMOVE THIS ';' */ |
662 | 671 | ||
663 | #ifdef MODULE | ||
664 | #define ARG_SEP ' ' | ||
665 | #else | ||
666 | #define ARG_SEP ',' | ||
667 | #endif | ||
668 | |||
669 | static int __init get_setup_token(char *p) | 672 | static int __init get_setup_token(char *p) |
670 | { | 673 | { |
671 | char *cur = setup_token; | 674 | char *cur = setup_token; |
@@ -682,7 +685,6 @@ static int __init get_setup_token(char *p) | |||
682 | return 0; | 685 | return 0; |
683 | } | 686 | } |
684 | 687 | ||
685 | |||
686 | static int __init sym53c8xx__setup(char *str) | 688 | static int __init sym53c8xx__setup(char *str) |
687 | { | 689 | { |
688 | #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT | 690 | #ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT |
@@ -804,6 +806,7 @@ static int __init sym53c8xx__setup(char *str) | |||
804 | #endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ | 806 | #endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ |
805 | return 1; | 807 | return 1; |
806 | } | 808 | } |
809 | #endif /* !MODULE */ | ||
807 | 810 | ||
808 | /*=================================================================== | 811 | /*=================================================================== |
809 | ** | 812 | ** |
@@ -8321,12 +8324,12 @@ char *ncr53c8xx; /* command line passed by insmod */ | |||
8321 | module_param(ncr53c8xx, charp, 0); | 8324 | module_param(ncr53c8xx, charp, 0); |
8322 | #endif | 8325 | #endif |
8323 | 8326 | ||
8327 | #ifndef MODULE | ||
8324 | static int __init ncr53c8xx_setup(char *str) | 8328 | static int __init ncr53c8xx_setup(char *str) |
8325 | { | 8329 | { |
8326 | return sym53c8xx__setup(str); | 8330 | return sym53c8xx__setup(str); |
8327 | } | 8331 | } |
8328 | 8332 | ||
8329 | #ifndef MODULE | ||
8330 | __setup("ncr53c8xx=", ncr53c8xx_setup); | 8333 | __setup("ncr53c8xx=", ncr53c8xx_setup); |
8331 | #endif | 8334 | #endif |
8332 | 8335 | ||
diff --git a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c index dd67a68c5c23..c116a6ae3c54 100644 --- a/drivers/scsi/oktagon_esp.c +++ b/drivers/scsi/oktagon_esp.c | |||
@@ -72,12 +72,12 @@ static void dma_advance_sg(Scsi_Cmnd *); | |||
72 | static int oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x); | 72 | static int oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x); |
73 | 73 | ||
74 | #ifdef USE_BOTTOM_HALF | 74 | #ifdef USE_BOTTOM_HALF |
75 | static void dma_commit(void *opaque); | 75 | static void dma_commit(struct work_struct *unused); |
76 | 76 | ||
77 | long oktag_to_io(long *paddr, long *addr, long len); | 77 | long oktag_to_io(long *paddr, long *addr, long len); |
78 | long oktag_from_io(long *addr, long *paddr, long len); | 78 | long oktag_from_io(long *addr, long *paddr, long len); |
79 | 79 | ||
80 | static DECLARE_WORK(tq_fake_dma, dma_commit, NULL); | 80 | static DECLARE_WORK(tq_fake_dma, dma_commit); |
81 | 81 | ||
82 | #define DMA_MAXTRANSFER 0x8000 | 82 | #define DMA_MAXTRANSFER 0x8000 |
83 | 83 | ||
@@ -266,7 +266,7 @@ oktagon_notify_reboot(struct notifier_block *this, unsigned long code, void *x) | |||
266 | */ | 266 | */ |
267 | 267 | ||
268 | 268 | ||
269 | static void dma_commit(void *opaque) | 269 | static void dma_commit(struct work_struct *unused) |
270 | { | 270 | { |
271 | long wait,len2,pos; | 271 | long wait,len2,pos; |
272 | struct NCR_ESP *esp; | 272 | struct NCR_ESP *esp; |
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index ee449b29fc82..aad362ba02e0 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c | |||
@@ -154,16 +154,11 @@ static int aha152x_config_cs(struct pcmcia_device *link) | |||
154 | 154 | ||
155 | DEBUG(0, "aha152x_config(0x%p)\n", link); | 155 | DEBUG(0, "aha152x_config(0x%p)\n", link); |
156 | 156 | ||
157 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
158 | tuple.TupleData = tuple_data; | 157 | tuple.TupleData = tuple_data; |
159 | tuple.TupleDataMax = 64; | 158 | tuple.TupleDataMax = 64; |
160 | tuple.TupleOffset = 0; | 159 | tuple.TupleOffset = 0; |
161 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
162 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
163 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
164 | link->conf.ConfigBase = parse.config.base; | ||
165 | |||
166 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 160 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
161 | tuple.Attributes = 0; | ||
167 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 162 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
168 | while (1) { | 163 | while (1) { |
169 | if (pcmcia_get_tuple_data(link, &tuple) != 0 || | 164 | if (pcmcia_get_tuple_data(link, &tuple) != 0 || |
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index 85f7ffac19a0..a1c5f265069f 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c | |||
@@ -136,14 +136,9 @@ static int fdomain_config(struct pcmcia_device *link) | |||
136 | 136 | ||
137 | DEBUG(0, "fdomain_config(0x%p)\n", link); | 137 | DEBUG(0, "fdomain_config(0x%p)\n", link); |
138 | 138 | ||
139 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
140 | tuple.TupleData = tuple_data; | 139 | tuple.TupleData = tuple_data; |
141 | tuple.TupleDataMax = 64; | 140 | tuple.TupleDataMax = 64; |
142 | tuple.TupleOffset = 0; | 141 | tuple.TupleOffset = 0; |
143 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
144 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
145 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
146 | link->conf.ConfigBase = parse.config.base; | ||
147 | 142 | ||
148 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 143 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
149 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 144 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index f2d79c3f0b8e..d72df5dae4ee 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -1685,16 +1685,10 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1685 | 1685 | ||
1686 | nsp_dbg(NSP_DEBUG_INIT, "in"); | 1686 | nsp_dbg(NSP_DEBUG_INIT, "in"); |
1687 | 1687 | ||
1688 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
1689 | tuple.Attributes = 0; | 1688 | tuple.Attributes = 0; |
1690 | tuple.TupleData = tuple_data; | 1689 | tuple.TupleData = tuple_data; |
1691 | tuple.TupleDataMax = sizeof(tuple_data); | 1690 | tuple.TupleDataMax = sizeof(tuple_data); |
1692 | tuple.TupleOffset = 0; | 1691 | tuple.TupleOffset = 0; |
1693 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
1694 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
1695 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
1696 | link->conf.ConfigBase = parse.config.base; | ||
1697 | link->conf.Present = parse.config.rmask[0]; | ||
1698 | 1692 | ||
1699 | /* Look up the current Vcc */ | 1693 | /* Look up the current Vcc */ |
1700 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); | 1694 | CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf)); |
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index 86c2ac6ae623..9d431fe7f47f 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c | |||
@@ -208,18 +208,11 @@ static int qlogic_config(struct pcmcia_device * link) | |||
208 | 208 | ||
209 | DEBUG(0, "qlogic_config(0x%p)\n", link); | 209 | DEBUG(0, "qlogic_config(0x%p)\n", link); |
210 | 210 | ||
211 | info->manf_id = link->manf_id; | ||
212 | |||
211 | tuple.TupleData = (cisdata_t *) tuple_data; | 213 | tuple.TupleData = (cisdata_t *) tuple_data; |
212 | tuple.TupleDataMax = 64; | 214 | tuple.TupleDataMax = 64; |
213 | tuple.TupleOffset = 0; | 215 | tuple.TupleOffset = 0; |
214 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
215 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
216 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
217 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
218 | link->conf.ConfigBase = parse.config.base; | ||
219 | |||
220 | tuple.DesiredTuple = CISTPL_MANFID; | ||
221 | if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) | ||
222 | info->manf_id = le16_to_cpu(tuple.TupleData[0]); | ||
223 | 216 | ||
224 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 217 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
225 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 218 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 72fe5d055de1..fb7acea60286 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c | |||
@@ -722,19 +722,11 @@ SYM53C500_config(struct pcmcia_device *link) | |||
722 | 722 | ||
723 | DEBUG(0, "SYM53C500_config(0x%p)\n", link); | 723 | DEBUG(0, "SYM53C500_config(0x%p)\n", link); |
724 | 724 | ||
725 | info->manf_id = link->manf_id; | ||
726 | |||
725 | tuple.TupleData = (cisdata_t *)tuple_data; | 727 | tuple.TupleData = (cisdata_t *)tuple_data; |
726 | tuple.TupleDataMax = 64; | 728 | tuple.TupleDataMax = 64; |
727 | tuple.TupleOffset = 0; | 729 | tuple.TupleOffset = 0; |
728 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
729 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
730 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
731 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
732 | link->conf.ConfigBase = parse.config.base; | ||
733 | |||
734 | tuple.DesiredTuple = CISTPL_MANFID; | ||
735 | if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && | ||
736 | (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS)) | ||
737 | info->manf_id = le16_to_cpu(tuple.TupleData[0]); | ||
738 | 730 | ||
739 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 731 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
740 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 732 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index 89a2a9f11e41..584ba4d6e038 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c | |||
@@ -31,7 +31,7 @@ typedef struct { | |||
31 | int base; /* Actual port address */ | 31 | int base; /* Actual port address */ |
32 | int mode; /* Transfer mode */ | 32 | int mode; /* Transfer mode */ |
33 | struct scsi_cmnd *cur_cmd; /* Current queued command */ | 33 | struct scsi_cmnd *cur_cmd; /* Current queued command */ |
34 | struct work_struct ppa_tq; /* Polling interrupt stuff */ | 34 | struct delayed_work ppa_tq; /* Polling interrupt stuff */ |
35 | unsigned long jstart; /* Jiffies at start */ | 35 | unsigned long jstart; /* Jiffies at start */ |
36 | unsigned long recon_tmo; /* How many usecs to wait for reconnection (6th bit) */ | 36 | unsigned long recon_tmo; /* How many usecs to wait for reconnection (6th bit) */ |
37 | unsigned int failed:1; /* Failure flag */ | 37 | unsigned int failed:1; /* Failure flag */ |
@@ -627,9 +627,9 @@ static int ppa_completion(struct scsi_cmnd *cmd) | |||
627 | * the scheduler's task queue to generate a stream of call-backs and | 627 | * the scheduler's task queue to generate a stream of call-backs and |
628 | * complete the request when the drive is ready. | 628 | * complete the request when the drive is ready. |
629 | */ | 629 | */ |
630 | static void ppa_interrupt(void *data) | 630 | static void ppa_interrupt(struct work_struct *work) |
631 | { | 631 | { |
632 | ppa_struct *dev = (ppa_struct *) data; | 632 | ppa_struct *dev = container_of(work, ppa_struct, ppa_tq.work); |
633 | struct scsi_cmnd *cmd = dev->cur_cmd; | 633 | struct scsi_cmnd *cmd = dev->cur_cmd; |
634 | 634 | ||
635 | if (!cmd) { | 635 | if (!cmd) { |
@@ -637,7 +637,6 @@ static void ppa_interrupt(void *data) | |||
637 | return; | 637 | return; |
638 | } | 638 | } |
639 | if (ppa_engine(dev, cmd)) { | 639 | if (ppa_engine(dev, cmd)) { |
640 | dev->ppa_tq.data = (void *) dev; | ||
641 | schedule_delayed_work(&dev->ppa_tq, 1); | 640 | schedule_delayed_work(&dev->ppa_tq, 1); |
642 | return; | 641 | return; |
643 | } | 642 | } |
@@ -822,8 +821,7 @@ static int ppa_queuecommand(struct scsi_cmnd *cmd, | |||
822 | cmd->result = DID_ERROR << 16; /* default return code */ | 821 | cmd->result = DID_ERROR << 16; /* default return code */ |
823 | cmd->SCp.phase = 0; /* bus free */ | 822 | cmd->SCp.phase = 0; /* bus free */ |
824 | 823 | ||
825 | dev->ppa_tq.data = dev; | 824 | schedule_delayed_work(&dev->ppa_tq, 0); |
826 | schedule_work(&dev->ppa_tq); | ||
827 | 825 | ||
828 | ppa_pb_claim(dev); | 826 | ppa_pb_claim(dev); |
829 | 827 | ||
@@ -1086,7 +1084,7 @@ static int __ppa_attach(struct parport *pb) | |||
1086 | else | 1084 | else |
1087 | ports = 8; | 1085 | ports = 8; |
1088 | 1086 | ||
1089 | INIT_WORK(&dev->ppa_tq, ppa_interrupt, dev); | 1087 | INIT_DELAYED_WORK(&dev->ppa_tq, ppa_interrupt); |
1090 | 1088 | ||
1091 | err = -ENOMEM; | 1089 | err = -ENOMEM; |
1092 | host = scsi_host_alloc(&ppa_template, sizeof(ppa_struct *)); | 1090 | host = scsi_host_alloc(&ppa_template, sizeof(ppa_struct *)); |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 285c8e8ff1a0..7b18a6c7b7eb 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -390,7 +390,7 @@ static struct sysfs_entry { | |||
390 | { "optrom_ctl", &sysfs_optrom_ctl_attr, }, | 390 | { "optrom_ctl", &sysfs_optrom_ctl_attr, }, |
391 | { "vpd", &sysfs_vpd_attr, 1 }, | 391 | { "vpd", &sysfs_vpd_attr, 1 }, |
392 | { "sfp", &sysfs_sfp_attr, 1 }, | 392 | { "sfp", &sysfs_sfp_attr, 1 }, |
393 | { 0 }, | 393 | { NULL }, |
394 | }; | 394 | }; |
395 | 395 | ||
396 | void | 396 | void |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 08cb5e3fb553..a823f0bc519d 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -59,9 +59,6 @@ int | |||
59 | qla2x00_initialize_adapter(scsi_qla_host_t *ha) | 59 | qla2x00_initialize_adapter(scsi_qla_host_t *ha) |
60 | { | 60 | { |
61 | int rval; | 61 | int rval; |
62 | uint8_t restart_risc = 0; | ||
63 | uint8_t retry; | ||
64 | uint32_t wait_time; | ||
65 | 62 | ||
66 | /* Clear adapter flags. */ | 63 | /* Clear adapter flags. */ |
67 | ha->flags.online = 0; | 64 | ha->flags.online = 0; |
@@ -104,87 +101,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
104 | 101 | ||
105 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); | 102 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); |
106 | 103 | ||
107 | retry = 10; | 104 | if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) { |
108 | /* | 105 | rval = ha->isp_ops.chip_diag(ha); |
109 | * Try to configure the loop. | 106 | if (rval) |
110 | */ | 107 | return (rval); |
111 | do { | 108 | rval = qla2x00_setup_chip(ha); |
112 | restart_risc = 0; | 109 | if (rval) |
113 | 110 | return (rval); | |
114 | /* If firmware needs to be loaded */ | ||
115 | if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) { | ||
116 | if ((rval = ha->isp_ops.chip_diag(ha)) == QLA_SUCCESS) { | ||
117 | rval = qla2x00_setup_chip(ha); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | if (rval == QLA_SUCCESS && | ||
122 | (rval = qla2x00_init_rings(ha)) == QLA_SUCCESS) { | ||
123 | check_fw_ready_again: | ||
124 | /* | ||
125 | * Wait for a successful LIP up to a maximum | ||
126 | * of (in seconds): RISC login timeout value, | ||
127 | * RISC retry count value, and port down retry | ||
128 | * value OR a minimum of 4 seconds OR If no | ||
129 | * cable, only 5 seconds. | ||
130 | */ | ||
131 | rval = qla2x00_fw_ready(ha); | ||
132 | if (rval == QLA_SUCCESS) { | ||
133 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | ||
134 | |||
135 | /* Issue a marker after FW becomes ready. */ | ||
136 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | ||
137 | |||
138 | /* | ||
139 | * Wait at most MAX_TARGET RSCNs for a stable | ||
140 | * link. | ||
141 | */ | ||
142 | wait_time = 256; | ||
143 | do { | ||
144 | clear_bit(LOOP_RESYNC_NEEDED, | ||
145 | &ha->dpc_flags); | ||
146 | rval = qla2x00_configure_loop(ha); | ||
147 | |||
148 | if (test_and_clear_bit(ISP_ABORT_NEEDED, | ||
149 | &ha->dpc_flags)) { | ||
150 | restart_risc = 1; | ||
151 | break; | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * If loop state change while we were | ||
156 | * discoverying devices then wait for | ||
157 | * LIP to complete | ||
158 | */ | ||
159 | |||
160 | if (atomic_read(&ha->loop_state) != | ||
161 | LOOP_READY && retry--) { | ||
162 | goto check_fw_ready_again; | ||
163 | } | ||
164 | wait_time--; | ||
165 | } while (!atomic_read(&ha->loop_down_timer) && | ||
166 | retry && | ||
167 | wait_time && | ||
168 | (test_bit(LOOP_RESYNC_NEEDED, | ||
169 | &ha->dpc_flags))); | ||
170 | |||
171 | if (wait_time == 0) | ||
172 | rval = QLA_FUNCTION_FAILED; | ||
173 | } else if (ha->device_flags & DFLG_NO_CABLE) | ||
174 | /* If no cable, then all is good. */ | ||
175 | rval = QLA_SUCCESS; | ||
176 | } | ||
177 | } while (restart_risc && retry--); | ||
178 | |||
179 | if (rval == QLA_SUCCESS) { | ||
180 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | ||
181 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | ||
182 | ha->marker_needed = 0; | ||
183 | |||
184 | ha->flags.online = 1; | ||
185 | } else { | ||
186 | DEBUG2_3(printk("%s(): **** FAILED ****\n", __func__)); | ||
187 | } | 111 | } |
112 | rval = qla2x00_init_rings(ha); | ||
188 | 113 | ||
189 | return (rval); | 114 | return (rval); |
190 | } | 115 | } |
@@ -2208,8 +2133,7 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2208 | 2133 | ||
2209 | atomic_set(&fcport->state, FCS_ONLINE); | 2134 | atomic_set(&fcport->state, FCS_ONLINE); |
2210 | 2135 | ||
2211 | if (ha->flags.init_done) | 2136 | qla2x00_reg_remote_port(ha, fcport); |
2212 | qla2x00_reg_remote_port(ha, fcport); | ||
2213 | } | 2137 | } |
2214 | 2138 | ||
2215 | void | 2139 | void |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 208607be78c7..cbe0cad83b68 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -95,6 +95,8 @@ MODULE_PARM_DESC(ql2xqfullrampup, | |||
95 | */ | 95 | */ |
96 | static int qla2xxx_slave_configure(struct scsi_device * device); | 96 | static int qla2xxx_slave_configure(struct scsi_device * device); |
97 | static int qla2xxx_slave_alloc(struct scsi_device *); | 97 | static int qla2xxx_slave_alloc(struct scsi_device *); |
98 | static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time); | ||
99 | static void qla2xxx_scan_start(struct Scsi_Host *); | ||
98 | static void qla2xxx_slave_destroy(struct scsi_device *); | 100 | static void qla2xxx_slave_destroy(struct scsi_device *); |
99 | static int qla2x00_queuecommand(struct scsi_cmnd *cmd, | 101 | static int qla2x00_queuecommand(struct scsi_cmnd *cmd, |
100 | void (*fn)(struct scsi_cmnd *)); | 102 | void (*fn)(struct scsi_cmnd *)); |
@@ -124,6 +126,8 @@ static struct scsi_host_template qla2x00_driver_template = { | |||
124 | 126 | ||
125 | .slave_alloc = qla2xxx_slave_alloc, | 127 | .slave_alloc = qla2xxx_slave_alloc, |
126 | .slave_destroy = qla2xxx_slave_destroy, | 128 | .slave_destroy = qla2xxx_slave_destroy, |
129 | .scan_finished = qla2xxx_scan_finished, | ||
130 | .scan_start = qla2xxx_scan_start, | ||
127 | .change_queue_depth = qla2x00_change_queue_depth, | 131 | .change_queue_depth = qla2x00_change_queue_depth, |
128 | .change_queue_type = qla2x00_change_queue_type, | 132 | .change_queue_type = qla2x00_change_queue_type, |
129 | .this_id = -1, | 133 | .this_id = -1, |
@@ -287,7 +291,7 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str) | |||
287 | return str; | 291 | return str; |
288 | } | 292 | } |
289 | 293 | ||
290 | char * | 294 | static char * |
291 | qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) | 295 | qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) |
292 | { | 296 | { |
293 | char un_str[10]; | 297 | char un_str[10]; |
@@ -325,7 +329,7 @@ qla2x00_fw_version_str(struct scsi_qla_host *ha, char *str) | |||
325 | return (str); | 329 | return (str); |
326 | } | 330 | } |
327 | 331 | ||
328 | char * | 332 | static char * |
329 | qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) | 333 | qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str) |
330 | { | 334 | { |
331 | sprintf(str, "%d.%02d.%02d ", ha->fw_major_version, | 335 | sprintf(str, "%d.%02d.%02d ", ha->fw_major_version, |
@@ -634,7 +638,7 @@ qla2x00_block_error_handler(struct scsi_cmnd *cmnd) | |||
634 | * Note: | 638 | * Note: |
635 | * Only return FAILED if command not returned by firmware. | 639 | * Only return FAILED if command not returned by firmware. |
636 | **************************************************************************/ | 640 | **************************************************************************/ |
637 | int | 641 | static int |
638 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) | 642 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) |
639 | { | 643 | { |
640 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 644 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
@@ -771,7 +775,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | |||
771 | * SUCCESS/FAILURE (defined as macro in scsi.h). | 775 | * SUCCESS/FAILURE (defined as macro in scsi.h). |
772 | * | 776 | * |
773 | **************************************************************************/ | 777 | **************************************************************************/ |
774 | int | 778 | static int |
775 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | 779 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) |
776 | { | 780 | { |
777 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 781 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
@@ -902,7 +906,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) | |||
902 | * SUCCESS/FAILURE (defined as macro in scsi.h). | 906 | * SUCCESS/FAILURE (defined as macro in scsi.h). |
903 | * | 907 | * |
904 | **************************************************************************/ | 908 | **************************************************************************/ |
905 | int | 909 | static int |
906 | qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | 910 | qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) |
907 | { | 911 | { |
908 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 912 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
@@ -963,7 +967,7 @@ eh_bus_reset_done: | |||
963 | * | 967 | * |
964 | * Note: | 968 | * Note: |
965 | **************************************************************************/ | 969 | **************************************************************************/ |
966 | int | 970 | static int |
967 | qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | 971 | qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) |
968 | { | 972 | { |
969 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 973 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); |
@@ -1366,6 +1370,29 @@ qla24xx_disable_intrs(scsi_qla_host_t *ha) | |||
1366 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1370 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1367 | } | 1371 | } |
1368 | 1372 | ||
1373 | static void | ||
1374 | qla2xxx_scan_start(struct Scsi_Host *shost) | ||
1375 | { | ||
1376 | scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; | ||
1377 | |||
1378 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | ||
1379 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | ||
1380 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | ||
1381 | } | ||
1382 | |||
1383 | static int | ||
1384 | qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) | ||
1385 | { | ||
1386 | scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; | ||
1387 | |||
1388 | if (!ha->host) | ||
1389 | return 1; | ||
1390 | if (time > ha->loop_reset_delay * HZ) | ||
1391 | return 1; | ||
1392 | |||
1393 | return atomic_read(&ha->loop_state) == LOOP_READY; | ||
1394 | } | ||
1395 | |||
1369 | /* | 1396 | /* |
1370 | * PCI driver interface | 1397 | * PCI driver interface |
1371 | */ | 1398 | */ |
@@ -1377,10 +1404,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1377 | struct Scsi_Host *host; | 1404 | struct Scsi_Host *host; |
1378 | scsi_qla_host_t *ha; | 1405 | scsi_qla_host_t *ha; |
1379 | unsigned long flags = 0; | 1406 | unsigned long flags = 0; |
1380 | unsigned long wait_switch = 0; | ||
1381 | char pci_info[20]; | 1407 | char pci_info[20]; |
1382 | char fw_str[30]; | 1408 | char fw_str[30]; |
1383 | fc_port_t *fcport; | ||
1384 | struct scsi_host_template *sht; | 1409 | struct scsi_host_template *sht; |
1385 | 1410 | ||
1386 | if (pci_enable_device(pdev)) | 1411 | if (pci_enable_device(pdev)) |
@@ -1631,30 +1656,19 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1631 | 1656 | ||
1632 | ha->isp_ops.enable_intrs(ha); | 1657 | ha->isp_ops.enable_intrs(ha); |
1633 | 1658 | ||
1634 | /* v2.19.5b6 */ | ||
1635 | /* | ||
1636 | * Wait around max loop_reset_delay secs for the devices to come | ||
1637 | * on-line. We don't want Linux scanning before we are ready. | ||
1638 | * | ||
1639 | */ | ||
1640 | for (wait_switch = jiffies + (ha->loop_reset_delay * HZ); | ||
1641 | time_before(jiffies,wait_switch) && | ||
1642 | !(ha->device_flags & (DFLG_NO_CABLE | DFLG_FABRIC_DEVICES)) | ||
1643 | && (ha->device_flags & SWITCH_FOUND) ;) { | ||
1644 | |||
1645 | qla2x00_check_fabric_devices(ha); | ||
1646 | |||
1647 | msleep(10); | ||
1648 | } | ||
1649 | |||
1650 | pci_set_drvdata(pdev, ha); | 1659 | pci_set_drvdata(pdev, ha); |
1660 | |||
1651 | ha->flags.init_done = 1; | 1661 | ha->flags.init_done = 1; |
1662 | ha->flags.online = 1; | ||
1663 | |||
1652 | num_hosts++; | 1664 | num_hosts++; |
1653 | 1665 | ||
1654 | ret = scsi_add_host(host, &pdev->dev); | 1666 | ret = scsi_add_host(host, &pdev->dev); |
1655 | if (ret) | 1667 | if (ret) |
1656 | goto probe_failed; | 1668 | goto probe_failed; |
1657 | 1669 | ||
1670 | scsi_scan_host(host); | ||
1671 | |||
1658 | qla2x00_alloc_sysfs_attr(ha); | 1672 | qla2x00_alloc_sysfs_attr(ha); |
1659 | 1673 | ||
1660 | qla2x00_init_host_attr(ha); | 1674 | qla2x00_init_host_attr(ha); |
@@ -1669,10 +1683,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1669 | ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no, | 1683 | ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no, |
1670 | ha->isp_ops.fw_version_str(ha, fw_str)); | 1684 | ha->isp_ops.fw_version_str(ha, fw_str)); |
1671 | 1685 | ||
1672 | /* Go with fc_rport registration. */ | ||
1673 | list_for_each_entry(fcport, &ha->fcports, list) | ||
1674 | qla2x00_reg_remote_port(ha, fcport); | ||
1675 | |||
1676 | return 0; | 1686 | return 0; |
1677 | 1687 | ||
1678 | probe_failed: | 1688 | probe_failed: |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index c71dbd5bd543..15390ad87456 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -449,7 +449,7 @@ nvram_data_to_access_addr(uint32_t naddr) | |||
449 | return FARX_ACCESS_NVRAM_DATA | naddr; | 449 | return FARX_ACCESS_NVRAM_DATA | naddr; |
450 | } | 450 | } |
451 | 451 | ||
452 | uint32_t | 452 | static uint32_t |
453 | qla24xx_read_flash_dword(scsi_qla_host_t *ha, uint32_t addr) | 453 | qla24xx_read_flash_dword(scsi_qla_host_t *ha, uint32_t addr) |
454 | { | 454 | { |
455 | int rval; | 455 | int rval; |
@@ -490,7 +490,7 @@ qla24xx_read_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
490 | return dwptr; | 490 | return dwptr; |
491 | } | 491 | } |
492 | 492 | ||
493 | int | 493 | static int |
494 | qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data) | 494 | qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data) |
495 | { | 495 | { |
496 | int rval; | 496 | int rval; |
@@ -512,7 +512,7 @@ qla24xx_write_flash_dword(scsi_qla_host_t *ha, uint32_t addr, uint32_t data) | |||
512 | return rval; | 512 | return rval; |
513 | } | 513 | } |
514 | 514 | ||
515 | void | 515 | static void |
516 | qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, | 516 | qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, |
517 | uint8_t *flash_id) | 517 | uint8_t *flash_id) |
518 | { | 518 | { |
@@ -537,7 +537,7 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id, | |||
537 | } | 537 | } |
538 | } | 538 | } |
539 | 539 | ||
540 | int | 540 | static int |
541 | qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | 541 | qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, |
542 | uint32_t dwords) | 542 | uint32_t dwords) |
543 | { | 543 | { |
diff --git a/drivers/scsi/qla4xxx/ql4_dbg.c b/drivers/scsi/qla4xxx/ql4_dbg.c index 752031fadfef..7b4e077a39c1 100644 --- a/drivers/scsi/qla4xxx/ql4_dbg.c +++ b/drivers/scsi/qla4xxx/ql4_dbg.c | |||
@@ -71,7 +71,7 @@ void __dump_registers(struct scsi_qla_host *ha) | |||
71 | readw(&ha->reg->u1.isp4010.nvram)); | 71 | readw(&ha->reg->u1.isp4010.nvram)); |
72 | } | 72 | } |
73 | 73 | ||
74 | else if (is_qla4022(ha)) { | 74 | else if (is_qla4022(ha) | is_qla4032(ha)) { |
75 | printk(KERN_INFO "0x%02X intr_mask = 0x%08X\n", | 75 | printk(KERN_INFO "0x%02X intr_mask = 0x%08X\n", |
76 | (uint8_t) offsetof(struct isp_reg, | 76 | (uint8_t) offsetof(struct isp_reg, |
77 | u1.isp4022.intr_mask), | 77 | u1.isp4022.intr_mask), |
@@ -119,7 +119,7 @@ void __dump_registers(struct scsi_qla_host *ha) | |||
119 | readw(&ha->reg->u2.isp4010.port_err_status)); | 119 | readw(&ha->reg->u2.isp4010.port_err_status)); |
120 | } | 120 | } |
121 | 121 | ||
122 | else if (is_qla4022(ha)) { | 122 | else if (is_qla4022(ha) | is_qla4032(ha)) { |
123 | printk(KERN_INFO "Page 0 Registers:\n"); | 123 | printk(KERN_INFO "Page 0 Registers:\n"); |
124 | printk(KERN_INFO "0x%02X ext_hw_conf = 0x%08X\n", | 124 | printk(KERN_INFO "0x%02X ext_hw_conf = 0x%08X\n", |
125 | (uint8_t) offsetof(struct isp_reg, | 125 | (uint8_t) offsetof(struct isp_reg, |
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index a7f6c7b1c590..4249e52a5592 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -40,7 +40,11 @@ | |||
40 | 40 | ||
41 | #ifndef PCI_DEVICE_ID_QLOGIC_ISP4022 | 41 | #ifndef PCI_DEVICE_ID_QLOGIC_ISP4022 |
42 | #define PCI_DEVICE_ID_QLOGIC_ISP4022 0x4022 | 42 | #define PCI_DEVICE_ID_QLOGIC_ISP4022 0x4022 |
43 | #endif /* */ | 43 | #endif |
44 | |||
45 | #ifndef PCI_DEVICE_ID_QLOGIC_ISP4032 | ||
46 | #define PCI_DEVICE_ID_QLOGIC_ISP4032 0x4032 | ||
47 | #endif | ||
44 | 48 | ||
45 | #define QLA_SUCCESS 0 | 49 | #define QLA_SUCCESS 0 |
46 | #define QLA_ERROR 1 | 50 | #define QLA_ERROR 1 |
@@ -277,7 +281,6 @@ struct scsi_qla_host { | |||
277 | #define AF_INTERRUPTS_ON 6 /* 0x00000040 Not Used */ | 281 | #define AF_INTERRUPTS_ON 6 /* 0x00000040 Not Used */ |
278 | #define AF_GET_CRASH_RECORD 7 /* 0x00000080 */ | 282 | #define AF_GET_CRASH_RECORD 7 /* 0x00000080 */ |
279 | #define AF_LINK_UP 8 /* 0x00000100 */ | 283 | #define AF_LINK_UP 8 /* 0x00000100 */ |
280 | #define AF_TOPCAT_CHIP_PRESENT 9 /* 0x00000200 */ | ||
281 | #define AF_IRQ_ATTACHED 10 /* 0x00000400 */ | 284 | #define AF_IRQ_ATTACHED 10 /* 0x00000400 */ |
282 | #define AF_ISNS_CMD_IN_PROCESS 12 /* 0x00001000 */ | 285 | #define AF_ISNS_CMD_IN_PROCESS 12 /* 0x00001000 */ |
283 | #define AF_ISNS_CMD_DONE 13 /* 0x00002000 */ | 286 | #define AF_ISNS_CMD_DONE 13 /* 0x00002000 */ |
@@ -317,16 +320,17 @@ struct scsi_qla_host { | |||
317 | /* NVRAM registers */ | 320 | /* NVRAM registers */ |
318 | struct eeprom_data *nvram; | 321 | struct eeprom_data *nvram; |
319 | spinlock_t hardware_lock ____cacheline_aligned; | 322 | spinlock_t hardware_lock ____cacheline_aligned; |
320 | spinlock_t list_lock; | ||
321 | uint32_t eeprom_cmd_data; | 323 | uint32_t eeprom_cmd_data; |
322 | 324 | ||
323 | /* Counters for general statistics */ | 325 | /* Counters for general statistics */ |
326 | uint64_t isr_count; | ||
324 | uint64_t adapter_error_count; | 327 | uint64_t adapter_error_count; |
325 | uint64_t device_error_count; | 328 | uint64_t device_error_count; |
326 | uint64_t total_io_count; | 329 | uint64_t total_io_count; |
327 | uint64_t total_mbytes_xferred; | 330 | uint64_t total_mbytes_xferred; |
328 | uint64_t link_failure_count; | 331 | uint64_t link_failure_count; |
329 | uint64_t invalid_crc_count; | 332 | uint64_t invalid_crc_count; |
333 | uint32_t bytes_xfered; | ||
330 | uint32_t spurious_int_count; | 334 | uint32_t spurious_int_count; |
331 | uint32_t aborted_io_count; | 335 | uint32_t aborted_io_count; |
332 | uint32_t io_timeout_count; | 336 | uint32_t io_timeout_count; |
@@ -438,6 +442,11 @@ static inline int is_qla4022(struct scsi_qla_host *ha) | |||
438 | return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4022; | 442 | return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4022; |
439 | } | 443 | } |
440 | 444 | ||
445 | static inline int is_qla4032(struct scsi_qla_host *ha) | ||
446 | { | ||
447 | return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4032; | ||
448 | } | ||
449 | |||
441 | static inline int adapter_up(struct scsi_qla_host *ha) | 450 | static inline int adapter_up(struct scsi_qla_host *ha) |
442 | { | 451 | { |
443 | return (test_bit(AF_ONLINE, &ha->flags) != 0) && | 452 | return (test_bit(AF_ONLINE, &ha->flags) != 0) && |
@@ -451,58 +460,58 @@ static inline struct scsi_qla_host* to_qla_host(struct Scsi_Host *shost) | |||
451 | 460 | ||
452 | static inline void __iomem* isp_semaphore(struct scsi_qla_host *ha) | 461 | static inline void __iomem* isp_semaphore(struct scsi_qla_host *ha) |
453 | { | 462 | { |
454 | return (is_qla4022(ha) ? | 463 | return (is_qla4010(ha) ? |
455 | &ha->reg->u1.isp4022.semaphore : | 464 | &ha->reg->u1.isp4010.nvram : |
456 | &ha->reg->u1.isp4010.nvram); | 465 | &ha->reg->u1.isp4022.semaphore); |
457 | } | 466 | } |
458 | 467 | ||
459 | static inline void __iomem* isp_nvram(struct scsi_qla_host *ha) | 468 | static inline void __iomem* isp_nvram(struct scsi_qla_host *ha) |
460 | { | 469 | { |
461 | return (is_qla4022(ha) ? | 470 | return (is_qla4010(ha) ? |
462 | &ha->reg->u1.isp4022.nvram : | 471 | &ha->reg->u1.isp4010.nvram : |
463 | &ha->reg->u1.isp4010.nvram); | 472 | &ha->reg->u1.isp4022.nvram); |
464 | } | 473 | } |
465 | 474 | ||
466 | static inline void __iomem* isp_ext_hw_conf(struct scsi_qla_host *ha) | 475 | static inline void __iomem* isp_ext_hw_conf(struct scsi_qla_host *ha) |
467 | { | 476 | { |
468 | return (is_qla4022(ha) ? | 477 | return (is_qla4010(ha) ? |
469 | &ha->reg->u2.isp4022.p0.ext_hw_conf : | 478 | &ha->reg->u2.isp4010.ext_hw_conf : |
470 | &ha->reg->u2.isp4010.ext_hw_conf); | 479 | &ha->reg->u2.isp4022.p0.ext_hw_conf); |
471 | } | 480 | } |
472 | 481 | ||
473 | static inline void __iomem* isp_port_status(struct scsi_qla_host *ha) | 482 | static inline void __iomem* isp_port_status(struct scsi_qla_host *ha) |
474 | { | 483 | { |
475 | return (is_qla4022(ha) ? | 484 | return (is_qla4010(ha) ? |
476 | &ha->reg->u2.isp4022.p0.port_status : | 485 | &ha->reg->u2.isp4010.port_status : |
477 | &ha->reg->u2.isp4010.port_status); | 486 | &ha->reg->u2.isp4022.p0.port_status); |
478 | } | 487 | } |
479 | 488 | ||
480 | static inline void __iomem* isp_port_ctrl(struct scsi_qla_host *ha) | 489 | static inline void __iomem* isp_port_ctrl(struct scsi_qla_host *ha) |
481 | { | 490 | { |
482 | return (is_qla4022(ha) ? | 491 | return (is_qla4010(ha) ? |
483 | &ha->reg->u2.isp4022.p0.port_ctrl : | 492 | &ha->reg->u2.isp4010.port_ctrl : |
484 | &ha->reg->u2.isp4010.port_ctrl); | 493 | &ha->reg->u2.isp4022.p0.port_ctrl); |
485 | } | 494 | } |
486 | 495 | ||
487 | static inline void __iomem* isp_port_error_status(struct scsi_qla_host *ha) | 496 | static inline void __iomem* isp_port_error_status(struct scsi_qla_host *ha) |
488 | { | 497 | { |
489 | return (is_qla4022(ha) ? | 498 | return (is_qla4010(ha) ? |
490 | &ha->reg->u2.isp4022.p0.port_err_status : | 499 | &ha->reg->u2.isp4010.port_err_status : |
491 | &ha->reg->u2.isp4010.port_err_status); | 500 | &ha->reg->u2.isp4022.p0.port_err_status); |
492 | } | 501 | } |
493 | 502 | ||
494 | static inline void __iomem * isp_gp_out(struct scsi_qla_host *ha) | 503 | static inline void __iomem * isp_gp_out(struct scsi_qla_host *ha) |
495 | { | 504 | { |
496 | return (is_qla4022(ha) ? | 505 | return (is_qla4010(ha) ? |
497 | &ha->reg->u2.isp4022.p0.gp_out : | 506 | &ha->reg->u2.isp4010.gp_out : |
498 | &ha->reg->u2.isp4010.gp_out); | 507 | &ha->reg->u2.isp4022.p0.gp_out); |
499 | } | 508 | } |
500 | 509 | ||
501 | static inline int eeprom_ext_hw_conf_offset(struct scsi_qla_host *ha) | 510 | static inline int eeprom_ext_hw_conf_offset(struct scsi_qla_host *ha) |
502 | { | 511 | { |
503 | return (is_qla4022(ha) ? | 512 | return (is_qla4010(ha) ? |
504 | offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2 : | 513 | offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2 : |
505 | offsetof(struct eeprom_data, isp4010.ext_hw_conf) / 2); | 514 | offsetof(struct eeprom_data, isp4022.ext_hw_conf) / 2); |
506 | } | 515 | } |
507 | 516 | ||
508 | int ql4xxx_sem_spinlock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits); | 517 | int ql4xxx_sem_spinlock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits); |
@@ -511,59 +520,59 @@ int ql4xxx_sem_lock(struct scsi_qla_host * ha, u32 sem_mask, u32 sem_bits); | |||
511 | 520 | ||
512 | static inline int ql4xxx_lock_flash(struct scsi_qla_host *a) | 521 | static inline int ql4xxx_lock_flash(struct scsi_qla_host *a) |
513 | { | 522 | { |
514 | if (is_qla4022(a)) | 523 | if (is_qla4010(a)) |
524 | return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK, | ||
525 | QL4010_FLASH_SEM_BITS); | ||
526 | else | ||
515 | return ql4xxx_sem_spinlock(a, QL4022_FLASH_SEM_MASK, | 527 | return ql4xxx_sem_spinlock(a, QL4022_FLASH_SEM_MASK, |
516 | (QL4022_RESOURCE_BITS_BASE_CODE | | 528 | (QL4022_RESOURCE_BITS_BASE_CODE | |
517 | (a->mac_index)) << 13); | 529 | (a->mac_index)) << 13); |
518 | else | ||
519 | return ql4xxx_sem_spinlock(a, QL4010_FLASH_SEM_MASK, | ||
520 | QL4010_FLASH_SEM_BITS); | ||
521 | } | 530 | } |
522 | 531 | ||
523 | static inline void ql4xxx_unlock_flash(struct scsi_qla_host *a) | 532 | static inline void ql4xxx_unlock_flash(struct scsi_qla_host *a) |
524 | { | 533 | { |
525 | if (is_qla4022(a)) | 534 | if (is_qla4010(a)) |
526 | ql4xxx_sem_unlock(a, QL4022_FLASH_SEM_MASK); | ||
527 | else | ||
528 | ql4xxx_sem_unlock(a, QL4010_FLASH_SEM_MASK); | 535 | ql4xxx_sem_unlock(a, QL4010_FLASH_SEM_MASK); |
536 | else | ||
537 | ql4xxx_sem_unlock(a, QL4022_FLASH_SEM_MASK); | ||
529 | } | 538 | } |
530 | 539 | ||
531 | static inline int ql4xxx_lock_nvram(struct scsi_qla_host *a) | 540 | static inline int ql4xxx_lock_nvram(struct scsi_qla_host *a) |
532 | { | 541 | { |
533 | if (is_qla4022(a)) | 542 | if (is_qla4010(a)) |
543 | return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK, | ||
544 | QL4010_NVRAM_SEM_BITS); | ||
545 | else | ||
534 | return ql4xxx_sem_spinlock(a, QL4022_NVRAM_SEM_MASK, | 546 | return ql4xxx_sem_spinlock(a, QL4022_NVRAM_SEM_MASK, |
535 | (QL4022_RESOURCE_BITS_BASE_CODE | | 547 | (QL4022_RESOURCE_BITS_BASE_CODE | |
536 | (a->mac_index)) << 10); | 548 | (a->mac_index)) << 10); |
537 | else | ||
538 | return ql4xxx_sem_spinlock(a, QL4010_NVRAM_SEM_MASK, | ||
539 | QL4010_NVRAM_SEM_BITS); | ||
540 | } | 549 | } |
541 | 550 | ||
542 | static inline void ql4xxx_unlock_nvram(struct scsi_qla_host *a) | 551 | static inline void ql4xxx_unlock_nvram(struct scsi_qla_host *a) |
543 | { | 552 | { |
544 | if (is_qla4022(a)) | 553 | if (is_qla4010(a)) |
545 | ql4xxx_sem_unlock(a, QL4022_NVRAM_SEM_MASK); | ||
546 | else | ||
547 | ql4xxx_sem_unlock(a, QL4010_NVRAM_SEM_MASK); | 554 | ql4xxx_sem_unlock(a, QL4010_NVRAM_SEM_MASK); |
555 | else | ||
556 | ql4xxx_sem_unlock(a, QL4022_NVRAM_SEM_MASK); | ||
548 | } | 557 | } |
549 | 558 | ||
550 | static inline int ql4xxx_lock_drvr(struct scsi_qla_host *a) | 559 | static inline int ql4xxx_lock_drvr(struct scsi_qla_host *a) |
551 | { | 560 | { |
552 | if (is_qla4022(a)) | 561 | if (is_qla4010(a)) |
562 | return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK, | ||
563 | QL4010_DRVR_SEM_BITS); | ||
564 | else | ||
553 | return ql4xxx_sem_lock(a, QL4022_DRVR_SEM_MASK, | 565 | return ql4xxx_sem_lock(a, QL4022_DRVR_SEM_MASK, |
554 | (QL4022_RESOURCE_BITS_BASE_CODE | | 566 | (QL4022_RESOURCE_BITS_BASE_CODE | |
555 | (a->mac_index)) << 1); | 567 | (a->mac_index)) << 1); |
556 | else | ||
557 | return ql4xxx_sem_lock(a, QL4010_DRVR_SEM_MASK, | ||
558 | QL4010_DRVR_SEM_BITS); | ||
559 | } | 568 | } |
560 | 569 | ||
561 | static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a) | 570 | static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a) |
562 | { | 571 | { |
563 | if (is_qla4022(a)) | 572 | if (is_qla4010(a)) |
564 | ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK); | ||
565 | else | ||
566 | ql4xxx_sem_unlock(a, QL4010_DRVR_SEM_MASK); | 573 | ql4xxx_sem_unlock(a, QL4010_DRVR_SEM_MASK); |
574 | else | ||
575 | ql4xxx_sem_unlock(a, QL4022_DRVR_SEM_MASK); | ||
567 | } | 576 | } |
568 | 577 | ||
569 | /*---------------------------------------------------------------------------*/ | 578 | /*---------------------------------------------------------------------------*/ |
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h index 427489de64bc..4eea8c571916 100644 --- a/drivers/scsi/qla4xxx/ql4_fw.h +++ b/drivers/scsi/qla4xxx/ql4_fw.h | |||
@@ -296,7 +296,6 @@ static inline uint32_t clr_rmask(uint32_t val) | |||
296 | /* ISP Semaphore definitions */ | 296 | /* ISP Semaphore definitions */ |
297 | 297 | ||
298 | /* ISP General Purpose Output definitions */ | 298 | /* ISP General Purpose Output definitions */ |
299 | #define GPOR_TOPCAT_RESET 0x00000004 | ||
300 | 299 | ||
301 | /* shadow registers (DMA'd from HA to system memory. read only) */ | 300 | /* shadow registers (DMA'd from HA to system memory. read only) */ |
302 | struct shadow_regs { | 301 | struct shadow_regs { |
@@ -339,10 +338,13 @@ union external_hw_config_reg { | |||
339 | /* Mailbox command definitions */ | 338 | /* Mailbox command definitions */ |
340 | #define MBOX_CMD_ABOUT_FW 0x0009 | 339 | #define MBOX_CMD_ABOUT_FW 0x0009 |
341 | #define MBOX_CMD_LUN_RESET 0x0016 | 340 | #define MBOX_CMD_LUN_RESET 0x0016 |
341 | #define MBOX_CMD_GET_MANAGEMENT_DATA 0x001E | ||
342 | #define MBOX_CMD_GET_FW_STATUS 0x001F | 342 | #define MBOX_CMD_GET_FW_STATUS 0x001F |
343 | #define MBOX_CMD_SET_ISNS_SERVICE 0x0021 | 343 | #define MBOX_CMD_SET_ISNS_SERVICE 0x0021 |
344 | #define ISNS_DISABLE 0 | 344 | #define ISNS_DISABLE 0 |
345 | #define ISNS_ENABLE 1 | 345 | #define ISNS_ENABLE 1 |
346 | #define MBOX_CMD_COPY_FLASH 0x0024 | ||
347 | #define MBOX_CMD_WRITE_FLASH 0x0025 | ||
346 | #define MBOX_CMD_READ_FLASH 0x0026 | 348 | #define MBOX_CMD_READ_FLASH 0x0026 |
347 | #define MBOX_CMD_CLEAR_DATABASE_ENTRY 0x0031 | 349 | #define MBOX_CMD_CLEAR_DATABASE_ENTRY 0x0031 |
348 | #define MBOX_CMD_CONN_CLOSE_SESS_LOGOUT 0x0056 | 350 | #define MBOX_CMD_CONN_CLOSE_SESS_LOGOUT 0x0056 |
@@ -360,10 +362,13 @@ union external_hw_config_reg { | |||
360 | #define DDB_DS_SESSION_FAILED 0x06 | 362 | #define DDB_DS_SESSION_FAILED 0x06 |
361 | #define DDB_DS_LOGIN_IN_PROCESS 0x07 | 363 | #define DDB_DS_LOGIN_IN_PROCESS 0x07 |
362 | #define MBOX_CMD_GET_FW_STATE 0x0069 | 364 | #define MBOX_CMD_GET_FW_STATE 0x0069 |
365 | #define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK_DEFAULTS 0x006A | ||
366 | #define MBOX_CMD_RESTORE_FACTORY_DEFAULTS 0x0087 | ||
363 | 367 | ||
364 | /* Mailbox 1 */ | 368 | /* Mailbox 1 */ |
365 | #define FW_STATE_READY 0x0000 | 369 | #define FW_STATE_READY 0x0000 |
366 | #define FW_STATE_CONFIG_WAIT 0x0001 | 370 | #define FW_STATE_CONFIG_WAIT 0x0001 |
371 | #define FW_STATE_WAIT_LOGIN 0x0002 | ||
367 | #define FW_STATE_ERROR 0x0004 | 372 | #define FW_STATE_ERROR 0x0004 |
368 | #define FW_STATE_DHCP_IN_PROGRESS 0x0008 | 373 | #define FW_STATE_DHCP_IN_PROGRESS 0x0008 |
369 | 374 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 1b221ff0f6f7..2122967bbf0b 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #ifndef __QLA4x_GBL_H | 8 | #ifndef __QLA4x_GBL_H |
9 | #define __QLA4x_GBL_H | 9 | #define __QLA4x_GBL_H |
10 | 10 | ||
11 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a); | ||
11 | int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port); | 12 | int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port); |
12 | int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb); | 13 | int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb); |
13 | int qla4xxx_initialize_adapter(struct scsi_qla_host * ha, | 14 | int qla4xxx_initialize_adapter(struct scsi_qla_host * ha, |
@@ -75,4 +76,4 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, | |||
75 | extern int ql4xextended_error_logging; | 76 | extern int ql4xextended_error_logging; |
76 | extern int ql4xdiscoverywait; | 77 | extern int ql4xdiscoverywait; |
77 | extern int ql4xdontresethba; | 78 | extern int ql4xdontresethba; |
78 | #endif /* _QLA4x_GBL_H */ | 79 | #endif /* _QLA4x_GBL_H */ |
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index bb3a1c11f44c..cc210f297a78 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -259,10 +259,16 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha) | |||
259 | "seconds expired= %d\n", ha->host_no, __func__, | 259 | "seconds expired= %d\n", ha->host_no, __func__, |
260 | ha->firmware_state, ha->addl_fw_state, | 260 | ha->firmware_state, ha->addl_fw_state, |
261 | timeout_count)); | 261 | timeout_count)); |
262 | if (is_qla4032(ha) && | ||
263 | !(ha->addl_fw_state & FW_ADDSTATE_LINK_UP) && | ||
264 | (timeout_count < ADAPTER_INIT_TOV - 5)) { | ||
265 | break; | ||
266 | } | ||
267 | |||
262 | msleep(1000); | 268 | msleep(1000); |
263 | } /* end of for */ | 269 | } /* end of for */ |
264 | 270 | ||
265 | if (timeout_count <= 0) | 271 | if (timeout_count == 0) |
266 | DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n", | 272 | DEBUG2(printk("scsi%ld: %s: FW Initialization timed out!\n", |
267 | ha->host_no, __func__)); | 273 | ha->host_no, __func__)); |
268 | 274 | ||
@@ -806,32 +812,6 @@ int qla4xxx_relogin_device(struct scsi_qla_host *ha, | |||
806 | return QLA_SUCCESS; | 812 | return QLA_SUCCESS; |
807 | } | 813 | } |
808 | 814 | ||
809 | /** | ||
810 | * qla4010_get_topcat_presence - check if it is QLA4040 TopCat Chip | ||
811 | * @ha: Pointer to host adapter structure. | ||
812 | * | ||
813 | **/ | ||
814 | static int qla4010_get_topcat_presence(struct scsi_qla_host *ha) | ||
815 | { | ||
816 | unsigned long flags; | ||
817 | uint16_t topcat; | ||
818 | |||
819 | if (ql4xxx_lock_nvram(ha) != QLA_SUCCESS) | ||
820 | return QLA_ERROR; | ||
821 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
822 | topcat = rd_nvram_word(ha, offsetof(struct eeprom_data, | ||
823 | isp4010.topcat)); | ||
824 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
825 | |||
826 | if ((topcat & TOPCAT_MASK) == TOPCAT_PRESENT) | ||
827 | set_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags); | ||
828 | else | ||
829 | clear_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags); | ||
830 | ql4xxx_unlock_nvram(ha); | ||
831 | return QLA_SUCCESS; | ||
832 | } | ||
833 | |||
834 | |||
835 | static int qla4xxx_config_nvram(struct scsi_qla_host *ha) | 815 | static int qla4xxx_config_nvram(struct scsi_qla_host *ha) |
836 | { | 816 | { |
837 | unsigned long flags; | 817 | unsigned long flags; |
@@ -866,7 +846,7 @@ static int qla4xxx_config_nvram(struct scsi_qla_host *ha) | |||
866 | /* set defaults */ | 846 | /* set defaults */ |
867 | if (is_qla4010(ha)) | 847 | if (is_qla4010(ha)) |
868 | extHwConfig.Asuint32_t = 0x1912; | 848 | extHwConfig.Asuint32_t = 0x1912; |
869 | else if (is_qla4022(ha)) | 849 | else if (is_qla4022(ha) | is_qla4032(ha)) |
870 | extHwConfig.Asuint32_t = 0x0023; | 850 | extHwConfig.Asuint32_t = 0x0023; |
871 | } | 851 | } |
872 | DEBUG(printk("scsi%ld: %s: Setting extHwConfig to 0xFFFF%04x\n", | 852 | DEBUG(printk("scsi%ld: %s: Setting extHwConfig to 0xFFFF%04x\n", |
@@ -927,7 +907,7 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) | |||
927 | 907 | ||
928 | spin_lock_irqsave(&ha->hardware_lock, flags); | 908 | spin_lock_irqsave(&ha->hardware_lock, flags); |
929 | writel(jiffies, &ha->reg->mailbox[7]); | 909 | writel(jiffies, &ha->reg->mailbox[7]); |
930 | if (is_qla4022(ha)) | 910 | if (is_qla4022(ha) | is_qla4032(ha)) |
931 | writel(set_rmask(NVR_WRITE_ENABLE), | 911 | writel(set_rmask(NVR_WRITE_ENABLE), |
932 | &ha->reg->u1.isp4022.nvram); | 912 | &ha->reg->u1.isp4022.nvram); |
933 | 913 | ||
@@ -978,7 +958,7 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) | |||
978 | return status; | 958 | return status; |
979 | } | 959 | } |
980 | 960 | ||
981 | static int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) | 961 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) |
982 | { | 962 | { |
983 | #define QL4_LOCK_DRVR_WAIT 300 | 963 | #define QL4_LOCK_DRVR_WAIT 300 |
984 | #define QL4_LOCK_DRVR_SLEEP 100 | 964 | #define QL4_LOCK_DRVR_SLEEP 100 |
@@ -1018,12 +998,7 @@ static int qla4xxx_start_firmware(struct scsi_qla_host *ha) | |||
1018 | int soft_reset = 1; | 998 | int soft_reset = 1; |
1019 | int config_chip = 0; | 999 | int config_chip = 0; |
1020 | 1000 | ||
1021 | if (is_qla4010(ha)){ | 1001 | if (is_qla4022(ha) | is_qla4032(ha)) |
1022 | if (qla4010_get_topcat_presence(ha) != QLA_SUCCESS) | ||
1023 | return QLA_ERROR; | ||
1024 | } | ||
1025 | |||
1026 | if (is_qla4022(ha)) | ||
1027 | ql4xxx_set_mac_number(ha); | 1002 | ql4xxx_set_mac_number(ha); |
1028 | 1003 | ||
1029 | if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS) | 1004 | if (ql4xxx_lock_drvr_wait(ha) != QLA_SUCCESS) |
diff --git a/drivers/scsi/qla4xxx/ql4_inline.h b/drivers/scsi/qla4xxx/ql4_inline.h index 0d61797af7da..6375eb017dd3 100644 --- a/drivers/scsi/qla4xxx/ql4_inline.h +++ b/drivers/scsi/qla4xxx/ql4_inline.h | |||
@@ -38,7 +38,7 @@ qla4xxx_lookup_ddb_by_fw_index(struct scsi_qla_host *ha, uint32_t fw_ddb_index) | |||
38 | static inline void | 38 | static inline void |
39 | __qla4xxx_enable_intrs(struct scsi_qla_host *ha) | 39 | __qla4xxx_enable_intrs(struct scsi_qla_host *ha) |
40 | { | 40 | { |
41 | if (is_qla4022(ha)) { | 41 | if (is_qla4022(ha) | is_qla4032(ha)) { |
42 | writel(set_rmask(IMR_SCSI_INTR_ENABLE), | 42 | writel(set_rmask(IMR_SCSI_INTR_ENABLE), |
43 | &ha->reg->u1.isp4022.intr_mask); | 43 | &ha->reg->u1.isp4022.intr_mask); |
44 | readl(&ha->reg->u1.isp4022.intr_mask); | 44 | readl(&ha->reg->u1.isp4022.intr_mask); |
@@ -52,7 +52,7 @@ __qla4xxx_enable_intrs(struct scsi_qla_host *ha) | |||
52 | static inline void | 52 | static inline void |
53 | __qla4xxx_disable_intrs(struct scsi_qla_host *ha) | 53 | __qla4xxx_disable_intrs(struct scsi_qla_host *ha) |
54 | { | 54 | { |
55 | if (is_qla4022(ha)) { | 55 | if (is_qla4022(ha) | is_qla4032(ha)) { |
56 | writel(clr_rmask(IMR_SCSI_INTR_ENABLE), | 56 | writel(clr_rmask(IMR_SCSI_INTR_ENABLE), |
57 | &ha->reg->u1.isp4022.intr_mask); | 57 | &ha->reg->u1.isp4022.intr_mask); |
58 | readl(&ha->reg->u1.isp4022.intr_mask); | 58 | readl(&ha->reg->u1.isp4022.intr_mask); |
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c index c0a254b89a30..d41ce380eedc 100644 --- a/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/drivers/scsi/qla4xxx/ql4_iocb.c | |||
@@ -294,6 +294,12 @@ int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb * srb) | |||
294 | cmd_entry->control_flags = CF_WRITE; | 294 | cmd_entry->control_flags = CF_WRITE; |
295 | else if (cmd->sc_data_direction == DMA_FROM_DEVICE) | 295 | else if (cmd->sc_data_direction == DMA_FROM_DEVICE) |
296 | cmd_entry->control_flags = CF_READ; | 296 | cmd_entry->control_flags = CF_READ; |
297 | |||
298 | ha->bytes_xfered += cmd->request_bufflen; | ||
299 | if (ha->bytes_xfered & ~0xFFFFF){ | ||
300 | ha->total_mbytes_xferred += ha->bytes_xfered >> 20; | ||
301 | ha->bytes_xfered &= 0xFFFFF; | ||
302 | } | ||
297 | } | 303 | } |
298 | 304 | ||
299 | /* Set tagged queueing control flags */ | 305 | /* Set tagged queueing control flags */ |
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index 1e283321a59d..ef975e0dc87f 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c | |||
@@ -627,6 +627,7 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id) | |||
627 | 627 | ||
628 | spin_lock_irqsave(&ha->hardware_lock, flags); | 628 | spin_lock_irqsave(&ha->hardware_lock, flags); |
629 | 629 | ||
630 | ha->isr_count++; | ||
630 | /* | 631 | /* |
631 | * Repeatedly service interrupts up to a maximum of | 632 | * Repeatedly service interrupts up to a maximum of |
632 | * MAX_REQS_SERVICED_PER_INTR | 633 | * MAX_REQS_SERVICED_PER_INTR |
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.c b/drivers/scsi/qla4xxx/ql4_nvram.c index e3957ca5b645..58afd135aa1d 100644 --- a/drivers/scsi/qla4xxx/ql4_nvram.c +++ b/drivers/scsi/qla4xxx/ql4_nvram.c | |||
@@ -7,15 +7,22 @@ | |||
7 | 7 | ||
8 | #include "ql4_def.h" | 8 | #include "ql4_def.h" |
9 | 9 | ||
10 | static inline void eeprom_cmd(uint32_t cmd, struct scsi_qla_host *ha) | ||
11 | { | ||
12 | writel(cmd, isp_nvram(ha)); | ||
13 | readl(isp_nvram(ha)); | ||
14 | udelay(1); | ||
15 | } | ||
16 | |||
10 | static inline int eeprom_size(struct scsi_qla_host *ha) | 17 | static inline int eeprom_size(struct scsi_qla_host *ha) |
11 | { | 18 | { |
12 | return is_qla4022(ha) ? FM93C86A_SIZE_16 : FM93C66A_SIZE_16; | 19 | return is_qla4010(ha) ? FM93C66A_SIZE_16 : FM93C86A_SIZE_16; |
13 | } | 20 | } |
14 | 21 | ||
15 | static inline int eeprom_no_addr_bits(struct scsi_qla_host *ha) | 22 | static inline int eeprom_no_addr_bits(struct scsi_qla_host *ha) |
16 | { | 23 | { |
17 | return is_qla4022(ha) ? FM93C86A_NO_ADDR_BITS_16 : | 24 | return is_qla4010(ha) ? FM93C56A_NO_ADDR_BITS_16 : |
18 | FM93C56A_NO_ADDR_BITS_16; | 25 | FM93C86A_NO_ADDR_BITS_16 ; |
19 | } | 26 | } |
20 | 27 | ||
21 | static inline int eeprom_no_data_bits(struct scsi_qla_host *ha) | 28 | static inline int eeprom_no_data_bits(struct scsi_qla_host *ha) |
@@ -28,8 +35,7 @@ static int fm93c56a_select(struct scsi_qla_host * ha) | |||
28 | DEBUG5(printk(KERN_ERR "fm93c56a_select:\n")); | 35 | DEBUG5(printk(KERN_ERR "fm93c56a_select:\n")); |
29 | 36 | ||
30 | ha->eeprom_cmd_data = AUBURN_EEPROM_CS_1 | 0x000f0000; | 37 | ha->eeprom_cmd_data = AUBURN_EEPROM_CS_1 | 0x000f0000; |
31 | writel(ha->eeprom_cmd_data, isp_nvram(ha)); | 38 | eeprom_cmd(ha->eeprom_cmd_data, ha); |
32 | readl(isp_nvram(ha)); | ||
33 | return 1; | 39 | return 1; |
34 | } | 40 | } |
35 | 41 | ||
@@ -41,12 +47,13 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr) | |||
41 | int previousBit; | 47 | int previousBit; |
42 | 48 | ||
43 | /* Clock in a zero, then do the start bit. */ | 49 | /* Clock in a zero, then do the start bit. */ |
44 | writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1, isp_nvram(ha)); | 50 | eeprom_cmd(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1, ha); |
45 | writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 | | 51 | |
46 | AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); | 52 | eeprom_cmd(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 | |
47 | writel(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 | | 53 | AUBURN_EEPROM_CLK_RISE, ha); |
48 | AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); | 54 | eeprom_cmd(ha->eeprom_cmd_data | AUBURN_EEPROM_DO_1 | |
49 | readl(isp_nvram(ha)); | 55 | AUBURN_EEPROM_CLK_FALL, ha); |
56 | |||
50 | mask = 1 << (FM93C56A_CMD_BITS - 1); | 57 | mask = 1 << (FM93C56A_CMD_BITS - 1); |
51 | 58 | ||
52 | /* Force the previous data bit to be different. */ | 59 | /* Force the previous data bit to be different. */ |
@@ -60,14 +67,14 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr) | |||
60 | * If the bit changed, then change the DO state to | 67 | * If the bit changed, then change the DO state to |
61 | * match. | 68 | * match. |
62 | */ | 69 | */ |
63 | writel(ha->eeprom_cmd_data | dataBit, isp_nvram(ha)); | 70 | eeprom_cmd(ha->eeprom_cmd_data | dataBit, ha); |
64 | previousBit = dataBit; | 71 | previousBit = dataBit; |
65 | } | 72 | } |
66 | writel(ha->eeprom_cmd_data | dataBit | | 73 | eeprom_cmd(ha->eeprom_cmd_data | dataBit | |
67 | AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); | 74 | AUBURN_EEPROM_CLK_RISE, ha); |
68 | writel(ha->eeprom_cmd_data | dataBit | | 75 | eeprom_cmd(ha->eeprom_cmd_data | dataBit | |
69 | AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); | 76 | AUBURN_EEPROM_CLK_FALL, ha); |
70 | readl(isp_nvram(ha)); | 77 | |
71 | cmd = cmd << 1; | 78 | cmd = cmd << 1; |
72 | } | 79 | } |
73 | mask = 1 << (eeprom_no_addr_bits(ha) - 1); | 80 | mask = 1 << (eeprom_no_addr_bits(ha) - 1); |
@@ -82,14 +89,15 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr) | |||
82 | * If the bit changed, then change the DO state to | 89 | * If the bit changed, then change the DO state to |
83 | * match. | 90 | * match. |
84 | */ | 91 | */ |
85 | writel(ha->eeprom_cmd_data | dataBit, isp_nvram(ha)); | 92 | eeprom_cmd(ha->eeprom_cmd_data | dataBit, ha); |
93 | |||
86 | previousBit = dataBit; | 94 | previousBit = dataBit; |
87 | } | 95 | } |
88 | writel(ha->eeprom_cmd_data | dataBit | | 96 | eeprom_cmd(ha->eeprom_cmd_data | dataBit | |
89 | AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); | 97 | AUBURN_EEPROM_CLK_RISE, ha); |
90 | writel(ha->eeprom_cmd_data | dataBit | | 98 | eeprom_cmd(ha->eeprom_cmd_data | dataBit | |
91 | AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); | 99 | AUBURN_EEPROM_CLK_FALL, ha); |
92 | readl(isp_nvram(ha)); | 100 | |
93 | addr = addr << 1; | 101 | addr = addr << 1; |
94 | } | 102 | } |
95 | return 1; | 103 | return 1; |
@@ -98,8 +106,7 @@ static int fm93c56a_cmd(struct scsi_qla_host * ha, int cmd, int addr) | |||
98 | static int fm93c56a_deselect(struct scsi_qla_host * ha) | 106 | static int fm93c56a_deselect(struct scsi_qla_host * ha) |
99 | { | 107 | { |
100 | ha->eeprom_cmd_data = AUBURN_EEPROM_CS_0 | 0x000f0000; | 108 | ha->eeprom_cmd_data = AUBURN_EEPROM_CS_0 | 0x000f0000; |
101 | writel(ha->eeprom_cmd_data, isp_nvram(ha)); | 109 | eeprom_cmd(ha->eeprom_cmd_data, ha); |
102 | readl(isp_nvram(ha)); | ||
103 | return 1; | 110 | return 1; |
104 | } | 111 | } |
105 | 112 | ||
@@ -112,12 +119,13 @@ static int fm93c56a_datain(struct scsi_qla_host * ha, unsigned short *value) | |||
112 | /* Read the data bits | 119 | /* Read the data bits |
113 | * The first bit is a dummy. Clock right over it. */ | 120 | * The first bit is a dummy. Clock right over it. */ |
114 | for (i = 0; i < eeprom_no_data_bits(ha); i++) { | 121 | for (i = 0; i < eeprom_no_data_bits(ha); i++) { |
115 | writel(ha->eeprom_cmd_data | | 122 | eeprom_cmd(ha->eeprom_cmd_data | |
116 | AUBURN_EEPROM_CLK_RISE, isp_nvram(ha)); | 123 | AUBURN_EEPROM_CLK_RISE, ha); |
117 | writel(ha->eeprom_cmd_data | | 124 | eeprom_cmd(ha->eeprom_cmd_data | |
118 | AUBURN_EEPROM_CLK_FALL, isp_nvram(ha)); | 125 | AUBURN_EEPROM_CLK_FALL, ha); |
119 | dataBit = | 126 | |
120 | (readw(isp_nvram(ha)) & AUBURN_EEPROM_DI_1) ? 1 : 0; | 127 | dataBit = (readw(isp_nvram(ha)) & AUBURN_EEPROM_DI_1) ? 1 : 0; |
128 | |||
121 | data = (data << 1) | dataBit; | 129 | data = (data << 1) | dataBit; |
122 | } | 130 | } |
123 | 131 | ||
diff --git a/drivers/scsi/qla4xxx/ql4_nvram.h b/drivers/scsi/qla4xxx/ql4_nvram.h index 08e2aed8c6cc..b47b4fc59d83 100644 --- a/drivers/scsi/qla4xxx/ql4_nvram.h +++ b/drivers/scsi/qla4xxx/ql4_nvram.h | |||
@@ -134,9 +134,7 @@ struct eeprom_data { | |||
134 | u16 phyConfig; /* x36 */ | 134 | u16 phyConfig; /* x36 */ |
135 | #define PHY_CONFIG_PHY_ADDR_MASK 0x1f | 135 | #define PHY_CONFIG_PHY_ADDR_MASK 0x1f |
136 | #define PHY_CONFIG_ENABLE_FW_MANAGEMENT_MASK 0x20 | 136 | #define PHY_CONFIG_ENABLE_FW_MANAGEMENT_MASK 0x20 |
137 | u16 topcat; /* x38 */ | 137 | u16 reserved_56; /* x38 */ |
138 | #define TOPCAT_PRESENT 0x0100 | ||
139 | #define TOPCAT_MASK 0xFF00 | ||
140 | 138 | ||
141 | #define EEPROM_UNUSED_1_SIZE 2 | 139 | #define EEPROM_UNUSED_1_SIZE 2 |
142 | u8 unused_1[EEPROM_UNUSED_1_SIZE]; /* x3A */ | 140 | u8 unused_1[EEPROM_UNUSED_1_SIZE]; /* x3A */ |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 5b8db6109536..969c9e431028 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -708,10 +708,10 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) | |||
708 | } | 708 | } |
709 | 709 | ||
710 | /** | 710 | /** |
711 | * qla4010_soft_reset - performs soft reset. | 711 | * qla4xxx_soft_reset - performs soft reset. |
712 | * @ha: Pointer to host adapter structure. | 712 | * @ha: Pointer to host adapter structure. |
713 | **/ | 713 | **/ |
714 | static int qla4010_soft_reset(struct scsi_qla_host *ha) | 714 | int qla4xxx_soft_reset(struct scsi_qla_host *ha) |
715 | { | 715 | { |
716 | uint32_t max_wait_time; | 716 | uint32_t max_wait_time; |
717 | unsigned long flags = 0; | 717 | unsigned long flags = 0; |
@@ -817,29 +817,6 @@ static int qla4010_soft_reset(struct scsi_qla_host *ha) | |||
817 | } | 817 | } |
818 | 818 | ||
819 | /** | 819 | /** |
820 | * qla4xxx_topcat_reset - performs hard reset of TopCat Chip. | ||
821 | * @ha: Pointer to host adapter structure. | ||
822 | **/ | ||
823 | static int qla4xxx_topcat_reset(struct scsi_qla_host *ha) | ||
824 | { | ||
825 | unsigned long flags; | ||
826 | |||
827 | ql4xxx_lock_nvram(ha); | ||
828 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
829 | writel(set_rmask(GPOR_TOPCAT_RESET), isp_gp_out(ha)); | ||
830 | readl(isp_gp_out(ha)); | ||
831 | mdelay(1); | ||
832 | |||
833 | writel(clr_rmask(GPOR_TOPCAT_RESET), isp_gp_out(ha)); | ||
834 | readl(isp_gp_out(ha)); | ||
835 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
836 | mdelay(2523); | ||
837 | |||
838 | ql4xxx_unlock_nvram(ha); | ||
839 | return QLA_SUCCESS; | ||
840 | } | ||
841 | |||
842 | /** | ||
843 | * qla4xxx_flush_active_srbs - returns all outstanding i/o requests to O.S. | 820 | * qla4xxx_flush_active_srbs - returns all outstanding i/o requests to O.S. |
844 | * @ha: Pointer to host adapter structure. | 821 | * @ha: Pointer to host adapter structure. |
845 | * | 822 | * |
@@ -867,26 +844,6 @@ static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha) | |||
867 | } | 844 | } |
868 | 845 | ||
869 | /** | 846 | /** |
870 | * qla4xxx_hard_reset - performs HBA Hard Reset | ||
871 | * @ha: Pointer to host adapter structure. | ||
872 | **/ | ||
873 | static int qla4xxx_hard_reset(struct scsi_qla_host *ha) | ||
874 | { | ||
875 | /* The QLA4010 really doesn't have an equivalent to a hard reset */ | ||
876 | qla4xxx_flush_active_srbs(ha); | ||
877 | if (test_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags)) { | ||
878 | int status = QLA_ERROR; | ||
879 | |||
880 | if ((qla4010_soft_reset(ha) == QLA_SUCCESS) && | ||
881 | (qla4xxx_topcat_reset(ha) == QLA_SUCCESS) && | ||
882 | (qla4010_soft_reset(ha) == QLA_SUCCESS)) | ||
883 | status = QLA_SUCCESS; | ||
884 | return status; | ||
885 | } else | ||
886 | return qla4010_soft_reset(ha); | ||
887 | } | ||
888 | |||
889 | /** | ||
890 | * qla4xxx_recover_adapter - recovers adapter after a fatal error | 847 | * qla4xxx_recover_adapter - recovers adapter after a fatal error |
891 | * @ha: Pointer to host adapter structure. | 848 | * @ha: Pointer to host adapter structure. |
892 | * @renew_ddb_list: Indicates what to do with the adapter's ddb list | 849 | * @renew_ddb_list: Indicates what to do with the adapter's ddb list |
@@ -919,18 +876,11 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, | |||
919 | if (status == QLA_SUCCESS) { | 876 | if (status == QLA_SUCCESS) { |
920 | DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n", | 877 | DEBUG2(printk("scsi%ld: %s - Performing soft reset..\n", |
921 | ha->host_no, __func__)); | 878 | ha->host_no, __func__)); |
922 | status = qla4xxx_soft_reset(ha); | 879 | qla4xxx_flush_active_srbs(ha); |
923 | } | 880 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) |
924 | /* FIXMEkaren: Do we want to keep interrupts enabled and process | 881 | status = qla4xxx_soft_reset(ha); |
925 | AENs after soft reset */ | 882 | else |
926 | 883 | status = QLA_ERROR; | |
927 | /* If firmware (SOFT) reset failed, or if all outstanding | ||
928 | * commands have not returned, then do a HARD reset. | ||
929 | */ | ||
930 | if (status == QLA_ERROR) { | ||
931 | DEBUG2(printk("scsi%ld: %s - Performing hard reset..\n", | ||
932 | ha->host_no, __func__)); | ||
933 | status = qla4xxx_hard_reset(ha); | ||
934 | } | 884 | } |
935 | 885 | ||
936 | /* Flush any pending ddb changed AENs */ | 886 | /* Flush any pending ddb changed AENs */ |
@@ -1011,18 +961,15 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha, | |||
1011 | * the mid-level tries to sleep when it reaches the driver threshold | 961 | * the mid-level tries to sleep when it reaches the driver threshold |
1012 | * "host->can_queue". This can cause a panic if we were in our interrupt code. | 962 | * "host->can_queue". This can cause a panic if we were in our interrupt code. |
1013 | **/ | 963 | **/ |
1014 | static void qla4xxx_do_dpc(void *data) | 964 | static void qla4xxx_do_dpc(struct work_struct *work) |
1015 | { | 965 | { |
1016 | struct scsi_qla_host *ha = (struct scsi_qla_host *) data; | 966 | struct scsi_qla_host *ha = |
967 | container_of(work, struct scsi_qla_host, dpc_work); | ||
1017 | struct ddb_entry *ddb_entry, *dtemp; | 968 | struct ddb_entry *ddb_entry, *dtemp; |
1018 | 969 | ||
1019 | DEBUG2(printk("scsi%ld: %s: DPC handler waking up.\n", | 970 | DEBUG2(printk("scsi%ld: %s: DPC handler waking up." |
1020 | ha->host_no, __func__)); | 971 | "flags = 0x%08lx, dpc_flags = 0x%08lx\n", |
1021 | 972 | ha->host_no, __func__, ha->flags, ha->dpc_flags)); | |
1022 | DEBUG2(printk("scsi%ld: %s: ha->flags = 0x%08lx\n", | ||
1023 | ha->host_no, __func__, ha->flags)); | ||
1024 | DEBUG2(printk("scsi%ld: %s: ha->dpc_flags = 0x%08lx\n", | ||
1025 | ha->host_no, __func__, ha->dpc_flags)); | ||
1026 | 973 | ||
1027 | /* Initialization not yet finished. Don't do anything yet. */ | 974 | /* Initialization not yet finished. Don't do anything yet. */ |
1028 | if (!test_bit(AF_INIT_DONE, &ha->flags)) | 975 | if (!test_bit(AF_INIT_DONE, &ha->flags)) |
@@ -1032,16 +979,8 @@ static void qla4xxx_do_dpc(void *data) | |||
1032 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || | 979 | test_bit(DPC_RESET_HA, &ha->dpc_flags) || |
1033 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || | 980 | test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags) || |
1034 | test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) { | 981 | test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) { |
1035 | if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags)) | 982 | if (test_bit(DPC_RESET_HA_DESTROY_DDB_LIST, &ha->dpc_flags) || |
1036 | /* | 983 | test_bit(DPC_RESET_HA, &ha->dpc_flags)) |
1037 | * dg 09/23 Never initialize ddb list | ||
1038 | * once we up and running | ||
1039 | * qla4xxx_recover_adapter(ha, | ||
1040 | * REBUILD_DDB_LIST); | ||
1041 | */ | ||
1042 | qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); | ||
1043 | |||
1044 | if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) | ||
1045 | qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); | 984 | qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); |
1046 | 985 | ||
1047 | if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { | 986 | if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { |
@@ -1122,7 +1061,8 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) | |||
1122 | destroy_workqueue(ha->dpc_thread); | 1061 | destroy_workqueue(ha->dpc_thread); |
1123 | 1062 | ||
1124 | /* Issue Soft Reset to put firmware in unknown state */ | 1063 | /* Issue Soft Reset to put firmware in unknown state */ |
1125 | qla4xxx_soft_reset(ha); | 1064 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) |
1065 | qla4xxx_soft_reset(ha); | ||
1126 | 1066 | ||
1127 | /* Remove timer thread, if present */ | 1067 | /* Remove timer thread, if present */ |
1128 | if (ha->timer_active) | 1068 | if (ha->timer_active) |
@@ -1261,7 +1201,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
1261 | init_waitqueue_head(&ha->mailbox_wait_queue); | 1201 | init_waitqueue_head(&ha->mailbox_wait_queue); |
1262 | 1202 | ||
1263 | spin_lock_init(&ha->hardware_lock); | 1203 | spin_lock_init(&ha->hardware_lock); |
1264 | spin_lock_init(&ha->list_lock); | ||
1265 | 1204 | ||
1266 | /* Allocate dma buffers */ | 1205 | /* Allocate dma buffers */ |
1267 | if (qla4xxx_mem_alloc(ha)) { | 1206 | if (qla4xxx_mem_alloc(ha)) { |
@@ -1315,7 +1254,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
1315 | ret = -ENODEV; | 1254 | ret = -ENODEV; |
1316 | goto probe_failed; | 1255 | goto probe_failed; |
1317 | } | 1256 | } |
1318 | INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc, ha); | 1257 | INIT_WORK(&ha->dpc_work, qla4xxx_do_dpc); |
1319 | 1258 | ||
1320 | ret = request_irq(pdev->irq, qla4xxx_intr_handler, | 1259 | ret = request_irq(pdev->irq, qla4xxx_intr_handler, |
1321 | SA_INTERRUPT|SA_SHIRQ, "qla4xxx", ha); | 1260 | SA_INTERRUPT|SA_SHIRQ, "qla4xxx", ha); |
@@ -1468,27 +1407,6 @@ struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t in | |||
1468 | } | 1407 | } |
1469 | 1408 | ||
1470 | /** | 1409 | /** |
1471 | * qla4xxx_soft_reset - performs a SOFT RESET of hba. | ||
1472 | * @ha: Pointer to host adapter structure. | ||
1473 | **/ | ||
1474 | int qla4xxx_soft_reset(struct scsi_qla_host *ha) | ||
1475 | { | ||
1476 | |||
1477 | DEBUG2(printk(KERN_WARNING "scsi%ld: %s: chip reset!\n", ha->host_no, | ||
1478 | __func__)); | ||
1479 | if (test_bit(AF_TOPCAT_CHIP_PRESENT, &ha->flags)) { | ||
1480 | int status = QLA_ERROR; | ||
1481 | |||
1482 | if ((qla4010_soft_reset(ha) == QLA_SUCCESS) && | ||
1483 | (qla4xxx_topcat_reset(ha) == QLA_SUCCESS) && | ||
1484 | (qla4010_soft_reset(ha) == QLA_SUCCESS) ) | ||
1485 | status = QLA_SUCCESS; | ||
1486 | return status; | ||
1487 | } else | ||
1488 | return qla4010_soft_reset(ha); | ||
1489 | } | ||
1490 | |||
1491 | /** | ||
1492 | * qla4xxx_eh_wait_on_command - waits for command to be returned by firmware | 1410 | * qla4xxx_eh_wait_on_command - waits for command to be returned by firmware |
1493 | * @ha: actual ha whose done queue will contain the comd returned by firmware. | 1411 | * @ha: actual ha whose done queue will contain the comd returned by firmware. |
1494 | * @cmd: Scsi Command to wait on. | 1412 | * @cmd: Scsi Command to wait on. |
@@ -1686,6 +1604,12 @@ static struct pci_device_id qla4xxx_pci_tbl[] = { | |||
1686 | .subvendor = PCI_ANY_ID, | 1604 | .subvendor = PCI_ANY_ID, |
1687 | .subdevice = PCI_ANY_ID, | 1605 | .subdevice = PCI_ANY_ID, |
1688 | }, | 1606 | }, |
1607 | { | ||
1608 | .vendor = PCI_VENDOR_ID_QLOGIC, | ||
1609 | .device = PCI_DEVICE_ID_QLOGIC_ISP4032, | ||
1610 | .subvendor = PCI_ANY_ID, | ||
1611 | .subdevice = PCI_ANY_ID, | ||
1612 | }, | ||
1689 | {0, 0}, | 1613 | {0, 0}, |
1690 | }; | 1614 | }; |
1691 | MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl); | 1615 | MODULE_DEVICE_TABLE(pci, qla4xxx_pci_tbl); |
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h index b3fe7e68988e..454e19c8ad68 100644 --- a/drivers/scsi/qla4xxx/ql4_version.h +++ b/drivers/scsi/qla4xxx/ql4_version.h | |||
@@ -5,9 +5,4 @@ | |||
5 | * See LICENSE.qla4xxx for copyright and licensing details. | 5 | * See LICENSE.qla4xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define QLA4XXX_DRIVER_VERSION "5.00.05b9-k" | 8 | #define QLA4XXX_DRIVER_VERSION "5.00.07-k" |
9 | |||
10 | #define QL4_DRIVER_MAJOR_VER 5 | ||
11 | #define QL4_DRIVER_MINOR_VER 0 | ||
12 | #define QL4_DRIVER_PATCH_VER 5 | ||
13 | #define QL4_DRIVER_BETA_VER 9 | ||
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index c59f31533ab4..fafc00deaade 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -156,8 +156,7 @@ static struct scsi_host_cmd_pool scsi_cmd_dma_pool = { | |||
156 | 156 | ||
157 | static DEFINE_MUTEX(host_cmd_pool_mutex); | 157 | static DEFINE_MUTEX(host_cmd_pool_mutex); |
158 | 158 | ||
159 | static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, | 159 | struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, gfp_t gfp_mask) |
160 | gfp_t gfp_mask) | ||
161 | { | 160 | { |
162 | struct scsi_cmnd *cmd; | 161 | struct scsi_cmnd *cmd; |
163 | 162 | ||
@@ -178,6 +177,7 @@ static struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *shost, | |||
178 | 177 | ||
179 | return cmd; | 178 | return cmd; |
180 | } | 179 | } |
180 | EXPORT_SYMBOL_GPL(__scsi_get_command); | ||
181 | 181 | ||
182 | /* | 182 | /* |
183 | * Function: scsi_get_command() | 183 | * Function: scsi_get_command() |
@@ -214,9 +214,29 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask) | |||
214 | put_device(&dev->sdev_gendev); | 214 | put_device(&dev->sdev_gendev); |
215 | 215 | ||
216 | return cmd; | 216 | return cmd; |
217 | } | 217 | } |
218 | EXPORT_SYMBOL(scsi_get_command); | 218 | EXPORT_SYMBOL(scsi_get_command); |
219 | 219 | ||
220 | void __scsi_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd, | ||
221 | struct device *dev) | ||
222 | { | ||
223 | unsigned long flags; | ||
224 | |||
225 | /* changing locks here, don't need to restore the irq state */ | ||
226 | spin_lock_irqsave(&shost->free_list_lock, flags); | ||
227 | if (unlikely(list_empty(&shost->free_list))) { | ||
228 | list_add(&cmd->list, &shost->free_list); | ||
229 | cmd = NULL; | ||
230 | } | ||
231 | spin_unlock_irqrestore(&shost->free_list_lock, flags); | ||
232 | |||
233 | if (likely(cmd != NULL)) | ||
234 | kmem_cache_free(shost->cmd_pool->slab, cmd); | ||
235 | |||
236 | put_device(dev); | ||
237 | } | ||
238 | EXPORT_SYMBOL(__scsi_put_command); | ||
239 | |||
220 | /* | 240 | /* |
221 | * Function: scsi_put_command() | 241 | * Function: scsi_put_command() |
222 | * | 242 | * |
@@ -231,26 +251,15 @@ EXPORT_SYMBOL(scsi_get_command); | |||
231 | void scsi_put_command(struct scsi_cmnd *cmd) | 251 | void scsi_put_command(struct scsi_cmnd *cmd) |
232 | { | 252 | { |
233 | struct scsi_device *sdev = cmd->device; | 253 | struct scsi_device *sdev = cmd->device; |
234 | struct Scsi_Host *shost = sdev->host; | ||
235 | unsigned long flags; | 254 | unsigned long flags; |
236 | 255 | ||
237 | /* serious error if the command hasn't come from a device list */ | 256 | /* serious error if the command hasn't come from a device list */ |
238 | spin_lock_irqsave(&cmd->device->list_lock, flags); | 257 | spin_lock_irqsave(&cmd->device->list_lock, flags); |
239 | BUG_ON(list_empty(&cmd->list)); | 258 | BUG_ON(list_empty(&cmd->list)); |
240 | list_del_init(&cmd->list); | 259 | list_del_init(&cmd->list); |
241 | spin_unlock(&cmd->device->list_lock); | 260 | spin_unlock_irqrestore(&cmd->device->list_lock, flags); |
242 | /* changing locks here, don't need to restore the irq state */ | ||
243 | spin_lock(&shost->free_list_lock); | ||
244 | if (unlikely(list_empty(&shost->free_list))) { | ||
245 | list_add(&cmd->list, &shost->free_list); | ||
246 | cmd = NULL; | ||
247 | } | ||
248 | spin_unlock_irqrestore(&shost->free_list_lock, flags); | ||
249 | |||
250 | if (likely(cmd != NULL)) | ||
251 | kmem_cache_free(shost->cmd_pool->slab, cmd); | ||
252 | 261 | ||
253 | put_device(&sdev->sdev_gendev); | 262 | __scsi_put_command(cmd->device->host, cmd, &sdev->sdev_gendev); |
254 | } | 263 | } |
255 | EXPORT_SYMBOL(scsi_put_command); | 264 | EXPORT_SYMBOL(scsi_put_command); |
256 | 265 | ||
@@ -871,9 +880,9 @@ EXPORT_SYMBOL(scsi_device_get); | |||
871 | */ | 880 | */ |
872 | void scsi_device_put(struct scsi_device *sdev) | 881 | void scsi_device_put(struct scsi_device *sdev) |
873 | { | 882 | { |
883 | #ifdef CONFIG_MODULE_UNLOAD | ||
874 | struct module *module = sdev->host->hostt->module; | 884 | struct module *module = sdev->host->hostt->module; |
875 | 885 | ||
876 | #ifdef CONFIG_MODULE_UNLOAD | ||
877 | /* The module refcount will be zero if scsi_device_get() | 886 | /* The module refcount will be zero if scsi_device_get() |
878 | * was called from a module removal routine */ | 887 | * was called from a module removal routine */ |
879 | if (module && module_refcount(module) != 0) | 888 | if (module && module_refcount(module) != 0) |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index aff1b0cfd4b2..2ecb6ff42444 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -453,9 +453,18 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) | |||
453 | } | 453 | } |
454 | 454 | ||
455 | /** | 455 | /** |
456 | * scsi_send_eh_cmnd - send a cmd to a device as part of error recovery. | 456 | * scsi_send_eh_cmnd - submit a scsi command as part of error recory |
457 | * @scmd: SCSI Cmd to send. | 457 | * @scmd: SCSI command structure to hijack |
458 | * @timeout: Timeout for cmd. | 458 | * @cmnd: CDB to send |
459 | * @cmnd_size: size in bytes of @cmnd | ||
460 | * @timeout: timeout for this request | ||
461 | * @copy_sense: request sense data if set to 1 | ||
462 | * | ||
463 | * This function is used to send a scsi command down to a target device | ||
464 | * as part of the error recovery process. If @copy_sense is 0 the command | ||
465 | * sent must be one that does not transfer any data. If @copy_sense is 1 | ||
466 | * the command must be REQUEST_SENSE and this functions copies out the | ||
467 | * sense buffer it got into @scmd->sense_buffer. | ||
459 | * | 468 | * |
460 | * Return value: | 469 | * Return value: |
461 | * SUCCESS or FAILED or NEEDS_RETRY | 470 | * SUCCESS or FAILED or NEEDS_RETRY |
@@ -469,6 +478,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
469 | DECLARE_COMPLETION_ONSTACK(done); | 478 | DECLARE_COMPLETION_ONSTACK(done); |
470 | unsigned long timeleft; | 479 | unsigned long timeleft; |
471 | unsigned long flags; | 480 | unsigned long flags; |
481 | struct scatterlist sgl; | ||
472 | unsigned char old_cmnd[MAX_COMMAND_SIZE]; | 482 | unsigned char old_cmnd[MAX_COMMAND_SIZE]; |
473 | enum dma_data_direction old_data_direction; | 483 | enum dma_data_direction old_data_direction; |
474 | unsigned short old_use_sg; | 484 | unsigned short old_use_sg; |
@@ -500,19 +510,24 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
500 | if (shost->hostt->unchecked_isa_dma) | 510 | if (shost->hostt->unchecked_isa_dma) |
501 | gfp_mask |= __GFP_DMA; | 511 | gfp_mask |= __GFP_DMA; |
502 | 512 | ||
503 | scmd->sc_data_direction = DMA_FROM_DEVICE; | 513 | sgl.page = alloc_page(gfp_mask); |
504 | scmd->request_bufflen = 252; | 514 | if (!sgl.page) |
505 | scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask); | ||
506 | if (!scmd->request_buffer) | ||
507 | return FAILED; | 515 | return FAILED; |
516 | sgl.offset = 0; | ||
517 | sgl.length = 252; | ||
518 | |||
519 | scmd->sc_data_direction = DMA_FROM_DEVICE; | ||
520 | scmd->request_bufflen = sgl.length; | ||
521 | scmd->request_buffer = &sgl; | ||
522 | scmd->use_sg = 1; | ||
508 | } else { | 523 | } else { |
509 | scmd->request_buffer = NULL; | 524 | scmd->request_buffer = NULL; |
510 | scmd->request_bufflen = 0; | 525 | scmd->request_bufflen = 0; |
511 | scmd->sc_data_direction = DMA_NONE; | 526 | scmd->sc_data_direction = DMA_NONE; |
527 | scmd->use_sg = 0; | ||
512 | } | 528 | } |
513 | 529 | ||
514 | scmd->underflow = 0; | 530 | scmd->underflow = 0; |
515 | scmd->use_sg = 0; | ||
516 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | 531 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); |
517 | 532 | ||
518 | if (sdev->scsi_level <= SCSI_2) | 533 | if (sdev->scsi_level <= SCSI_2) |
@@ -583,7 +598,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
583 | memcpy(scmd->sense_buffer, scmd->request_buffer, | 598 | memcpy(scmd->sense_buffer, scmd->request_buffer, |
584 | sizeof(scmd->sense_buffer)); | 599 | sizeof(scmd->sense_buffer)); |
585 | } | 600 | } |
586 | kfree(scmd->request_buffer); | 601 | __free_page(sgl.page); |
587 | } | 602 | } |
588 | 603 | ||
589 | 604 | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 3ac4890ce086..fb616c69151f 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -704,7 +704,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate, | |||
704 | return NULL; | 704 | return NULL; |
705 | } | 705 | } |
706 | 706 | ||
707 | static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) | 707 | struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) |
708 | { | 708 | { |
709 | struct scsi_host_sg_pool *sgp; | 709 | struct scsi_host_sg_pool *sgp; |
710 | struct scatterlist *sgl; | 710 | struct scatterlist *sgl; |
@@ -745,7 +745,9 @@ static struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_m | |||
745 | return sgl; | 745 | return sgl; |
746 | } | 746 | } |
747 | 747 | ||
748 | static void scsi_free_sgtable(struct scatterlist *sgl, int index) | 748 | EXPORT_SYMBOL(scsi_alloc_sgtable); |
749 | |||
750 | void scsi_free_sgtable(struct scatterlist *sgl, int index) | ||
749 | { | 751 | { |
750 | struct scsi_host_sg_pool *sgp; | 752 | struct scsi_host_sg_pool *sgp; |
751 | 753 | ||
@@ -755,6 +757,8 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index) | |||
755 | mempool_free(sgl, sgp->pool); | 757 | mempool_free(sgl, sgp->pool); |
756 | } | 758 | } |
757 | 759 | ||
760 | EXPORT_SYMBOL(scsi_free_sgtable); | ||
761 | |||
758 | /* | 762 | /* |
759 | * Function: scsi_release_buffers() | 763 | * Function: scsi_release_buffers() |
760 | * | 764 | * |
@@ -996,25 +1000,14 @@ static int scsi_init_io(struct scsi_cmnd *cmd) | |||
996 | int count; | 1000 | int count; |
997 | 1001 | ||
998 | /* | 1002 | /* |
999 | * if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer | 1003 | * We used to not use scatter-gather for single segment request, |
1000 | */ | ||
1001 | if (blk_pc_request(req) && !req->bio) { | ||
1002 | cmd->request_bufflen = req->data_len; | ||
1003 | cmd->request_buffer = req->data; | ||
1004 | req->buffer = req->data; | ||
1005 | cmd->use_sg = 0; | ||
1006 | return 0; | ||
1007 | } | ||
1008 | |||
1009 | /* | ||
1010 | * we used to not use scatter-gather for single segment request, | ||
1011 | * but now we do (it makes highmem I/O easier to support without | 1004 | * but now we do (it makes highmem I/O easier to support without |
1012 | * kmapping pages) | 1005 | * kmapping pages) |
1013 | */ | 1006 | */ |
1014 | cmd->use_sg = req->nr_phys_segments; | 1007 | cmd->use_sg = req->nr_phys_segments; |
1015 | 1008 | ||
1016 | /* | 1009 | /* |
1017 | * if sg table allocation fails, requeue request later. | 1010 | * If sg table allocation fails, requeue request later. |
1018 | */ | 1011 | */ |
1019 | sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC); | 1012 | sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC); |
1020 | if (unlikely(!sgpnt)) { | 1013 | if (unlikely(!sgpnt)) { |
@@ -1022,24 +1015,21 @@ static int scsi_init_io(struct scsi_cmnd *cmd) | |||
1022 | return BLKPREP_DEFER; | 1015 | return BLKPREP_DEFER; |
1023 | } | 1016 | } |
1024 | 1017 | ||
1018 | req->buffer = NULL; | ||
1025 | cmd->request_buffer = (char *) sgpnt; | 1019 | cmd->request_buffer = (char *) sgpnt; |
1026 | cmd->request_bufflen = req->nr_sectors << 9; | ||
1027 | if (blk_pc_request(req)) | 1020 | if (blk_pc_request(req)) |
1028 | cmd->request_bufflen = req->data_len; | 1021 | cmd->request_bufflen = req->data_len; |
1029 | req->buffer = NULL; | 1022 | else |
1023 | cmd->request_bufflen = req->nr_sectors << 9; | ||
1030 | 1024 | ||
1031 | /* | 1025 | /* |
1032 | * Next, walk the list, and fill in the addresses and sizes of | 1026 | * Next, walk the list, and fill in the addresses and sizes of |
1033 | * each segment. | 1027 | * each segment. |
1034 | */ | 1028 | */ |
1035 | count = blk_rq_map_sg(req->q, req, cmd->request_buffer); | 1029 | count = blk_rq_map_sg(req->q, req, cmd->request_buffer); |
1036 | |||
1037 | /* | ||
1038 | * mapped well, send it off | ||
1039 | */ | ||
1040 | if (likely(count <= cmd->use_sg)) { | 1030 | if (likely(count <= cmd->use_sg)) { |
1041 | cmd->use_sg = count; | 1031 | cmd->use_sg = count; |
1042 | return 0; | 1032 | return BLKPREP_OK; |
1043 | } | 1033 | } |
1044 | 1034 | ||
1045 | printk(KERN_ERR "Incorrect number of segments after building list\n"); | 1035 | printk(KERN_ERR "Incorrect number of segments after building list\n"); |
@@ -1069,6 +1059,27 @@ static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk, | |||
1069 | return -EOPNOTSUPP; | 1059 | return -EOPNOTSUPP; |
1070 | } | 1060 | } |
1071 | 1061 | ||
1062 | static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, | ||
1063 | struct request *req) | ||
1064 | { | ||
1065 | struct scsi_cmnd *cmd; | ||
1066 | |||
1067 | if (!req->special) { | ||
1068 | cmd = scsi_get_command(sdev, GFP_ATOMIC); | ||
1069 | if (unlikely(!cmd)) | ||
1070 | return NULL; | ||
1071 | req->special = cmd; | ||
1072 | } else { | ||
1073 | cmd = req->special; | ||
1074 | } | ||
1075 | |||
1076 | /* pull a tag out of the request if we have one */ | ||
1077 | cmd->tag = req->tag; | ||
1078 | cmd->request = req; | ||
1079 | |||
1080 | return cmd; | ||
1081 | } | ||
1082 | |||
1072 | static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | 1083 | static void scsi_blk_pc_done(struct scsi_cmnd *cmd) |
1073 | { | 1084 | { |
1074 | BUG_ON(!blk_pc_request(cmd->request)); | 1085 | BUG_ON(!blk_pc_request(cmd->request)); |
@@ -1081,9 +1092,37 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | |||
1081 | scsi_io_completion(cmd, cmd->request_bufflen); | 1092 | scsi_io_completion(cmd, cmd->request_bufflen); |
1082 | } | 1093 | } |
1083 | 1094 | ||
1084 | static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | 1095 | static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) |
1085 | { | 1096 | { |
1086 | struct request *req = cmd->request; | 1097 | struct scsi_cmnd *cmd; |
1098 | |||
1099 | cmd = scsi_get_cmd_from_req(sdev, req); | ||
1100 | if (unlikely(!cmd)) | ||
1101 | return BLKPREP_DEFER; | ||
1102 | |||
1103 | /* | ||
1104 | * BLOCK_PC requests may transfer data, in which case they must | ||
1105 | * a bio attached to them. Or they might contain a SCSI command | ||
1106 | * that does not transfer data, in which case they may optionally | ||
1107 | * submit a request without an attached bio. | ||
1108 | */ | ||
1109 | if (req->bio) { | ||
1110 | int ret; | ||
1111 | |||
1112 | BUG_ON(!req->nr_phys_segments); | ||
1113 | |||
1114 | ret = scsi_init_io(cmd); | ||
1115 | if (unlikely(ret)) | ||
1116 | return ret; | ||
1117 | } else { | ||
1118 | BUG_ON(req->data_len); | ||
1119 | BUG_ON(req->data); | ||
1120 | |||
1121 | cmd->request_bufflen = 0; | ||
1122 | cmd->request_buffer = NULL; | ||
1123 | cmd->use_sg = 0; | ||
1124 | req->buffer = NULL; | ||
1125 | } | ||
1087 | 1126 | ||
1088 | BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); | 1127 | BUILD_BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); |
1089 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); | 1128 | memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); |
@@ -1099,154 +1138,138 @@ static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) | |||
1099 | cmd->allowed = req->retries; | 1138 | cmd->allowed = req->retries; |
1100 | cmd->timeout_per_command = req->timeout; | 1139 | cmd->timeout_per_command = req->timeout; |
1101 | cmd->done = scsi_blk_pc_done; | 1140 | cmd->done = scsi_blk_pc_done; |
1141 | return BLKPREP_OK; | ||
1102 | } | 1142 | } |
1103 | 1143 | ||
1104 | static int scsi_prep_fn(struct request_queue *q, struct request *req) | 1144 | /* |
1145 | * Setup a REQ_TYPE_FS command. These are simple read/write request | ||
1146 | * from filesystems that still need to be translated to SCSI CDBs from | ||
1147 | * the ULD. | ||
1148 | */ | ||
1149 | static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) | ||
1105 | { | 1150 | { |
1106 | struct scsi_device *sdev = q->queuedata; | ||
1107 | struct scsi_cmnd *cmd; | 1151 | struct scsi_cmnd *cmd; |
1108 | int specials_only = 0; | 1152 | struct scsi_driver *drv; |
1153 | int ret; | ||
1109 | 1154 | ||
1110 | /* | 1155 | /* |
1111 | * Just check to see if the device is online. If it isn't, we | 1156 | * Filesystem requests must transfer data. |
1112 | * refuse to process any commands. The device must be brought | ||
1113 | * online before trying any recovery commands | ||
1114 | */ | 1157 | */ |
1115 | if (unlikely(!scsi_device_online(sdev))) { | 1158 | BUG_ON(!req->nr_phys_segments); |
1116 | sdev_printk(KERN_ERR, sdev, | 1159 | |
1117 | "rejecting I/O to offline device\n"); | 1160 | cmd = scsi_get_cmd_from_req(sdev, req); |
1118 | goto kill; | 1161 | if (unlikely(!cmd)) |
1119 | } | 1162 | return BLKPREP_DEFER; |
1120 | if (unlikely(sdev->sdev_state != SDEV_RUNNING)) { | 1163 | |
1121 | /* OK, we're not in a running state don't prep | 1164 | ret = scsi_init_io(cmd); |
1122 | * user commands */ | 1165 | if (unlikely(ret)) |
1123 | if (sdev->sdev_state == SDEV_DEL) { | 1166 | return ret; |
1124 | /* Device is fully deleted, no commands | 1167 | |
1125 | * at all allowed down */ | 1168 | /* |
1126 | sdev_printk(KERN_ERR, sdev, | 1169 | * Initialize the actual SCSI command for this request. |
1127 | "rejecting I/O to dead device\n"); | 1170 | */ |
1128 | goto kill; | 1171 | drv = *(struct scsi_driver **)req->rq_disk->private_data; |
1129 | } | 1172 | if (unlikely(!drv->init_command(cmd))) { |
1130 | /* OK, we only allow special commands (i.e. not | 1173 | scsi_release_buffers(cmd); |
1131 | * user initiated ones */ | 1174 | scsi_put_command(cmd); |
1132 | specials_only = sdev->sdev_state; | 1175 | return BLKPREP_KILL; |
1133 | } | 1176 | } |
1134 | 1177 | ||
1178 | return BLKPREP_OK; | ||
1179 | } | ||
1180 | |||
1181 | static int scsi_prep_fn(struct request_queue *q, struct request *req) | ||
1182 | { | ||
1183 | struct scsi_device *sdev = q->queuedata; | ||
1184 | int ret = BLKPREP_OK; | ||
1185 | |||
1135 | /* | 1186 | /* |
1136 | * Find the actual device driver associated with this command. | 1187 | * If the device is not in running state we will reject some |
1137 | * The SPECIAL requests are things like character device or | 1188 | * or all commands. |
1138 | * ioctls, which did not originate from ll_rw_blk. Note that | ||
1139 | * the special field is also used to indicate the cmd for | ||
1140 | * the remainder of a partially fulfilled request that can | ||
1141 | * come up when there is a medium error. We have to treat | ||
1142 | * these two cases differently. We differentiate by looking | ||
1143 | * at request->cmd, as this tells us the real story. | ||
1144 | */ | 1189 | */ |
1145 | if (blk_special_request(req) && req->special) | 1190 | if (unlikely(sdev->sdev_state != SDEV_RUNNING)) { |
1146 | cmd = req->special; | 1191 | switch (sdev->sdev_state) { |
1147 | else if (blk_pc_request(req) || blk_fs_request(req)) { | 1192 | case SDEV_OFFLINE: |
1148 | if (unlikely(specials_only) && !(req->cmd_flags & REQ_PREEMPT)){ | 1193 | /* |
1149 | if (specials_only == SDEV_QUIESCE || | 1194 | * If the device is offline we refuse to process any |
1150 | specials_only == SDEV_BLOCK) | 1195 | * commands. The device must be brought online |
1151 | goto defer; | 1196 | * before trying any recovery commands. |
1152 | 1197 | */ | |
1153 | sdev_printk(KERN_ERR, sdev, | 1198 | sdev_printk(KERN_ERR, sdev, |
1154 | "rejecting I/O to device being removed\n"); | 1199 | "rejecting I/O to offline device\n"); |
1155 | goto kill; | 1200 | ret = BLKPREP_KILL; |
1201 | break; | ||
1202 | case SDEV_DEL: | ||
1203 | /* | ||
1204 | * If the device is fully deleted, we refuse to | ||
1205 | * process any commands as well. | ||
1206 | */ | ||
1207 | sdev_printk(KERN_ERR, sdev, | ||
1208 | "rejecting I/O to dead device\n"); | ||
1209 | ret = BLKPREP_KILL; | ||
1210 | break; | ||
1211 | case SDEV_QUIESCE: | ||
1212 | case SDEV_BLOCK: | ||
1213 | /* | ||
1214 | * If the devices is blocked we defer normal commands. | ||
1215 | */ | ||
1216 | if (!(req->cmd_flags & REQ_PREEMPT)) | ||
1217 | ret = BLKPREP_DEFER; | ||
1218 | break; | ||
1219 | default: | ||
1220 | /* | ||
1221 | * For any other not fully online state we only allow | ||
1222 | * special commands. In particular any user initiated | ||
1223 | * command is not allowed. | ||
1224 | */ | ||
1225 | if (!(req->cmd_flags & REQ_PREEMPT)) | ||
1226 | ret = BLKPREP_KILL; | ||
1227 | break; | ||
1156 | } | 1228 | } |
1157 | 1229 | ||
1158 | /* | 1230 | if (ret != BLKPREP_OK) |
1159 | * Now try and find a command block that we can use. | 1231 | goto out; |
1160 | */ | ||
1161 | if (!req->special) { | ||
1162 | cmd = scsi_get_command(sdev, GFP_ATOMIC); | ||
1163 | if (unlikely(!cmd)) | ||
1164 | goto defer; | ||
1165 | } else | ||
1166 | cmd = req->special; | ||
1167 | |||
1168 | /* pull a tag out of the request if we have one */ | ||
1169 | cmd->tag = req->tag; | ||
1170 | } else { | ||
1171 | blk_dump_rq_flags(req, "SCSI bad req"); | ||
1172 | goto kill; | ||
1173 | } | 1232 | } |
1174 | |||
1175 | /* note the overloading of req->special. When the tag | ||
1176 | * is active it always means cmd. If the tag goes | ||
1177 | * back for re-queueing, it may be reset */ | ||
1178 | req->special = cmd; | ||
1179 | cmd->request = req; | ||
1180 | |||
1181 | /* | ||
1182 | * FIXME: drop the lock here because the functions below | ||
1183 | * expect to be called without the queue lock held. Also, | ||
1184 | * previously, we dequeued the request before dropping the | ||
1185 | * lock. We hope REQ_STARTED prevents anything untoward from | ||
1186 | * happening now. | ||
1187 | */ | ||
1188 | if (blk_fs_request(req) || blk_pc_request(req)) { | ||
1189 | int ret; | ||
1190 | 1233 | ||
1234 | switch (req->cmd_type) { | ||
1235 | case REQ_TYPE_BLOCK_PC: | ||
1236 | ret = scsi_setup_blk_pc_cmnd(sdev, req); | ||
1237 | break; | ||
1238 | case REQ_TYPE_FS: | ||
1239 | ret = scsi_setup_fs_cmnd(sdev, req); | ||
1240 | break; | ||
1241 | default: | ||
1191 | /* | 1242 | /* |
1192 | * This will do a couple of things: | 1243 | * All other command types are not supported. |
1193 | * 1) Fill in the actual SCSI command. | ||
1194 | * 2) Fill in any other upper-level specific fields | ||
1195 | * (timeout). | ||
1196 | * | 1244 | * |
1197 | * If this returns 0, it means that the request failed | 1245 | * Note that these days the SCSI subsystem does not use |
1198 | * (reading past end of disk, reading offline device, | 1246 | * REQ_TYPE_SPECIAL requests anymore. These are only used |
1199 | * etc). This won't actually talk to the device, but | 1247 | * (directly or via blk_insert_request) by non-SCSI drivers. |
1200 | * some kinds of consistency checking may cause the | ||
1201 | * request to be rejected immediately. | ||
1202 | */ | 1248 | */ |
1249 | blk_dump_rq_flags(req, "SCSI bad req"); | ||
1250 | ret = BLKPREP_KILL; | ||
1251 | break; | ||
1252 | } | ||
1203 | 1253 | ||
1204 | /* | 1254 | out: |
1205 | * This sets up the scatter-gather table (allocating if | 1255 | switch (ret) { |
1206 | * required). | 1256 | case BLKPREP_KILL: |
1207 | */ | 1257 | req->errors = DID_NO_CONNECT << 16; |
1208 | ret = scsi_init_io(cmd); | 1258 | break; |
1209 | switch(ret) { | 1259 | case BLKPREP_DEFER: |
1210 | /* For BLKPREP_KILL/DEFER the cmd was released */ | ||
1211 | case BLKPREP_KILL: | ||
1212 | goto kill; | ||
1213 | case BLKPREP_DEFER: | ||
1214 | goto defer; | ||
1215 | } | ||
1216 | |||
1217 | /* | 1260 | /* |
1218 | * Initialize the actual SCSI command for this request. | 1261 | * If we defer, the elv_next_request() returns NULL, but the |
1262 | * queue must be restarted, so we plug here if no returning | ||
1263 | * command will automatically do that. | ||
1219 | */ | 1264 | */ |
1220 | if (blk_pc_request(req)) { | 1265 | if (sdev->device_busy == 0) |
1221 | scsi_setup_blk_pc_cmnd(cmd); | 1266 | blk_plug_device(q); |
1222 | } else if (req->rq_disk) { | 1267 | break; |
1223 | struct scsi_driver *drv; | 1268 | default: |
1224 | 1269 | req->cmd_flags |= REQ_DONTPREP; | |
1225 | drv = *(struct scsi_driver **)req->rq_disk->private_data; | ||
1226 | if (unlikely(!drv->init_command(cmd))) { | ||
1227 | scsi_release_buffers(cmd); | ||
1228 | scsi_put_command(cmd); | ||
1229 | goto kill; | ||
1230 | } | ||
1231 | } | ||
1232 | } | 1270 | } |
1233 | 1271 | ||
1234 | /* | 1272 | return ret; |
1235 | * The request is now prepped, no need to come back here | ||
1236 | */ | ||
1237 | req->cmd_flags |= REQ_DONTPREP; | ||
1238 | return BLKPREP_OK; | ||
1239 | |||
1240 | defer: | ||
1241 | /* If we defer, the elv_next_request() returns NULL, but the | ||
1242 | * queue must be restarted, so we plug here if no returning | ||
1243 | * command will automatically do that. */ | ||
1244 | if (sdev->device_busy == 0) | ||
1245 | blk_plug_device(q); | ||
1246 | return BLKPREP_DEFER; | ||
1247 | kill: | ||
1248 | req->errors = DID_NO_CONNECT << 16; | ||
1249 | return BLKPREP_KILL; | ||
1250 | } | 1273 | } |
1251 | 1274 | ||
1252 | /* | 1275 | /* |
@@ -1548,29 +1571,40 @@ u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost) | |||
1548 | } | 1571 | } |
1549 | EXPORT_SYMBOL(scsi_calculate_bounce_limit); | 1572 | EXPORT_SYMBOL(scsi_calculate_bounce_limit); |
1550 | 1573 | ||
1551 | struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) | 1574 | struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, |
1575 | request_fn_proc *request_fn) | ||
1552 | { | 1576 | { |
1553 | struct Scsi_Host *shost = sdev->host; | ||
1554 | struct request_queue *q; | 1577 | struct request_queue *q; |
1555 | 1578 | ||
1556 | q = blk_init_queue(scsi_request_fn, NULL); | 1579 | q = blk_init_queue(request_fn, NULL); |
1557 | if (!q) | 1580 | if (!q) |
1558 | return NULL; | 1581 | return NULL; |
1559 | 1582 | ||
1560 | blk_queue_prep_rq(q, scsi_prep_fn); | ||
1561 | |||
1562 | blk_queue_max_hw_segments(q, shost->sg_tablesize); | 1583 | blk_queue_max_hw_segments(q, shost->sg_tablesize); |
1563 | blk_queue_max_phys_segments(q, SCSI_MAX_PHYS_SEGMENTS); | 1584 | blk_queue_max_phys_segments(q, SCSI_MAX_PHYS_SEGMENTS); |
1564 | blk_queue_max_sectors(q, shost->max_sectors); | 1585 | blk_queue_max_sectors(q, shost->max_sectors); |
1565 | blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); | 1586 | blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); |
1566 | blk_queue_segment_boundary(q, shost->dma_boundary); | 1587 | blk_queue_segment_boundary(q, shost->dma_boundary); |
1567 | blk_queue_issue_flush_fn(q, scsi_issue_flush_fn); | ||
1568 | blk_queue_softirq_done(q, scsi_softirq_done); | ||
1569 | 1588 | ||
1570 | if (!shost->use_clustering) | 1589 | if (!shost->use_clustering) |
1571 | clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); | 1590 | clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); |
1572 | return q; | 1591 | return q; |
1573 | } | 1592 | } |
1593 | EXPORT_SYMBOL(__scsi_alloc_queue); | ||
1594 | |||
1595 | struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) | ||
1596 | { | ||
1597 | struct request_queue *q; | ||
1598 | |||
1599 | q = __scsi_alloc_queue(sdev->host, scsi_request_fn); | ||
1600 | if (!q) | ||
1601 | return NULL; | ||
1602 | |||
1603 | blk_queue_prep_rq(q, scsi_prep_fn); | ||
1604 | blk_queue_issue_flush_fn(q, scsi_issue_flush_fn); | ||
1605 | blk_queue_softirq_done(q, scsi_softirq_done); | ||
1606 | return q; | ||
1607 | } | ||
1574 | 1608 | ||
1575 | void scsi_free_queue(struct request_queue *q) | 1609 | void scsi_free_queue(struct request_queue *q) |
1576 | { | 1610 | { |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index 5d023d44e5e7..f458c2f686d2 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -39,6 +39,9 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) | |||
39 | { }; | 39 | { }; |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | /* scsi_scan.c */ | ||
43 | int scsi_complete_async_scans(void); | ||
44 | |||
42 | /* scsi_devinfo.c */ | 45 | /* scsi_devinfo.c */ |
43 | extern int scsi_get_device_flags(struct scsi_device *sdev, | 46 | extern int scsi_get_device_flags(struct scsi_device *sdev, |
44 | const unsigned char *vendor, | 47 | const unsigned char *vendor, |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 94a274645f6f..14e635aa44ce 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -29,7 +29,9 @@ | |||
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/blkdev.h> | 31 | #include <linux/blkdev.h> |
32 | #include <asm/semaphore.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/kthread.h> | ||
34 | #include <linux/spinlock.h> | ||
33 | 35 | ||
34 | #include <scsi/scsi.h> | 36 | #include <scsi/scsi.h> |
35 | #include <scsi/scsi_cmnd.h> | 37 | #include <scsi/scsi_cmnd.h> |
@@ -87,6 +89,17 @@ module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR); | |||
87 | MODULE_PARM_DESC(max_luns, | 89 | MODULE_PARM_DESC(max_luns, |
88 | "last scsi LUN (should be between 1 and 2^32-1)"); | 90 | "last scsi LUN (should be between 1 and 2^32-1)"); |
89 | 91 | ||
92 | #ifdef CONFIG_SCSI_SCAN_ASYNC | ||
93 | #define SCSI_SCAN_TYPE_DEFAULT "async" | ||
94 | #else | ||
95 | #define SCSI_SCAN_TYPE_DEFAULT "sync" | ||
96 | #endif | ||
97 | |||
98 | static char scsi_scan_type[6] = SCSI_SCAN_TYPE_DEFAULT; | ||
99 | |||
100 | module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO); | ||
101 | MODULE_PARM_DESC(scan, "sync, async or none"); | ||
102 | |||
90 | /* | 103 | /* |
91 | * max_scsi_report_luns: the maximum number of LUNS that will be | 104 | * max_scsi_report_luns: the maximum number of LUNS that will be |
92 | * returned from the REPORT LUNS command. 8 times this value must | 105 | * returned from the REPORT LUNS command. 8 times this value must |
@@ -108,6 +121,68 @@ MODULE_PARM_DESC(inq_timeout, | |||
108 | "Timeout (in seconds) waiting for devices to answer INQUIRY." | 121 | "Timeout (in seconds) waiting for devices to answer INQUIRY." |
109 | " Default is 5. Some non-compliant devices need more."); | 122 | " Default is 5. Some non-compliant devices need more."); |
110 | 123 | ||
124 | static DEFINE_SPINLOCK(async_scan_lock); | ||
125 | static LIST_HEAD(scanning_hosts); | ||
126 | |||
127 | struct async_scan_data { | ||
128 | struct list_head list; | ||
129 | struct Scsi_Host *shost; | ||
130 | struct completion prev_finished; | ||
131 | }; | ||
132 | |||
133 | /** | ||
134 | * scsi_complete_async_scans - Wait for asynchronous scans to complete | ||
135 | * | ||
136 | * Asynchronous scans add themselves to the scanning_hosts list. Once | ||
137 | * that list is empty, we know that the scans are complete. Rather than | ||
138 | * waking up periodically to check the state of the list, we pretend to be | ||
139 | * a scanning task by adding ourselves at the end of the list and going to | ||
140 | * sleep. When the task before us wakes us up, we take ourselves off the | ||
141 | * list and return. | ||
142 | */ | ||
143 | int scsi_complete_async_scans(void) | ||
144 | { | ||
145 | struct async_scan_data *data; | ||
146 | |||
147 | do { | ||
148 | if (list_empty(&scanning_hosts)) | ||
149 | return 0; | ||
150 | /* If we can't get memory immediately, that's OK. Just | ||
151 | * sleep a little. Even if we never get memory, the async | ||
152 | * scans will finish eventually. | ||
153 | */ | ||
154 | data = kmalloc(sizeof(*data), GFP_KERNEL); | ||
155 | if (!data) | ||
156 | msleep(1); | ||
157 | } while (!data); | ||
158 | |||
159 | data->shost = NULL; | ||
160 | init_completion(&data->prev_finished); | ||
161 | |||
162 | spin_lock(&async_scan_lock); | ||
163 | /* Check that there's still somebody else on the list */ | ||
164 | if (list_empty(&scanning_hosts)) | ||
165 | goto done; | ||
166 | list_add_tail(&data->list, &scanning_hosts); | ||
167 | spin_unlock(&async_scan_lock); | ||
168 | |||
169 | printk(KERN_INFO "scsi: waiting for bus probes to complete ...\n"); | ||
170 | wait_for_completion(&data->prev_finished); | ||
171 | |||
172 | spin_lock(&async_scan_lock); | ||
173 | list_del(&data->list); | ||
174 | done: | ||
175 | spin_unlock(&async_scan_lock); | ||
176 | |||
177 | kfree(data); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | #ifdef MODULE | ||
182 | /* Only exported for the benefit of scsi_wait_scan */ | ||
183 | EXPORT_SYMBOL_GPL(scsi_complete_async_scans); | ||
184 | #endif | ||
185 | |||
111 | /** | 186 | /** |
112 | * scsi_unlock_floptical - unlock device via a special MODE SENSE command | 187 | * scsi_unlock_floptical - unlock device via a special MODE SENSE command |
113 | * @sdev: scsi device to send command to | 188 | * @sdev: scsi device to send command to |
@@ -362,9 +437,10 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, | |||
362 | goto retry; | 437 | goto retry; |
363 | } | 438 | } |
364 | 439 | ||
365 | static void scsi_target_reap_usercontext(void *data) | 440 | static void scsi_target_reap_usercontext(struct work_struct *work) |
366 | { | 441 | { |
367 | struct scsi_target *starget = data; | 442 | struct scsi_target *starget = |
443 | container_of(work, struct scsi_target, ew.work); | ||
368 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 444 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
369 | unsigned long flags; | 445 | unsigned long flags; |
370 | 446 | ||
@@ -400,7 +476,7 @@ void scsi_target_reap(struct scsi_target *starget) | |||
400 | starget->state = STARGET_DEL; | 476 | starget->state = STARGET_DEL; |
401 | spin_unlock_irqrestore(shost->host_lock, flags); | 477 | spin_unlock_irqrestore(shost->host_lock, flags); |
402 | execute_in_process_context(scsi_target_reap_usercontext, | 478 | execute_in_process_context(scsi_target_reap_usercontext, |
403 | starget, &starget->ew); | 479 | &starget->ew); |
404 | return; | 480 | return; |
405 | 481 | ||
406 | } | 482 | } |
@@ -619,7 +695,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
619 | * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized | 695 | * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized |
620 | **/ | 696 | **/ |
621 | static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | 697 | static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, |
622 | int *bflags) | 698 | int *bflags, int async) |
623 | { | 699 | { |
624 | /* | 700 | /* |
625 | * XXX do not save the inquiry, since it can change underneath us, | 701 | * XXX do not save the inquiry, since it can change underneath us, |
@@ -805,7 +881,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
805 | * register it and tell the rest of the kernel | 881 | * register it and tell the rest of the kernel |
806 | * about it. | 882 | * about it. |
807 | */ | 883 | */ |
808 | if (scsi_sysfs_add_sdev(sdev) != 0) | 884 | if (!async && scsi_sysfs_add_sdev(sdev) != 0) |
809 | return SCSI_SCAN_NO_RESPONSE; | 885 | return SCSI_SCAN_NO_RESPONSE; |
810 | 886 | ||
811 | return SCSI_SCAN_LUN_PRESENT; | 887 | return SCSI_SCAN_LUN_PRESENT; |
@@ -974,7 +1050,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, | |||
974 | goto out_free_result; | 1050 | goto out_free_result; |
975 | } | 1051 | } |
976 | 1052 | ||
977 | res = scsi_add_lun(sdev, result, &bflags); | 1053 | res = scsi_add_lun(sdev, result, &bflags, shost->async_scan); |
978 | if (res == SCSI_SCAN_LUN_PRESENT) { | 1054 | if (res == SCSI_SCAN_LUN_PRESENT) { |
979 | if (bflags & BLIST_KEY) { | 1055 | if (bflags & BLIST_KEY) { |
980 | sdev->lockable = 0; | 1056 | sdev->lockable = 0; |
@@ -1474,6 +1550,12 @@ void scsi_scan_target(struct device *parent, unsigned int channel, | |||
1474 | { | 1550 | { |
1475 | struct Scsi_Host *shost = dev_to_shost(parent); | 1551 | struct Scsi_Host *shost = dev_to_shost(parent); |
1476 | 1552 | ||
1553 | if (strncmp(scsi_scan_type, "none", 4) == 0) | ||
1554 | return; | ||
1555 | |||
1556 | if (!shost->async_scan) | ||
1557 | scsi_complete_async_scans(); | ||
1558 | |||
1477 | mutex_lock(&shost->scan_mutex); | 1559 | mutex_lock(&shost->scan_mutex); |
1478 | if (scsi_host_scan_allowed(shost)) | 1560 | if (scsi_host_scan_allowed(shost)) |
1479 | __scsi_scan_target(parent, channel, id, lun, rescan); | 1561 | __scsi_scan_target(parent, channel, id, lun, rescan); |
@@ -1519,6 +1601,9 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, | |||
1519 | "%s: <%u:%u:%u>\n", | 1601 | "%s: <%u:%u:%u>\n", |
1520 | __FUNCTION__, channel, id, lun)); | 1602 | __FUNCTION__, channel, id, lun)); |
1521 | 1603 | ||
1604 | if (!shost->async_scan) | ||
1605 | scsi_complete_async_scans(); | ||
1606 | |||
1522 | if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || | 1607 | if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || |
1523 | ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || | 1608 | ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || |
1524 | ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) | 1609 | ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) |
@@ -1539,14 +1624,143 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, | |||
1539 | return 0; | 1624 | return 0; |
1540 | } | 1625 | } |
1541 | 1626 | ||
1627 | static void scsi_sysfs_add_devices(struct Scsi_Host *shost) | ||
1628 | { | ||
1629 | struct scsi_device *sdev; | ||
1630 | shost_for_each_device(sdev, shost) { | ||
1631 | if (scsi_sysfs_add_sdev(sdev) != 0) | ||
1632 | scsi_destroy_sdev(sdev); | ||
1633 | } | ||
1634 | } | ||
1635 | |||
1636 | /** | ||
1637 | * scsi_prep_async_scan - prepare for an async scan | ||
1638 | * @shost: the host which will be scanned | ||
1639 | * Returns: a cookie to be passed to scsi_finish_async_scan() | ||
1640 | * | ||
1641 | * Tells the midlayer this host is going to do an asynchronous scan. | ||
1642 | * It reserves the host's position in the scanning list and ensures | ||
1643 | * that other asynchronous scans started after this one won't affect the | ||
1644 | * ordering of the discovered devices. | ||
1645 | */ | ||
1646 | static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) | ||
1647 | { | ||
1648 | struct async_scan_data *data; | ||
1649 | |||
1650 | if (strncmp(scsi_scan_type, "sync", 4) == 0) | ||
1651 | return NULL; | ||
1652 | |||
1653 | if (shost->async_scan) { | ||
1654 | printk("%s called twice for host %d", __FUNCTION__, | ||
1655 | shost->host_no); | ||
1656 | dump_stack(); | ||
1657 | return NULL; | ||
1658 | } | ||
1659 | |||
1660 | data = kmalloc(sizeof(*data), GFP_KERNEL); | ||
1661 | if (!data) | ||
1662 | goto err; | ||
1663 | data->shost = scsi_host_get(shost); | ||
1664 | if (!data->shost) | ||
1665 | goto err; | ||
1666 | init_completion(&data->prev_finished); | ||
1667 | |||
1668 | spin_lock(&async_scan_lock); | ||
1669 | shost->async_scan = 1; | ||
1670 | if (list_empty(&scanning_hosts)) | ||
1671 | complete(&data->prev_finished); | ||
1672 | list_add_tail(&data->list, &scanning_hosts); | ||
1673 | spin_unlock(&async_scan_lock); | ||
1674 | |||
1675 | return data; | ||
1676 | |||
1677 | err: | ||
1678 | kfree(data); | ||
1679 | return NULL; | ||
1680 | } | ||
1681 | |||
1682 | /** | ||
1683 | * scsi_finish_async_scan - asynchronous scan has finished | ||
1684 | * @data: cookie returned from earlier call to scsi_prep_async_scan() | ||
1685 | * | ||
1686 | * All the devices currently attached to this host have been found. | ||
1687 | * This function announces all the devices it has found to the rest | ||
1688 | * of the system. | ||
1689 | */ | ||
1690 | static void scsi_finish_async_scan(struct async_scan_data *data) | ||
1691 | { | ||
1692 | struct Scsi_Host *shost; | ||
1693 | |||
1694 | if (!data) | ||
1695 | return; | ||
1696 | |||
1697 | shost = data->shost; | ||
1698 | if (!shost->async_scan) { | ||
1699 | printk("%s called twice for host %d", __FUNCTION__, | ||
1700 | shost->host_no); | ||
1701 | dump_stack(); | ||
1702 | return; | ||
1703 | } | ||
1704 | |||
1705 | wait_for_completion(&data->prev_finished); | ||
1706 | |||
1707 | scsi_sysfs_add_devices(shost); | ||
1708 | |||
1709 | spin_lock(&async_scan_lock); | ||
1710 | shost->async_scan = 0; | ||
1711 | list_del(&data->list); | ||
1712 | if (!list_empty(&scanning_hosts)) { | ||
1713 | struct async_scan_data *next = list_entry(scanning_hosts.next, | ||
1714 | struct async_scan_data, list); | ||
1715 | complete(&next->prev_finished); | ||
1716 | } | ||
1717 | spin_unlock(&async_scan_lock); | ||
1718 | |||
1719 | scsi_host_put(shost); | ||
1720 | kfree(data); | ||
1721 | } | ||
1722 | |||
1723 | static void do_scsi_scan_host(struct Scsi_Host *shost) | ||
1724 | { | ||
1725 | if (shost->hostt->scan_finished) { | ||
1726 | unsigned long start = jiffies; | ||
1727 | if (shost->hostt->scan_start) | ||
1728 | shost->hostt->scan_start(shost); | ||
1729 | |||
1730 | while (!shost->hostt->scan_finished(shost, jiffies - start)) | ||
1731 | msleep(10); | ||
1732 | } else { | ||
1733 | scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD, | ||
1734 | SCAN_WILD_CARD, 0); | ||
1735 | } | ||
1736 | } | ||
1737 | |||
1738 | static int do_scan_async(void *_data) | ||
1739 | { | ||
1740 | struct async_scan_data *data = _data; | ||
1741 | do_scsi_scan_host(data->shost); | ||
1742 | scsi_finish_async_scan(data); | ||
1743 | return 0; | ||
1744 | } | ||
1745 | |||
1542 | /** | 1746 | /** |
1543 | * scsi_scan_host - scan the given adapter | 1747 | * scsi_scan_host - scan the given adapter |
1544 | * @shost: adapter to scan | 1748 | * @shost: adapter to scan |
1545 | **/ | 1749 | **/ |
1546 | void scsi_scan_host(struct Scsi_Host *shost) | 1750 | void scsi_scan_host(struct Scsi_Host *shost) |
1547 | { | 1751 | { |
1548 | scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD, | 1752 | struct async_scan_data *data; |
1549 | SCAN_WILD_CARD, 0); | 1753 | |
1754 | if (strncmp(scsi_scan_type, "none", 4) == 0) | ||
1755 | return; | ||
1756 | |||
1757 | data = scsi_prep_async_scan(shost); | ||
1758 | if (!data) { | ||
1759 | do_scsi_scan_host(shost); | ||
1760 | return; | ||
1761 | } | ||
1762 | |||
1763 | kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no); | ||
1550 | } | 1764 | } |
1551 | EXPORT_SYMBOL(scsi_scan_host); | 1765 | EXPORT_SYMBOL(scsi_scan_host); |
1552 | 1766 | ||
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index e1a91665d1c2..259c90cfa367 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -218,16 +218,16 @@ static void scsi_device_cls_release(struct class_device *class_dev) | |||
218 | put_device(&sdev->sdev_gendev); | 218 | put_device(&sdev->sdev_gendev); |
219 | } | 219 | } |
220 | 220 | ||
221 | static void scsi_device_dev_release_usercontext(void *data) | 221 | static void scsi_device_dev_release_usercontext(struct work_struct *work) |
222 | { | 222 | { |
223 | struct device *dev = data; | ||
224 | struct scsi_device *sdev; | 223 | struct scsi_device *sdev; |
225 | struct device *parent; | 224 | struct device *parent; |
226 | struct scsi_target *starget; | 225 | struct scsi_target *starget; |
227 | unsigned long flags; | 226 | unsigned long flags; |
228 | 227 | ||
229 | parent = dev->parent; | 228 | sdev = container_of(work, struct scsi_device, ew.work); |
230 | sdev = to_scsi_device(dev); | 229 | |
230 | parent = sdev->sdev_gendev.parent; | ||
231 | starget = to_scsi_target(parent); | 231 | starget = to_scsi_target(parent); |
232 | 232 | ||
233 | spin_lock_irqsave(sdev->host->host_lock, flags); | 233 | spin_lock_irqsave(sdev->host->host_lock, flags); |
@@ -258,7 +258,7 @@ static void scsi_device_dev_release_usercontext(void *data) | |||
258 | static void scsi_device_dev_release(struct device *dev) | 258 | static void scsi_device_dev_release(struct device *dev) |
259 | { | 259 | { |
260 | struct scsi_device *sdp = to_scsi_device(dev); | 260 | struct scsi_device *sdp = to_scsi_device(dev); |
261 | execute_in_process_context(scsi_device_dev_release_usercontext, dev, | 261 | execute_in_process_context(scsi_device_dev_release_usercontext, |
262 | &sdp->ew); | 262 | &sdp->ew); |
263 | } | 263 | } |
264 | 264 | ||
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c new file mode 100644 index 000000000000..37bbfbdb870f --- /dev/null +++ b/drivers/scsi/scsi_tgt_if.c | |||
@@ -0,0 +1,352 @@ | |||
1 | /* | ||
2 | * SCSI target kernel/user interface functions | ||
3 | * | ||
4 | * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org> | ||
5 | * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation; either version 2 of the | ||
10 | * License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * 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., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | */ | ||
22 | #include <linux/miscdevice.h> | ||
23 | #include <linux/file.h> | ||
24 | #include <net/tcp.h> | ||
25 | #include <scsi/scsi.h> | ||
26 | #include <scsi/scsi_cmnd.h> | ||
27 | #include <scsi/scsi_device.h> | ||
28 | #include <scsi/scsi_host.h> | ||
29 | #include <scsi/scsi_tgt.h> | ||
30 | #include <scsi/scsi_tgt_if.h> | ||
31 | |||
32 | #include <asm/cacheflush.h> | ||
33 | |||
34 | #include "scsi_tgt_priv.h" | ||
35 | |||
36 | struct tgt_ring { | ||
37 | u32 tr_idx; | ||
38 | unsigned long tr_pages[TGT_RING_PAGES]; | ||
39 | spinlock_t tr_lock; | ||
40 | }; | ||
41 | |||
42 | /* tx_ring : kernel->user, rx_ring : user->kernel */ | ||
43 | static struct tgt_ring tx_ring, rx_ring; | ||
44 | static DECLARE_WAIT_QUEUE_HEAD(tgt_poll_wait); | ||
45 | |||
46 | static inline void tgt_ring_idx_inc(struct tgt_ring *ring) | ||
47 | { | ||
48 | if (ring->tr_idx == TGT_MAX_EVENTS - 1) | ||
49 | ring->tr_idx = 0; | ||
50 | else | ||
51 | ring->tr_idx++; | ||
52 | } | ||
53 | |||
54 | static struct tgt_event *tgt_head_event(struct tgt_ring *ring, u32 idx) | ||
55 | { | ||
56 | u32 pidx, off; | ||
57 | |||
58 | pidx = idx / TGT_EVENT_PER_PAGE; | ||
59 | off = idx % TGT_EVENT_PER_PAGE; | ||
60 | |||
61 | return (struct tgt_event *) | ||
62 | (ring->tr_pages[pidx] + sizeof(struct tgt_event) * off); | ||
63 | } | ||
64 | |||
65 | static int tgt_uspace_send_event(u32 type, struct tgt_event *p) | ||
66 | { | ||
67 | struct tgt_event *ev; | ||
68 | struct tgt_ring *ring = &tx_ring; | ||
69 | unsigned long flags; | ||
70 | int err = 0; | ||
71 | |||
72 | spin_lock_irqsave(&ring->tr_lock, flags); | ||
73 | |||
74 | ev = tgt_head_event(ring, ring->tr_idx); | ||
75 | if (!ev->hdr.status) | ||
76 | tgt_ring_idx_inc(ring); | ||
77 | else | ||
78 | err = -BUSY; | ||
79 | |||
80 | spin_unlock_irqrestore(&ring->tr_lock, flags); | ||
81 | |||
82 | if (err) | ||
83 | return err; | ||
84 | |||
85 | memcpy(ev, p, sizeof(*ev)); | ||
86 | ev->hdr.type = type; | ||
87 | mb(); | ||
88 | ev->hdr.status = 1; | ||
89 | |||
90 | flush_dcache_page(virt_to_page(ev)); | ||
91 | |||
92 | wake_up_interruptible(&tgt_poll_wait); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 tag) | ||
98 | { | ||
99 | struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); | ||
100 | struct tgt_event ev; | ||
101 | int err; | ||
102 | |||
103 | memset(&ev, 0, sizeof(ev)); | ||
104 | ev.p.cmd_req.host_no = shost->host_no; | ||
105 | ev.p.cmd_req.data_len = cmd->request_bufflen; | ||
106 | memcpy(ev.p.cmd_req.scb, cmd->cmnd, sizeof(ev.p.cmd_req.scb)); | ||
107 | memcpy(ev.p.cmd_req.lun, lun, sizeof(ev.p.cmd_req.lun)); | ||
108 | ev.p.cmd_req.attribute = cmd->tag; | ||
109 | ev.p.cmd_req.tag = tag; | ||
110 | |||
111 | dprintk("%p %d %u %x %llx\n", cmd, shost->host_no, | ||
112 | ev.p.cmd_req.data_len, cmd->tag, | ||
113 | (unsigned long long) ev.p.cmd_req.tag); | ||
114 | |||
115 | err = tgt_uspace_send_event(TGT_KEVENT_CMD_REQ, &ev); | ||
116 | if (err) | ||
117 | eprintk("tx buf is full, could not send\n"); | ||
118 | |||
119 | return err; | ||
120 | } | ||
121 | |||
122 | int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag) | ||
123 | { | ||
124 | struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); | ||
125 | struct tgt_event ev; | ||
126 | int err; | ||
127 | |||
128 | memset(&ev, 0, sizeof(ev)); | ||
129 | ev.p.cmd_done.host_no = shost->host_no; | ||
130 | ev.p.cmd_done.tag = tag; | ||
131 | ev.p.cmd_done.result = cmd->result; | ||
132 | |||
133 | dprintk("%p %d %llu %u %x\n", cmd, shost->host_no, | ||
134 | (unsigned long long) ev.p.cmd_req.tag, | ||
135 | ev.p.cmd_req.data_len, cmd->tag); | ||
136 | |||
137 | err = tgt_uspace_send_event(TGT_KEVENT_CMD_DONE, &ev); | ||
138 | if (err) | ||
139 | eprintk("tx buf is full, could not send\n"); | ||
140 | |||
141 | return err; | ||
142 | } | ||
143 | |||
144 | int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, | ||
145 | struct scsi_lun *scsilun, void *data) | ||
146 | { | ||
147 | struct tgt_event ev; | ||
148 | int err; | ||
149 | |||
150 | memset(&ev, 0, sizeof(ev)); | ||
151 | ev.p.tsk_mgmt_req.host_no = host_no; | ||
152 | ev.p.tsk_mgmt_req.function = function; | ||
153 | ev.p.tsk_mgmt_req.tag = tag; | ||
154 | memcpy(ev.p.tsk_mgmt_req.lun, scsilun, sizeof(ev.p.tsk_mgmt_req.lun)); | ||
155 | ev.p.tsk_mgmt_req.mid = (u64) (unsigned long) data; | ||
156 | |||
157 | dprintk("%d %x %llx %llx\n", host_no, function, (unsigned long long) tag, | ||
158 | (unsigned long long) ev.p.tsk_mgmt_req.mid); | ||
159 | |||
160 | err = tgt_uspace_send_event(TGT_KEVENT_TSK_MGMT_REQ, &ev); | ||
161 | if (err) | ||
162 | eprintk("tx buf is full, could not send\n"); | ||
163 | |||
164 | return err; | ||
165 | } | ||
166 | |||
167 | static int event_recv_msg(struct tgt_event *ev) | ||
168 | { | ||
169 | int err = 0; | ||
170 | |||
171 | switch (ev->hdr.type) { | ||
172 | case TGT_UEVENT_CMD_RSP: | ||
173 | err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no, | ||
174 | ev->p.cmd_rsp.tag, | ||
175 | ev->p.cmd_rsp.result, | ||
176 | ev->p.cmd_rsp.len, | ||
177 | ev->p.cmd_rsp.uaddr, | ||
178 | ev->p.cmd_rsp.rw); | ||
179 | break; | ||
180 | case TGT_UEVENT_TSK_MGMT_RSP: | ||
181 | err = scsi_tgt_kspace_tsk_mgmt(ev->p.tsk_mgmt_rsp.host_no, | ||
182 | ev->p.tsk_mgmt_rsp.mid, | ||
183 | ev->p.tsk_mgmt_rsp.result); | ||
184 | break; | ||
185 | default: | ||
186 | eprintk("unknown type %d\n", ev->hdr.type); | ||
187 | err = -EINVAL; | ||
188 | } | ||
189 | |||
190 | return err; | ||
191 | } | ||
192 | |||
193 | static ssize_t tgt_write(struct file *file, const char __user * buffer, | ||
194 | size_t count, loff_t * ppos) | ||
195 | { | ||
196 | struct tgt_event *ev; | ||
197 | struct tgt_ring *ring = &rx_ring; | ||
198 | |||
199 | while (1) { | ||
200 | ev = tgt_head_event(ring, ring->tr_idx); | ||
201 | /* do we need this? */ | ||
202 | flush_dcache_page(virt_to_page(ev)); | ||
203 | |||
204 | if (!ev->hdr.status) | ||
205 | break; | ||
206 | |||
207 | tgt_ring_idx_inc(ring); | ||
208 | event_recv_msg(ev); | ||
209 | ev->hdr.status = 0; | ||
210 | }; | ||
211 | |||
212 | return count; | ||
213 | } | ||
214 | |||
215 | static unsigned int tgt_poll(struct file * file, struct poll_table_struct *wait) | ||
216 | { | ||
217 | struct tgt_event *ev; | ||
218 | struct tgt_ring *ring = &tx_ring; | ||
219 | unsigned long flags; | ||
220 | unsigned int mask = 0; | ||
221 | u32 idx; | ||
222 | |||
223 | poll_wait(file, &tgt_poll_wait, wait); | ||
224 | |||
225 | spin_lock_irqsave(&ring->tr_lock, flags); | ||
226 | |||
227 | idx = ring->tr_idx ? ring->tr_idx - 1 : TGT_MAX_EVENTS - 1; | ||
228 | ev = tgt_head_event(ring, idx); | ||
229 | if (ev->hdr.status) | ||
230 | mask |= POLLIN | POLLRDNORM; | ||
231 | |||
232 | spin_unlock_irqrestore(&ring->tr_lock, flags); | ||
233 | |||
234 | return mask; | ||
235 | } | ||
236 | |||
237 | static int uspace_ring_map(struct vm_area_struct *vma, unsigned long addr, | ||
238 | struct tgt_ring *ring) | ||
239 | { | ||
240 | int i, err; | ||
241 | |||
242 | for (i = 0; i < TGT_RING_PAGES; i++) { | ||
243 | struct page *page = virt_to_page(ring->tr_pages[i]); | ||
244 | err = vm_insert_page(vma, addr, page); | ||
245 | if (err) | ||
246 | return err; | ||
247 | addr += PAGE_SIZE; | ||
248 | } | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
253 | static int tgt_mmap(struct file *filp, struct vm_area_struct *vma) | ||
254 | { | ||
255 | unsigned long addr; | ||
256 | int err; | ||
257 | |||
258 | if (vma->vm_pgoff) | ||
259 | return -EINVAL; | ||
260 | |||
261 | if (vma->vm_end - vma->vm_start != TGT_RING_SIZE * 2) { | ||
262 | eprintk("mmap size must be %lu, not %lu \n", | ||
263 | TGT_RING_SIZE * 2, vma->vm_end - vma->vm_start); | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | |||
267 | addr = vma->vm_start; | ||
268 | err = uspace_ring_map(vma, addr, &tx_ring); | ||
269 | if (err) | ||
270 | return err; | ||
271 | err = uspace_ring_map(vma, addr + TGT_RING_SIZE, &rx_ring); | ||
272 | |||
273 | return err; | ||
274 | } | ||
275 | |||
276 | static int tgt_open(struct inode *inode, struct file *file) | ||
277 | { | ||
278 | tx_ring.tr_idx = rx_ring.tr_idx = 0; | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static struct file_operations tgt_fops = { | ||
284 | .owner = THIS_MODULE, | ||
285 | .open = tgt_open, | ||
286 | .poll = tgt_poll, | ||
287 | .write = tgt_write, | ||
288 | .mmap = tgt_mmap, | ||
289 | }; | ||
290 | |||
291 | static struct miscdevice tgt_miscdev = { | ||
292 | .minor = MISC_DYNAMIC_MINOR, | ||
293 | .name = "tgt", | ||
294 | .fops = &tgt_fops, | ||
295 | }; | ||
296 | |||
297 | static void tgt_ring_exit(struct tgt_ring *ring) | ||
298 | { | ||
299 | int i; | ||
300 | |||
301 | for (i = 0; i < TGT_RING_PAGES; i++) | ||
302 | free_page(ring->tr_pages[i]); | ||
303 | } | ||
304 | |||
305 | static int tgt_ring_init(struct tgt_ring *ring) | ||
306 | { | ||
307 | int i; | ||
308 | |||
309 | spin_lock_init(&ring->tr_lock); | ||
310 | |||
311 | for (i = 0; i < TGT_RING_PAGES; i++) { | ||
312 | ring->tr_pages[i] = get_zeroed_page(GFP_KERNEL); | ||
313 | if (!ring->tr_pages[i]) { | ||
314 | eprintk("out of memory\n"); | ||
315 | return -ENOMEM; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | void scsi_tgt_if_exit(void) | ||
323 | { | ||
324 | tgt_ring_exit(&tx_ring); | ||
325 | tgt_ring_exit(&rx_ring); | ||
326 | misc_deregister(&tgt_miscdev); | ||
327 | } | ||
328 | |||
329 | int scsi_tgt_if_init(void) | ||
330 | { | ||
331 | int err; | ||
332 | |||
333 | err = tgt_ring_init(&tx_ring); | ||
334 | if (err) | ||
335 | return err; | ||
336 | |||
337 | err = tgt_ring_init(&rx_ring); | ||
338 | if (err) | ||
339 | goto free_tx_ring; | ||
340 | |||
341 | err = misc_register(&tgt_miscdev); | ||
342 | if (err) | ||
343 | goto free_rx_ring; | ||
344 | |||
345 | return 0; | ||
346 | free_rx_ring: | ||
347 | tgt_ring_exit(&rx_ring); | ||
348 | free_tx_ring: | ||
349 | tgt_ring_exit(&tx_ring); | ||
350 | |||
351 | return err; | ||
352 | } | ||
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c new file mode 100644 index 000000000000..386dbae17b44 --- /dev/null +++ b/drivers/scsi/scsi_tgt_lib.c | |||
@@ -0,0 +1,745 @@ | |||
1 | /* | ||
2 | * SCSI target lib functions | ||
3 | * | ||
4 | * Copyright (C) 2005 Mike Christie <michaelc@cs.wisc.edu> | ||
5 | * Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation; either version 2 of the | ||
10 | * License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * 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., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | */ | ||
22 | #include <linux/blkdev.h> | ||
23 | #include <linux/hash.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/pagemap.h> | ||
26 | #include <scsi/scsi.h> | ||
27 | #include <scsi/scsi_cmnd.h> | ||
28 | #include <scsi/scsi_device.h> | ||
29 | #include <scsi/scsi_host.h> | ||
30 | #include <scsi/scsi_tgt.h> | ||
31 | #include <../drivers/md/dm-bio-list.h> | ||
32 | |||
33 | #include "scsi_tgt_priv.h" | ||
34 | |||
35 | static struct workqueue_struct *scsi_tgtd; | ||
36 | static kmem_cache_t *scsi_tgt_cmd_cache; | ||
37 | |||
38 | /* | ||
39 | * TODO: this struct will be killed when the block layer supports large bios | ||
40 | * and James's work struct code is in | ||
41 | */ | ||
42 | struct scsi_tgt_cmd { | ||
43 | /* TODO replace work with James b's code */ | ||
44 | struct work_struct work; | ||
45 | /* TODO replace the lists with a large bio */ | ||
46 | struct bio_list xfer_done_list; | ||
47 | struct bio_list xfer_list; | ||
48 | |||
49 | struct list_head hash_list; | ||
50 | struct request *rq; | ||
51 | u64 tag; | ||
52 | |||
53 | void *buffer; | ||
54 | unsigned bufflen; | ||
55 | }; | ||
56 | |||
57 | #define TGT_HASH_ORDER 4 | ||
58 | #define cmd_hashfn(tag) hash_long((unsigned long) (tag), TGT_HASH_ORDER) | ||
59 | |||
60 | struct scsi_tgt_queuedata { | ||
61 | struct Scsi_Host *shost; | ||
62 | struct list_head cmd_hash[1 << TGT_HASH_ORDER]; | ||
63 | spinlock_t cmd_hash_lock; | ||
64 | }; | ||
65 | |||
66 | /* | ||
67 | * Function: scsi_host_get_command() | ||
68 | * | ||
69 | * Purpose: Allocate and setup a scsi command block and blk request | ||
70 | * | ||
71 | * Arguments: shost - scsi host | ||
72 | * data_dir - dma data dir | ||
73 | * gfp_mask- allocator flags | ||
74 | * | ||
75 | * Returns: The allocated scsi command structure. | ||
76 | * | ||
77 | * This should be called by target LLDs to get a command. | ||
78 | */ | ||
79 | struct scsi_cmnd *scsi_host_get_command(struct Scsi_Host *shost, | ||
80 | enum dma_data_direction data_dir, | ||
81 | gfp_t gfp_mask) | ||
82 | { | ||
83 | int write = (data_dir == DMA_TO_DEVICE); | ||
84 | struct request *rq; | ||
85 | struct scsi_cmnd *cmd; | ||
86 | struct scsi_tgt_cmd *tcmd; | ||
87 | |||
88 | /* Bail if we can't get a reference to the device */ | ||
89 | if (!get_device(&shost->shost_gendev)) | ||
90 | return NULL; | ||
91 | |||
92 | tcmd = kmem_cache_alloc(scsi_tgt_cmd_cache, GFP_ATOMIC); | ||
93 | if (!tcmd) | ||
94 | goto put_dev; | ||
95 | |||
96 | rq = blk_get_request(shost->uspace_req_q, write, gfp_mask); | ||
97 | if (!rq) | ||
98 | goto free_tcmd; | ||
99 | |||
100 | cmd = __scsi_get_command(shost, gfp_mask); | ||
101 | if (!cmd) | ||
102 | goto release_rq; | ||
103 | |||
104 | memset(cmd, 0, sizeof(*cmd)); | ||
105 | cmd->sc_data_direction = data_dir; | ||
106 | cmd->jiffies_at_alloc = jiffies; | ||
107 | cmd->request = rq; | ||
108 | |||
109 | rq->special = cmd; | ||
110 | rq->cmd_type = REQ_TYPE_SPECIAL; | ||
111 | rq->cmd_flags |= REQ_TYPE_BLOCK_PC; | ||
112 | rq->end_io_data = tcmd; | ||
113 | |||
114 | bio_list_init(&tcmd->xfer_list); | ||
115 | bio_list_init(&tcmd->xfer_done_list); | ||
116 | tcmd->rq = rq; | ||
117 | |||
118 | return cmd; | ||
119 | |||
120 | release_rq: | ||
121 | blk_put_request(rq); | ||
122 | free_tcmd: | ||
123 | kmem_cache_free(scsi_tgt_cmd_cache, tcmd); | ||
124 | put_dev: | ||
125 | put_device(&shost->shost_gendev); | ||
126 | return NULL; | ||
127 | |||
128 | } | ||
129 | EXPORT_SYMBOL_GPL(scsi_host_get_command); | ||
130 | |||
131 | /* | ||
132 | * Function: scsi_host_put_command() | ||
133 | * | ||
134 | * Purpose: Free a scsi command block | ||
135 | * | ||
136 | * Arguments: shost - scsi host | ||
137 | * cmd - command block to free | ||
138 | * | ||
139 | * Returns: Nothing. | ||
140 | * | ||
141 | * Notes: The command must not belong to any lists. | ||
142 | */ | ||
143 | void scsi_host_put_command(struct Scsi_Host *shost, struct scsi_cmnd *cmd) | ||
144 | { | ||
145 | struct request_queue *q = shost->uspace_req_q; | ||
146 | struct request *rq = cmd->request; | ||
147 | struct scsi_tgt_cmd *tcmd = rq->end_io_data; | ||
148 | unsigned long flags; | ||
149 | |||
150 | kmem_cache_free(scsi_tgt_cmd_cache, tcmd); | ||
151 | |||
152 | spin_lock_irqsave(q->queue_lock, flags); | ||
153 | __blk_put_request(q, rq); | ||
154 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
155 | |||
156 | __scsi_put_command(shost, cmd, &shost->shost_gendev); | ||
157 | } | ||
158 | EXPORT_SYMBOL_GPL(scsi_host_put_command); | ||
159 | |||
160 | static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd) | ||
161 | { | ||
162 | struct bio *bio; | ||
163 | |||
164 | /* must call bio_endio in case bio was bounced */ | ||
165 | while ((bio = bio_list_pop(&tcmd->xfer_done_list))) { | ||
166 | bio_endio(bio, bio->bi_size, 0); | ||
167 | bio_unmap_user(bio); | ||
168 | } | ||
169 | |||
170 | while ((bio = bio_list_pop(&tcmd->xfer_list))) { | ||
171 | bio_endio(bio, bio->bi_size, 0); | ||
172 | bio_unmap_user(bio); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | static void cmd_hashlist_del(struct scsi_cmnd *cmd) | ||
177 | { | ||
178 | struct request_queue *q = cmd->request->q; | ||
179 | struct scsi_tgt_queuedata *qdata = q->queuedata; | ||
180 | unsigned long flags; | ||
181 | struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; | ||
182 | |||
183 | spin_lock_irqsave(&qdata->cmd_hash_lock, flags); | ||
184 | list_del(&tcmd->hash_list); | ||
185 | spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); | ||
186 | } | ||
187 | |||
188 | static void scsi_tgt_cmd_destroy(struct work_struct *work) | ||
189 | { | ||
190 | struct scsi_tgt_cmd *tcmd = | ||
191 | container_of(work, struct scsi_tgt_cmd, work); | ||
192 | struct scsi_cmnd *cmd = tcmd->rq->special; | ||
193 | |||
194 | dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction, | ||
195 | rq_data_dir(cmd->request)); | ||
196 | /* | ||
197 | * We fix rq->cmd_flags here since when we told bio_map_user | ||
198 | * to write vm for WRITE commands, blk_rq_bio_prep set | ||
199 | * rq_data_dir the flags to READ. | ||
200 | */ | ||
201 | if (cmd->sc_data_direction == DMA_TO_DEVICE) | ||
202 | cmd->request->cmd_flags |= REQ_RW; | ||
203 | else | ||
204 | cmd->request->cmd_flags &= ~REQ_RW; | ||
205 | |||
206 | scsi_unmap_user_pages(tcmd); | ||
207 | scsi_host_put_command(scsi_tgt_cmd_to_host(cmd), cmd); | ||
208 | } | ||
209 | |||
210 | static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd, | ||
211 | u64 tag) | ||
212 | { | ||
213 | struct scsi_tgt_queuedata *qdata = rq->q->queuedata; | ||
214 | unsigned long flags; | ||
215 | struct list_head *head; | ||
216 | |||
217 | tcmd->tag = tag; | ||
218 | INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); | ||
219 | spin_lock_irqsave(&qdata->cmd_hash_lock, flags); | ||
220 | head = &qdata->cmd_hash[cmd_hashfn(tag)]; | ||
221 | list_add(&tcmd->hash_list, head); | ||
222 | spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); | ||
223 | } | ||
224 | |||
225 | /* | ||
226 | * scsi_tgt_alloc_queue - setup queue used for message passing | ||
227 | * shost: scsi host | ||
228 | * | ||
229 | * This should be called by the LLD after host allocation. | ||
230 | * And will be released when the host is released. | ||
231 | */ | ||
232 | int scsi_tgt_alloc_queue(struct Scsi_Host *shost) | ||
233 | { | ||
234 | struct scsi_tgt_queuedata *queuedata; | ||
235 | struct request_queue *q; | ||
236 | int err, i; | ||
237 | |||
238 | /* | ||
239 | * Do we need to send a netlink event or should uspace | ||
240 | * just respond to the hotplug event? | ||
241 | */ | ||
242 | q = __scsi_alloc_queue(shost, NULL); | ||
243 | if (!q) | ||
244 | return -ENOMEM; | ||
245 | |||
246 | queuedata = kzalloc(sizeof(*queuedata), GFP_KERNEL); | ||
247 | if (!queuedata) { | ||
248 | err = -ENOMEM; | ||
249 | goto cleanup_queue; | ||
250 | } | ||
251 | queuedata->shost = shost; | ||
252 | q->queuedata = queuedata; | ||
253 | |||
254 | /* | ||
255 | * this is a silly hack. We should probably just queue as many | ||
256 | * command as is recvd to userspace. uspace can then make | ||
257 | * sure we do not overload the HBA | ||
258 | */ | ||
259 | q->nr_requests = shost->hostt->can_queue; | ||
260 | /* | ||
261 | * We currently only support software LLDs so this does | ||
262 | * not matter for now. Do we need this for the cards we support? | ||
263 | * If so we should make it a host template value. | ||
264 | */ | ||
265 | blk_queue_dma_alignment(q, 0); | ||
266 | shost->uspace_req_q = q; | ||
267 | |||
268 | for (i = 0; i < ARRAY_SIZE(queuedata->cmd_hash); i++) | ||
269 | INIT_LIST_HEAD(&queuedata->cmd_hash[i]); | ||
270 | spin_lock_init(&queuedata->cmd_hash_lock); | ||
271 | |||
272 | return 0; | ||
273 | |||
274 | cleanup_queue: | ||
275 | blk_cleanup_queue(q); | ||
276 | return err; | ||
277 | } | ||
278 | EXPORT_SYMBOL_GPL(scsi_tgt_alloc_queue); | ||
279 | |||
280 | void scsi_tgt_free_queue(struct Scsi_Host *shost) | ||
281 | { | ||
282 | int i; | ||
283 | unsigned long flags; | ||
284 | struct request_queue *q = shost->uspace_req_q; | ||
285 | struct scsi_cmnd *cmd; | ||
286 | struct scsi_tgt_queuedata *qdata = q->queuedata; | ||
287 | struct scsi_tgt_cmd *tcmd, *n; | ||
288 | LIST_HEAD(cmds); | ||
289 | |||
290 | spin_lock_irqsave(&qdata->cmd_hash_lock, flags); | ||
291 | |||
292 | for (i = 0; i < ARRAY_SIZE(qdata->cmd_hash); i++) { | ||
293 | list_for_each_entry_safe(tcmd, n, &qdata->cmd_hash[i], | ||
294 | hash_list) { | ||
295 | list_del(&tcmd->hash_list); | ||
296 | list_add(&tcmd->hash_list, &cmds); | ||
297 | } | ||
298 | } | ||
299 | |||
300 | spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); | ||
301 | |||
302 | while (!list_empty(&cmds)) { | ||
303 | tcmd = list_entry(cmds.next, struct scsi_tgt_cmd, hash_list); | ||
304 | list_del(&tcmd->hash_list); | ||
305 | cmd = tcmd->rq->special; | ||
306 | |||
307 | shost->hostt->eh_abort_handler(cmd); | ||
308 | scsi_tgt_cmd_destroy(&tcmd->work); | ||
309 | } | ||
310 | } | ||
311 | EXPORT_SYMBOL_GPL(scsi_tgt_free_queue); | ||
312 | |||
313 | struct Scsi_Host *scsi_tgt_cmd_to_host(struct scsi_cmnd *cmd) | ||
314 | { | ||
315 | struct scsi_tgt_queuedata *queue = cmd->request->q->queuedata; | ||
316 | return queue->shost; | ||
317 | } | ||
318 | EXPORT_SYMBOL_GPL(scsi_tgt_cmd_to_host); | ||
319 | |||
320 | /* | ||
321 | * scsi_tgt_queue_command - queue command for userspace processing | ||
322 | * @cmd: scsi command | ||
323 | * @scsilun: scsi lun | ||
324 | * @tag: unique value to identify this command for tmf | ||
325 | */ | ||
326 | int scsi_tgt_queue_command(struct scsi_cmnd *cmd, struct scsi_lun *scsilun, | ||
327 | u64 tag) | ||
328 | { | ||
329 | struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; | ||
330 | int err; | ||
331 | |||
332 | init_scsi_tgt_cmd(cmd->request, tcmd, tag); | ||
333 | err = scsi_tgt_uspace_send_cmd(cmd, scsilun, tag); | ||
334 | if (err) | ||
335 | cmd_hashlist_del(cmd); | ||
336 | |||
337 | return err; | ||
338 | } | ||
339 | EXPORT_SYMBOL_GPL(scsi_tgt_queue_command); | ||
340 | |||
341 | /* | ||
342 | * This is run from a interrpt handler normally and the unmap | ||
343 | * needs process context so we must queue | ||
344 | */ | ||
345 | static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd) | ||
346 | { | ||
347 | struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; | ||
348 | |||
349 | dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); | ||
350 | |||
351 | scsi_tgt_uspace_send_status(cmd, tcmd->tag); | ||
352 | queue_work(scsi_tgtd, &tcmd->work); | ||
353 | } | ||
354 | |||
355 | static int __scsi_tgt_transfer_response(struct scsi_cmnd *cmd) | ||
356 | { | ||
357 | struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); | ||
358 | int err; | ||
359 | |||
360 | dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); | ||
361 | |||
362 | err = shost->hostt->transfer_response(cmd, scsi_tgt_cmd_done); | ||
363 | switch (err) { | ||
364 | case SCSI_MLQUEUE_HOST_BUSY: | ||
365 | case SCSI_MLQUEUE_DEVICE_BUSY: | ||
366 | return -EAGAIN; | ||
367 | } | ||
368 | |||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | static void scsi_tgt_transfer_response(struct scsi_cmnd *cmd) | ||
373 | { | ||
374 | struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; | ||
375 | int err; | ||
376 | |||
377 | err = __scsi_tgt_transfer_response(cmd); | ||
378 | if (!err) | ||
379 | return; | ||
380 | |||
381 | cmd->result = DID_BUS_BUSY << 16; | ||
382 | err = scsi_tgt_uspace_send_status(cmd, tcmd->tag); | ||
383 | if (err <= 0) | ||
384 | /* the eh will have to pick this up */ | ||
385 | printk(KERN_ERR "Could not send cmd %p status\n", cmd); | ||
386 | } | ||
387 | |||
388 | static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask) | ||
389 | { | ||
390 | struct request *rq = cmd->request; | ||
391 | struct scsi_tgt_cmd *tcmd = rq->end_io_data; | ||
392 | int count; | ||
393 | |||
394 | cmd->use_sg = rq->nr_phys_segments; | ||
395 | cmd->request_buffer = scsi_alloc_sgtable(cmd, gfp_mask); | ||
396 | if (!cmd->request_buffer) | ||
397 | return -ENOMEM; | ||
398 | |||
399 | cmd->request_bufflen = rq->data_len; | ||
400 | |||
401 | dprintk("cmd %p addr %p cnt %d %lu\n", cmd, tcmd->buffer, cmd->use_sg, | ||
402 | rq_data_dir(rq)); | ||
403 | count = blk_rq_map_sg(rq->q, rq, cmd->request_buffer); | ||
404 | if (likely(count <= cmd->use_sg)) { | ||
405 | cmd->use_sg = count; | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | eprintk("cmd %p addr %p cnt %d\n", cmd, tcmd->buffer, cmd->use_sg); | ||
410 | scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); | ||
411 | return -EINVAL; | ||
412 | } | ||
413 | |||
414 | /* TODO: test this crap and replace bio_map_user with new interface maybe */ | ||
415 | static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd, | ||
416 | int rw) | ||
417 | { | ||
418 | struct request_queue *q = cmd->request->q; | ||
419 | struct request *rq = cmd->request; | ||
420 | void *uaddr = tcmd->buffer; | ||
421 | unsigned int len = tcmd->bufflen; | ||
422 | struct bio *bio; | ||
423 | int err; | ||
424 | |||
425 | while (len > 0) { | ||
426 | dprintk("%lx %u\n", (unsigned long) uaddr, len); | ||
427 | bio = bio_map_user(q, NULL, (unsigned long) uaddr, len, rw); | ||
428 | if (IS_ERR(bio)) { | ||
429 | err = PTR_ERR(bio); | ||
430 | dprintk("fail to map %lx %u %d %x\n", | ||
431 | (unsigned long) uaddr, len, err, cmd->cmnd[0]); | ||
432 | goto unmap_bios; | ||
433 | } | ||
434 | |||
435 | uaddr += bio->bi_size; | ||
436 | len -= bio->bi_size; | ||
437 | |||
438 | /* | ||
439 | * The first bio is added and merged. We could probably | ||
440 | * try to add others using scsi_merge_bio() but for now | ||
441 | * we keep it simple. The first bio should be pretty large | ||
442 | * (either hitting the 1 MB bio pages limit or a queue limit) | ||
443 | * already but for really large IO we may want to try and | ||
444 | * merge these. | ||
445 | */ | ||
446 | if (!rq->bio) { | ||
447 | blk_rq_bio_prep(q, rq, bio); | ||
448 | rq->data_len = bio->bi_size; | ||
449 | } else | ||
450 | /* put list of bios to transfer in next go around */ | ||
451 | bio_list_add(&tcmd->xfer_list, bio); | ||
452 | } | ||
453 | |||
454 | cmd->offset = 0; | ||
455 | err = scsi_tgt_init_cmd(cmd, GFP_KERNEL); | ||
456 | if (err) | ||
457 | goto unmap_bios; | ||
458 | |||
459 | return 0; | ||
460 | |||
461 | unmap_bios: | ||
462 | if (rq->bio) { | ||
463 | bio_unmap_user(rq->bio); | ||
464 | while ((bio = bio_list_pop(&tcmd->xfer_list))) | ||
465 | bio_unmap_user(bio); | ||
466 | } | ||
467 | |||
468 | return err; | ||
469 | } | ||
470 | |||
471 | static int scsi_tgt_transfer_data(struct scsi_cmnd *); | ||
472 | |||
473 | static void scsi_tgt_data_transfer_done(struct scsi_cmnd *cmd) | ||
474 | { | ||
475 | struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; | ||
476 | struct bio *bio; | ||
477 | int err; | ||
478 | |||
479 | /* should we free resources here on error ? */ | ||
480 | if (cmd->result) { | ||
481 | send_uspace_err: | ||
482 | err = scsi_tgt_uspace_send_status(cmd, tcmd->tag); | ||
483 | if (err <= 0) | ||
484 | /* the tgt uspace eh will have to pick this up */ | ||
485 | printk(KERN_ERR "Could not send cmd %p status\n", cmd); | ||
486 | return; | ||
487 | } | ||
488 | |||
489 | dprintk("cmd %p request_bufflen %u bufflen %u\n", | ||
490 | cmd, cmd->request_bufflen, tcmd->bufflen); | ||
491 | |||
492 | scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); | ||
493 | bio_list_add(&tcmd->xfer_done_list, cmd->request->bio); | ||
494 | |||
495 | tcmd->buffer += cmd->request_bufflen; | ||
496 | cmd->offset += cmd->request_bufflen; | ||
497 | |||
498 | if (!tcmd->xfer_list.head) { | ||
499 | scsi_tgt_transfer_response(cmd); | ||
500 | return; | ||
501 | } | ||
502 | |||
503 | dprintk("cmd2 %p request_bufflen %u bufflen %u\n", | ||
504 | cmd, cmd->request_bufflen, tcmd->bufflen); | ||
505 | |||
506 | bio = bio_list_pop(&tcmd->xfer_list); | ||
507 | BUG_ON(!bio); | ||
508 | |||
509 | blk_rq_bio_prep(cmd->request->q, cmd->request, bio); | ||
510 | cmd->request->data_len = bio->bi_size; | ||
511 | err = scsi_tgt_init_cmd(cmd, GFP_ATOMIC); | ||
512 | if (err) { | ||
513 | cmd->result = DID_ERROR << 16; | ||
514 | goto send_uspace_err; | ||
515 | } | ||
516 | |||
517 | if (scsi_tgt_transfer_data(cmd)) { | ||
518 | cmd->result = DID_NO_CONNECT << 16; | ||
519 | goto send_uspace_err; | ||
520 | } | ||
521 | } | ||
522 | |||
523 | static int scsi_tgt_transfer_data(struct scsi_cmnd *cmd) | ||
524 | { | ||
525 | int err; | ||
526 | struct Scsi_Host *host = scsi_tgt_cmd_to_host(cmd); | ||
527 | |||
528 | err = host->hostt->transfer_data(cmd, scsi_tgt_data_transfer_done); | ||
529 | switch (err) { | ||
530 | case SCSI_MLQUEUE_HOST_BUSY: | ||
531 | case SCSI_MLQUEUE_DEVICE_BUSY: | ||
532 | return -EAGAIN; | ||
533 | default: | ||
534 | return 0; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | static int scsi_tgt_copy_sense(struct scsi_cmnd *cmd, unsigned long uaddr, | ||
539 | unsigned len) | ||
540 | { | ||
541 | char __user *p = (char __user *) uaddr; | ||
542 | |||
543 | if (copy_from_user(cmd->sense_buffer, p, | ||
544 | min_t(unsigned, SCSI_SENSE_BUFFERSIZE, len))) { | ||
545 | printk(KERN_ERR "Could not copy the sense buffer\n"); | ||
546 | return -EIO; | ||
547 | } | ||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | static int scsi_tgt_abort_cmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) | ||
552 | { | ||
553 | struct scsi_tgt_cmd *tcmd; | ||
554 | int err; | ||
555 | |||
556 | err = shost->hostt->eh_abort_handler(cmd); | ||
557 | if (err) | ||
558 | eprintk("fail to abort %p\n", cmd); | ||
559 | |||
560 | tcmd = cmd->request->end_io_data; | ||
561 | scsi_tgt_cmd_destroy(&tcmd->work); | ||
562 | return err; | ||
563 | } | ||
564 | |||
565 | static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag) | ||
566 | { | ||
567 | struct scsi_tgt_queuedata *qdata = q->queuedata; | ||
568 | struct request *rq = NULL; | ||
569 | struct list_head *head; | ||
570 | struct scsi_tgt_cmd *tcmd; | ||
571 | unsigned long flags; | ||
572 | |||
573 | head = &qdata->cmd_hash[cmd_hashfn(tag)]; | ||
574 | spin_lock_irqsave(&qdata->cmd_hash_lock, flags); | ||
575 | list_for_each_entry(tcmd, head, hash_list) { | ||
576 | if (tcmd->tag == tag) { | ||
577 | rq = tcmd->rq; | ||
578 | list_del(&tcmd->hash_list); | ||
579 | break; | ||
580 | } | ||
581 | } | ||
582 | spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); | ||
583 | |||
584 | return rq; | ||
585 | } | ||
586 | |||
587 | int scsi_tgt_kspace_exec(int host_no, u64 tag, int result, u32 len, | ||
588 | unsigned long uaddr, u8 rw) | ||
589 | { | ||
590 | struct Scsi_Host *shost; | ||
591 | struct scsi_cmnd *cmd; | ||
592 | struct request *rq; | ||
593 | struct scsi_tgt_cmd *tcmd; | ||
594 | int err = 0; | ||
595 | |||
596 | dprintk("%d %llu %d %u %lx %u\n", host_no, (unsigned long long) tag, | ||
597 | result, len, uaddr, rw); | ||
598 | |||
599 | /* TODO: replace with a O(1) alg */ | ||
600 | shost = scsi_host_lookup(host_no); | ||
601 | if (IS_ERR(shost)) { | ||
602 | printk(KERN_ERR "Could not find host no %d\n", host_no); | ||
603 | return -EINVAL; | ||
604 | } | ||
605 | |||
606 | if (!shost->uspace_req_q) { | ||
607 | printk(KERN_ERR "Not target scsi host %d\n", host_no); | ||
608 | goto done; | ||
609 | } | ||
610 | |||
611 | rq = tgt_cmd_hash_lookup(shost->uspace_req_q, tag); | ||
612 | if (!rq) { | ||
613 | printk(KERN_ERR "Could not find tag %llu\n", | ||
614 | (unsigned long long) tag); | ||
615 | err = -EINVAL; | ||
616 | goto done; | ||
617 | } | ||
618 | cmd = rq->special; | ||
619 | |||
620 | dprintk("cmd %p result %d len %d bufflen %u %lu %x\n", cmd, | ||
621 | result, len, cmd->request_bufflen, rq_data_dir(rq), cmd->cmnd[0]); | ||
622 | |||
623 | if (result == TASK_ABORTED) { | ||
624 | scsi_tgt_abort_cmd(shost, cmd); | ||
625 | goto done; | ||
626 | } | ||
627 | /* | ||
628 | * store the userspace values here, the working values are | ||
629 | * in the request_* values | ||
630 | */ | ||
631 | tcmd = cmd->request->end_io_data; | ||
632 | tcmd->buffer = (void *)uaddr; | ||
633 | tcmd->bufflen = len; | ||
634 | cmd->result = result; | ||
635 | |||
636 | if (!tcmd->bufflen || cmd->request_buffer) { | ||
637 | err = __scsi_tgt_transfer_response(cmd); | ||
638 | goto done; | ||
639 | } | ||
640 | |||
641 | /* | ||
642 | * TODO: Do we need to handle case where request does not | ||
643 | * align with LLD. | ||
644 | */ | ||
645 | err = scsi_map_user_pages(rq->end_io_data, cmd, rw); | ||
646 | if (err) { | ||
647 | eprintk("%p %d\n", cmd, err); | ||
648 | err = -EAGAIN; | ||
649 | goto done; | ||
650 | } | ||
651 | |||
652 | /* userspace failure */ | ||
653 | if (cmd->result) { | ||
654 | if (status_byte(cmd->result) == CHECK_CONDITION) | ||
655 | scsi_tgt_copy_sense(cmd, uaddr, len); | ||
656 | err = __scsi_tgt_transfer_response(cmd); | ||
657 | goto done; | ||
658 | } | ||
659 | /* ask the target LLD to transfer the data to the buffer */ | ||
660 | err = scsi_tgt_transfer_data(cmd); | ||
661 | |||
662 | done: | ||
663 | scsi_host_put(shost); | ||
664 | return err; | ||
665 | } | ||
666 | |||
667 | int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, int function, u64 tag, | ||
668 | struct scsi_lun *scsilun, void *data) | ||
669 | { | ||
670 | int err; | ||
671 | |||
672 | /* TODO: need to retry if this fails. */ | ||
673 | err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, function, | ||
674 | tag, scsilun, data); | ||
675 | if (err < 0) | ||
676 | eprintk("The task management request lost!\n"); | ||
677 | return err; | ||
678 | } | ||
679 | EXPORT_SYMBOL_GPL(scsi_tgt_tsk_mgmt_request); | ||
680 | |||
681 | int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result) | ||
682 | { | ||
683 | struct Scsi_Host *shost; | ||
684 | int err = -EINVAL; | ||
685 | |||
686 | dprintk("%d %d %llx\n", host_no, result, (unsigned long long) mid); | ||
687 | |||
688 | shost = scsi_host_lookup(host_no); | ||
689 | if (IS_ERR(shost)) { | ||
690 | printk(KERN_ERR "Could not find host no %d\n", host_no); | ||
691 | return err; | ||
692 | } | ||
693 | |||
694 | if (!shost->uspace_req_q) { | ||
695 | printk(KERN_ERR "Not target scsi host %d\n", host_no); | ||
696 | goto done; | ||
697 | } | ||
698 | |||
699 | err = shost->hostt->tsk_mgmt_response(mid, result); | ||
700 | done: | ||
701 | scsi_host_put(shost); | ||
702 | return err; | ||
703 | } | ||
704 | |||
705 | static int __init scsi_tgt_init(void) | ||
706 | { | ||
707 | int err; | ||
708 | |||
709 | scsi_tgt_cmd_cache = kmem_cache_create("scsi_tgt_cmd", | ||
710 | sizeof(struct scsi_tgt_cmd), | ||
711 | 0, 0, NULL, NULL); | ||
712 | if (!scsi_tgt_cmd_cache) | ||
713 | return -ENOMEM; | ||
714 | |||
715 | scsi_tgtd = create_workqueue("scsi_tgtd"); | ||
716 | if (!scsi_tgtd) { | ||
717 | err = -ENOMEM; | ||
718 | goto free_kmemcache; | ||
719 | } | ||
720 | |||
721 | err = scsi_tgt_if_init(); | ||
722 | if (err) | ||
723 | goto destroy_wq; | ||
724 | |||
725 | return 0; | ||
726 | |||
727 | destroy_wq: | ||
728 | destroy_workqueue(scsi_tgtd); | ||
729 | free_kmemcache: | ||
730 | kmem_cache_destroy(scsi_tgt_cmd_cache); | ||
731 | return err; | ||
732 | } | ||
733 | |||
734 | static void __exit scsi_tgt_exit(void) | ||
735 | { | ||
736 | destroy_workqueue(scsi_tgtd); | ||
737 | scsi_tgt_if_exit(); | ||
738 | kmem_cache_destroy(scsi_tgt_cmd_cache); | ||
739 | } | ||
740 | |||
741 | module_init(scsi_tgt_init); | ||
742 | module_exit(scsi_tgt_exit); | ||
743 | |||
744 | MODULE_DESCRIPTION("SCSI target core"); | ||
745 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/scsi/scsi_tgt_priv.h b/drivers/scsi/scsi_tgt_priv.h new file mode 100644 index 000000000000..84488c51ff62 --- /dev/null +++ b/drivers/scsi/scsi_tgt_priv.h | |||
@@ -0,0 +1,25 @@ | |||
1 | struct scsi_cmnd; | ||
2 | struct scsi_lun; | ||
3 | struct Scsi_Host; | ||
4 | struct task_struct; | ||
5 | |||
6 | /* tmp - will replace with SCSI logging stuff */ | ||
7 | #define eprintk(fmt, args...) \ | ||
8 | do { \ | ||
9 | printk("%s(%d) " fmt, __FUNCTION__, __LINE__, ##args); \ | ||
10 | } while (0) | ||
11 | |||
12 | #define dprintk(fmt, args...) | ||
13 | /* #define dprintk eprintk */ | ||
14 | |||
15 | extern void scsi_tgt_if_exit(void); | ||
16 | extern int scsi_tgt_if_init(void); | ||
17 | |||
18 | extern int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, | ||
19 | u64 tag); | ||
20 | extern int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag); | ||
21 | extern int scsi_tgt_kspace_exec(int host_no, u64 tag, int result, u32 len, | ||
22 | unsigned long uaddr, u8 rw); | ||
23 | extern int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, | ||
24 | struct scsi_lun *scsilun, void *data); | ||
25 | extern int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result); | ||
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 38c215a78f69..3571ce8934e7 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -241,9 +241,9 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names) | |||
241 | #define FC_MGMTSRVR_PORTID 0x00000a | 241 | #define FC_MGMTSRVR_PORTID 0x00000a |
242 | 242 | ||
243 | 243 | ||
244 | static void fc_timeout_deleted_rport(void *data); | 244 | static void fc_timeout_deleted_rport(struct work_struct *work); |
245 | static void fc_timeout_fail_rport_io(void *data); | 245 | static void fc_timeout_fail_rport_io(struct work_struct *work); |
246 | static void fc_scsi_scan_rport(void *data); | 246 | static void fc_scsi_scan_rport(struct work_struct *work); |
247 | 247 | ||
248 | /* | 248 | /* |
249 | * Attribute counts pre object type... | 249 | * Attribute counts pre object type... |
@@ -1613,7 +1613,7 @@ fc_flush_work(struct Scsi_Host *shost) | |||
1613 | * 1 on success / 0 already queued / < 0 for error | 1613 | * 1 on success / 0 already queued / < 0 for error |
1614 | **/ | 1614 | **/ |
1615 | static int | 1615 | static int |
1616 | fc_queue_devloss_work(struct Scsi_Host *shost, struct work_struct *work, | 1616 | fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work, |
1617 | unsigned long delay) | 1617 | unsigned long delay) |
1618 | { | 1618 | { |
1619 | if (unlikely(!fc_host_devloss_work_q(shost))) { | 1619 | if (unlikely(!fc_host_devloss_work_q(shost))) { |
@@ -1625,9 +1625,6 @@ fc_queue_devloss_work(struct Scsi_Host *shost, struct work_struct *work, | |||
1625 | return -EINVAL; | 1625 | return -EINVAL; |
1626 | } | 1626 | } |
1627 | 1627 | ||
1628 | if (delay == 0) | ||
1629 | return queue_work(fc_host_devloss_work_q(shost), work); | ||
1630 | |||
1631 | return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay); | 1628 | return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay); |
1632 | } | 1629 | } |
1633 | 1630 | ||
@@ -1712,12 +1709,13 @@ EXPORT_SYMBOL(fc_remove_host); | |||
1712 | * fc_starget_delete - called to delete the scsi decendents of an rport | 1709 | * fc_starget_delete - called to delete the scsi decendents of an rport |
1713 | * (target and all sdevs) | 1710 | * (target and all sdevs) |
1714 | * | 1711 | * |
1715 | * @data: remote port to be operated on. | 1712 | * @work: remote port to be operated on. |
1716 | **/ | 1713 | **/ |
1717 | static void | 1714 | static void |
1718 | fc_starget_delete(void *data) | 1715 | fc_starget_delete(struct work_struct *work) |
1719 | { | 1716 | { |
1720 | struct fc_rport *rport = (struct fc_rport *)data; | 1717 | struct fc_rport *rport = |
1718 | container_of(work, struct fc_rport, stgt_delete_work); | ||
1721 | struct Scsi_Host *shost = rport_to_shost(rport); | 1719 | struct Scsi_Host *shost = rport_to_shost(rport); |
1722 | unsigned long flags; | 1720 | unsigned long flags; |
1723 | struct fc_internal *i = to_fc_internal(shost->transportt); | 1721 | struct fc_internal *i = to_fc_internal(shost->transportt); |
@@ -1751,12 +1749,13 @@ fc_starget_delete(void *data) | |||
1751 | /** | 1749 | /** |
1752 | * fc_rport_final_delete - finish rport termination and delete it. | 1750 | * fc_rport_final_delete - finish rport termination and delete it. |
1753 | * | 1751 | * |
1754 | * @data: remote port to be deleted. | 1752 | * @work: remote port to be deleted. |
1755 | **/ | 1753 | **/ |
1756 | static void | 1754 | static void |
1757 | fc_rport_final_delete(void *data) | 1755 | fc_rport_final_delete(struct work_struct *work) |
1758 | { | 1756 | { |
1759 | struct fc_rport *rport = (struct fc_rport *)data; | 1757 | struct fc_rport *rport = |
1758 | container_of(work, struct fc_rport, rport_delete_work); | ||
1760 | struct device *dev = &rport->dev; | 1759 | struct device *dev = &rport->dev; |
1761 | struct Scsi_Host *shost = rport_to_shost(rport); | 1760 | struct Scsi_Host *shost = rport_to_shost(rport); |
1762 | struct fc_internal *i = to_fc_internal(shost->transportt); | 1761 | struct fc_internal *i = to_fc_internal(shost->transportt); |
@@ -1770,7 +1769,7 @@ fc_rport_final_delete(void *data) | |||
1770 | 1769 | ||
1771 | /* Delete SCSI target and sdevs */ | 1770 | /* Delete SCSI target and sdevs */ |
1772 | if (rport->scsi_target_id != -1) | 1771 | if (rport->scsi_target_id != -1) |
1773 | fc_starget_delete(data); | 1772 | fc_starget_delete(&rport->stgt_delete_work); |
1774 | else if (i->f->dev_loss_tmo_callbk) | 1773 | else if (i->f->dev_loss_tmo_callbk) |
1775 | i->f->dev_loss_tmo_callbk(rport); | 1774 | i->f->dev_loss_tmo_callbk(rport); |
1776 | else if (i->f->terminate_rport_io) | 1775 | else if (i->f->terminate_rport_io) |
@@ -1829,11 +1828,11 @@ fc_rport_create(struct Scsi_Host *shost, int channel, | |||
1829 | rport->channel = channel; | 1828 | rport->channel = channel; |
1830 | rport->fast_io_fail_tmo = -1; | 1829 | rport->fast_io_fail_tmo = -1; |
1831 | 1830 | ||
1832 | INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport); | 1831 | INIT_DELAYED_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport); |
1833 | INIT_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io, rport); | 1832 | INIT_DELAYED_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io); |
1834 | INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport); | 1833 | INIT_WORK(&rport->scan_work, fc_scsi_scan_rport); |
1835 | INIT_WORK(&rport->stgt_delete_work, fc_starget_delete, rport); | 1834 | INIT_WORK(&rport->stgt_delete_work, fc_starget_delete); |
1836 | INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete, rport); | 1835 | INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete); |
1837 | 1836 | ||
1838 | spin_lock_irqsave(shost->host_lock, flags); | 1837 | spin_lock_irqsave(shost->host_lock, flags); |
1839 | 1838 | ||
@@ -1963,7 +1962,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, | |||
1963 | } | 1962 | } |
1964 | 1963 | ||
1965 | if (match) { | 1964 | if (match) { |
1966 | struct work_struct *work = | 1965 | struct delayed_work *work = |
1967 | &rport->dev_loss_work; | 1966 | &rport->dev_loss_work; |
1968 | 1967 | ||
1969 | memcpy(&rport->node_name, &ids->node_name, | 1968 | memcpy(&rport->node_name, &ids->node_name, |
@@ -2267,12 +2266,13 @@ EXPORT_SYMBOL(fc_remote_port_rolechg); | |||
2267 | * was a SCSI target (thus was blocked), and failed | 2266 | * was a SCSI target (thus was blocked), and failed |
2268 | * to return in the alloted time. | 2267 | * to return in the alloted time. |
2269 | * | 2268 | * |
2270 | * @data: rport target that failed to reappear in the alloted time. | 2269 | * @work: rport target that failed to reappear in the alloted time. |
2271 | **/ | 2270 | **/ |
2272 | static void | 2271 | static void |
2273 | fc_timeout_deleted_rport(void *data) | 2272 | fc_timeout_deleted_rport(struct work_struct *work) |
2274 | { | 2273 | { |
2275 | struct fc_rport *rport = (struct fc_rport *)data; | 2274 | struct fc_rport *rport = |
2275 | container_of(work, struct fc_rport, dev_loss_work.work); | ||
2276 | struct Scsi_Host *shost = rport_to_shost(rport); | 2276 | struct Scsi_Host *shost = rport_to_shost(rport); |
2277 | struct fc_host_attrs *fc_host = shost_to_fc_host(shost); | 2277 | struct fc_host_attrs *fc_host = shost_to_fc_host(shost); |
2278 | unsigned long flags; | 2278 | unsigned long flags; |
@@ -2366,15 +2366,16 @@ fc_timeout_deleted_rport(void *data) | |||
2366 | * fc_timeout_fail_rport_io - Timeout handler for a fast io failing on a | 2366 | * fc_timeout_fail_rport_io - Timeout handler for a fast io failing on a |
2367 | * disconnected SCSI target. | 2367 | * disconnected SCSI target. |
2368 | * | 2368 | * |
2369 | * @data: rport to terminate io on. | 2369 | * @work: rport to terminate io on. |
2370 | * | 2370 | * |
2371 | * Notes: Only requests the failure of the io, not that all are flushed | 2371 | * Notes: Only requests the failure of the io, not that all are flushed |
2372 | * prior to returning. | 2372 | * prior to returning. |
2373 | **/ | 2373 | **/ |
2374 | static void | 2374 | static void |
2375 | fc_timeout_fail_rport_io(void *data) | 2375 | fc_timeout_fail_rport_io(struct work_struct *work) |
2376 | { | 2376 | { |
2377 | struct fc_rport *rport = (struct fc_rport *)data; | 2377 | struct fc_rport *rport = |
2378 | container_of(work, struct fc_rport, fail_io_work.work); | ||
2378 | struct Scsi_Host *shost = rport_to_shost(rport); | 2379 | struct Scsi_Host *shost = rport_to_shost(rport); |
2379 | struct fc_internal *i = to_fc_internal(shost->transportt); | 2380 | struct fc_internal *i = to_fc_internal(shost->transportt); |
2380 | 2381 | ||
@@ -2387,12 +2388,13 @@ fc_timeout_fail_rport_io(void *data) | |||
2387 | /** | 2388 | /** |
2388 | * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. | 2389 | * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. |
2389 | * | 2390 | * |
2390 | * @data: remote port to be scanned. | 2391 | * @work: remote port to be scanned. |
2391 | **/ | 2392 | **/ |
2392 | static void | 2393 | static void |
2393 | fc_scsi_scan_rport(void *data) | 2394 | fc_scsi_scan_rport(struct work_struct *work) |
2394 | { | 2395 | { |
2395 | struct fc_rport *rport = (struct fc_rport *)data; | 2396 | struct fc_rport *rport = |
2397 | container_of(work, struct fc_rport, scan_work); | ||
2396 | struct Scsi_Host *shost = rport_to_shost(rport); | 2398 | struct Scsi_Host *shost = rport_to_shost(rport); |
2397 | unsigned long flags; | 2399 | unsigned long flags; |
2398 | 2400 | ||
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 9b25124a989e..9c22f1342715 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
@@ -234,9 +234,11 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, | |||
234 | return 0; | 234 | return 0; |
235 | } | 235 | } |
236 | 236 | ||
237 | static void session_recovery_timedout(void *data) | 237 | static void session_recovery_timedout(struct work_struct *work) |
238 | { | 238 | { |
239 | struct iscsi_cls_session *session = data; | 239 | struct iscsi_cls_session *session = |
240 | container_of(work, struct iscsi_cls_session, | ||
241 | recovery_work.work); | ||
240 | 242 | ||
241 | dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed " | 243 | dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed " |
242 | "out after %d secs\n", session->recovery_tmo); | 244 | "out after %d secs\n", session->recovery_tmo); |
@@ -276,7 +278,7 @@ iscsi_alloc_session(struct Scsi_Host *shost, | |||
276 | 278 | ||
277 | session->transport = transport; | 279 | session->transport = transport; |
278 | session->recovery_tmo = 120; | 280 | session->recovery_tmo = 120; |
279 | INIT_WORK(&session->recovery_work, session_recovery_timedout, session); | 281 | INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout); |
280 | INIT_LIST_HEAD(&session->host_list); | 282 | INIT_LIST_HEAD(&session->host_list); |
281 | INIT_LIST_HEAD(&session->sess_list); | 283 | INIT_LIST_HEAD(&session->sess_list); |
282 | 284 | ||
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 9f070f0d0f2b..3fded4831460 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c | |||
@@ -964,9 +964,10 @@ struct work_queue_wrapper { | |||
964 | }; | 964 | }; |
965 | 965 | ||
966 | static void | 966 | static void |
967 | spi_dv_device_work_wrapper(void *data) | 967 | spi_dv_device_work_wrapper(struct work_struct *work) |
968 | { | 968 | { |
969 | struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; | 969 | struct work_queue_wrapper *wqw = |
970 | container_of(work, struct work_queue_wrapper, work); | ||
970 | struct scsi_device *sdev = wqw->sdev; | 971 | struct scsi_device *sdev = wqw->sdev; |
971 | 972 | ||
972 | kfree(wqw); | 973 | kfree(wqw); |
@@ -1006,7 +1007,7 @@ spi_schedule_dv_device(struct scsi_device *sdev) | |||
1006 | return; | 1007 | return; |
1007 | } | 1008 | } |
1008 | 1009 | ||
1009 | INIT_WORK(&wqw->work, spi_dv_device_work_wrapper, wqw); | 1010 | INIT_WORK(&wqw->work, spi_dv_device_work_wrapper); |
1010 | wqw->sdev = sdev; | 1011 | wqw->sdev = sdev; |
1011 | 1012 | ||
1012 | schedule_work(&wqw->work); | 1013 | schedule_work(&wqw->work); |
diff --git a/drivers/scsi/scsi_wait_scan.c b/drivers/scsi/scsi_wait_scan.c new file mode 100644 index 000000000000..8a636103083d --- /dev/null +++ b/drivers/scsi/scsi_wait_scan.c | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * scsi_wait_scan.c | ||
3 | * | ||
4 | * Copyright (C) 2006 James Bottomley <James.Bottomley@SteelEye.com> | ||
5 | * | ||
6 | * This is a simple module to wait until all the async scans are | ||
7 | * complete. The idea is to use it in initrd/initramfs scripts. You | ||
8 | * modprobe it after all the modprobes of the root SCSI drivers and it | ||
9 | * will wait until they have all finished scanning their busses before | ||
10 | * allowing the boot to proceed | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include "scsi_priv.h" | ||
15 | |||
16 | static int __init wait_scan_init(void) | ||
17 | { | ||
18 | scsi_complete_async_scans(); | ||
19 | return 0; | ||
20 | } | ||
21 | |||
22 | static void __exit wait_scan_exit(void) | ||
23 | { | ||
24 | } | ||
25 | |||
26 | MODULE_DESCRIPTION("SCSI wait for scans"); | ||
27 | MODULE_AUTHOR("James Bottomley"); | ||
28 | MODULE_LICENSE("GPL"); | ||
29 | |||
30 | late_initcall(wait_scan_init); | ||
31 | module_exit(wait_scan_exit); | ||
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 84ff203ffedd..f6a452846fab 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1051,6 +1051,14 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) | |||
1051 | &sshdr, SD_TIMEOUT, | 1051 | &sshdr, SD_TIMEOUT, |
1052 | SD_MAX_RETRIES); | 1052 | SD_MAX_RETRIES); |
1053 | 1053 | ||
1054 | /* | ||
1055 | * If the drive has indicated to us that it | ||
1056 | * doesn't have any media in it, don't bother | ||
1057 | * with any more polling. | ||
1058 | */ | ||
1059 | if (media_not_present(sdkp, &sshdr)) | ||
1060 | return; | ||
1061 | |||
1054 | if (the_result) | 1062 | if (the_result) |
1055 | sense_valid = scsi_sense_valid(&sshdr); | 1063 | sense_valid = scsi_sense_valid(&sshdr); |
1056 | retries++; | 1064 | retries++; |
@@ -1059,14 +1067,6 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname) | |||
1059 | ((driver_byte(the_result) & DRIVER_SENSE) && | 1067 | ((driver_byte(the_result) & DRIVER_SENSE) && |
1060 | sense_valid && sshdr.sense_key == UNIT_ATTENTION))); | 1068 | sense_valid && sshdr.sense_key == UNIT_ATTENTION))); |
1061 | 1069 | ||
1062 | /* | ||
1063 | * If the drive has indicated to us that it doesn't have | ||
1064 | * any media in it, don't bother with any of the rest of | ||
1065 | * this crap. | ||
1066 | */ | ||
1067 | if (media_not_present(sdkp, &sshdr)) | ||
1068 | return; | ||
1069 | |||
1070 | if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { | 1070 | if ((driver_byte(the_result) & DRIVER_SENSE) == 0) { |
1071 | /* no sense, TUR either succeeded or failed | 1071 | /* no sense, TUR either succeeded or failed |
1072 | * with a status error */ | 1072 | * with a status error */ |
@@ -1467,7 +1467,6 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, | |||
1467 | res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); | 1467 | res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); |
1468 | 1468 | ||
1469 | if (scsi_status_is_good(res)) { | 1469 | if (scsi_status_is_good(res)) { |
1470 | int ct = 0; | ||
1471 | int offset = data.header_length + data.block_descriptor_length; | 1470 | int offset = data.header_length + data.block_descriptor_length; |
1472 | 1471 | ||
1473 | if (offset >= SD_BUF_SIZE - 2) { | 1472 | if (offset >= SD_BUF_SIZE - 2) { |
@@ -1496,11 +1495,13 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, | |||
1496 | sdkp->DPOFUA = 0; | 1495 | sdkp->DPOFUA = 0; |
1497 | } | 1496 | } |
1498 | 1497 | ||
1499 | ct = sdkp->RCD + 2*sdkp->WCE; | 1498 | printk(KERN_NOTICE "SCSI device %s: " |
1500 | 1499 | "write cache: %s, read cache: %s, %s\n", | |
1501 | printk(KERN_NOTICE "SCSI device %s: drive cache: %s%s\n", | 1500 | diskname, |
1502 | diskname, sd_cache_types[ct], | 1501 | sdkp->WCE ? "enabled" : "disabled", |
1503 | sdkp->DPOFUA ? " w/ FUA" : ""); | 1502 | sdkp->RCD ? "disabled" : "enabled", |
1503 | sdkp->DPOFUA ? "supports DPO and FUA" | ||
1504 | : "doesn't support DPO or FUA"); | ||
1504 | 1505 | ||
1505 | return; | 1506 | return; |
1506 | } | 1507 | } |
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index e1a52c525ed4..587274dd7059 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c | |||
@@ -9,7 +9,7 @@ | |||
9 | Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, | 9 | Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, |
10 | Michael Schaefer, J"org Weule, and Eric Youngdale. | 10 | Michael Schaefer, J"org Weule, and Eric Youngdale. |
11 | 11 | ||
12 | Copyright 1992 - 2005 Kai Makisara | 12 | Copyright 1992 - 2006 Kai Makisara |
13 | email Kai.Makisara@kolumbus.fi | 13 | email Kai.Makisara@kolumbus.fi |
14 | 14 | ||
15 | Some small formal changes - aeb, 950809 | 15 | Some small formal changes - aeb, 950809 |
@@ -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 = "20050830"; | 20 | static const char *verstr = "20061107"; |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | 23 | ||
@@ -999,7 +999,7 @@ static int check_tape(struct scsi_tape *STp, struct file *filp) | |||
999 | STp->min_block = ((STp->buffer)->b_data[4] << 8) | | 999 | STp->min_block = ((STp->buffer)->b_data[4] << 8) | |
1000 | (STp->buffer)->b_data[5]; | 1000 | (STp->buffer)->b_data[5]; |
1001 | if ( DEB( debugging || ) !STp->inited) | 1001 | if ( DEB( debugging || ) !STp->inited) |
1002 | printk(KERN_WARNING | 1002 | printk(KERN_INFO |
1003 | "%s: Block limits %d - %d bytes.\n", name, | 1003 | "%s: Block limits %d - %d bytes.\n", name, |
1004 | STp->min_block, STp->max_block); | 1004 | STp->min_block, STp->max_block); |
1005 | } else { | 1005 | } else { |
@@ -1224,7 +1224,7 @@ static int st_flush(struct file *filp, fl_owner_t id) | |||
1224 | } | 1224 | } |
1225 | 1225 | ||
1226 | DEBC( if (STp->nbr_requests) | 1226 | DEBC( if (STp->nbr_requests) |
1227 | printk(KERN_WARNING "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n", | 1227 | printk(KERN_DEBUG "%s: Number of r/w requests %d, dio used in %d, pages %d (%d).\n", |
1228 | name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable)); | 1228 | name, STp->nbr_requests, STp->nbr_dio, STp->nbr_pages, STp->nbr_combinable)); |
1229 | 1229 | ||
1230 | if (STps->rw == ST_WRITING && !STp->pos_unknown) { | 1230 | if (STps->rw == ST_WRITING && !STp->pos_unknown) { |
@@ -4056,11 +4056,11 @@ static int st_probe(struct device *dev) | |||
4056 | goto out_free_tape; | 4056 | goto out_free_tape; |
4057 | } | 4057 | } |
4058 | 4058 | ||
4059 | sdev_printk(KERN_WARNING, SDp, | 4059 | sdev_printk(KERN_NOTICE, SDp, |
4060 | "Attached scsi tape %s\n", tape_name(tpnt)); | 4060 | "Attached scsi tape %s\n", tape_name(tpnt)); |
4061 | printk(KERN_WARNING "%s: try direct i/o: %s (alignment %d B)\n", | 4061 | sdev_printk(KERN_INFO, SDp, "%s: try direct i/o: %s (alignment %d B)\n", |
4062 | tape_name(tpnt), tpnt->try_dio ? "yes" : "no", | 4062 | tape_name(tpnt), tpnt->try_dio ? "yes" : "no", |
4063 | queue_dma_alignment(SDp->request_queue) + 1); | 4063 | queue_dma_alignment(SDp->request_queue) + 1); |
4064 | 4064 | ||
4065 | return 0; | 4065 | return 0; |
4066 | 4066 | ||
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 185c270bb043..ba6bcdaf2a6a 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c | |||
@@ -11,8 +11,6 @@ | |||
11 | * Written By: | 11 | * Written By: |
12 | * Ed Lin <promise_linux@promise.com> | 12 | * Ed Lin <promise_linux@promise.com> |
13 | * | 13 | * |
14 | * Version: 3.0.0.1 | ||
15 | * | ||
16 | */ | 14 | */ |
17 | 15 | ||
18 | #include <linux/init.h> | 16 | #include <linux/init.h> |
@@ -37,9 +35,9 @@ | |||
37 | #include <scsi/scsi_tcq.h> | 35 | #include <scsi/scsi_tcq.h> |
38 | 36 | ||
39 | #define DRV_NAME "stex" | 37 | #define DRV_NAME "stex" |
40 | #define ST_DRIVER_VERSION "3.0.0.1" | 38 | #define ST_DRIVER_VERSION "3.1.0.1" |
41 | #define ST_VER_MAJOR 3 | 39 | #define ST_VER_MAJOR 3 |
42 | #define ST_VER_MINOR 0 | 40 | #define ST_VER_MINOR 1 |
43 | #define ST_OEM 0 | 41 | #define ST_OEM 0 |
44 | #define ST_BUILD_VER 1 | 42 | #define ST_BUILD_VER 1 |
45 | 43 | ||
@@ -76,8 +74,10 @@ enum { | |||
76 | MU_STATE_STARTED = 4, | 74 | MU_STATE_STARTED = 4, |
77 | MU_STATE_RESETTING = 5, | 75 | MU_STATE_RESETTING = 5, |
78 | 76 | ||
79 | MU_MAX_DELAY_TIME = 240000, | 77 | MU_MAX_DELAY = 120, |
80 | MU_HANDSHAKE_SIGNATURE = 0x55aaaa55, | 78 | MU_HANDSHAKE_SIGNATURE = 0x55aaaa55, |
79 | MU_HANDSHAKE_SIGNATURE_HALF = 0x5a5a0000, | ||
80 | MU_HARD_RESET_WAIT = 30000, | ||
81 | HMU_PARTNER_TYPE = 2, | 81 | HMU_PARTNER_TYPE = 2, |
82 | 82 | ||
83 | /* firmware returned values */ | 83 | /* firmware returned values */ |
@@ -120,7 +120,8 @@ enum { | |||
120 | 120 | ||
121 | st_shasta = 0, | 121 | st_shasta = 0, |
122 | st_vsc = 1, | 122 | st_vsc = 1, |
123 | st_yosemite = 2, | 123 | st_vsc1 = 2, |
124 | st_yosemite = 3, | ||
124 | 125 | ||
125 | PASSTHRU_REQ_TYPE = 0x00000001, | 126 | PASSTHRU_REQ_TYPE = 0x00000001, |
126 | PASSTHRU_REQ_NO_WAKEUP = 0x00000100, | 127 | PASSTHRU_REQ_NO_WAKEUP = 0x00000100, |
@@ -150,6 +151,8 @@ enum { | |||
150 | MGT_CMD_SIGNATURE = 0xba, | 151 | MGT_CMD_SIGNATURE = 0xba, |
151 | 152 | ||
152 | INQUIRY_EVPD = 0x01, | 153 | INQUIRY_EVPD = 0x01, |
154 | |||
155 | ST_ADDITIONAL_MEM = 0x200000, | ||
153 | }; | 156 | }; |
154 | 157 | ||
155 | /* SCSI inquiry data */ | 158 | /* SCSI inquiry data */ |
@@ -211,7 +214,9 @@ struct handshake_frame { | |||
211 | __le32 partner_ver_minor; | 214 | __le32 partner_ver_minor; |
212 | __le32 partner_ver_oem; | 215 | __le32 partner_ver_oem; |
213 | __le32 partner_ver_build; | 216 | __le32 partner_ver_build; |
214 | u32 reserved1[4]; | 217 | __le32 extra_offset; /* NEW */ |
218 | __le32 extra_size; /* NEW */ | ||
219 | u32 reserved1[2]; | ||
215 | }; | 220 | }; |
216 | 221 | ||
217 | struct req_msg { | 222 | struct req_msg { |
@@ -302,6 +307,7 @@ struct st_hba { | |||
302 | void __iomem *mmio_base; /* iomapped PCI memory space */ | 307 | void __iomem *mmio_base; /* iomapped PCI memory space */ |
303 | void *dma_mem; | 308 | void *dma_mem; |
304 | dma_addr_t dma_handle; | 309 | dma_addr_t dma_handle; |
310 | size_t dma_size; | ||
305 | 311 | ||
306 | struct Scsi_Host *host; | 312 | struct Scsi_Host *host; |
307 | struct pci_dev *pdev; | 313 | struct pci_dev *pdev; |
@@ -507,6 +513,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb) | |||
507 | size_t count = sizeof(struct st_frame); | 513 | size_t count = sizeof(struct st_frame); |
508 | 514 | ||
509 | p = hba->copy_buffer; | 515 | p = hba->copy_buffer; |
516 | stex_internal_copy(ccb->cmd, p, &count, ccb->sg_count, ST_FROM_CMD); | ||
510 | memset(p->base, 0, sizeof(u32)*6); | 517 | memset(p->base, 0, sizeof(u32)*6); |
511 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); | 518 | *(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0); |
512 | p->rom_addr = 0; | 519 | p->rom_addr = 0; |
@@ -901,27 +908,34 @@ static int stex_handshake(struct st_hba *hba) | |||
901 | void __iomem *base = hba->mmio_base; | 908 | void __iomem *base = hba->mmio_base; |
902 | struct handshake_frame *h; | 909 | struct handshake_frame *h; |
903 | dma_addr_t status_phys; | 910 | dma_addr_t status_phys; |
904 | int i; | 911 | u32 data; |
912 | unsigned long before; | ||
905 | 913 | ||
906 | if (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { | 914 | if (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { |
907 | writel(MU_INBOUND_DOORBELL_HANDSHAKE, base + IDBL); | 915 | writel(MU_INBOUND_DOORBELL_HANDSHAKE, base + IDBL); |
908 | readl(base + IDBL); | 916 | readl(base + IDBL); |
909 | for (i = 0; readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE | 917 | before = jiffies; |
910 | && i < MU_MAX_DELAY_TIME; i++) { | 918 | while (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { |
919 | if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) { | ||
920 | printk(KERN_ERR DRV_NAME | ||
921 | "(%s): no handshake signature\n", | ||
922 | pci_name(hba->pdev)); | ||
923 | return -1; | ||
924 | } | ||
911 | rmb(); | 925 | rmb(); |
912 | msleep(1); | 926 | msleep(1); |
913 | } | 927 | } |
914 | |||
915 | if (i == MU_MAX_DELAY_TIME) { | ||
916 | printk(KERN_ERR DRV_NAME | ||
917 | "(%s): no handshake signature\n", | ||
918 | pci_name(hba->pdev)); | ||
919 | return -1; | ||
920 | } | ||
921 | } | 928 | } |
922 | 929 | ||
923 | udelay(10); | 930 | udelay(10); |
924 | 931 | ||
932 | data = readl(base + OMR1); | ||
933 | if ((data & 0xffff0000) == MU_HANDSHAKE_SIGNATURE_HALF) { | ||
934 | data &= 0x0000ffff; | ||
935 | if (hba->host->can_queue > data) | ||
936 | hba->host->can_queue = data; | ||
937 | } | ||
938 | |||
925 | h = (struct handshake_frame *)(hba->dma_mem + MU_REQ_BUFFER_SIZE); | 939 | h = (struct handshake_frame *)(hba->dma_mem + MU_REQ_BUFFER_SIZE); |
926 | h->rb_phy = cpu_to_le32(hba->dma_handle); | 940 | h->rb_phy = cpu_to_le32(hba->dma_handle); |
927 | h->rb_phy_hi = cpu_to_le32((hba->dma_handle >> 16) >> 16); | 941 | h->rb_phy_hi = cpu_to_le32((hba->dma_handle >> 16) >> 16); |
@@ -931,6 +945,11 @@ static int stex_handshake(struct st_hba *hba) | |||
931 | h->status_cnt = cpu_to_le16(MU_STATUS_COUNT); | 945 | h->status_cnt = cpu_to_le16(MU_STATUS_COUNT); |
932 | stex_gettime(&h->hosttime); | 946 | stex_gettime(&h->hosttime); |
933 | h->partner_type = HMU_PARTNER_TYPE; | 947 | h->partner_type = HMU_PARTNER_TYPE; |
948 | if (hba->dma_size > STEX_BUFFER_SIZE) { | ||
949 | h->extra_offset = cpu_to_le32(STEX_BUFFER_SIZE); | ||
950 | h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM); | ||
951 | } else | ||
952 | h->extra_offset = h->extra_size = 0; | ||
934 | 953 | ||
935 | status_phys = hba->dma_handle + MU_REQ_BUFFER_SIZE; | 954 | status_phys = hba->dma_handle + MU_REQ_BUFFER_SIZE; |
936 | writel(status_phys, base + IMR0); | 955 | writel(status_phys, base + IMR0); |
@@ -944,19 +963,18 @@ static int stex_handshake(struct st_hba *hba) | |||
944 | readl(base + IDBL); /* flush */ | 963 | readl(base + IDBL); /* flush */ |
945 | 964 | ||
946 | udelay(10); | 965 | udelay(10); |
947 | for (i = 0; readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE | 966 | before = jiffies; |
948 | && i < MU_MAX_DELAY_TIME; i++) { | 967 | while (readl(base + OMR0) != MU_HANDSHAKE_SIGNATURE) { |
968 | if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) { | ||
969 | printk(KERN_ERR DRV_NAME | ||
970 | "(%s): no signature after handshake frame\n", | ||
971 | pci_name(hba->pdev)); | ||
972 | return -1; | ||
973 | } | ||
949 | rmb(); | 974 | rmb(); |
950 | msleep(1); | 975 | msleep(1); |
951 | } | 976 | } |
952 | 977 | ||
953 | if (i == MU_MAX_DELAY_TIME) { | ||
954 | printk(KERN_ERR DRV_NAME | ||
955 | "(%s): no signature after handshake frame\n", | ||
956 | pci_name(hba->pdev)); | ||
957 | return -1; | ||
958 | } | ||
959 | |||
960 | writel(0, base + IMR0); | 978 | writel(0, base + IMR0); |
961 | readl(base + IMR0); | 979 | readl(base + IMR0); |
962 | writel(0, base + OMR0); | 980 | writel(0, base + OMR0); |
@@ -1038,9 +1056,9 @@ static void stex_hard_reset(struct st_hba *hba) | |||
1038 | pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET; | 1056 | pci_bctl &= ~PCI_BRIDGE_CTL_BUS_RESET; |
1039 | pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); | 1057 | pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, pci_bctl); |
1040 | 1058 | ||
1041 | for (i = 0; i < MU_MAX_DELAY_TIME; i++) { | 1059 | for (i = 0; i < MU_HARD_RESET_WAIT; i++) { |
1042 | pci_read_config_word(hba->pdev, PCI_COMMAND, &pci_cmd); | 1060 | pci_read_config_word(hba->pdev, PCI_COMMAND, &pci_cmd); |
1043 | if (pci_cmd & PCI_COMMAND_MASTER) | 1061 | if (pci_cmd != 0xffff && (pci_cmd & PCI_COMMAND_MASTER)) |
1044 | break; | 1062 | break; |
1045 | msleep(1); | 1063 | msleep(1); |
1046 | } | 1064 | } |
@@ -1100,18 +1118,18 @@ static int stex_reset(struct scsi_cmnd *cmd) | |||
1100 | static int stex_biosparam(struct scsi_device *sdev, | 1118 | static int stex_biosparam(struct scsi_device *sdev, |
1101 | struct block_device *bdev, sector_t capacity, int geom[]) | 1119 | struct block_device *bdev, sector_t capacity, int geom[]) |
1102 | { | 1120 | { |
1103 | int heads = 255, sectors = 63, cylinders; | 1121 | int heads = 255, sectors = 63; |
1104 | 1122 | ||
1105 | if (capacity < 0x200000) { | 1123 | if (capacity < 0x200000) { |
1106 | heads = 64; | 1124 | heads = 64; |
1107 | sectors = 32; | 1125 | sectors = 32; |
1108 | } | 1126 | } |
1109 | 1127 | ||
1110 | cylinders = sector_div(capacity, heads * sectors); | 1128 | sector_div(capacity, heads * sectors); |
1111 | 1129 | ||
1112 | geom[0] = heads; | 1130 | geom[0] = heads; |
1113 | geom[1] = sectors; | 1131 | geom[1] = sectors; |
1114 | geom[2] = cylinders; | 1132 | geom[2] = capacity; |
1115 | 1133 | ||
1116 | return 0; | 1134 | return 0; |
1117 | } | 1135 | } |
@@ -1193,8 +1211,13 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1193 | goto out_iounmap; | 1211 | goto out_iounmap; |
1194 | } | 1212 | } |
1195 | 1213 | ||
1214 | hba->cardtype = (unsigned int) id->driver_data; | ||
1215 | if (hba->cardtype == st_vsc && (pdev->subsystem_device & 0xf) == 0x1) | ||
1216 | hba->cardtype = st_vsc1; | ||
1217 | hba->dma_size = (hba->cardtype == st_vsc1) ? | ||
1218 | (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE); | ||
1196 | hba->dma_mem = dma_alloc_coherent(&pdev->dev, | 1219 | hba->dma_mem = dma_alloc_coherent(&pdev->dev, |
1197 | STEX_BUFFER_SIZE, &hba->dma_handle, GFP_KERNEL); | 1220 | hba->dma_size, &hba->dma_handle, GFP_KERNEL); |
1198 | if (!hba->dma_mem) { | 1221 | if (!hba->dma_mem) { |
1199 | err = -ENOMEM; | 1222 | err = -ENOMEM; |
1200 | printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n", | 1223 | printk(KERN_ERR DRV_NAME "(%s): dma mem alloc failed\n", |
@@ -1207,8 +1230,6 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1207 | hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; | 1230 | hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE; |
1208 | hba->mu_status = MU_STATE_STARTING; | 1231 | hba->mu_status = MU_STATE_STARTING; |
1209 | 1232 | ||
1210 | hba->cardtype = (unsigned int) id->driver_data; | ||
1211 | |||
1212 | /* firmware uses id/lun pair for a logical drive, but lun would be | 1233 | /* firmware uses id/lun pair for a logical drive, but lun would be |
1213 | always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use | 1234 | always 0 if CONFIG_SCSI_MULTI_LUN not configured, so we use |
1214 | channel to map lun here */ | 1235 | channel to map lun here */ |
@@ -1233,7 +1254,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1233 | if (err) | 1254 | if (err) |
1234 | goto out_free_irq; | 1255 | goto out_free_irq; |
1235 | 1256 | ||
1236 | err = scsi_init_shared_tag_map(host, ST_CAN_QUEUE); | 1257 | err = scsi_init_shared_tag_map(host, host->can_queue); |
1237 | if (err) { | 1258 | if (err) { |
1238 | printk(KERN_ERR DRV_NAME "(%s): init shared queue failed\n", | 1259 | printk(KERN_ERR DRV_NAME "(%s): init shared queue failed\n", |
1239 | pci_name(pdev)); | 1260 | pci_name(pdev)); |
@@ -1256,7 +1277,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1256 | out_free_irq: | 1277 | out_free_irq: |
1257 | free_irq(pdev->irq, hba); | 1278 | free_irq(pdev->irq, hba); |
1258 | out_pci_free: | 1279 | out_pci_free: |
1259 | dma_free_coherent(&pdev->dev, STEX_BUFFER_SIZE, | 1280 | dma_free_coherent(&pdev->dev, hba->dma_size, |
1260 | hba->dma_mem, hba->dma_handle); | 1281 | hba->dma_mem, hba->dma_handle); |
1261 | out_iounmap: | 1282 | out_iounmap: |
1262 | iounmap(hba->mmio_base); | 1283 | iounmap(hba->mmio_base); |
@@ -1317,7 +1338,7 @@ static void stex_hba_free(struct st_hba *hba) | |||
1317 | 1338 | ||
1318 | pci_release_regions(hba->pdev); | 1339 | pci_release_regions(hba->pdev); |
1319 | 1340 | ||
1320 | dma_free_coherent(&hba->pdev->dev, STEX_BUFFER_SIZE, | 1341 | dma_free_coherent(&hba->pdev->dev, hba->dma_size, |
1321 | hba->dma_mem, hba->dma_handle); | 1342 | hba->dma_mem, hba->dma_handle); |
1322 | } | 1343 | } |
1323 | 1344 | ||
@@ -1346,15 +1367,32 @@ static void stex_shutdown(struct pci_dev *pdev) | |||
1346 | } | 1367 | } |
1347 | 1368 | ||
1348 | static struct pci_device_id stex_pci_tbl[] = { | 1369 | static struct pci_device_id stex_pci_tbl[] = { |
1349 | { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1370 | /* st_shasta */ |
1350 | { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1371 | { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
1351 | { 0x105a, 0xf350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1372 | st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */ |
1352 | { 0x105a, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1373 | { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
1353 | { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1374 | st_shasta }, /* SuperTrak EX12350 */ |
1354 | { 0x105a, 0x8301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1375 | { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
1355 | { 0x105a, 0x8302, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_shasta }, | 1376 | st_shasta }, /* SuperTrak EX4350 */ |
1356 | { 0x1725, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, | 1377 | { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
1357 | { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite }, | 1378 | st_shasta }, /* SuperTrak EX24350 */ |
1379 | |||
1380 | /* st_vsc */ | ||
1381 | { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc }, | ||
1382 | |||
1383 | /* st_yosemite */ | ||
1384 | { 0x105a, 0x8650, PCI_ANY_ID, 0x4600, 0, 0, | ||
1385 | st_yosemite }, /* SuperTrak EX4650 */ | ||
1386 | { 0x105a, 0x8650, PCI_ANY_ID, 0x4610, 0, 0, | ||
1387 | st_yosemite }, /* SuperTrak EX4650o */ | ||
1388 | { 0x105a, 0x8650, PCI_ANY_ID, 0x8600, 0, 0, | ||
1389 | st_yosemite }, /* SuperTrak EX8650EL */ | ||
1390 | { 0x105a, 0x8650, PCI_ANY_ID, 0x8601, 0, 0, | ||
1391 | st_yosemite }, /* SuperTrak EX8650 */ | ||
1392 | { 0x105a, 0x8650, PCI_ANY_ID, 0x8602, 0, 0, | ||
1393 | st_yosemite }, /* SuperTrak EX8654 */ | ||
1394 | { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
1395 | st_yosemite }, /* generic st_yosemite */ | ||
1358 | { } /* terminate list */ | 1396 | { } /* terminate list */ |
1359 | }; | 1397 | }; |
1360 | MODULE_DEVICE_TABLE(pci, stex_pci_tbl); | 1398 | MODULE_DEVICE_TABLE(pci, stex_pci_tbl); |
diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h index 646e840266e2..76a069b7ac0b 100644 --- a/drivers/scsi/t128.h +++ b/drivers/scsi/t128.h | |||
@@ -8,20 +8,20 @@ | |||
8 | * drew@colorado.edu | 8 | * drew@colorado.edu |
9 | * +1 (303) 440-4894 | 9 | * +1 (303) 440-4894 |
10 | * | 10 | * |
11 | * DISTRIBUTION RELEASE 3. | 11 | * DISTRIBUTION RELEASE 3. |
12 | * | 12 | * |
13 | * For more information, please consult | 13 | * For more information, please consult |
14 | * | 14 | * |
15 | * Trantor Systems, Ltd. | 15 | * Trantor Systems, Ltd. |
16 | * T128/T128F/T228 SCSI Host Adapter | 16 | * T128/T128F/T228 SCSI Host Adapter |
17 | * Hardware Specifications | 17 | * Hardware Specifications |
18 | * | 18 | * |
19 | * Trantor Systems, Ltd. | 19 | * Trantor Systems, Ltd. |
20 | * 5415 Randall Place | 20 | * 5415 Randall Place |
21 | * Fremont, CA 94538 | 21 | * Fremont, CA 94538 |
22 | * 1+ (415) 770-1400, FAX 1+ (415) 770-9910 | 22 | * 1+ (415) 770-1400, FAX 1+ (415) 770-9910 |
23 | * | 23 | * |
24 | * and | 24 | * and |
25 | * | 25 | * |
26 | * NCR 5380 Family | 26 | * NCR 5380 Family |
27 | * SCSI Protocol Controller | 27 | * SCSI Protocol Controller |
@@ -48,15 +48,15 @@ | |||
48 | #define TDEBUG_TRANSFER 0x2 | 48 | #define TDEBUG_TRANSFER 0x2 |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * The trantor boards are memory mapped. They use an NCR5380 or | 51 | * The trantor boards are memory mapped. They use an NCR5380 or |
52 | * equivalent (my sample board had part second sourced from ZILOG). | 52 | * equivalent (my sample board had part second sourced from ZILOG). |
53 | * NCR's recommended "Pseudo-DMA" architecture is used, where | 53 | * NCR's recommended "Pseudo-DMA" architecture is used, where |
54 | * a PAL drives the DMA signals on the 5380 allowing fast, blind | 54 | * a PAL drives the DMA signals on the 5380 allowing fast, blind |
55 | * transfers with proper handshaking. | 55 | * transfers with proper handshaking. |
56 | */ | 56 | */ |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * Note : a boot switch is provided for the purpose of informing the | 59 | * Note : a boot switch is provided for the purpose of informing the |
60 | * firmware to boot or not boot from attached SCSI devices. So, I imagine | 60 | * firmware to boot or not boot from attached SCSI devices. So, I imagine |
61 | * there are fewer people who've yanked the ROM like they do on the Seagate | 61 | * there are fewer people who've yanked the ROM like they do on the Seagate |
62 | * to make bootup faster, and I'll probably use this for autodetection. | 62 | * to make bootup faster, and I'll probably use this for autodetection. |
@@ -92,19 +92,20 @@ | |||
92 | #define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */ | 92 | #define T_DATA_REG_OFFSET 0x1e00 /* rw 512 bytes long */ |
93 | 93 | ||
94 | #ifndef ASM | 94 | #ifndef ASM |
95 | static int t128_abort(Scsi_Cmnd *); | 95 | static int t128_abort(struct scsi_cmnd *); |
96 | static int t128_biosparam(struct scsi_device *, struct block_device *, | 96 | static int t128_biosparam(struct scsi_device *, struct block_device *, |
97 | sector_t, int*); | 97 | sector_t, int*); |
98 | static int t128_detect(struct scsi_host_template *); | 98 | static int t128_detect(struct scsi_host_template *); |
99 | static int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); | 99 | static int t128_queue_command(struct scsi_cmnd *, |
100 | static int t128_bus_reset(Scsi_Cmnd *); | 100 | void (*done)(struct scsi_cmnd *)); |
101 | static int t128_bus_reset(struct scsi_cmnd *); | ||
101 | 102 | ||
102 | #ifndef CMD_PER_LUN | 103 | #ifndef CMD_PER_LUN |
103 | #define CMD_PER_LUN 2 | 104 | #define CMD_PER_LUN 2 |
104 | #endif | 105 | #endif |
105 | 106 | ||
106 | #ifndef CAN_QUEUE | 107 | #ifndef CAN_QUEUE |
107 | #define CAN_QUEUE 32 | 108 | #define CAN_QUEUE 32 |
108 | #endif | 109 | #endif |
109 | 110 | ||
110 | #ifndef HOSTS_C | 111 | #ifndef HOSTS_C |
@@ -120,7 +121,7 @@ static int t128_bus_reset(Scsi_Cmnd *); | |||
120 | 121 | ||
121 | #define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20)) | 122 | #define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20)) |
122 | 123 | ||
123 | #if !(TDEBUG & TDEBUG_TRANSFER) | 124 | #if !(TDEBUG & TDEBUG_TRANSFER) |
124 | #define NCR5380_read(reg) readb(T128_address(reg)) | 125 | #define NCR5380_read(reg) readb(T128_address(reg)) |
125 | #define NCR5380_write(reg, value) writeb((value),(T128_address(reg))) | 126 | #define NCR5380_write(reg, value) writeb((value),(T128_address(reg))) |
126 | #else | 127 | #else |
@@ -129,7 +130,7 @@ static int t128_bus_reset(Scsi_Cmnd *); | |||
129 | , instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg))) | 130 | , instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg))) |
130 | 131 | ||
131 | #define NCR5380_write(reg, value) { \ | 132 | #define NCR5380_write(reg, value) { \ |
132 | printk("scsi%d : write %02x to register %d at address %08x\n", \ | 133 | printk("scsi%d : write %02x to register %d at address %08x\n", \ |
133 | instance->hostno, (value), (reg), T128_address(reg)); \ | 134 | instance->hostno, (value), (reg), T128_address(reg)); \ |
134 | writeb((value), (T128_address(reg))); \ | 135 | writeb((value), (T128_address(reg))); \ |
135 | } | 136 | } |
@@ -142,10 +143,10 @@ static int t128_bus_reset(Scsi_Cmnd *); | |||
142 | #define NCR5380_bus_reset t128_bus_reset | 143 | #define NCR5380_bus_reset t128_bus_reset |
143 | #define NCR5380_proc_info t128_proc_info | 144 | #define NCR5380_proc_info t128_proc_info |
144 | 145 | ||
145 | /* 15 14 12 10 7 5 3 | 146 | /* 15 14 12 10 7 5 3 |
146 | 1101 0100 1010 1000 */ | 147 | 1101 0100 1010 1000 */ |
147 | 148 | ||
148 | #define T128_IRQS 0xc4a8 | 149 | #define T128_IRQS 0xc4a8 |
149 | 150 | ||
150 | #endif /* else def HOSTS_C */ | 151 | #endif /* else def HOSTS_C */ |
151 | #endif /* ndef ASM */ | 152 | #endif /* ndef ASM */ |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index b691d3e14754..787a8f134677 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c | |||
@@ -282,7 +282,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) | |||
282 | } | 282 | } |
283 | 283 | ||
284 | /* Setup any dynamic params in the uart desc */ | 284 | /* Setup any dynamic params in the uart desc */ |
285 | int cpm_uart_init_portdesc(void) | 285 | int __init cpm_uart_init_portdesc(void) |
286 | { | 286 | { |
287 | #if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2) | 287 | #if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2) |
288 | u32 addr; | 288 | u32 addr; |
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index aee1b31f1a1c..3db206d29b33 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c | |||
@@ -60,7 +60,8 @@ struct timer_list mcfrs_timer_struct; | |||
60 | #if defined(CONFIG_HW_FEITH) | 60 | #if defined(CONFIG_HW_FEITH) |
61 | #define CONSOLE_BAUD_RATE 38400 | 61 | #define CONSOLE_BAUD_RATE 38400 |
62 | #define DEFAULT_CBAUD B38400 | 62 | #define DEFAULT_CBAUD B38400 |
63 | #elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || defined(CONFIG_M5329EVB) | 63 | #elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) || \ |
64 | defined(CONFIG_M5329EVB) || defined(CONFIG_GILBARCO) | ||
64 | #define CONSOLE_BAUD_RATE 115200 | 65 | #define CONSOLE_BAUD_RATE 115200 |
65 | #define DEFAULT_CBAUD B115200 | 66 | #define DEFAULT_CBAUD B115200 |
66 | #elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ | 67 | #elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ |
@@ -109,12 +110,30 @@ static struct mcf_serial mcfrs_table[] = { | |||
109 | .irq = IRQBASE, | 110 | .irq = IRQBASE, |
110 | .flags = ASYNC_BOOT_AUTOCONF, | 111 | .flags = ASYNC_BOOT_AUTOCONF, |
111 | }, | 112 | }, |
113 | #ifdef MCFUART_BASE2 | ||
112 | { /* ttyS1 */ | 114 | { /* ttyS1 */ |
113 | .magic = 0, | 115 | .magic = 0, |
114 | .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE2), | 116 | .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE2), |
115 | .irq = IRQBASE+1, | 117 | .irq = IRQBASE+1, |
116 | .flags = ASYNC_BOOT_AUTOCONF, | 118 | .flags = ASYNC_BOOT_AUTOCONF, |
117 | }, | 119 | }, |
120 | #endif | ||
121 | #ifdef MCFUART_BASE3 | ||
122 | { /* ttyS2 */ | ||
123 | .magic = 0, | ||
124 | .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE3), | ||
125 | .irq = IRQBASE+2, | ||
126 | .flags = ASYNC_BOOT_AUTOCONF, | ||
127 | }, | ||
128 | #endif | ||
129 | #ifdef MCFUART_BASE4 | ||
130 | { /* ttyS3 */ | ||
131 | .magic = 0, | ||
132 | .addr = (volatile unsigned char *) (MCF_MBAR+MCFUART_BASE4), | ||
133 | .irq = IRQBASE+3, | ||
134 | .flags = ASYNC_BOOT_AUTOCONF, | ||
135 | }, | ||
136 | #endif | ||
118 | }; | 137 | }; |
119 | 138 | ||
120 | 139 | ||
@@ -1516,6 +1535,22 @@ static void mcfrs_irqinit(struct mcf_serial *info) | |||
1516 | imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + | 1535 | imrp = (volatile unsigned long *) (MCF_MBAR + MCFICM_INTC0 + |
1517 | MCFINTC_IMRL); | 1536 | MCFINTC_IMRL); |
1518 | *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); | 1537 | *imrp &= ~((1 << (info->irq - MCFINT_VECBASE)) | 1); |
1538 | #if defined(CONFIG_M527x) | ||
1539 | { | ||
1540 | /* | ||
1541 | * External Pin Mask Setting & Enable External Pin for Interface | ||
1542 | * mrcbis@aliceposta.it | ||
1543 | */ | ||
1544 | unsigned short *serpin_enable_mask; | ||
1545 | serpin_enable_mask = (MCF_IPSBAR + MCF_GPIO_PAR_UART); | ||
1546 | if (info->line == 0) | ||
1547 | *serpin_enable_mask |= UART0_ENABLE_MASK; | ||
1548 | else if (info->line == 1) | ||
1549 | *serpin_enable_mask |= UART1_ENABLE_MASK; | ||
1550 | else if (info->line == 2) | ||
1551 | *serpin_enable_mask |= UART2_ENABLE_MASK; | ||
1552 | } | ||
1553 | #endif | ||
1519 | #elif defined(CONFIG_M520x) | 1554 | #elif defined(CONFIG_M520x) |
1520 | volatile unsigned char *icrp, *uartp; | 1555 | volatile unsigned char *icrp, *uartp; |
1521 | volatile unsigned long *imrp; | 1556 | volatile unsigned long *imrp; |
@@ -1713,7 +1748,7 @@ mcfrs_init(void) | |||
1713 | /* Initialize the tty_driver structure */ | 1748 | /* Initialize the tty_driver structure */ |
1714 | mcfrs_serial_driver->owner = THIS_MODULE; | 1749 | mcfrs_serial_driver->owner = THIS_MODULE; |
1715 | mcfrs_serial_driver->name = "ttyS"; | 1750 | mcfrs_serial_driver->name = "ttyS"; |
1716 | mcfrs_serial_driver->driver_name = "serial"; | 1751 | mcfrs_serial_driver->driver_name = "mcfserial"; |
1717 | mcfrs_serial_driver->major = TTY_MAJOR; | 1752 | mcfrs_serial_driver->major = TTY_MAJOR; |
1718 | mcfrs_serial_driver->minor_start = 64; | 1753 | mcfrs_serial_driver->minor_start = 64; |
1719 | mcfrs_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; | 1754 | mcfrs_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; |
@@ -1797,10 +1832,23 @@ void mcfrs_init_console(void) | |||
1797 | uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8; | 1832 | uartp[MCFUART_UMR] = MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8; |
1798 | uartp[MCFUART_UMR] = MCFUART_MR2_STOP1; | 1833 | uartp[MCFUART_UMR] = MCFUART_MR2_STOP1; |
1799 | 1834 | ||
1835 | #ifdef CONFIG_M5272 | ||
1836 | { | ||
1837 | /* | ||
1838 | * For the MCF5272, also compute the baudrate fraction. | ||
1839 | */ | ||
1840 | int fraction = MCF_BUSCLK - (clk * 32 * mcfrs_console_baud); | ||
1841 | fraction *= 16; | ||
1842 | fraction /= (32 * mcfrs_console_baud); | ||
1843 | uartp[MCFUART_UFPD] = (fraction & 0xf); /* set fraction */ | ||
1844 | clk = (MCF_BUSCLK / mcfrs_console_baud) / 32; | ||
1845 | } | ||
1846 | #else | ||
1800 | clk = ((MCF_BUSCLK / mcfrs_console_baud) + 16) / 32; /* set baud */ | 1847 | clk = ((MCF_BUSCLK / mcfrs_console_baud) + 16) / 32; /* set baud */ |
1848 | #endif | ||
1849 | |||
1801 | uartp[MCFUART_UBG1] = (clk & 0xff00) >> 8; /* set msb baud */ | 1850 | uartp[MCFUART_UBG1] = (clk & 0xff00) >> 8; /* set msb baud */ |
1802 | uartp[MCFUART_UBG2] = (clk & 0xff); /* set lsb baud */ | 1851 | uartp[MCFUART_UBG2] = (clk & 0xff); /* set lsb baud */ |
1803 | |||
1804 | uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER; | 1852 | uartp[MCFUART_UCSR] = MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER; |
1805 | uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; | 1853 | uartp[MCFUART_UCR] = MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE; |
1806 | 1854 | ||
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 4f80c5b4a753..6dd579ed9777 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/serial/mpc52xx_uart.c | ||
3 | * | ||
4 | * Driver for the PSC of the Freescale MPC52xx PSCs configured as UARTs. | 2 | * Driver for the PSC of the Freescale MPC52xx PSCs configured as UARTs. |
5 | * | 3 | * |
6 | * FIXME According to the usermanual the status bits in the status register | 4 | * FIXME According to the usermanual the status bits in the status register |
@@ -14,18 +12,20 @@ | |||
14 | * | 12 | * |
15 | * | 13 | * |
16 | * Maintainer : Sylvain Munaut <tnt@246tNt.com> | 14 | * Maintainer : Sylvain Munaut <tnt@246tNt.com> |
17 | * | 15 | * |
18 | * Some of the code has been inspired/copied from the 2.4 code written | 16 | * Some of the code has been inspired/copied from the 2.4 code written |
19 | * by Dale Farnsworth <dfarnsworth@mvista.com>. | 17 | * by Dale Farnsworth <dfarnsworth@mvista.com>. |
20 | * | 18 | * |
21 | * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com> | 19 | * Copyright (C) 2006 Secret Lab Technologies Ltd. |
20 | * Grant Likely <grant.likely@secretlab.ca> | ||
21 | * Copyright (C) 2004-2006 Sylvain Munaut <tnt@246tNt.com> | ||
22 | * Copyright (C) 2003 MontaVista, Software, Inc. | 22 | * Copyright (C) 2003 MontaVista, Software, Inc. |
23 | * | 23 | * |
24 | * This file is licensed under the terms of the GNU General Public License | 24 | * This file is licensed under the terms of the GNU General Public License |
25 | * version 2. This program is licensed "as is" without any warranty of any | 25 | * version 2. This program is licensed "as is" without any warranty of any |
26 | * kind, whether express or implied. | 26 | * kind, whether express or implied. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | /* Platform device Usage : | 29 | /* Platform device Usage : |
30 | * | 30 | * |
31 | * Since PSCs can have multiple function, the correct driver for each one | 31 | * Since PSCs can have multiple function, the correct driver for each one |
@@ -44,7 +44,24 @@ | |||
44 | * will be mapped to. | 44 | * will be mapped to. |
45 | */ | 45 | */ |
46 | 46 | ||
47 | #include <linux/platform_device.h> | 47 | /* OF Platform device Usage : |
48 | * | ||
49 | * This driver is only used for PSCs configured in uart mode. The device | ||
50 | * tree will have a node for each PSC in uart mode w/ device_type = "serial" | ||
51 | * and "mpc52xx-psc-uart" in the compatible string | ||
52 | * | ||
53 | * By default, PSC devices are enumerated in the order they are found. However | ||
54 | * a particular PSC number can be forces by adding 'device_no = <port#>' | ||
55 | * to the device node. | ||
56 | * | ||
57 | * The driver init all necessary registers to place the PSC in uart mode without | ||
58 | * DCD. However, the pin multiplexing aren't changed and should be set either | ||
59 | * by the bootloader or in the platform init code. | ||
60 | */ | ||
61 | |||
62 | #undef DEBUG | ||
63 | |||
64 | #include <linux/device.h> | ||
48 | #include <linux/module.h> | 65 | #include <linux/module.h> |
49 | #include <linux/tty.h> | 66 | #include <linux/tty.h> |
50 | #include <linux/serial.h> | 67 | #include <linux/serial.h> |
@@ -54,6 +71,12 @@ | |||
54 | #include <asm/delay.h> | 71 | #include <asm/delay.h> |
55 | #include <asm/io.h> | 72 | #include <asm/io.h> |
56 | 73 | ||
74 | #if defined(CONFIG_PPC_MERGE) | ||
75 | #include <asm/of_platform.h> | ||
76 | #else | ||
77 | #include <linux/platform_device.h> | ||
78 | #endif | ||
79 | |||
57 | #include <asm/mpc52xx.h> | 80 | #include <asm/mpc52xx.h> |
58 | #include <asm/mpc52xx_psc.h> | 81 | #include <asm/mpc52xx_psc.h> |
59 | 82 | ||
@@ -80,6 +103,12 @@ static struct uart_port mpc52xx_uart_ports[MPC52xx_PSC_MAXNUM]; | |||
80 | * it's cleared, then a memset(...,0,...) should be added to | 103 | * it's cleared, then a memset(...,0,...) should be added to |
81 | * the console_init | 104 | * the console_init |
82 | */ | 105 | */ |
106 | #if defined(CONFIG_PPC_MERGE) | ||
107 | /* lookup table for matching device nodes to index numbers */ | ||
108 | static struct device_node *mpc52xx_uart_nodes[MPC52xx_PSC_MAXNUM]; | ||
109 | |||
110 | static void mpc52xx_uart_of_enumerate(void); | ||
111 | #endif | ||
83 | 112 | ||
84 | #define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) | 113 | #define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) |
85 | 114 | ||
@@ -96,32 +125,40 @@ static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id); | |||
96 | #define uart_console(port) (0) | 125 | #define uart_console(port) (0) |
97 | #endif | 126 | #endif |
98 | 127 | ||
128 | #if defined(CONFIG_PPC_MERGE) | ||
129 | static struct of_device_id mpc52xx_uart_of_match[] = { | ||
130 | { .type = "serial", .compatible = "mpc52xx-psc-uart", }, | ||
131 | { .type = "serial", .compatible = "mpc5200-psc", }, /* Efika only! */ | ||
132 | {}, | ||
133 | }; | ||
134 | #endif | ||
135 | |||
99 | 136 | ||
100 | /* ======================================================================== */ | 137 | /* ======================================================================== */ |
101 | /* UART operations */ | 138 | /* UART operations */ |
102 | /* ======================================================================== */ | 139 | /* ======================================================================== */ |
103 | 140 | ||
104 | static unsigned int | 141 | static unsigned int |
105 | mpc52xx_uart_tx_empty(struct uart_port *port) | 142 | mpc52xx_uart_tx_empty(struct uart_port *port) |
106 | { | 143 | { |
107 | int status = in_be16(&PSC(port)->mpc52xx_psc_status); | 144 | int status = in_be16(&PSC(port)->mpc52xx_psc_status); |
108 | return (status & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0; | 145 | return (status & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0; |
109 | } | 146 | } |
110 | 147 | ||
111 | static void | 148 | static void |
112 | mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) | 149 | mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) |
113 | { | 150 | { |
114 | /* Not implemented */ | 151 | /* Not implemented */ |
115 | } | 152 | } |
116 | 153 | ||
117 | static unsigned int | 154 | static unsigned int |
118 | mpc52xx_uart_get_mctrl(struct uart_port *port) | 155 | mpc52xx_uart_get_mctrl(struct uart_port *port) |
119 | { | 156 | { |
120 | /* Not implemented */ | 157 | /* Not implemented */ |
121 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; | 158 | return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; |
122 | } | 159 | } |
123 | 160 | ||
124 | static void | 161 | static void |
125 | mpc52xx_uart_stop_tx(struct uart_port *port) | 162 | mpc52xx_uart_stop_tx(struct uart_port *port) |
126 | { | 163 | { |
127 | /* port->lock taken by caller */ | 164 | /* port->lock taken by caller */ |
@@ -129,7 +166,7 @@ mpc52xx_uart_stop_tx(struct uart_port *port) | |||
129 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 166 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); |
130 | } | 167 | } |
131 | 168 | ||
132 | static void | 169 | static void |
133 | mpc52xx_uart_start_tx(struct uart_port *port) | 170 | mpc52xx_uart_start_tx(struct uart_port *port) |
134 | { | 171 | { |
135 | /* port->lock taken by caller */ | 172 | /* port->lock taken by caller */ |
@@ -137,12 +174,12 @@ mpc52xx_uart_start_tx(struct uart_port *port) | |||
137 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 174 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); |
138 | } | 175 | } |
139 | 176 | ||
140 | static void | 177 | static void |
141 | mpc52xx_uart_send_xchar(struct uart_port *port, char ch) | 178 | mpc52xx_uart_send_xchar(struct uart_port *port, char ch) |
142 | { | 179 | { |
143 | unsigned long flags; | 180 | unsigned long flags; |
144 | spin_lock_irqsave(&port->lock, flags); | 181 | spin_lock_irqsave(&port->lock, flags); |
145 | 182 | ||
146 | port->x_char = ch; | 183 | port->x_char = ch; |
147 | if (ch) { | 184 | if (ch) { |
148 | /* Make sure tx interrupts are on */ | 185 | /* Make sure tx interrupts are on */ |
@@ -150,7 +187,7 @@ mpc52xx_uart_send_xchar(struct uart_port *port, char ch) | |||
150 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; | 187 | port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; |
151 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); | 188 | out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); |
152 | } | 189 | } |
153 | 190 | ||
154 | spin_unlock_irqrestore(&port->lock, flags); | 191 | spin_unlock_irqrestore(&port->lock, flags); |
155 | } | 192 | } |
156 | 193 | ||
@@ -178,7 +215,7 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl) | |||
178 | out_8(&PSC(port)->command,MPC52xx_PSC_START_BRK); | 215 | out_8(&PSC(port)->command,MPC52xx_PSC_START_BRK); |
179 | else | 216 | else |
180 | out_8(&PSC(port)->command,MPC52xx_PSC_STOP_BRK); | 217 | out_8(&PSC(port)->command,MPC52xx_PSC_STOP_BRK); |
181 | 218 | ||
182 | spin_unlock_irqrestore(&port->lock, flags); | 219 | spin_unlock_irqrestore(&port->lock, flags); |
183 | } | 220 | } |
184 | 221 | ||
@@ -197,11 +234,11 @@ mpc52xx_uart_startup(struct uart_port *port) | |||
197 | /* Reset/activate the port, clear and enable interrupts */ | 234 | /* Reset/activate the port, clear and enable interrupts */ |
198 | out_8(&psc->command,MPC52xx_PSC_RST_RX); | 235 | out_8(&psc->command,MPC52xx_PSC_RST_RX); |
199 | out_8(&psc->command,MPC52xx_PSC_RST_TX); | 236 | out_8(&psc->command,MPC52xx_PSC_RST_TX); |
200 | 237 | ||
201 | out_be32(&psc->sicr,0); /* UART mode DCD ignored */ | 238 | out_be32(&psc->sicr,0); /* UART mode DCD ignored */ |
202 | 239 | ||
203 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ | 240 | out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ |
204 | 241 | ||
205 | out_8(&psc->rfcntl, 0x00); | 242 | out_8(&psc->rfcntl, 0x00); |
206 | out_be16(&psc->rfalarm, 0x1ff); | 243 | out_be16(&psc->rfalarm, 0x1ff); |
207 | out_8(&psc->tfcntl, 0x07); | 244 | out_8(&psc->tfcntl, 0x07); |
@@ -209,10 +246,10 @@ mpc52xx_uart_startup(struct uart_port *port) | |||
209 | 246 | ||
210 | port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY; | 247 | port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY; |
211 | out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); | 248 | out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); |
212 | 249 | ||
213 | out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); | 250 | out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); |
214 | out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); | 251 | out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); |
215 | 252 | ||
216 | return 0; | 253 | return 0; |
217 | } | 254 | } |
218 | 255 | ||
@@ -220,19 +257,19 @@ static void | |||
220 | mpc52xx_uart_shutdown(struct uart_port *port) | 257 | mpc52xx_uart_shutdown(struct uart_port *port) |
221 | { | 258 | { |
222 | struct mpc52xx_psc __iomem *psc = PSC(port); | 259 | struct mpc52xx_psc __iomem *psc = PSC(port); |
223 | 260 | ||
224 | /* Shut down the port, interrupt and all */ | 261 | /* Shut down the port, interrupt and all */ |
225 | out_8(&psc->command,MPC52xx_PSC_RST_RX); | 262 | out_8(&psc->command,MPC52xx_PSC_RST_RX); |
226 | out_8(&psc->command,MPC52xx_PSC_RST_TX); | 263 | out_8(&psc->command,MPC52xx_PSC_RST_TX); |
227 | 264 | ||
228 | port->read_status_mask = 0; | 265 | port->read_status_mask = 0; |
229 | out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); | 266 | out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); |
230 | 267 | ||
231 | /* Release interrupt */ | 268 | /* Release interrupt */ |
232 | free_irq(port->irq, port); | 269 | free_irq(port->irq, port); |
233 | } | 270 | } |
234 | 271 | ||
235 | static void | 272 | static void |
236 | mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new, | 273 | mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new, |
237 | struct termios *old) | 274 | struct termios *old) |
238 | { | 275 | { |
@@ -241,10 +278,10 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new, | |||
241 | unsigned char mr1, mr2; | 278 | unsigned char mr1, mr2; |
242 | unsigned short ctr; | 279 | unsigned short ctr; |
243 | unsigned int j, baud, quot; | 280 | unsigned int j, baud, quot; |
244 | 281 | ||
245 | /* Prepare what we're gonna write */ | 282 | /* Prepare what we're gonna write */ |
246 | mr1 = 0; | 283 | mr1 = 0; |
247 | 284 | ||
248 | switch (new->c_cflag & CSIZE) { | 285 | switch (new->c_cflag & CSIZE) { |
249 | case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS; | 286 | case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS; |
250 | break; | 287 | break; |
@@ -261,8 +298,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new, | |||
261 | MPC52xx_PSC_MODE_PARODD : MPC52xx_PSC_MODE_PAREVEN; | 298 | MPC52xx_PSC_MODE_PARODD : MPC52xx_PSC_MODE_PAREVEN; |
262 | } else | 299 | } else |
263 | mr1 |= MPC52xx_PSC_MODE_PARNONE; | 300 | mr1 |= MPC52xx_PSC_MODE_PARNONE; |
264 | 301 | ||
265 | 302 | ||
266 | mr2 = 0; | 303 | mr2 = 0; |
267 | 304 | ||
268 | if (new->c_cflag & CSTOPB) | 305 | if (new->c_cflag & CSTOPB) |
@@ -276,7 +313,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new, | |||
276 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); | 313 | baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); |
277 | quot = uart_get_divisor(port, baud); | 314 | quot = uart_get_divisor(port, baud); |
278 | ctr = quot & 0xffff; | 315 | ctr = quot & 0xffff; |
279 | 316 | ||
280 | /* Get the lock */ | 317 | /* Get the lock */ |
281 | spin_lock_irqsave(&port->lock, flags); | 318 | spin_lock_irqsave(&port->lock, flags); |
282 | 319 | ||
@@ -290,14 +327,14 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new, | |||
290 | * boot for the console, all stuff is not yet ready to receive at that | 327 | * boot for the console, all stuff is not yet ready to receive at that |
291 | * time and that just makes the kernel oops */ | 328 | * time and that just makes the kernel oops */ |
292 | /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */ | 329 | /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */ |
293 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && | 330 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && |
294 | --j) | 331 | --j) |
295 | udelay(1); | 332 | udelay(1); |
296 | 333 | ||
297 | if (!j) | 334 | if (!j) |
298 | printk( KERN_ERR "mpc52xx_uart.c: " | 335 | printk( KERN_ERR "mpc52xx_uart.c: " |
299 | "Unable to flush RX & TX fifos in-time in set_termios." | 336 | "Unable to flush RX & TX fifos in-time in set_termios." |
300 | "Some chars may have been lost.\n" ); | 337 | "Some chars may have been lost.\n" ); |
301 | 338 | ||
302 | /* Reset the TX & RX */ | 339 | /* Reset the TX & RX */ |
303 | out_8(&psc->command,MPC52xx_PSC_RST_RX); | 340 | out_8(&psc->command,MPC52xx_PSC_RST_RX); |
@@ -309,7 +346,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new, | |||
309 | out_8(&psc->mode,mr2); | 346 | out_8(&psc->mode,mr2); |
310 | out_8(&psc->ctur,ctr >> 8); | 347 | out_8(&psc->ctur,ctr >> 8); |
311 | out_8(&psc->ctlr,ctr & 0xff); | 348 | out_8(&psc->ctlr,ctr & 0xff); |
312 | 349 | ||
313 | /* Reenable TX & RX */ | 350 | /* Reenable TX & RX */ |
314 | out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); | 351 | out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); |
315 | out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); | 352 | out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); |
@@ -332,7 +369,7 @@ mpc52xx_uart_release_port(struct uart_port *port) | |||
332 | port->membase = NULL; | 369 | port->membase = NULL; |
333 | } | 370 | } |
334 | 371 | ||
335 | release_mem_region(port->mapbase, MPC52xx_PSC_SIZE); | 372 | release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc)); |
336 | } | 373 | } |
337 | 374 | ||
338 | static int | 375 | static int |
@@ -341,12 +378,13 @@ mpc52xx_uart_request_port(struct uart_port *port) | |||
341 | int err; | 378 | int err; |
342 | 379 | ||
343 | if (port->flags & UPF_IOREMAP) /* Need to remap ? */ | 380 | if (port->flags & UPF_IOREMAP) /* Need to remap ? */ |
344 | port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE); | 381 | port->membase = ioremap(port->mapbase, |
382 | sizeof(struct mpc52xx_psc)); | ||
345 | 383 | ||
346 | if (!port->membase) | 384 | if (!port->membase) |
347 | return -EINVAL; | 385 | return -EINVAL; |
348 | 386 | ||
349 | err = request_mem_region(port->mapbase, MPC52xx_PSC_SIZE, | 387 | err = request_mem_region(port->mapbase, sizeof(struct mpc52xx_psc), |
350 | "mpc52xx_psc_uart") != NULL ? 0 : -EBUSY; | 388 | "mpc52xx_psc_uart") != NULL ? 0 : -EBUSY; |
351 | 389 | ||
352 | if (err && (port->flags & UPF_IOREMAP)) { | 390 | if (err && (port->flags & UPF_IOREMAP)) { |
@@ -373,7 +411,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
373 | 411 | ||
374 | if ( (ser->irq != port->irq) || | 412 | if ( (ser->irq != port->irq) || |
375 | (ser->io_type != SERIAL_IO_MEM) || | 413 | (ser->io_type != SERIAL_IO_MEM) || |
376 | (ser->baud_base != port->uartclk) || | 414 | (ser->baud_base != port->uartclk) || |
377 | (ser->iomem_base != (void*)port->mapbase) || | 415 | (ser->iomem_base != (void*)port->mapbase) || |
378 | (ser->hub6 != 0 ) ) | 416 | (ser->hub6 != 0 ) ) |
379 | return -EINVAL; | 417 | return -EINVAL; |
@@ -404,11 +442,11 @@ static struct uart_ops mpc52xx_uart_ops = { | |||
404 | .verify_port = mpc52xx_uart_verify_port | 442 | .verify_port = mpc52xx_uart_verify_port |
405 | }; | 443 | }; |
406 | 444 | ||
407 | 445 | ||
408 | /* ======================================================================== */ | 446 | /* ======================================================================== */ |
409 | /* Interrupt handling */ | 447 | /* Interrupt handling */ |
410 | /* ======================================================================== */ | 448 | /* ======================================================================== */ |
411 | 449 | ||
412 | static inline int | 450 | static inline int |
413 | mpc52xx_uart_int_rx_chars(struct uart_port *port) | 451 | mpc52xx_uart_int_rx_chars(struct uart_port *port) |
414 | { | 452 | { |
@@ -435,11 +473,11 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
435 | 473 | ||
436 | flag = TTY_NORMAL; | 474 | flag = TTY_NORMAL; |
437 | port->icount.rx++; | 475 | port->icount.rx++; |
438 | 476 | ||
439 | if ( status & (MPC52xx_PSC_SR_PE | | 477 | if ( status & (MPC52xx_PSC_SR_PE | |
440 | MPC52xx_PSC_SR_FE | | 478 | MPC52xx_PSC_SR_FE | |
441 | MPC52xx_PSC_SR_RB) ) { | 479 | MPC52xx_PSC_SR_RB) ) { |
442 | 480 | ||
443 | if (status & MPC52xx_PSC_SR_RB) { | 481 | if (status & MPC52xx_PSC_SR_RB) { |
444 | flag = TTY_BREAK; | 482 | flag = TTY_BREAK; |
445 | uart_handle_break(port); | 483 | uart_handle_break(port); |
@@ -464,7 +502,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port) | |||
464 | } | 502 | } |
465 | 503 | ||
466 | tty_flip_buffer_push(tty); | 504 | tty_flip_buffer_push(tty); |
467 | 505 | ||
468 | return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY; | 506 | return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY; |
469 | } | 507 | } |
470 | 508 | ||
@@ -509,25 +547,25 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port) | |||
509 | return 1; | 547 | return 1; |
510 | } | 548 | } |
511 | 549 | ||
512 | static irqreturn_t | 550 | static irqreturn_t |
513 | mpc52xx_uart_int(int irq, void *dev_id) | 551 | mpc52xx_uart_int(int irq, void *dev_id) |
514 | { | 552 | { |
515 | struct uart_port *port = dev_id; | 553 | struct uart_port *port = dev_id; |
516 | unsigned long pass = ISR_PASS_LIMIT; | 554 | unsigned long pass = ISR_PASS_LIMIT; |
517 | unsigned int keepgoing; | 555 | unsigned int keepgoing; |
518 | unsigned short status; | 556 | unsigned short status; |
519 | 557 | ||
520 | spin_lock(&port->lock); | 558 | spin_lock(&port->lock); |
521 | 559 | ||
522 | /* While we have stuff to do, we continue */ | 560 | /* While we have stuff to do, we continue */ |
523 | do { | 561 | do { |
524 | /* If we don't find anything to do, we stop */ | 562 | /* If we don't find anything to do, we stop */ |
525 | keepgoing = 0; | 563 | keepgoing = 0; |
526 | 564 | ||
527 | /* Read status */ | 565 | /* Read status */ |
528 | status = in_be16(&PSC(port)->mpc52xx_psc_isr); | 566 | status = in_be16(&PSC(port)->mpc52xx_psc_isr); |
529 | status &= port->read_status_mask; | 567 | status &= port->read_status_mask; |
530 | 568 | ||
531 | /* Do we need to receive chars ? */ | 569 | /* Do we need to receive chars ? */ |
532 | /* For this RX interrupts must be on and some chars waiting */ | 570 | /* For this RX interrupts must be on and some chars waiting */ |
533 | if ( status & MPC52xx_PSC_IMR_RXRDY ) | 571 | if ( status & MPC52xx_PSC_IMR_RXRDY ) |
@@ -537,15 +575,15 @@ mpc52xx_uart_int(int irq, void *dev_id) | |||
537 | /* For this, TX must be ready and TX interrupt enabled */ | 575 | /* For this, TX must be ready and TX interrupt enabled */ |
538 | if ( status & MPC52xx_PSC_IMR_TXRDY ) | 576 | if ( status & MPC52xx_PSC_IMR_TXRDY ) |
539 | keepgoing |= mpc52xx_uart_int_tx_chars(port); | 577 | keepgoing |= mpc52xx_uart_int_tx_chars(port); |
540 | 578 | ||
541 | /* Limit number of iteration */ | 579 | /* Limit number of iteration */ |
542 | if ( !(--pass) ) | 580 | if ( !(--pass) ) |
543 | keepgoing = 0; | 581 | keepgoing = 0; |
544 | 582 | ||
545 | } while (keepgoing); | 583 | } while (keepgoing); |
546 | 584 | ||
547 | spin_unlock(&port->lock); | 585 | spin_unlock(&port->lock); |
548 | 586 | ||
549 | return IRQ_HANDLED; | 587 | return IRQ_HANDLED; |
550 | } | 588 | } |
551 | 589 | ||
@@ -563,13 +601,18 @@ mpc52xx_console_get_options(struct uart_port *port, | |||
563 | struct mpc52xx_psc __iomem *psc = PSC(port); | 601 | struct mpc52xx_psc __iomem *psc = PSC(port); |
564 | unsigned char mr1; | 602 | unsigned char mr1; |
565 | 603 | ||
604 | pr_debug("mpc52xx_console_get_options(port=%p)\n", port); | ||
605 | |||
566 | /* Read the mode registers */ | 606 | /* Read the mode registers */ |
567 | out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1); | 607 | out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1); |
568 | mr1 = in_8(&psc->mode); | 608 | mr1 = in_8(&psc->mode); |
569 | 609 | ||
570 | /* CT{U,L}R are write-only ! */ | 610 | /* CT{U,L}R are write-only ! */ |
571 | *baud = __res.bi_baudrate ? | 611 | *baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD; |
572 | __res.bi_baudrate : CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD; | 612 | #if !defined(CONFIG_PPC_MERGE) |
613 | if (__res.bi_baudrate) | ||
614 | *baud = __res.bi_baudrate; | ||
615 | #endif | ||
573 | 616 | ||
574 | /* Parse them */ | 617 | /* Parse them */ |
575 | switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) { | 618 | switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) { |
@@ -579,26 +622,26 @@ mpc52xx_console_get_options(struct uart_port *port, | |||
579 | case MPC52xx_PSC_MODE_8_BITS: | 622 | case MPC52xx_PSC_MODE_8_BITS: |
580 | default: *bits = 8; | 623 | default: *bits = 8; |
581 | } | 624 | } |
582 | 625 | ||
583 | if (mr1 & MPC52xx_PSC_MODE_PARNONE) | 626 | if (mr1 & MPC52xx_PSC_MODE_PARNONE) |
584 | *parity = 'n'; | 627 | *parity = 'n'; |
585 | else | 628 | else |
586 | *parity = mr1 & MPC52xx_PSC_MODE_PARODD ? 'o' : 'e'; | 629 | *parity = mr1 & MPC52xx_PSC_MODE_PARODD ? 'o' : 'e'; |
587 | } | 630 | } |
588 | 631 | ||
589 | static void | 632 | static void |
590 | mpc52xx_console_write(struct console *co, const char *s, unsigned int count) | 633 | mpc52xx_console_write(struct console *co, const char *s, unsigned int count) |
591 | { | 634 | { |
592 | struct uart_port *port = &mpc52xx_uart_ports[co->index]; | 635 | struct uart_port *port = &mpc52xx_uart_ports[co->index]; |
593 | struct mpc52xx_psc __iomem *psc = PSC(port); | 636 | struct mpc52xx_psc __iomem *psc = PSC(port); |
594 | unsigned int i, j; | 637 | unsigned int i, j; |
595 | 638 | ||
596 | /* Disable interrupts */ | 639 | /* Disable interrupts */ |
597 | out_be16(&psc->mpc52xx_psc_imr, 0); | 640 | out_be16(&psc->mpc52xx_psc_imr, 0); |
598 | 641 | ||
599 | /* Wait the TX buffer to be empty */ | 642 | /* Wait the TX buffer to be empty */ |
600 | j = 5000000; /* Maximum wait */ | 643 | j = 5000000; /* Maximum wait */ |
601 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && | 644 | while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && |
602 | --j) | 645 | --j) |
603 | udelay(1); | 646 | udelay(1); |
604 | 647 | ||
@@ -607,13 +650,13 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count) | |||
607 | /* Line return handling */ | 650 | /* Line return handling */ |
608 | if (*s == '\n') | 651 | if (*s == '\n') |
609 | out_8(&psc->mpc52xx_psc_buffer_8, '\r'); | 652 | out_8(&psc->mpc52xx_psc_buffer_8, '\r'); |
610 | 653 | ||
611 | /* Send the char */ | 654 | /* Send the char */ |
612 | out_8(&psc->mpc52xx_psc_buffer_8, *s); | 655 | out_8(&psc->mpc52xx_psc_buffer_8, *s); |
613 | 656 | ||
614 | /* Wait the TX buffer to be empty */ | 657 | /* Wait the TX buffer to be empty */ |
615 | j = 20000; /* Maximum wait */ | 658 | j = 20000; /* Maximum wait */ |
616 | while (!(in_be16(&psc->mpc52xx_psc_status) & | 659 | while (!(in_be16(&psc->mpc52xx_psc_status) & |
617 | MPC52xx_PSC_SR_TXEMP) && --j) | 660 | MPC52xx_PSC_SR_TXEMP) && --j) |
618 | udelay(1); | 661 | udelay(1); |
619 | } | 662 | } |
@@ -622,6 +665,7 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count) | |||
622 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); | 665 | out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); |
623 | } | 666 | } |
624 | 667 | ||
668 | #if !defined(CONFIG_PPC_MERGE) | ||
625 | static int __init | 669 | static int __init |
626 | mpc52xx_console_setup(struct console *co, char *options) | 670 | mpc52xx_console_setup(struct console *co, char *options) |
627 | { | 671 | { |
@@ -634,7 +678,7 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
634 | 678 | ||
635 | if (co->index < 0 || co->index >= MPC52xx_PSC_MAXNUM) | 679 | if (co->index < 0 || co->index >= MPC52xx_PSC_MAXNUM) |
636 | return -EINVAL; | 680 | return -EINVAL; |
637 | 681 | ||
638 | /* Basic port init. Needed since we use some uart_??? func before | 682 | /* Basic port init. Needed since we use some uart_??? func before |
639 | * real init for early access */ | 683 | * real init for early access */ |
640 | spin_lock_init(&port->lock); | 684 | spin_lock_init(&port->lock); |
@@ -656,6 +700,78 @@ mpc52xx_console_setup(struct console *co, char *options) | |||
656 | return uart_set_options(port, co, baud, parity, bits, flow); | 700 | return uart_set_options(port, co, baud, parity, bits, flow); |
657 | } | 701 | } |
658 | 702 | ||
703 | #else | ||
704 | |||
705 | static int __init | ||
706 | mpc52xx_console_setup(struct console *co, char *options) | ||
707 | { | ||
708 | struct uart_port *port = &mpc52xx_uart_ports[co->index]; | ||
709 | struct device_node *np = mpc52xx_uart_nodes[co->index]; | ||
710 | unsigned int ipb_freq; | ||
711 | struct resource res; | ||
712 | int ret; | ||
713 | |||
714 | int baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD; | ||
715 | int bits = 8; | ||
716 | int parity = 'n'; | ||
717 | int flow = 'n'; | ||
718 | |||
719 | pr_debug("mpc52xx_console_setup co=%p, co->index=%i, options=%s\n", | ||
720 | co, co->index, options); | ||
721 | |||
722 | if ((co->index < 0) || (co->index > MPC52xx_PSC_MAXNUM)) { | ||
723 | pr_debug("PSC%x out of range\n", co->index); | ||
724 | return -EINVAL; | ||
725 | } | ||
726 | |||
727 | if (!np) { | ||
728 | pr_debug("PSC%x not found in device tree\n", co->index); | ||
729 | return -EINVAL; | ||
730 | } | ||
731 | |||
732 | pr_debug("Console on ttyPSC%x is %s\n", | ||
733 | co->index, mpc52xx_uart_nodes[co->index]->full_name); | ||
734 | |||
735 | /* Fetch register locations */ | ||
736 | if ((ret = of_address_to_resource(np, 0, &res)) != 0) { | ||
737 | pr_debug("Could not get resources for PSC%x\n", co->index); | ||
738 | return ret; | ||
739 | } | ||
740 | |||
741 | /* Search for bus-frequency property in this node or a parent */ | ||
742 | if ((ipb_freq = mpc52xx_find_ipb_freq(np)) == 0) { | ||
743 | pr_debug("Could not find IPB bus frequency!\n"); | ||
744 | return -EINVAL; | ||
745 | } | ||
746 | |||
747 | /* Basic port init. Needed since we use some uart_??? func before | ||
748 | * real init for early access */ | ||
749 | spin_lock_init(&port->lock); | ||
750 | port->uartclk = ipb_freq / 2; | ||
751 | port->ops = &mpc52xx_uart_ops; | ||
752 | port->mapbase = res.start; | ||
753 | port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc)); | ||
754 | port->irq = irq_of_parse_and_map(np, 0); | ||
755 | |||
756 | if (port->membase == NULL) | ||
757 | return -EINVAL; | ||
758 | |||
759 | pr_debug("mpc52xx-psc uart at %lx, mapped to %p, irq=%x, freq=%i\n", | ||
760 | port->mapbase, port->membase, port->irq, port->uartclk); | ||
761 | |||
762 | /* Setup the port parameters accoding to options */ | ||
763 | if (options) | ||
764 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
765 | else | ||
766 | mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow); | ||
767 | |||
768 | pr_debug("Setting console parameters: %i %i%c1 flow=%c\n", | ||
769 | baud, bits, parity, flow); | ||
770 | |||
771 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
772 | } | ||
773 | #endif /* defined(CONFIG_PPC_MERGE) */ | ||
774 | |||
659 | 775 | ||
660 | static struct uart_driver mpc52xx_uart_driver; | 776 | static struct uart_driver mpc52xx_uart_driver; |
661 | 777 | ||
@@ -669,10 +785,11 @@ static struct console mpc52xx_console = { | |||
669 | .data = &mpc52xx_uart_driver, | 785 | .data = &mpc52xx_uart_driver, |
670 | }; | 786 | }; |
671 | 787 | ||
672 | 788 | ||
673 | static int __init | 789 | static int __init |
674 | mpc52xx_console_init(void) | 790 | mpc52xx_console_init(void) |
675 | { | 791 | { |
792 | mpc52xx_uart_of_enumerate(); | ||
676 | register_console(&mpc52xx_console); | 793 | register_console(&mpc52xx_console); |
677 | return 0; | 794 | return 0; |
678 | } | 795 | } |
@@ -700,6 +817,7 @@ static struct uart_driver mpc52xx_uart_driver = { | |||
700 | }; | 817 | }; |
701 | 818 | ||
702 | 819 | ||
820 | #if !defined(CONFIG_PPC_MERGE) | ||
703 | /* ======================================================================== */ | 821 | /* ======================================================================== */ |
704 | /* Platform Driver */ | 822 | /* Platform Driver */ |
705 | /* ======================================================================== */ | 823 | /* ======================================================================== */ |
@@ -723,8 +841,6 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
723 | /* Init the port structure */ | 841 | /* Init the port structure */ |
724 | port = &mpc52xx_uart_ports[idx]; | 842 | port = &mpc52xx_uart_ports[idx]; |
725 | 843 | ||
726 | memset(port, 0x00, sizeof(struct uart_port)); | ||
727 | |||
728 | spin_lock_init(&port->lock); | 844 | spin_lock_init(&port->lock); |
729 | port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */ | 845 | port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */ |
730 | port->fifosize = 512; | 846 | port->fifosize = 512; |
@@ -733,6 +849,7 @@ mpc52xx_uart_probe(struct platform_device *dev) | |||
733 | ( uart_console(port) ? 0 : UPF_IOREMAP ); | 849 | ( uart_console(port) ? 0 : UPF_IOREMAP ); |
734 | port->line = idx; | 850 | port->line = idx; |
735 | port->ops = &mpc52xx_uart_ops; | 851 | port->ops = &mpc52xx_uart_ops; |
852 | port->dev = &dev->dev; | ||
736 | 853 | ||
737 | /* Search for IRQ and mapbase */ | 854 | /* Search for IRQ and mapbase */ |
738 | for (i=0 ; i<dev->num_resources ; i++, res++) { | 855 | for (i=0 ; i<dev->num_resources ; i++, res++) { |
@@ -771,7 +888,7 @@ mpc52xx_uart_suspend(struct platform_device *dev, pm_message_t state) | |||
771 | { | 888 | { |
772 | struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev); | 889 | struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev); |
773 | 890 | ||
774 | if (sport) | 891 | if (port) |
775 | uart_suspend_port(&mpc52xx_uart_driver, port); | 892 | uart_suspend_port(&mpc52xx_uart_driver, port); |
776 | 893 | ||
777 | return 0; | 894 | return 0; |
@@ -789,6 +906,7 @@ mpc52xx_uart_resume(struct platform_device *dev) | |||
789 | } | 906 | } |
790 | #endif | 907 | #endif |
791 | 908 | ||
909 | |||
792 | static struct platform_driver mpc52xx_uart_platform_driver = { | 910 | static struct platform_driver mpc52xx_uart_platform_driver = { |
793 | .probe = mpc52xx_uart_probe, | 911 | .probe = mpc52xx_uart_probe, |
794 | .remove = mpc52xx_uart_remove, | 912 | .remove = mpc52xx_uart_remove, |
@@ -800,6 +918,184 @@ static struct platform_driver mpc52xx_uart_platform_driver = { | |||
800 | .name = "mpc52xx-psc", | 918 | .name = "mpc52xx-psc", |
801 | }, | 919 | }, |
802 | }; | 920 | }; |
921 | #endif /* !defined(CONFIG_PPC_MERGE) */ | ||
922 | |||
923 | |||
924 | #if defined(CONFIG_PPC_MERGE) | ||
925 | /* ======================================================================== */ | ||
926 | /* OF Platform Driver */ | ||
927 | /* ======================================================================== */ | ||
928 | |||
929 | static int __devinit | ||
930 | mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) | ||
931 | { | ||
932 | int idx = -1; | ||
933 | unsigned int ipb_freq; | ||
934 | struct uart_port *port = NULL; | ||
935 | struct resource res; | ||
936 | int ret; | ||
937 | |||
938 | dev_dbg(&op->dev, "mpc52xx_uart_probe(op=%p, match=%p)\n", op, match); | ||
939 | |||
940 | /* Check validity & presence */ | ||
941 | for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++) | ||
942 | if (mpc52xx_uart_nodes[idx] == op->node) | ||
943 | break; | ||
944 | if (idx >= MPC52xx_PSC_MAXNUM) | ||
945 | return -EINVAL; | ||
946 | pr_debug("Found %s assigned to ttyPSC%x\n", | ||
947 | mpc52xx_uart_nodes[idx]->full_name, idx); | ||
948 | |||
949 | /* Search for bus-frequency property in this node or a parent */ | ||
950 | if ((ipb_freq = mpc52xx_find_ipb_freq(op->node)) == 0) { | ||
951 | dev_dbg(&op->dev, "Could not find IPB bus frequency!\n"); | ||
952 | return -EINVAL; | ||
953 | } | ||
954 | |||
955 | /* Init the port structure */ | ||
956 | port = &mpc52xx_uart_ports[idx]; | ||
957 | |||
958 | spin_lock_init(&port->lock); | ||
959 | port->uartclk = ipb_freq / 2; | ||
960 | port->fifosize = 512; | ||
961 | port->iotype = UPIO_MEM; | ||
962 | port->flags = UPF_BOOT_AUTOCONF | | ||
963 | ( uart_console(port) ? 0 : UPF_IOREMAP ); | ||
964 | port->line = idx; | ||
965 | port->ops = &mpc52xx_uart_ops; | ||
966 | port->dev = &op->dev; | ||
967 | |||
968 | /* Search for IRQ and mapbase */ | ||
969 | if ((ret = of_address_to_resource(op->node, 0, &res)) != 0) | ||
970 | return ret; | ||
971 | |||
972 | port->mapbase = res.start; | ||
973 | port->irq = irq_of_parse_and_map(op->node, 0); | ||
974 | |||
975 | dev_dbg(&op->dev, "mpc52xx-psc uart at %lx, irq=%x, freq=%i\n", | ||
976 | port->mapbase, port->irq, port->uartclk); | ||
977 | |||
978 | if ((port->irq==NO_IRQ) || !port->mapbase) { | ||
979 | printk(KERN_ERR "Could not allocate resources for PSC\n"); | ||
980 | return -EINVAL; | ||
981 | } | ||
982 | |||
983 | /* Add the port to the uart sub-system */ | ||
984 | ret = uart_add_one_port(&mpc52xx_uart_driver, port); | ||
985 | if (!ret) | ||
986 | dev_set_drvdata(&op->dev, (void*)port); | ||
987 | |||
988 | return ret; | ||
989 | } | ||
990 | |||
991 | static int | ||
992 | mpc52xx_uart_of_remove(struct of_device *op) | ||
993 | { | ||
994 | struct uart_port *port = dev_get_drvdata(&op->dev); | ||
995 | dev_set_drvdata(&op->dev, NULL); | ||
996 | |||
997 | if (port) | ||
998 | uart_remove_one_port(&mpc52xx_uart_driver, port); | ||
999 | |||
1000 | return 0; | ||
1001 | } | ||
1002 | |||
1003 | #ifdef CONFIG_PM | ||
1004 | static int | ||
1005 | mpc52xx_uart_of_suspend(struct of_device *op, pm_message_t state) | ||
1006 | { | ||
1007 | struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev); | ||
1008 | |||
1009 | if (port) | ||
1010 | uart_suspend_port(&mpc52xx_uart_driver, port); | ||
1011 | |||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
1015 | static int | ||
1016 | mpc52xx_uart_of_resume(struct of_device *op) | ||
1017 | { | ||
1018 | struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev); | ||
1019 | |||
1020 | if (port) | ||
1021 | uart_resume_port(&mpc52xx_uart_driver, port); | ||
1022 | |||
1023 | return 0; | ||
1024 | } | ||
1025 | #endif | ||
1026 | |||
1027 | static void | ||
1028 | mpc52xx_uart_of_assign(struct device_node *np, int idx) | ||
1029 | { | ||
1030 | int free_idx = -1; | ||
1031 | int i; | ||
1032 | |||
1033 | /* Find the first free node */ | ||
1034 | for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { | ||
1035 | if (mpc52xx_uart_nodes[i] == NULL) { | ||
1036 | free_idx = i; | ||
1037 | break; | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1041 | if ((idx < 0) || (idx >= MPC52xx_PSC_MAXNUM)) | ||
1042 | idx = free_idx; | ||
1043 | |||
1044 | if (idx < 0) | ||
1045 | return; /* No free slot; abort */ | ||
1046 | |||
1047 | /* If the slot is already occupied, then swap slots */ | ||
1048 | if (mpc52xx_uart_nodes[idx] && (free_idx != -1)) | ||
1049 | mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx]; | ||
1050 | mpc52xx_uart_nodes[i] = np; | ||
1051 | } | ||
1052 | |||
1053 | static void | ||
1054 | mpc52xx_uart_of_enumerate(void) | ||
1055 | { | ||
1056 | static int enum_done = 0; | ||
1057 | struct device_node *np; | ||
1058 | const unsigned int *devno; | ||
1059 | int i; | ||
1060 | |||
1061 | if (enum_done) | ||
1062 | return; | ||
1063 | |||
1064 | for_each_node_by_type(np, "serial") { | ||
1065 | if (!of_match_node(mpc52xx_uart_of_match, np)) | ||
1066 | continue; | ||
1067 | |||
1068 | /* Is a particular device number requested? */ | ||
1069 | devno = get_property(np, "device_no", NULL); | ||
1070 | mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1); | ||
1071 | } | ||
1072 | |||
1073 | enum_done = 1; | ||
1074 | |||
1075 | for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { | ||
1076 | if (mpc52xx_uart_nodes[i]) | ||
1077 | pr_debug("%s assigned to ttyPSC%x\n", | ||
1078 | mpc52xx_uart_nodes[i]->full_name, i); | ||
1079 | } | ||
1080 | } | ||
1081 | |||
1082 | MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); | ||
1083 | |||
1084 | static struct of_platform_driver mpc52xx_uart_of_driver = { | ||
1085 | .owner = THIS_MODULE, | ||
1086 | .name = "mpc52xx-psc-uart", | ||
1087 | .match_table = mpc52xx_uart_of_match, | ||
1088 | .probe = mpc52xx_uart_of_probe, | ||
1089 | .remove = mpc52xx_uart_of_remove, | ||
1090 | #ifdef CONFIG_PM | ||
1091 | .suspend = mpc52xx_uart_of_suspend, | ||
1092 | .resume = mpc52xx_uart_of_resume, | ||
1093 | #endif | ||
1094 | .driver = { | ||
1095 | .name = "mpc52xx-psc-uart", | ||
1096 | }, | ||
1097 | }; | ||
1098 | #endif /* defined(CONFIG_PPC_MERGE) */ | ||
803 | 1099 | ||
804 | 1100 | ||
805 | /* ======================================================================== */ | 1101 | /* ======================================================================== */ |
@@ -811,22 +1107,45 @@ mpc52xx_uart_init(void) | |||
811 | { | 1107 | { |
812 | int ret; | 1108 | int ret; |
813 | 1109 | ||
814 | printk(KERN_INFO "Serial: MPC52xx PSC driver\n"); | 1110 | printk(KERN_INFO "Serial: MPC52xx PSC UART driver\n"); |
815 | 1111 | ||
816 | ret = uart_register_driver(&mpc52xx_uart_driver); | 1112 | if ((ret = uart_register_driver(&mpc52xx_uart_driver)) != 0) { |
817 | if (ret == 0) { | 1113 | printk(KERN_ERR "%s: uart_register_driver failed (%i)\n", |
818 | ret = platform_driver_register(&mpc52xx_uart_platform_driver); | 1114 | __FILE__, ret); |
819 | if (ret) | 1115 | return ret; |
820 | uart_unregister_driver(&mpc52xx_uart_driver); | ||
821 | } | 1116 | } |
822 | 1117 | ||
823 | return ret; | 1118 | #if defined(CONFIG_PPC_MERGE) |
1119 | mpc52xx_uart_of_enumerate(); | ||
1120 | |||
1121 | ret = of_register_platform_driver(&mpc52xx_uart_of_driver); | ||
1122 | if (ret) { | ||
1123 | printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n", | ||
1124 | __FILE__, ret); | ||
1125 | uart_unregister_driver(&mpc52xx_uart_driver); | ||
1126 | return ret; | ||
1127 | } | ||
1128 | #else | ||
1129 | ret = platform_driver_register(&mpc52xx_uart_platform_driver); | ||
1130 | if (ret) { | ||
1131 | printk(KERN_ERR "%s: platform_driver_register failed (%i)\n", | ||
1132 | __FILE__, ret); | ||
1133 | uart_unregister_driver(&mpc52xx_uart_driver); | ||
1134 | return ret; | ||
1135 | } | ||
1136 | #endif | ||
1137 | |||
1138 | return 0; | ||
824 | } | 1139 | } |
825 | 1140 | ||
826 | static void __exit | 1141 | static void __exit |
827 | mpc52xx_uart_exit(void) | 1142 | mpc52xx_uart_exit(void) |
828 | { | 1143 | { |
1144 | #if defined(CONFIG_PPC_MERGE) | ||
1145 | of_unregister_platform_driver(&mpc52xx_uart_of_driver); | ||
1146 | #else | ||
829 | platform_driver_unregister(&mpc52xx_uart_platform_driver); | 1147 | platform_driver_unregister(&mpc52xx_uart_platform_driver); |
1148 | #endif | ||
830 | uart_unregister_driver(&mpc52xx_uart_driver); | 1149 | uart_unregister_driver(&mpc52xx_uart_driver); |
831 | } | 1150 | } |
832 | 1151 | ||
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 00f9ffd69489..431433f4dd6d 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -723,7 +723,7 @@ static int serial_config(struct pcmcia_device * link) | |||
723 | u_char *buf; | 723 | u_char *buf; |
724 | cisparse_t *parse; | 724 | cisparse_t *parse; |
725 | cistpl_cftable_entry_t *cf; | 725 | cistpl_cftable_entry_t *cf; |
726 | int i, last_ret, last_fn; | 726 | int i; |
727 | 727 | ||
728 | DEBUG(0, "serial_config(0x%p)\n", link); | 728 | DEBUG(0, "serial_config(0x%p)\n", link); |
729 | 729 | ||
@@ -740,15 +740,6 @@ static int serial_config(struct pcmcia_device * link) | |||
740 | tuple->TupleOffset = 0; | 740 | tuple->TupleOffset = 0; |
741 | tuple->TupleDataMax = 255; | 741 | tuple->TupleDataMax = 255; |
742 | tuple->Attributes = 0; | 742 | tuple->Attributes = 0; |
743 | /* Get configuration register information */ | ||
744 | tuple->DesiredTuple = CISTPL_CONFIG; | ||
745 | last_ret = first_tuple(link, tuple, parse); | ||
746 | if (last_ret != CS_SUCCESS) { | ||
747 | last_fn = ParseTuple; | ||
748 | goto cs_failed; | ||
749 | } | ||
750 | link->conf.ConfigBase = parse->config.base; | ||
751 | link->conf.Present = parse->config.rmask[0]; | ||
752 | 743 | ||
753 | /* Is this a compliant multifunction card? */ | 744 | /* Is this a compliant multifunction card? */ |
754 | tuple->DesiredTuple = CISTPL_LONGLINK_MFC; | 745 | tuple->DesiredTuple = CISTPL_LONGLINK_MFC; |
@@ -757,27 +748,25 @@ static int serial_config(struct pcmcia_device * link) | |||
757 | 748 | ||
758 | /* Is this a multiport card? */ | 749 | /* Is this a multiport card? */ |
759 | tuple->DesiredTuple = CISTPL_MANFID; | 750 | tuple->DesiredTuple = CISTPL_MANFID; |
760 | if (first_tuple(link, tuple, parse) == CS_SUCCESS) { | 751 | info->manfid = link->manf_id; |
761 | info->manfid = parse->manfid.manf; | 752 | info->prodid = link->card_id; |
762 | info->prodid = parse->manfid.card; | 753 | |
763 | 754 | for (i = 0; i < ARRAY_SIZE(quirks); i++) | |
764 | for (i = 0; i < ARRAY_SIZE(quirks); i++) | 755 | if ((quirks[i].manfid == ~0 || |
765 | if ((quirks[i].manfid == ~0 || | 756 | quirks[i].manfid == info->manfid) && |
766 | quirks[i].manfid == info->manfid) && | 757 | (quirks[i].prodid == ~0 || |
767 | (quirks[i].prodid == ~0 || | 758 | quirks[i].prodid == info->prodid)) { |
768 | quirks[i].prodid == info->prodid)) { | 759 | info->quirk = &quirks[i]; |
769 | info->quirk = &quirks[i]; | 760 | break; |
770 | break; | 761 | } |
771 | } | ||
772 | } | ||
773 | 762 | ||
774 | /* Another check for dual-serial cards: look for either serial or | 763 | /* Another check for dual-serial cards: look for either serial or |
775 | multifunction cards that ask for appropriate IO port ranges */ | 764 | multifunction cards that ask for appropriate IO port ranges */ |
776 | tuple->DesiredTuple = CISTPL_FUNCID; | 765 | tuple->DesiredTuple = CISTPL_FUNCID; |
777 | if ((info->multi == 0) && | 766 | if ((info->multi == 0) && |
778 | ((first_tuple(link, tuple, parse) != CS_SUCCESS) || | 767 | (link->has_func_id) && |
779 | (parse->funcid.func == CISTPL_FUNCID_MULTI) || | 768 | ((link->func_id == CISTPL_FUNCID_MULTI) || |
780 | (parse->funcid.func == CISTPL_FUNCID_SERIAL))) { | 769 | (link->func_id == CISTPL_FUNCID_SERIAL))) { |
781 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; | 770 | tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; |
782 | if (first_tuple(link, tuple, parse) == CS_SUCCESS) { | 771 | if (first_tuple(link, tuple, parse) == CS_SUCCESS) { |
783 | if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) | 772 | if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) |
@@ -814,8 +803,6 @@ static int serial_config(struct pcmcia_device * link) | |||
814 | kfree(cfg_mem); | 803 | kfree(cfg_mem); |
815 | return 0; | 804 | return 0; |
816 | 805 | ||
817 | cs_failed: | ||
818 | cs_error(link, last_fn, last_ret); | ||
819 | failed: | 806 | failed: |
820 | serial_remove(link); | 807 | serial_remove(link); |
821 | kfree(cfg_mem); | 808 | kfree(cfg_mem); |
@@ -925,6 +912,30 @@ static struct pcmcia_device_id serial_ids[] = { | |||
925 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), | 912 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"), |
926 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"), | 913 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"), |
927 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), | 914 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "GLOBETROTTER.cis"), |
915 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100 1.00.",0x19ca78af,0xf964f42b), | ||
916 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83), | ||
917 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232 1.00.",0x19ca78af,0x69fb7490), | ||
918 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232",0x19ca78af,0xb6bc0235), | ||
919 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232",0x63f2e0bd,0xb9e175d3), | ||
920 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232-5",0x63f2e0bd,0xfce33442), | ||
921 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232",0x3beb8cf2,0x171e7190), | ||
922 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232-5",0x3beb8cf2,0x20da4262), | ||
923 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF428",0x3beb8cf2,0xea5dd57d), | ||
924 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF500",0x3beb8cf2,0xd77255fa), | ||
925 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: IC232",0x3beb8cf2,0x6a709903), | ||
926 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: SL232",0x3beb8cf2,0x18430676), | ||
927 | PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: XL232",0x3beb8cf2,0x6f933767), | ||
928 | PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7), | ||
929 | PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41), | ||
930 | PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029), | ||
931 | PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), | ||
932 | PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc), | ||
933 | PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7), | ||
934 | PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41), | ||
935 | PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029), | ||
936 | PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), | ||
937 | PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), | ||
938 | PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4), | ||
928 | /* too generic */ | 939 | /* too generic */ |
929 | /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ | 940 | /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ |
930 | /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */ | 941 | /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */ |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index cfcc3caf49d8..3b5f19ec2126 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -775,7 +775,7 @@ static int sci_notifier(struct notifier_block *self, | |||
775 | * | 775 | * |
776 | * Clean this up later.. | 776 | * Clean this up later.. |
777 | */ | 777 | */ |
778 | clk = clk_get("module_clk"); | 778 | clk = clk_get(NULL, "module_clk"); |
779 | port->uartclk = clk_get_rate(clk) * 16; | 779 | port->uartclk = clk_get_rate(clk) * 16; |
780 | clk_put(clk); | 780 | clk_put(clk); |
781 | } | 781 | } |
@@ -960,7 +960,7 @@ static void sci_set_termios(struct uart_port *port, struct termios *termios, | |||
960 | default: | 960 | default: |
961 | { | 961 | { |
962 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | 962 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) |
963 | struct clk *clk = clk_get("module_clk"); | 963 | struct clk *clk = clk_get(NULL, "module_clk"); |
964 | t = SCBRR_VALUE(baud, clk_get_rate(clk)); | 964 | t = SCBRR_VALUE(baud, clk_get_rate(clk)); |
965 | clk_put(clk); | 965 | clk_put(clk); |
966 | #else | 966 | #else |
@@ -1128,7 +1128,7 @@ static void __init sci_init_ports(void) | |||
1128 | * XXX: We should use a proper SCI/SCIF clock | 1128 | * XXX: We should use a proper SCI/SCIF clock |
1129 | */ | 1129 | */ |
1130 | { | 1130 | { |
1131 | struct clk *clk = clk_get("module_clk"); | 1131 | struct clk *clk = clk_get(NULL, "module_clk"); |
1132 | sci_ports[i].port.uartclk = clk_get_rate(clk) * 16; | 1132 | sci_ports[i].port.uartclk = clk_get_rate(clk) * 16; |
1133 | clk_put(clk); | 1133 | clk_put(clk); |
1134 | } | 1134 | } |
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 7ee992146ae9..e4557cc4f74b 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h | |||
@@ -133,6 +133,20 @@ | |||
133 | # define SCIF_ORER 0x0001 /* Overrun error bit */ | 133 | # define SCIF_ORER 0x0001 /* Overrun error bit */ |
134 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | 134 | # define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ |
135 | # define SCIF_ONLY | 135 | # define SCIF_ONLY |
136 | #elif defined(CONFIG_CPU_SUBTYPE_SH7206) | ||
137 | # define SCSPTR0 0xfffe8020 /* 16 bit SCIF */ | ||
138 | # define SCSPTR1 0xfffe8820 /* 16 bit SCIF */ | ||
139 | # define SCSPTR2 0xfffe9020 /* 16 bit SCIF */ | ||
140 | # define SCSPTR3 0xfffe9820 /* 16 bit SCIF */ | ||
141 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | ||
142 | # define SCIF_ONLY | ||
143 | #elif defined(CONFIG_CPU_SUBTYPE_SH7619) | ||
144 | # define SCSPTR0 0xf8400020 /* 16 bit SCIF */ | ||
145 | # define SCSPTR1 0xf8410020 /* 16 bit SCIF */ | ||
146 | # define SCSPTR2 0xf8420020 /* 16 bit SCIF */ | ||
147 | # define SCIF_ORER 0x0001 /* overrun error bit */ | ||
148 | # define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ | ||
149 | # define SCIF_ONLY | ||
136 | #else | 150 | #else |
137 | # error CPU subtype not defined | 151 | # error CPU subtype not defined |
138 | #endif | 152 | #endif |
@@ -365,6 +379,7 @@ SCIx_FNS(SCxSR, 0x08, 8, 0x10, 8, 0x08, 16, 0x10, 16, 0x04, 8) | |||
365 | SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) | 379 | SCIx_FNS(SCxRDR, 0x0a, 8, 0x14, 8, 0x0A, 8, 0x14, 8, 0x05, 8) |
366 | SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) | 380 | SCIF_FNS(SCFCR, 0x0c, 8, 0x18, 16) |
367 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) | 381 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) || defined(CONFIG_CPU_SUBTYPE_SH7780) |
382 | SCIF_FNS(SCFDR, 0x0e, 16, 0x1C, 16) | ||
368 | SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) | 383 | SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) |
369 | SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) | 384 | SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) |
370 | SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) | 385 | SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) |
@@ -544,6 +559,28 @@ static inline int sci_rxd_in(struct uart_port *port) | |||
544 | if (port->mapbase == 0xffe10000) | 559 | if (port->mapbase == 0xffe10000) |
545 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | 560 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ |
546 | } | 561 | } |
562 | #elif defined(CONFIG_CPU_SUBTYPE_SH7206) | ||
563 | static inline int sci_rxd_in(struct uart_port *port) | ||
564 | { | ||
565 | if (port->mapbase == 0xfffe8000) | ||
566 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
567 | if (port->mapbase == 0xfffe8800) | ||
568 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
569 | if (port->mapbase == 0xfffe9000) | ||
570 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
571 | if (port->mapbase == 0xfffe9800) | ||
572 | return ctrl_inw(SCSPTR3) & 0x0001 ? 1 : 0; /* SCIF */ | ||
573 | } | ||
574 | #elif defined(CONFIG_CPU_SUBTYPE_SH7619) | ||
575 | static inline int sci_rxd_in(struct uart_port *port) | ||
576 | { | ||
577 | if (port->mapbase == 0xf8400000) | ||
578 | return ctrl_inw(SCSPTR0) & 0x0001 ? 1 : 0; /* SCIF */ | ||
579 | if (port->mapbase == 0xf8410000) | ||
580 | return ctrl_inw(SCSPTR1) & 0x0001 ? 1 : 0; /* SCIF */ | ||
581 | if (port->mapbase == 0xf8420000) | ||
582 | return ctrl_inw(SCSPTR2) & 0x0001 ? 1 : 0; /* SCIF */ | ||
583 | } | ||
547 | #endif | 584 | #endif |
548 | 585 | ||
549 | /* | 586 | /* |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 72025df5561d..494d9b856488 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -148,7 +148,7 @@ struct chip_data { | |||
148 | void (*cs_control)(u32 command); | 148 | void (*cs_control)(u32 command); |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static void pump_messages(void *data); | 151 | static void pump_messages(struct work_struct *work); |
152 | 152 | ||
153 | static int flush(struct driver_data *drv_data) | 153 | static int flush(struct driver_data *drv_data) |
154 | { | 154 | { |
@@ -884,9 +884,10 @@ static void pump_transfers(unsigned long data) | |||
884 | } | 884 | } |
885 | } | 885 | } |
886 | 886 | ||
887 | static void pump_messages(void *data) | 887 | static void pump_messages(struct work_struct *work) |
888 | { | 888 | { |
889 | struct driver_data *drv_data = data; | 889 | struct driver_data *drv_data = |
890 | container_of(work, struct driver_data, pump_messages); | ||
890 | unsigned long flags; | 891 | unsigned long flags; |
891 | 892 | ||
892 | /* Lock queue and check for queue work */ | 893 | /* Lock queue and check for queue work */ |
@@ -1098,7 +1099,7 @@ static int init_queue(struct driver_data *drv_data) | |||
1098 | tasklet_init(&drv_data->pump_transfers, | 1099 | tasklet_init(&drv_data->pump_transfers, |
1099 | pump_transfers, (unsigned long)drv_data); | 1100 | pump_transfers, (unsigned long)drv_data); |
1100 | 1101 | ||
1101 | INIT_WORK(&drv_data->pump_messages, pump_messages, drv_data); | 1102 | INIT_WORK(&drv_data->pump_messages, pump_messages); |
1102 | drv_data->workqueue = create_singlethread_workqueue( | 1103 | drv_data->workqueue = create_singlethread_workqueue( |
1103 | drv_data->master->cdev.dev->bus_id); | 1104 | drv_data->master->cdev.dev->bus_id); |
1104 | if (drv_data->workqueue == NULL) | 1105 | if (drv_data->workqueue == NULL) |
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index a23862ef72b2..08c1c57c6128 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c | |||
@@ -265,9 +265,10 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
265 | * Drivers can provide word-at-a-time i/o primitives, or provide | 265 | * Drivers can provide word-at-a-time i/o primitives, or provide |
266 | * transfer-at-a-time ones to leverage dma or fifo hardware. | 266 | * transfer-at-a-time ones to leverage dma or fifo hardware. |
267 | */ | 267 | */ |
268 | static void bitbang_work(void *_bitbang) | 268 | static void bitbang_work(struct work_struct *work) |
269 | { | 269 | { |
270 | struct spi_bitbang *bitbang = _bitbang; | 270 | struct spi_bitbang *bitbang = |
271 | container_of(work, struct spi_bitbang, work); | ||
271 | unsigned long flags; | 272 | unsigned long flags; |
272 | 273 | ||
273 | spin_lock_irqsave(&bitbang->lock, flags); | 274 | spin_lock_irqsave(&bitbang->lock, flags); |
@@ -456,7 +457,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) | |||
456 | if (!bitbang->master || !bitbang->chipselect) | 457 | if (!bitbang->master || !bitbang->chipselect) |
457 | return -EINVAL; | 458 | return -EINVAL; |
458 | 459 | ||
459 | INIT_WORK(&bitbang->work, bitbang_work, bitbang); | 460 | INIT_WORK(&bitbang->work, bitbang_work); |
460 | spin_lock_init(&bitbang->lock); | 461 | spin_lock_init(&bitbang->lock); |
461 | INIT_LIST_HEAD(&bitbang->queue); | 462 | INIT_LIST_HEAD(&bitbang->queue); |
462 | 463 | ||
diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index dda0ca45d904..164a5dcf1f1e 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c | |||
@@ -69,25 +69,21 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | |||
69 | 69 | ||
70 | static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) | 70 | static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) |
71 | { | 71 | { |
72 | tuple_t tuple; | ||
73 | u_short buf[128]; | ||
74 | char *str; | 72 | char *str; |
75 | int last_ret, last_fn, i, place; | 73 | int i, place; |
76 | DEBUG(0, "ixj_get_serial(0x%p)\n", link); | 74 | DEBUG(0, "ixj_get_serial(0x%p)\n", link); |
77 | tuple.TupleData = (cisdata_t *) buf; | 75 | |
78 | tuple.TupleOffset = 0; | 76 | str = link->prod_id[0]; |
79 | tuple.TupleDataMax = 80; | 77 | if (!str) |
80 | tuple.Attributes = 0; | 78 | goto cs_failed; |
81 | tuple.DesiredTuple = CISTPL_VERS_1; | ||
82 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
83 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
84 | str = (char *) buf; | ||
85 | printk("PCMCIA Version %d.%d\n", str[0], str[1]); | ||
86 | str += 2; | ||
87 | printk("%s", str); | 79 | printk("%s", str); |
88 | str = str + strlen(str) + 1; | 80 | str = link->prod_id[1]; |
81 | if (!str) | ||
82 | goto cs_failed; | ||
89 | printk(" %s", str); | 83 | printk(" %s", str); |
90 | str = str + strlen(str) + 1; | 84 | str = link->prod_id[2]; |
85 | if (!str) | ||
86 | goto cs_failed; | ||
91 | place = 1; | 87 | place = 1; |
92 | for (i = strlen(str) - 1; i >= 0; i--) { | 88 | for (i = strlen(str) - 1; i >= 0; i--) { |
93 | switch (str[i]) { | 89 | switch (str[i]) { |
@@ -122,7 +118,9 @@ static void ixj_get_serial(struct pcmcia_device * link, IXJ * j) | |||
122 | } | 118 | } |
123 | place = place * 0x10; | 119 | place = place * 0x10; |
124 | } | 120 | } |
125 | str = str + strlen(str) + 1; | 121 | str = link->prod_id[3]; |
122 | if (!str) | ||
123 | goto cs_failed; | ||
126 | printk(" version %s\n", str); | 124 | printk(" version %s\n", str); |
127 | cs_failed: | 125 | cs_failed: |
128 | return; | 126 | return; |
@@ -146,13 +144,6 @@ static int ixj_config(struct pcmcia_device * link) | |||
146 | tuple.TupleData = (cisdata_t *) buf; | 144 | tuple.TupleData = (cisdata_t *) buf; |
147 | tuple.TupleOffset = 0; | 145 | tuple.TupleOffset = 0; |
148 | tuple.TupleDataMax = 255; | 146 | tuple.TupleDataMax = 255; |
149 | tuple.Attributes = 0; | ||
150 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
151 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
152 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
153 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
154 | link->conf.ConfigBase = parse.config.base; | ||
155 | link->conf.Present = parse.config.rmask[0]; | ||
156 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 147 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
157 | tuple.Attributes = 0; | 148 | tuple.Attributes = 0; |
158 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 149 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index e6565633ba0f..3dfa3e40e148 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -158,7 +158,7 @@ struct cxacru_data { | |||
158 | const struct cxacru_modem_type *modem_type; | 158 | const struct cxacru_modem_type *modem_type; |
159 | 159 | ||
160 | int line_status; | 160 | int line_status; |
161 | struct work_struct poll_work; | 161 | struct delayed_work poll_work; |
162 | 162 | ||
163 | /* contol handles */ | 163 | /* contol handles */ |
164 | struct mutex cm_serialize; | 164 | struct mutex cm_serialize; |
@@ -347,7 +347,7 @@ static int cxacru_card_status(struct cxacru_data *instance) | |||
347 | return 0; | 347 | return 0; |
348 | } | 348 | } |
349 | 349 | ||
350 | static void cxacru_poll_status(struct cxacru_data *instance); | 350 | static void cxacru_poll_status(struct work_struct *work); |
351 | 351 | ||
352 | static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | 352 | static int cxacru_atm_start(struct usbatm_data *usbatm_instance, |
353 | struct atm_dev *atm_dev) | 353 | struct atm_dev *atm_dev) |
@@ -376,12 +376,14 @@ static int cxacru_atm_start(struct usbatm_data *usbatm_instance, | |||
376 | } | 376 | } |
377 | 377 | ||
378 | /* Start status polling */ | 378 | /* Start status polling */ |
379 | cxacru_poll_status(instance); | 379 | cxacru_poll_status(&instance->poll_work.work); |
380 | return 0; | 380 | return 0; |
381 | } | 381 | } |
382 | 382 | ||
383 | static void cxacru_poll_status(struct cxacru_data *instance) | 383 | static void cxacru_poll_status(struct work_struct *work) |
384 | { | 384 | { |
385 | struct cxacru_data *instance = | ||
386 | container_of(work, struct cxacru_data, poll_work.work); | ||
385 | u32 buf[CXINF_MAX] = {}; | 387 | u32 buf[CXINF_MAX] = {}; |
386 | struct usbatm_data *usbatm = instance->usbatm; | 388 | struct usbatm_data *usbatm = instance->usbatm; |
387 | struct atm_dev *atm_dev = usbatm->atm_dev; | 389 | struct atm_dev *atm_dev = usbatm->atm_dev; |
@@ -720,7 +722,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, | |||
720 | 722 | ||
721 | mutex_init(&instance->cm_serialize); | 723 | mutex_init(&instance->cm_serialize); |
722 | 724 | ||
723 | INIT_WORK(&instance->poll_work, (void *)cxacru_poll_status, instance); | 725 | INIT_DELAYED_WORK(&instance->poll_work, cxacru_poll_status); |
724 | 726 | ||
725 | usbatm_instance->driver_data = instance; | 727 | usbatm_instance->driver_data = instance; |
726 | 728 | ||
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index a823486495c3..8ed6c75adf0f 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -142,7 +142,7 @@ struct speedtch_instance_data { | |||
142 | 142 | ||
143 | struct speedtch_params params; /* set in probe, constant afterwards */ | 143 | struct speedtch_params params; /* set in probe, constant afterwards */ |
144 | 144 | ||
145 | struct work_struct status_checker; | 145 | struct delayed_work status_checker; |
146 | 146 | ||
147 | unsigned char last_status; | 147 | unsigned char last_status; |
148 | 148 | ||
@@ -498,8 +498,11 @@ static int speedtch_start_synchro(struct speedtch_instance_data *instance) | |||
498 | return ret; | 498 | return ret; |
499 | } | 499 | } |
500 | 500 | ||
501 | static void speedtch_check_status(struct speedtch_instance_data *instance) | 501 | static void speedtch_check_status(struct work_struct *work) |
502 | { | 502 | { |
503 | struct speedtch_instance_data *instance = | ||
504 | container_of(work, struct speedtch_instance_data, | ||
505 | status_checker.work); | ||
503 | struct usbatm_data *usbatm = instance->usbatm; | 506 | struct usbatm_data *usbatm = instance->usbatm; |
504 | struct atm_dev *atm_dev = usbatm->atm_dev; | 507 | struct atm_dev *atm_dev = usbatm->atm_dev; |
505 | unsigned char *buf = instance->scratch_buffer; | 508 | unsigned char *buf = instance->scratch_buffer; |
@@ -576,7 +579,7 @@ static void speedtch_status_poll(unsigned long data) | |||
576 | { | 579 | { |
577 | struct speedtch_instance_data *instance = (void *)data; | 580 | struct speedtch_instance_data *instance = (void *)data; |
578 | 581 | ||
579 | schedule_work(&instance->status_checker); | 582 | schedule_delayed_work(&instance->status_checker, 0); |
580 | 583 | ||
581 | /* The following check is racy, but the race is harmless */ | 584 | /* The following check is racy, but the race is harmless */ |
582 | if (instance->poll_delay < MAX_POLL_DELAY) | 585 | if (instance->poll_delay < MAX_POLL_DELAY) |
@@ -596,7 +599,7 @@ static void speedtch_resubmit_int(unsigned long data) | |||
596 | if (int_urb) { | 599 | if (int_urb) { |
597 | ret = usb_submit_urb(int_urb, GFP_ATOMIC); | 600 | ret = usb_submit_urb(int_urb, GFP_ATOMIC); |
598 | if (!ret) | 601 | if (!ret) |
599 | schedule_work(&instance->status_checker); | 602 | schedule_delayed_work(&instance->status_checker, 0); |
600 | else { | 603 | else { |
601 | atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); | 604 | atm_dbg(instance->usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); |
602 | mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); | 605 | mod_timer(&instance->resubmit_timer, jiffies + msecs_to_jiffies(RESUBMIT_DELAY)); |
@@ -640,7 +643,7 @@ static void speedtch_handle_int(struct urb *int_urb) | |||
640 | 643 | ||
641 | if ((int_urb = instance->int_urb)) { | 644 | if ((int_urb = instance->int_urb)) { |
642 | ret = usb_submit_urb(int_urb, GFP_ATOMIC); | 645 | ret = usb_submit_urb(int_urb, GFP_ATOMIC); |
643 | schedule_work(&instance->status_checker); | 646 | schedule_delayed_work(&instance->status_checker, 0); |
644 | if (ret < 0) { | 647 | if (ret < 0) { |
645 | atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); | 648 | atm_dbg(usbatm, "%s: usb_submit_urb failed with result %d\n", __func__, ret); |
646 | goto fail; | 649 | goto fail; |
@@ -855,7 +858,7 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
855 | 858 | ||
856 | usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); | 859 | usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0); |
857 | 860 | ||
858 | INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); | 861 | INIT_DELAYED_WORK(&instance->status_checker, speedtch_check_status); |
859 | 862 | ||
860 | instance->status_checker.timer.function = speedtch_status_poll; | 863 | instance->status_checker.timer.function = speedtch_status_poll; |
861 | instance->status_checker.timer.data = (unsigned long)instance; | 864 | instance->status_checker.timer.data = (unsigned long)instance; |
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index c137c041f7a4..f2d196fa1e8b 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -655,9 +655,9 @@ static int request_dsp(struct uea_softc *sc) | |||
655 | /* | 655 | /* |
656 | * The uea_load_page() function must be called within a process context | 656 | * The uea_load_page() function must be called within a process context |
657 | */ | 657 | */ |
658 | static void uea_load_page(void *xsc) | 658 | static void uea_load_page(struct work_struct *work) |
659 | { | 659 | { |
660 | struct uea_softc *sc = xsc; | 660 | struct uea_softc *sc = container_of(work, struct uea_softc, task); |
661 | u16 pageno = sc->pageno; | 661 | u16 pageno = sc->pageno; |
662 | u16 ovl = sc->ovl; | 662 | u16 ovl = sc->ovl; |
663 | struct block_info bi; | 663 | struct block_info bi; |
@@ -1348,7 +1348,7 @@ static int uea_boot(struct uea_softc *sc) | |||
1348 | 1348 | ||
1349 | uea_enters(INS_TO_USBDEV(sc)); | 1349 | uea_enters(INS_TO_USBDEV(sc)); |
1350 | 1350 | ||
1351 | INIT_WORK(&sc->task, uea_load_page, sc); | 1351 | INIT_WORK(&sc->task, uea_load_page); |
1352 | init_waitqueue_head(&sc->sync_q); | 1352 | init_waitqueue_head(&sc->sync_q); |
1353 | init_waitqueue_head(&sc->cmv_ack_wait); | 1353 | init_waitqueue_head(&sc->cmv_ack_wait); |
1354 | 1354 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index ec3438dc8ee5..7f1fa956dcdb 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -421,9 +421,9 @@ static void acm_write_bulk(struct urb *urb) | |||
421 | schedule_work(&acm->work); | 421 | schedule_work(&acm->work); |
422 | } | 422 | } |
423 | 423 | ||
424 | static void acm_softint(void *private) | 424 | static void acm_softint(struct work_struct *work) |
425 | { | 425 | { |
426 | struct acm *acm = private; | 426 | struct acm *acm = container_of(work, struct acm, work); |
427 | dbg("Entering acm_softint."); | 427 | dbg("Entering acm_softint."); |
428 | 428 | ||
429 | if (!ACM_READY(acm)) | 429 | if (!ACM_READY(acm)) |
@@ -927,7 +927,7 @@ skip_normal_probe: | |||
927 | acm->rx_buflimit = num_rx_buf; | 927 | acm->rx_buflimit = num_rx_buf; |
928 | acm->urb_task.func = acm_rx_tasklet; | 928 | acm->urb_task.func = acm_rx_tasklet; |
929 | acm->urb_task.data = (unsigned long) acm; | 929 | acm->urb_task.data = (unsigned long) acm; |
930 | INIT_WORK(&acm->work, acm_softint, acm); | 930 | INIT_WORK(&acm->work, acm_softint); |
931 | spin_lock_init(&acm->throttle_lock); | 931 | spin_lock_init(&acm->throttle_lock); |
932 | spin_lock_init(&acm->write_lock); | 932 | spin_lock_init(&acm->write_lock); |
933 | spin_lock_init(&acm->read_lock); | 933 | spin_lock_init(&acm->read_lock); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 0ce393eb3c4b..9be41ed1f9a6 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -68,7 +68,7 @@ struct usb_hub { | |||
68 | 68 | ||
69 | unsigned has_indicators:1; | 69 | unsigned has_indicators:1; |
70 | u8 indicator[USB_MAXCHILDREN]; | 70 | u8 indicator[USB_MAXCHILDREN]; |
71 | struct work_struct leds; | 71 | struct delayed_work leds; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | 74 | ||
@@ -218,9 +218,10 @@ static void set_port_led( | |||
218 | 218 | ||
219 | #define LED_CYCLE_PERIOD ((2*HZ)/3) | 219 | #define LED_CYCLE_PERIOD ((2*HZ)/3) |
220 | 220 | ||
221 | static void led_work (void *__hub) | 221 | static void led_work (struct work_struct *work) |
222 | { | 222 | { |
223 | struct usb_hub *hub = __hub; | 223 | struct usb_hub *hub = |
224 | container_of(work, struct usb_hub, leds.work); | ||
224 | struct usb_device *hdev = hub->hdev; | 225 | struct usb_device *hdev = hub->hdev; |
225 | unsigned i; | 226 | unsigned i; |
226 | unsigned changed = 0; | 227 | unsigned changed = 0; |
@@ -405,9 +406,10 @@ hub_clear_tt_buffer (struct usb_device *hdev, u16 devinfo, u16 tt) | |||
405 | * talking to TTs must queue control transfers (not just bulk and iso), so | 406 | * talking to TTs must queue control transfers (not just bulk and iso), so |
406 | * both can talk to the same hub concurrently. | 407 | * both can talk to the same hub concurrently. |
407 | */ | 408 | */ |
408 | static void hub_tt_kevent (void *arg) | 409 | static void hub_tt_kevent (struct work_struct *work) |
409 | { | 410 | { |
410 | struct usb_hub *hub = arg; | 411 | struct usb_hub *hub = |
412 | container_of(work, struct usb_hub, tt.kevent); | ||
411 | unsigned long flags; | 413 | unsigned long flags; |
412 | 414 | ||
413 | spin_lock_irqsave (&hub->tt.lock, flags); | 415 | spin_lock_irqsave (&hub->tt.lock, flags); |
@@ -694,7 +696,7 @@ static int hub_configure(struct usb_hub *hub, | |||
694 | 696 | ||
695 | spin_lock_init (&hub->tt.lock); | 697 | spin_lock_init (&hub->tt.lock); |
696 | INIT_LIST_HEAD (&hub->tt.clear_list); | 698 | INIT_LIST_HEAD (&hub->tt.clear_list); |
697 | INIT_WORK (&hub->tt.kevent, hub_tt_kevent, hub); | 699 | INIT_WORK (&hub->tt.kevent, hub_tt_kevent); |
698 | switch (hdev->descriptor.bDeviceProtocol) { | 700 | switch (hdev->descriptor.bDeviceProtocol) { |
699 | case 0: | 701 | case 0: |
700 | break; | 702 | break; |
@@ -938,7 +940,7 @@ descriptor_error: | |||
938 | INIT_LIST_HEAD(&hub->event_list); | 940 | INIT_LIST_HEAD(&hub->event_list); |
939 | hub->intfdev = &intf->dev; | 941 | hub->intfdev = &intf->dev; |
940 | hub->hdev = hdev; | 942 | hub->hdev = hdev; |
941 | INIT_WORK(&hub->leds, led_work, hub); | 943 | INIT_DELAYED_WORK(&hub->leds, led_work); |
942 | 944 | ||
943 | usb_set_intfdata (intf, hub); | 945 | usb_set_intfdata (intf, hub); |
944 | intf->needs_remote_wakeup = 1; | 946 | intf->needs_remote_wakeup = 1; |
@@ -2381,7 +2383,7 @@ check_highspeed (struct usb_hub *hub, struct usb_device *udev, int port1) | |||
2381 | /* hub LEDs are probably harder to miss than syslog */ | 2383 | /* hub LEDs are probably harder to miss than syslog */ |
2382 | if (hub->has_indicators) { | 2384 | if (hub->has_indicators) { |
2383 | hub->indicator[port1-1] = INDICATOR_GREEN_BLINK; | 2385 | hub->indicator[port1-1] = INDICATOR_GREEN_BLINK; |
2384 | schedule_work (&hub->leds); | 2386 | schedule_delayed_work (&hub->leds, 0); |
2385 | } | 2387 | } |
2386 | } | 2388 | } |
2387 | kfree(qual); | 2389 | kfree(qual); |
@@ -2555,7 +2557,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, | |||
2555 | if (hub->has_indicators) { | 2557 | if (hub->has_indicators) { |
2556 | hub->indicator[port1-1] = | 2558 | hub->indicator[port1-1] = |
2557 | INDICATOR_AMBER_BLINK; | 2559 | INDICATOR_AMBER_BLINK; |
2558 | schedule_work (&hub->leds); | 2560 | schedule_delayed_work (&hub->leds, 0); |
2559 | } | 2561 | } |
2560 | status = -ENOTCONN; /* Don't retry */ | 2562 | status = -ENOTCONN; /* Don't retry */ |
2561 | goto loop_disable; | 2563 | goto loop_disable; |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 29b0fa9ff9d0..7390b67c609d 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1501,9 +1501,10 @@ struct set_config_request { | |||
1501 | }; | 1501 | }; |
1502 | 1502 | ||
1503 | /* Worker routine for usb_driver_set_configuration() */ | 1503 | /* Worker routine for usb_driver_set_configuration() */ |
1504 | static void driver_set_config_work(void *_req) | 1504 | static void driver_set_config_work(struct work_struct *work) |
1505 | { | 1505 | { |
1506 | struct set_config_request *req = _req; | 1506 | struct set_config_request *req = |
1507 | container_of(work, struct set_config_request, work); | ||
1507 | 1508 | ||
1508 | usb_lock_device(req->udev); | 1509 | usb_lock_device(req->udev); |
1509 | usb_set_configuration(req->udev, req->config); | 1510 | usb_set_configuration(req->udev, req->config); |
@@ -1541,7 +1542,7 @@ int usb_driver_set_configuration(struct usb_device *udev, int config) | |||
1541 | return -ENOMEM; | 1542 | return -ENOMEM; |
1542 | req->udev = udev; | 1543 | req->udev = udev; |
1543 | req->config = config; | 1544 | req->config = config; |
1544 | INIT_WORK(&req->work, driver_set_config_work, req); | 1545 | INIT_WORK(&req->work, driver_set_config_work); |
1545 | 1546 | ||
1546 | usb_get_dev(udev); | 1547 | usb_get_dev(udev); |
1547 | if (!schedule_work(&req->work)) { | 1548 | if (!schedule_work(&req->work)) { |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 81cb52564e68..02426d0b9a34 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -203,9 +203,10 @@ static void ksuspend_usb_cleanup(void) | |||
203 | #ifdef CONFIG_USB_SUSPEND | 203 | #ifdef CONFIG_USB_SUSPEND |
204 | 204 | ||
205 | /* usb_autosuspend_work - callback routine to autosuspend a USB device */ | 205 | /* usb_autosuspend_work - callback routine to autosuspend a USB device */ |
206 | static void usb_autosuspend_work(void *_udev) | 206 | static void usb_autosuspend_work(struct work_struct *work) |
207 | { | 207 | { |
208 | struct usb_device *udev = _udev; | 208 | struct usb_device *udev = |
209 | container_of(work, struct usb_device, autosuspend.work); | ||
209 | 210 | ||
210 | usb_pm_lock(udev); | 211 | usb_pm_lock(udev); |
211 | udev->auto_pm = 1; | 212 | udev->auto_pm = 1; |
@@ -215,7 +216,7 @@ static void usb_autosuspend_work(void *_udev) | |||
215 | 216 | ||
216 | #else | 217 | #else |
217 | 218 | ||
218 | static void usb_autosuspend_work(void *_udev) | 219 | static void usb_autosuspend_work(struct work_struct *work) |
219 | {} | 220 | {} |
220 | 221 | ||
221 | #endif /* CONFIG_USB_SUSPEND */ | 222 | #endif /* CONFIG_USB_SUSPEND */ |
@@ -304,7 +305,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
304 | 305 | ||
305 | #ifdef CONFIG_PM | 306 | #ifdef CONFIG_PM |
306 | mutex_init(&dev->pm_mutex); | 307 | mutex_init(&dev->pm_mutex); |
307 | INIT_WORK(&dev->autosuspend, usb_autosuspend_work, dev); | 308 | INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); |
308 | #endif | 309 | #endif |
309 | return dev; | 310 | return dev; |
310 | } | 311 | } |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 3bd1dfe565c1..d15bf22b9a03 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -1833,9 +1833,9 @@ static void rx_fill (struct eth_dev *dev, gfp_t gfp_flags) | |||
1833 | spin_unlock_irqrestore(&dev->req_lock, flags); | 1833 | spin_unlock_irqrestore(&dev->req_lock, flags); |
1834 | } | 1834 | } |
1835 | 1835 | ||
1836 | static void eth_work (void *_dev) | 1836 | static void eth_work (struct work_struct *work) |
1837 | { | 1837 | { |
1838 | struct eth_dev *dev = _dev; | 1838 | struct eth_dev *dev = container_of(work, struct eth_dev, work); |
1839 | 1839 | ||
1840 | if (test_and_clear_bit (WORK_RX_MEMORY, &dev->todo)) { | 1840 | if (test_and_clear_bit (WORK_RX_MEMORY, &dev->todo)) { |
1841 | if (netif_running (dev->net)) | 1841 | if (netif_running (dev->net)) |
@@ -2398,7 +2398,7 @@ autoconf_fail: | |||
2398 | dev = netdev_priv(net); | 2398 | dev = netdev_priv(net); |
2399 | spin_lock_init (&dev->lock); | 2399 | spin_lock_init (&dev->lock); |
2400 | spin_lock_init (&dev->req_lock); | 2400 | spin_lock_init (&dev->req_lock); |
2401 | INIT_WORK (&dev->work, eth_work, dev); | 2401 | INIT_WORK (&dev->work, eth_work); |
2402 | INIT_LIST_HEAD (&dev->tx_reqs); | 2402 | INIT_LIST_HEAD (&dev->tx_reqs); |
2403 | INIT_LIST_HEAD (&dev->rx_reqs); | 2403 | INIT_LIST_HEAD (&dev->rx_reqs); |
2404 | 2404 | ||
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 54f554e0f0ad..ac9f11d19817 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -169,21 +169,14 @@ static int sl811_cs_config(struct pcmcia_device *link) | |||
169 | 169 | ||
170 | DBG(0, "sl811_cs_config(0x%p)\n", link); | 170 | DBG(0, "sl811_cs_config(0x%p)\n", link); |
171 | 171 | ||
172 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
173 | tuple.Attributes = 0; | ||
174 | tuple.TupleData = buf; | ||
175 | tuple.TupleDataMax = sizeof(buf); | ||
176 | tuple.TupleOffset = 0; | ||
177 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | ||
178 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); | ||
179 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); | ||
180 | link->conf.ConfigBase = parse.config.base; | ||
181 | link->conf.Present = parse.config.rmask[0]; | ||
182 | |||
183 | /* Look up the current Vcc */ | 172 | /* Look up the current Vcc */ |
184 | CS_CHECK(GetConfigurationInfo, | 173 | CS_CHECK(GetConfigurationInfo, |
185 | pcmcia_get_configuration_info(link, &conf)); | 174 | pcmcia_get_configuration_info(link, &conf)); |
186 | 175 | ||
176 | tuple.Attributes = 0; | ||
177 | tuple.TupleData = buf; | ||
178 | tuple.TupleDataMax = sizeof(buf); | ||
179 | tuple.TupleOffset = 0; | ||
187 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 180 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
188 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); | 181 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
189 | while (1) { | 182 | while (1) { |
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index ef54e310bfc4..a9d7119e3176 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -163,7 +163,7 @@ struct u132_endp { | |||
163 | u16 queue_next; | 163 | u16 queue_next; |
164 | struct urb *urb_list[ENDP_QUEUE_SIZE]; | 164 | struct urb *urb_list[ENDP_QUEUE_SIZE]; |
165 | struct list_head urb_more; | 165 | struct list_head urb_more; |
166 | struct work_struct scheduler; | 166 | struct delayed_work scheduler; |
167 | }; | 167 | }; |
168 | struct u132_ring { | 168 | struct u132_ring { |
169 | unsigned in_use:1; | 169 | unsigned in_use:1; |
@@ -171,7 +171,7 @@ struct u132_ring { | |||
171 | u8 number; | 171 | u8 number; |
172 | struct u132 *u132; | 172 | struct u132 *u132; |
173 | struct u132_endp *curr_endp; | 173 | struct u132_endp *curr_endp; |
174 | struct work_struct scheduler; | 174 | struct delayed_work scheduler; |
175 | }; | 175 | }; |
176 | #define OHCI_QUIRK_AMD756 0x01 | 176 | #define OHCI_QUIRK_AMD756 0x01 |
177 | #define OHCI_QUIRK_SUPERIO 0x02 | 177 | #define OHCI_QUIRK_SUPERIO 0x02 |
@@ -198,7 +198,7 @@ struct u132 { | |||
198 | u32 hc_roothub_portstatus[MAX_ROOT_PORTS]; | 198 | u32 hc_roothub_portstatus[MAX_ROOT_PORTS]; |
199 | int flags; | 199 | int flags; |
200 | unsigned long next_statechange; | 200 | unsigned long next_statechange; |
201 | struct work_struct monitor; | 201 | struct delayed_work monitor; |
202 | int num_endpoints; | 202 | int num_endpoints; |
203 | struct u132_addr addr[MAX_U132_ADDRS]; | 203 | struct u132_addr addr[MAX_U132_ADDRS]; |
204 | struct u132_udev udev[MAX_U132_UDEVS]; | 204 | struct u132_udev udev[MAX_U132_UDEVS]; |
@@ -310,7 +310,7 @@ static void u132_ring_requeue_work(struct u132 *u132, struct u132_ring *ring, | |||
310 | if (delta > 0) { | 310 | if (delta > 0) { |
311 | if (queue_delayed_work(workqueue, &ring->scheduler, delta)) | 311 | if (queue_delayed_work(workqueue, &ring->scheduler, delta)) |
312 | return; | 312 | return; |
313 | } else if (queue_work(workqueue, &ring->scheduler)) | 313 | } else if (queue_delayed_work(workqueue, &ring->scheduler, 0)) |
314 | return; | 314 | return; |
315 | kref_put(&u132->kref, u132_hcd_delete); | 315 | kref_put(&u132->kref, u132_hcd_delete); |
316 | return; | 316 | return; |
@@ -389,12 +389,8 @@ static inline void u132_endp_init_kref(struct u132 *u132, | |||
389 | static void u132_endp_queue_work(struct u132 *u132, struct u132_endp *endp, | 389 | static void u132_endp_queue_work(struct u132 *u132, struct u132_endp *endp, |
390 | unsigned int delta) | 390 | unsigned int delta) |
391 | { | 391 | { |
392 | if (delta > 0) { | 392 | if (queue_delayed_work(workqueue, &endp->scheduler, delta)) |
393 | if (queue_delayed_work(workqueue, &endp->scheduler, delta)) | 393 | kref_get(&endp->kref); |
394 | kref_get(&endp->kref); | ||
395 | } else if (queue_work(workqueue, &endp->scheduler)) | ||
396 | kref_get(&endp->kref); | ||
397 | return; | ||
398 | } | 394 | } |
399 | 395 | ||
400 | static void u132_endp_cancel_work(struct u132 *u132, struct u132_endp *endp) | 396 | static void u132_endp_cancel_work(struct u132 *u132, struct u132_endp *endp) |
@@ -410,24 +406,14 @@ static inline void u132_monitor_put_kref(struct u132 *u132) | |||
410 | 406 | ||
411 | static void u132_monitor_queue_work(struct u132 *u132, unsigned int delta) | 407 | static void u132_monitor_queue_work(struct u132 *u132, unsigned int delta) |
412 | { | 408 | { |
413 | if (delta > 0) { | 409 | if (queue_delayed_work(workqueue, &u132->monitor, delta)) |
414 | if (queue_delayed_work(workqueue, &u132->monitor, delta)) { | 410 | kref_get(&u132->kref); |
415 | kref_get(&u132->kref); | ||
416 | } | ||
417 | } else if (queue_work(workqueue, &u132->monitor)) | ||
418 | kref_get(&u132->kref); | ||
419 | return; | ||
420 | } | 411 | } |
421 | 412 | ||
422 | static void u132_monitor_requeue_work(struct u132 *u132, unsigned int delta) | 413 | static void u132_monitor_requeue_work(struct u132 *u132, unsigned int delta) |
423 | { | 414 | { |
424 | if (delta > 0) { | 415 | if (!queue_delayed_work(workqueue, &u132->monitor, delta)) |
425 | if (queue_delayed_work(workqueue, &u132->monitor, delta)) | 416 | kref_put(&u132->kref, u132_hcd_delete); |
426 | return; | ||
427 | } else if (queue_work(workqueue, &u132->monitor)) | ||
428 | return; | ||
429 | kref_put(&u132->kref, u132_hcd_delete); | ||
430 | return; | ||
431 | } | 417 | } |
432 | 418 | ||
433 | static void u132_monitor_cancel_work(struct u132 *u132) | 419 | static void u132_monitor_cancel_work(struct u132 *u132) |
@@ -489,9 +475,9 @@ static int read_roothub_info(struct u132 *u132) | |||
489 | return 0; | 475 | return 0; |
490 | } | 476 | } |
491 | 477 | ||
492 | static void u132_hcd_monitor_work(void *data) | 478 | static void u132_hcd_monitor_work(struct work_struct *work) |
493 | { | 479 | { |
494 | struct u132 *u132 = data; | 480 | struct u132 *u132 = container_of(work, struct u132, monitor.work); |
495 | if (u132->going > 1) { | 481 | if (u132->going > 1) { |
496 | dev_err(&u132->platform_dev->dev, "device has been removed %d\n" | 482 | dev_err(&u132->platform_dev->dev, "device has been removed %d\n" |
497 | , u132->going); | 483 | , u132->going); |
@@ -1315,15 +1301,14 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1315 | } | 1301 | } |
1316 | } | 1302 | } |
1317 | 1303 | ||
1318 | static void u132_hcd_ring_work_scheduler(void *data); | ||
1319 | static void u132_hcd_endp_work_scheduler(void *data); | ||
1320 | /* | 1304 | /* |
1321 | * this work function is only executed from the work queue | 1305 | * this work function is only executed from the work queue |
1322 | * | 1306 | * |
1323 | */ | 1307 | */ |
1324 | static void u132_hcd_ring_work_scheduler(void *data) | 1308 | static void u132_hcd_ring_work_scheduler(struct work_struct *work) |
1325 | { | 1309 | { |
1326 | struct u132_ring *ring = data; | 1310 | struct u132_ring *ring = |
1311 | container_of(work, struct u132_ring, scheduler.work); | ||
1327 | struct u132 *u132 = ring->u132; | 1312 | struct u132 *u132 = ring->u132; |
1328 | down(&u132->scheduler_lock); | 1313 | down(&u132->scheduler_lock); |
1329 | if (ring->in_use) { | 1314 | if (ring->in_use) { |
@@ -1382,10 +1367,11 @@ static void u132_hcd_ring_work_scheduler(void *data) | |||
1382 | } | 1367 | } |
1383 | } | 1368 | } |
1384 | 1369 | ||
1385 | static void u132_hcd_endp_work_scheduler(void *data) | 1370 | static void u132_hcd_endp_work_scheduler(struct work_struct *work) |
1386 | { | 1371 | { |
1387 | struct u132_ring *ring; | 1372 | struct u132_ring *ring; |
1388 | struct u132_endp *endp = data; | 1373 | struct u132_endp *endp = |
1374 | container_of(work, struct u132_endp, scheduler.work); | ||
1389 | struct u132 *u132 = endp->u132; | 1375 | struct u132 *u132 = endp->u132; |
1390 | down(&u132->scheduler_lock); | 1376 | down(&u132->scheduler_lock); |
1391 | ring = endp->ring; | 1377 | ring = endp->ring; |
@@ -1943,7 +1929,7 @@ static int create_endpoint_and_queue_int(struct u132 *u132, | |||
1943 | if (!endp) { | 1929 | if (!endp) { |
1944 | return -ENOMEM; | 1930 | return -ENOMEM; |
1945 | } | 1931 | } |
1946 | INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp); | 1932 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
1947 | spin_lock_init(&endp->queue_lock.slock); | 1933 | spin_lock_init(&endp->queue_lock.slock); |
1948 | INIT_LIST_HEAD(&endp->urb_more); | 1934 | INIT_LIST_HEAD(&endp->urb_more); |
1949 | ring = endp->ring = &u132->ring[0]; | 1935 | ring = endp->ring = &u132->ring[0]; |
@@ -2032,7 +2018,7 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, | |||
2032 | if (!endp) { | 2018 | if (!endp) { |
2033 | return -ENOMEM; | 2019 | return -ENOMEM; |
2034 | } | 2020 | } |
2035 | INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp); | 2021 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
2036 | spin_lock_init(&endp->queue_lock.slock); | 2022 | spin_lock_init(&endp->queue_lock.slock); |
2037 | INIT_LIST_HEAD(&endp->urb_more); | 2023 | INIT_LIST_HEAD(&endp->urb_more); |
2038 | endp->dequeueing = 0; | 2024 | endp->dequeueing = 0; |
@@ -2117,7 +2103,7 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2117 | if (!endp) { | 2103 | if (!endp) { |
2118 | return -ENOMEM; | 2104 | return -ENOMEM; |
2119 | } | 2105 | } |
2120 | INIT_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler, (void *)endp); | 2106 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
2121 | spin_lock_init(&endp->queue_lock.slock); | 2107 | spin_lock_init(&endp->queue_lock.slock); |
2122 | INIT_LIST_HEAD(&endp->urb_more); | 2108 | INIT_LIST_HEAD(&endp->urb_more); |
2123 | ring = endp->ring = &u132->ring[0]; | 2109 | ring = endp->ring = &u132->ring[0]; |
@@ -3096,10 +3082,10 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3096 | ring->number = rings + 1; | 3082 | ring->number = rings + 1; |
3097 | ring->length = 0; | 3083 | ring->length = 0; |
3098 | ring->curr_endp = NULL; | 3084 | ring->curr_endp = NULL; |
3099 | INIT_WORK(&ring->scheduler, u132_hcd_ring_work_scheduler, | 3085 | INIT_DELAYED_WORK(&ring->scheduler, |
3100 | (void *)ring); | 3086 | u132_hcd_ring_work_scheduler); |
3101 | } down(&u132->sw_lock); | 3087 | } down(&u132->sw_lock); |
3102 | INIT_WORK(&u132->monitor, u132_hcd_monitor_work, (void *)u132); | 3088 | INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work); |
3103 | while (ports-- > 0) { | 3089 | while (ports-- > 0) { |
3104 | struct u132_port *port = &u132->port[ports]; | 3090 | struct u132_port *port = &u132->port[ports]; |
3105 | port->u132 = u132; | 3091 | port->u132 = u132; |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index a49644b7c58e..4295bab4f1e2 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -969,9 +969,10 @@ static void hid_retry_timeout(unsigned long _hid) | |||
969 | } | 969 | } |
970 | 970 | ||
971 | /* Workqueue routine to reset the device or clear a halt */ | 971 | /* Workqueue routine to reset the device or clear a halt */ |
972 | static void hid_reset(void *_hid) | 972 | static void hid_reset(struct work_struct *work) |
973 | { | 973 | { |
974 | struct hid_device *hid = (struct hid_device *) _hid; | 974 | struct hid_device *hid = |
975 | container_of(work, struct hid_device, reset_work); | ||
975 | int rc_lock, rc = 0; | 976 | int rc_lock, rc = 0; |
976 | 977 | ||
977 | if (test_bit(HID_CLEAR_HALT, &hid->iofl)) { | 978 | if (test_bit(HID_CLEAR_HALT, &hid->iofl)) { |
@@ -2043,7 +2044,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
2043 | 2044 | ||
2044 | init_waitqueue_head(&hid->wait); | 2045 | init_waitqueue_head(&hid->wait); |
2045 | 2046 | ||
2046 | INIT_WORK(&hid->reset_work, hid_reset, hid); | 2047 | INIT_WORK(&hid->reset_work, hid_reset); |
2047 | setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid); | 2048 | setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid); |
2048 | 2049 | ||
2049 | spin_lock_init(&hid->inlock); | 2050 | spin_lock_init(&hid->inlock); |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index ba30ca6a14aa..02cbb7fff24f 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -76,7 +76,7 @@ struct appledisplay { | |||
76 | char *urbdata; /* interrupt URB data buffer */ | 76 | char *urbdata; /* interrupt URB data buffer */ |
77 | char *msgdata; /* control message data buffer */ | 77 | char *msgdata; /* control message data buffer */ |
78 | 78 | ||
79 | struct work_struct work; | 79 | struct delayed_work work; |
80 | int button_pressed; | 80 | int button_pressed; |
81 | spinlock_t lock; | 81 | spinlock_t lock; |
82 | }; | 82 | }; |
@@ -117,7 +117,7 @@ static void appledisplay_complete(struct urb *urb) | |||
117 | case ACD_BTN_BRIGHT_UP: | 117 | case ACD_BTN_BRIGHT_UP: |
118 | case ACD_BTN_BRIGHT_DOWN: | 118 | case ACD_BTN_BRIGHT_DOWN: |
119 | pdata->button_pressed = 1; | 119 | pdata->button_pressed = 1; |
120 | queue_work(wq, &pdata->work); | 120 | queue_delayed_work(wq, &pdata->work, 0); |
121 | break; | 121 | break; |
122 | case ACD_BTN_NONE: | 122 | case ACD_BTN_NONE: |
123 | default: | 123 | default: |
@@ -184,9 +184,10 @@ static struct backlight_properties appledisplay_bl_data = { | |||
184 | .max_brightness = 0xFF | 184 | .max_brightness = 0xFF |
185 | }; | 185 | }; |
186 | 186 | ||
187 | static void appledisplay_work(void *private) | 187 | static void appledisplay_work(struct work_struct *work) |
188 | { | 188 | { |
189 | struct appledisplay *pdata = private; | 189 | struct appledisplay *pdata = |
190 | container_of(work, struct appledisplay, work.work); | ||
190 | int retval; | 191 | int retval; |
191 | 192 | ||
192 | up(&pdata->bd->sem); | 193 | up(&pdata->bd->sem); |
@@ -238,7 +239,7 @@ static int appledisplay_probe(struct usb_interface *iface, | |||
238 | pdata->udev = udev; | 239 | pdata->udev = udev; |
239 | 240 | ||
240 | spin_lock_init(&pdata->lock); | 241 | spin_lock_init(&pdata->lock); |
241 | INIT_WORK(&pdata->work, appledisplay_work, pdata); | 242 | INIT_DELAYED_WORK(&pdata->work, appledisplay_work); |
242 | 243 | ||
243 | /* Allocate buffer for control messages */ | 244 | /* Allocate buffer for control messages */ |
244 | pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL); | 245 | pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL); |
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index cb0ba3107d7f..18b1925032a8 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -156,9 +156,9 @@ struct usb_ftdi { | |||
156 | struct usb_device *udev; | 156 | struct usb_device *udev; |
157 | struct usb_interface *interface; | 157 | struct usb_interface *interface; |
158 | struct usb_class_driver *class; | 158 | struct usb_class_driver *class; |
159 | struct work_struct status_work; | 159 | struct delayed_work status_work; |
160 | struct work_struct command_work; | 160 | struct delayed_work command_work; |
161 | struct work_struct respond_work; | 161 | struct delayed_work respond_work; |
162 | struct u132_platform_data platform_data; | 162 | struct u132_platform_data platform_data; |
163 | struct resource resources[0]; | 163 | struct resource resources[0]; |
164 | struct platform_device platform_dev; | 164 | struct platform_device platform_dev; |
@@ -210,23 +210,14 @@ static void ftdi_elan_init_kref(struct usb_ftdi *ftdi) | |||
210 | 210 | ||
211 | static void ftdi_status_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) | 211 | static void ftdi_status_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) |
212 | { | 212 | { |
213 | if (delta > 0) { | 213 | if (!queue_delayed_work(status_queue, &ftdi->status_work, delta)) |
214 | if (queue_delayed_work(status_queue, &ftdi->status_work, delta)) | 214 | kref_put(&ftdi->kref, ftdi_elan_delete); |
215 | return; | ||
216 | } else if (queue_work(status_queue, &ftdi->status_work)) | ||
217 | return; | ||
218 | kref_put(&ftdi->kref, ftdi_elan_delete); | ||
219 | return; | ||
220 | } | 215 | } |
221 | 216 | ||
222 | static void ftdi_status_queue_work(struct usb_ftdi *ftdi, unsigned int delta) | 217 | static void ftdi_status_queue_work(struct usb_ftdi *ftdi, unsigned int delta) |
223 | { | 218 | { |
224 | if (delta > 0) { | 219 | if (queue_delayed_work(status_queue, &ftdi->status_work, delta)) |
225 | if (queue_delayed_work(status_queue, &ftdi->status_work, delta)) | 220 | kref_get(&ftdi->kref); |
226 | kref_get(&ftdi->kref); | ||
227 | } else if (queue_work(status_queue, &ftdi->status_work)) | ||
228 | kref_get(&ftdi->kref); | ||
229 | return; | ||
230 | } | 221 | } |
231 | 222 | ||
232 | static void ftdi_status_cancel_work(struct usb_ftdi *ftdi) | 223 | static void ftdi_status_cancel_work(struct usb_ftdi *ftdi) |
@@ -237,25 +228,14 @@ static void ftdi_status_cancel_work(struct usb_ftdi *ftdi) | |||
237 | 228 | ||
238 | static void ftdi_command_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) | 229 | static void ftdi_command_requeue_work(struct usb_ftdi *ftdi, unsigned int delta) |
239 | { | 230 | { |
240 | if (delta > 0) { | 231 | if (!queue_delayed_work(command_queue, &ftdi->command_work, delta)) |
241 | if (queue_delayed_work(command_queue, &ftdi->command_work, | 232 | kref_put(&ftdi->kref, ftdi_elan_delete); |
242 | delta)) | ||
243 | return; | ||
244 | } else if (queue_work(command_queue, &ftdi->command_work)) | ||
245 | return; | ||
246 | kref_put(&ftdi->kref, ftdi_elan_delete); | ||
247 | return; | ||
248 | } | 233 | } |
249 | 234 | ||
250 | static void ftdi_command_queue_work(struct usb_ftdi *ftdi, unsigned int delta) | 235 | static void ftdi_command_queue_work(struct usb_ftdi *ftdi, unsigned int delta) |
251 | { | 236 | { |
252 | if (delta > 0) { | 237 | if (queue_delayed_work(command_queue, &ftdi->command_work, delta)) |
253 | if (queue_delayed_work(command_queue, &ftdi->command_work, | 238 | kref_get(&ftdi->kref); |
254 | delta)) | ||
255 | kref_get(&ftdi->kref); | ||
256 | } else if (queue_work(command_queue, &ftdi->command_work)) | ||
257 | kref_get(&ftdi->kref); | ||
258 | return; | ||
259 | } | 239 | } |
260 | 240 | ||
261 | static void ftdi_command_cancel_work(struct usb_ftdi *ftdi) | 241 | static void ftdi_command_cancel_work(struct usb_ftdi *ftdi) |
@@ -267,25 +247,14 @@ static void ftdi_command_cancel_work(struct usb_ftdi *ftdi) | |||
267 | static void ftdi_response_requeue_work(struct usb_ftdi *ftdi, | 247 | static void ftdi_response_requeue_work(struct usb_ftdi *ftdi, |
268 | unsigned int delta) | 248 | unsigned int delta) |
269 | { | 249 | { |
270 | if (delta > 0) { | 250 | if (!queue_delayed_work(respond_queue, &ftdi->respond_work, delta)) |
271 | if (queue_delayed_work(respond_queue, &ftdi->respond_work, | 251 | kref_put(&ftdi->kref, ftdi_elan_delete); |
272 | delta)) | ||
273 | return; | ||
274 | } else if (queue_work(respond_queue, &ftdi->respond_work)) | ||
275 | return; | ||
276 | kref_put(&ftdi->kref, ftdi_elan_delete); | ||
277 | return; | ||
278 | } | 252 | } |
279 | 253 | ||
280 | static void ftdi_respond_queue_work(struct usb_ftdi *ftdi, unsigned int delta) | 254 | static void ftdi_respond_queue_work(struct usb_ftdi *ftdi, unsigned int delta) |
281 | { | 255 | { |
282 | if (delta > 0) { | 256 | if (queue_delayed_work(respond_queue, &ftdi->respond_work, delta)) |
283 | if (queue_delayed_work(respond_queue, &ftdi->respond_work, | 257 | kref_get(&ftdi->kref); |
284 | delta)) | ||
285 | kref_get(&ftdi->kref); | ||
286 | } else if (queue_work(respond_queue, &ftdi->respond_work)) | ||
287 | kref_get(&ftdi->kref); | ||
288 | return; | ||
289 | } | 258 | } |
290 | 259 | ||
291 | static void ftdi_response_cancel_work(struct usb_ftdi *ftdi) | 260 | static void ftdi_response_cancel_work(struct usb_ftdi *ftdi) |
@@ -475,9 +444,11 @@ static void ftdi_elan_kick_command_queue(struct usb_ftdi *ftdi) | |||
475 | return; | 444 | return; |
476 | } | 445 | } |
477 | 446 | ||
478 | static void ftdi_elan_command_work(void *data) | 447 | static void ftdi_elan_command_work(struct work_struct *work) |
479 | { | 448 | { |
480 | struct usb_ftdi *ftdi = data; | 449 | struct usb_ftdi *ftdi = |
450 | container_of(work, struct usb_ftdi, command_work.work); | ||
451 | |||
481 | if (ftdi->disconnected > 0) { | 452 | if (ftdi->disconnected > 0) { |
482 | ftdi_elan_put_kref(ftdi); | 453 | ftdi_elan_put_kref(ftdi); |
483 | return; | 454 | return; |
@@ -500,9 +471,10 @@ static void ftdi_elan_kick_respond_queue(struct usb_ftdi *ftdi) | |||
500 | return; | 471 | return; |
501 | } | 472 | } |
502 | 473 | ||
503 | static void ftdi_elan_respond_work(void *data) | 474 | static void ftdi_elan_respond_work(struct work_struct *work) |
504 | { | 475 | { |
505 | struct usb_ftdi *ftdi = data; | 476 | struct usb_ftdi *ftdi = |
477 | container_of(work, struct usb_ftdi, respond_work.work); | ||
506 | if (ftdi->disconnected > 0) { | 478 | if (ftdi->disconnected > 0) { |
507 | ftdi_elan_put_kref(ftdi); | 479 | ftdi_elan_put_kref(ftdi); |
508 | return; | 480 | return; |
@@ -534,9 +506,10 @@ static void ftdi_elan_respond_work(void *data) | |||
534 | * after the FTDI has been synchronized | 506 | * after the FTDI has been synchronized |
535 | * | 507 | * |
536 | */ | 508 | */ |
537 | static void ftdi_elan_status_work(void *data) | 509 | static void ftdi_elan_status_work(struct work_struct *work) |
538 | { | 510 | { |
539 | struct usb_ftdi *ftdi = data; | 511 | struct usb_ftdi *ftdi = |
512 | container_of(work, struct usb_ftdi, status_work.work); | ||
540 | int work_delay_in_msec = 0; | 513 | int work_delay_in_msec = 0; |
541 | if (ftdi->disconnected > 0) { | 514 | if (ftdi->disconnected > 0) { |
542 | ftdi_elan_put_kref(ftdi); | 515 | ftdi_elan_put_kref(ftdi); |
@@ -2677,12 +2650,9 @@ static int ftdi_elan_probe(struct usb_interface *interface, | |||
2677 | ftdi->class = NULL; | 2650 | ftdi->class = NULL; |
2678 | dev_info(&ftdi->udev->dev, "USB FDTI=%p ELAN interface %d now a" | 2651 | dev_info(&ftdi->udev->dev, "USB FDTI=%p ELAN interface %d now a" |
2679 | "ctivated\n", ftdi, iface_desc->desc.bInterfaceNumber); | 2652 | "ctivated\n", ftdi, iface_desc->desc.bInterfaceNumber); |
2680 | INIT_WORK(&ftdi->status_work, ftdi_elan_status_work, | 2653 | INIT_DELAYED_WORK(&ftdi->status_work, ftdi_elan_status_work); |
2681 | (void *)ftdi); | 2654 | INIT_DELAYED_WORK(&ftdi->command_work, ftdi_elan_command_work); |
2682 | INIT_WORK(&ftdi->command_work, ftdi_elan_command_work, | 2655 | INIT_DELAYED_WORK(&ftdi->respond_work, ftdi_elan_respond_work); |
2683 | (void *)ftdi); | ||
2684 | INIT_WORK(&ftdi->respond_work, ftdi_elan_respond_work, | ||
2685 | (void *)ftdi); | ||
2686 | ftdi_status_queue_work(ftdi, msecs_to_jiffies(3 *1000)); | 2656 | ftdi_status_queue_work(ftdi, msecs_to_jiffies(3 *1000)); |
2687 | return 0; | 2657 | return 0; |
2688 | } else { | 2658 | } else { |
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 9110793f81d3..9659c79e187e 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c | |||
@@ -81,8 +81,8 @@ struct interfacekit { | |||
81 | unsigned char *data; | 81 | unsigned char *data; |
82 | dma_addr_t data_dma; | 82 | dma_addr_t data_dma; |
83 | 83 | ||
84 | struct work_struct do_notify; | 84 | struct delayed_work do_notify; |
85 | struct work_struct do_resubmit; | 85 | struct delayed_work do_resubmit; |
86 | unsigned long input_events; | 86 | unsigned long input_events; |
87 | unsigned long sensor_events; | 87 | unsigned long sensor_events; |
88 | }; | 88 | }; |
@@ -374,7 +374,7 @@ static void interfacekit_irq(struct urb *urb) | |||
374 | } | 374 | } |
375 | 375 | ||
376 | if (kit->input_events || kit->sensor_events) | 376 | if (kit->input_events || kit->sensor_events) |
377 | schedule_work(&kit->do_notify); | 377 | schedule_delayed_work(&kit->do_notify, 0); |
378 | 378 | ||
379 | resubmit: | 379 | resubmit: |
380 | status = usb_submit_urb(urb, SLAB_ATOMIC); | 380 | status = usb_submit_urb(urb, SLAB_ATOMIC); |
@@ -384,9 +384,10 @@ resubmit: | |||
384 | kit->udev->devpath, status); | 384 | kit->udev->devpath, status); |
385 | } | 385 | } |
386 | 386 | ||
387 | static void do_notify(void *data) | 387 | static void do_notify(struct work_struct *work) |
388 | { | 388 | { |
389 | struct interfacekit *kit = data; | 389 | struct interfacekit *kit = |
390 | container_of(work, struct interfacekit, do_notify.work); | ||
390 | int i; | 391 | int i; |
391 | char sysfs_file[8]; | 392 | char sysfs_file[8]; |
392 | 393 | ||
@@ -405,9 +406,11 @@ static void do_notify(void *data) | |||
405 | } | 406 | } |
406 | } | 407 | } |
407 | 408 | ||
408 | static void do_resubmit(void *data) | 409 | static void do_resubmit(struct work_struct *work) |
409 | { | 410 | { |
410 | set_outputs(data); | 411 | struct interfacekit *kit = |
412 | container_of(work, struct interfacekit, do_resubmit.work); | ||
413 | set_outputs(kit); | ||
411 | } | 414 | } |
412 | 415 | ||
413 | #define show_set_output(value) \ | 416 | #define show_set_output(value) \ |
@@ -575,8 +578,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic | |||
575 | 578 | ||
576 | kit->udev = usb_get_dev(dev); | 579 | kit->udev = usb_get_dev(dev); |
577 | kit->intf = intf; | 580 | kit->intf = intf; |
578 | INIT_WORK(&kit->do_notify, do_notify, kit); | 581 | INIT_DELAYED_WORK(&kit->do_notify, do_notify); |
579 | INIT_WORK(&kit->do_resubmit, do_resubmit, kit); | 582 | INIT_DELAYED_WORK(&kit->do_resubmit, do_resubmit); |
580 | usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data, | 583 | usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data, |
581 | maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, | 584 | maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, |
582 | interfacekit_irq, kit, endpoint->bInterval); | 585 | interfacekit_irq, kit, endpoint->bInterval); |
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c index c3469b0a67c2..2bb4fa572bb7 100644 --- a/drivers/usb/misc/phidgetmotorcontrol.c +++ b/drivers/usb/misc/phidgetmotorcontrol.c | |||
@@ -41,7 +41,7 @@ struct motorcontrol { | |||
41 | unsigned char *data; | 41 | unsigned char *data; |
42 | dma_addr_t data_dma; | 42 | dma_addr_t data_dma; |
43 | 43 | ||
44 | struct work_struct do_notify; | 44 | struct delayed_work do_notify; |
45 | unsigned long input_events; | 45 | unsigned long input_events; |
46 | unsigned long speed_events; | 46 | unsigned long speed_events; |
47 | unsigned long exceed_events; | 47 | unsigned long exceed_events; |
@@ -148,7 +148,7 @@ static void motorcontrol_irq(struct urb *urb) | |||
148 | set_bit(1, &mc->exceed_events); | 148 | set_bit(1, &mc->exceed_events); |
149 | 149 | ||
150 | if (mc->input_events || mc->exceed_events || mc->speed_events) | 150 | if (mc->input_events || mc->exceed_events || mc->speed_events) |
151 | schedule_work(&mc->do_notify); | 151 | schedule_delayed_work(&mc->do_notify, 0); |
152 | 152 | ||
153 | resubmit: | 153 | resubmit: |
154 | status = usb_submit_urb(urb, SLAB_ATOMIC); | 154 | status = usb_submit_urb(urb, SLAB_ATOMIC); |
@@ -159,9 +159,10 @@ resubmit: | |||
159 | mc->udev->devpath, status); | 159 | mc->udev->devpath, status); |
160 | } | 160 | } |
161 | 161 | ||
162 | static void do_notify(void *data) | 162 | static void do_notify(struct work_struct *work) |
163 | { | 163 | { |
164 | struct motorcontrol *mc = data; | 164 | struct motorcontrol *mc = |
165 | container_of(work, struct motorcontrol, do_notify.work); | ||
165 | int i; | 166 | int i; |
166 | char sysfs_file[8]; | 167 | char sysfs_file[8]; |
167 | 168 | ||
@@ -348,7 +349,7 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic | |||
348 | mc->udev = usb_get_dev(dev); | 349 | mc->udev = usb_get_dev(dev); |
349 | mc->intf = intf; | 350 | mc->intf = intf; |
350 | mc->acceleration[0] = mc->acceleration[1] = 10; | 351 | mc->acceleration[0] = mc->acceleration[1] = 10; |
351 | INIT_WORK(&mc->do_notify, do_notify, mc); | 352 | INIT_DELAYED_WORK(&mc->do_notify, do_notify); |
352 | usb_fill_int_urb(mc->irq, mc->udev, pipe, mc->data, | 353 | usb_fill_int_urb(mc->irq, mc->udev, pipe, mc->data, |
353 | maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, | 354 | maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, |
354 | motorcontrol_irq, mc, endpoint->bInterval); | 355 | motorcontrol_irq, mc, endpoint->bInterval); |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index 7c906a43e497..fa78326d0bf0 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
@@ -222,7 +222,7 @@ struct kaweth_device | |||
222 | int suspend_lowmem_ctrl; | 222 | int suspend_lowmem_ctrl; |
223 | int linkstate; | 223 | int linkstate; |
224 | int opened; | 224 | int opened; |
225 | struct work_struct lowmem_work; | 225 | struct delayed_work lowmem_work; |
226 | 226 | ||
227 | struct usb_device *dev; | 227 | struct usb_device *dev; |
228 | struct net_device *net; | 228 | struct net_device *net; |
@@ -530,9 +530,10 @@ resubmit: | |||
530 | kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC); | 530 | kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC); |
531 | } | 531 | } |
532 | 532 | ||
533 | static void kaweth_resubmit_tl(void *d) | 533 | static void kaweth_resubmit_tl(struct work_struct *work) |
534 | { | 534 | { |
535 | struct kaweth_device *kaweth = (struct kaweth_device *)d; | 535 | struct kaweth_device *kaweth = |
536 | container_of(work, struct kaweth_device, lowmem_work.work); | ||
536 | 537 | ||
537 | if (IS_BLOCKED(kaweth->status)) | 538 | if (IS_BLOCKED(kaweth->status)) |
538 | return; | 539 | return; |
@@ -1126,7 +1127,7 @@ err_fw: | |||
1126 | 1127 | ||
1127 | /* kaweth is zeroed as part of alloc_netdev */ | 1128 | /* kaweth is zeroed as part of alloc_netdev */ |
1128 | 1129 | ||
1129 | INIT_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl, (void *)kaweth); | 1130 | INIT_DELAYED_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl); |
1130 | 1131 | ||
1131 | SET_MODULE_OWNER(netdev); | 1132 | SET_MODULE_OWNER(netdev); |
1132 | 1133 | ||
diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 69eb0db399df..b5690b3834e3 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c | |||
@@ -1281,9 +1281,9 @@ static inline void setup_pegasus_II(pegasus_t * pegasus) | |||
1281 | static struct workqueue_struct *pegasus_workqueue = NULL; | 1281 | static struct workqueue_struct *pegasus_workqueue = NULL; |
1282 | #define CARRIER_CHECK_DELAY (2 * HZ) | 1282 | #define CARRIER_CHECK_DELAY (2 * HZ) |
1283 | 1283 | ||
1284 | static void check_carrier(void *data) | 1284 | static void check_carrier(struct work_struct *work) |
1285 | { | 1285 | { |
1286 | pegasus_t *pegasus = data; | 1286 | pegasus_t *pegasus = container_of(work, pegasus_t, carrier_check.work); |
1287 | set_carrier(pegasus->net); | 1287 | set_carrier(pegasus->net); |
1288 | if (!(pegasus->flags & PEGASUS_UNPLUG)) { | 1288 | if (!(pegasus->flags & PEGASUS_UNPLUG)) { |
1289 | queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, | 1289 | queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, |
@@ -1319,7 +1319,7 @@ static int pegasus_probe(struct usb_interface *intf, | |||
1319 | 1319 | ||
1320 | tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus); | 1320 | tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus); |
1321 | 1321 | ||
1322 | INIT_WORK(&pegasus->carrier_check, check_carrier, pegasus); | 1322 | INIT_DELAYED_WORK(&pegasus->carrier_check, check_carrier); |
1323 | 1323 | ||
1324 | pegasus->intf = intf; | 1324 | pegasus->intf = intf; |
1325 | pegasus->usb = dev; | 1325 | pegasus->usb = dev; |
diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h index 006438069b66..98f6898cae1f 100644 --- a/drivers/usb/net/pegasus.h +++ b/drivers/usb/net/pegasus.h | |||
@@ -95,7 +95,7 @@ typedef struct pegasus { | |||
95 | int dev_index; | 95 | int dev_index; |
96 | int intr_interval; | 96 | int intr_interval; |
97 | struct tasklet_struct rx_tl; | 97 | struct tasklet_struct rx_tl; |
98 | struct work_struct carrier_check; | 98 | struct delayed_work carrier_check; |
99 | struct urb *ctrl_urb, *rx_urb, *tx_urb, *intr_urb; | 99 | struct urb *ctrl_urb, *rx_urb, *tx_urb, *intr_urb; |
100 | struct sk_buff *rx_pool[RX_SKBS]; | 100 | struct sk_buff *rx_pool[RX_SKBS]; |
101 | struct sk_buff *rx_skb; | 101 | struct sk_buff *rx_skb; |
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 7672e11c94c4..327f97555679 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -782,9 +782,10 @@ static struct ethtool_ops usbnet_ethtool_ops = { | |||
782 | * especially now that control transfers can be queued. | 782 | * especially now that control transfers can be queued. |
783 | */ | 783 | */ |
784 | static void | 784 | static void |
785 | kevent (void *data) | 785 | kevent (struct work_struct *work) |
786 | { | 786 | { |
787 | struct usbnet *dev = data; | 787 | struct usbnet *dev = |
788 | container_of(work, struct usbnet, kevent); | ||
788 | int status; | 789 | int status; |
789 | 790 | ||
790 | /* usb_clear_halt() needs a thread context */ | 791 | /* usb_clear_halt() needs a thread context */ |
@@ -1146,7 +1147,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) | |||
1146 | skb_queue_head_init (&dev->done); | 1147 | skb_queue_head_init (&dev->done); |
1147 | dev->bh.func = usbnet_bh; | 1148 | dev->bh.func = usbnet_bh; |
1148 | dev->bh.data = (unsigned long) dev; | 1149 | dev->bh.data = (unsigned long) dev; |
1149 | INIT_WORK (&dev->kevent, kevent, dev); | 1150 | INIT_WORK (&dev->kevent, kevent); |
1150 | dev->delay.function = usbnet_bh; | 1151 | dev->delay.function = usbnet_bh; |
1151 | dev->delay.data = (unsigned long) dev; | 1152 | dev->delay.data = (unsigned long) dev; |
1152 | init_timer (&dev->delay); | 1153 | init_timer (&dev->delay); |
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index b1b5707bc99a..86bcf63b6ba5 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -92,6 +92,7 @@ struct aircable_private { | |||
92 | struct circ_buf *rx_buf; /* read buffer */ | 92 | struct circ_buf *rx_buf; /* read buffer */ |
93 | int rx_flags; /* for throttilng */ | 93 | int rx_flags; /* for throttilng */ |
94 | struct work_struct rx_work; /* work cue for the receiving line */ | 94 | struct work_struct rx_work; /* work cue for the receiving line */ |
95 | struct usb_serial_port *port; /* USB port with which associated */ | ||
95 | }; | 96 | }; |
96 | 97 | ||
97 | /* Private methods */ | 98 | /* Private methods */ |
@@ -251,10 +252,11 @@ static void aircable_send(struct usb_serial_port *port) | |||
251 | schedule_work(&port->work); | 252 | schedule_work(&port->work); |
252 | } | 253 | } |
253 | 254 | ||
254 | static void aircable_read(void *params) | 255 | static void aircable_read(struct work_struct *work) |
255 | { | 256 | { |
256 | struct usb_serial_port *port = params; | 257 | struct aircable_private *priv = |
257 | struct aircable_private *priv = usb_get_serial_port_data(port); | 258 | container_of(work, struct aircable_private, rx_work); |
259 | struct usb_serial_port *port = priv->port; | ||
258 | struct tty_struct *tty; | 260 | struct tty_struct *tty; |
259 | unsigned char *data; | 261 | unsigned char *data; |
260 | int count; | 262 | int count; |
@@ -349,7 +351,8 @@ static int aircable_attach (struct usb_serial *serial) | |||
349 | } | 351 | } |
350 | 352 | ||
351 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); | 353 | priv->rx_flags &= ~(THROTTLED | ACTUALLY_THROTTLED); |
352 | INIT_WORK(&priv->rx_work, aircable_read, port); | 354 | priv->port = port; |
355 | INIT_WORK(&priv->rx_work, aircable_read); | ||
353 | 356 | ||
354 | usb_set_serial_port_data(serial->port[0], priv); | 357 | usb_set_serial_port_data(serial->port[0], priv); |
355 | 358 | ||
@@ -516,7 +519,7 @@ static void aircable_read_bulk_callback(struct urb *urb) | |||
516 | package_length - shift); | 519 | package_length - shift); |
517 | } | 520 | } |
518 | } | 521 | } |
519 | aircable_read(port); | 522 | aircable_read(&priv->rx_work); |
520 | } | 523 | } |
521 | 524 | ||
522 | /* Schedule the next read _if_ we are still open */ | 525 | /* Schedule the next read _if_ we are still open */ |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 5e3ac281a2f8..83d0e21145b0 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -430,13 +430,14 @@ struct digi_port { | |||
430 | int dp_in_close; /* close in progress */ | 430 | int dp_in_close; /* close in progress */ |
431 | wait_queue_head_t dp_close_wait; /* wait queue for close */ | 431 | wait_queue_head_t dp_close_wait; /* wait queue for close */ |
432 | struct work_struct dp_wakeup_work; | 432 | struct work_struct dp_wakeup_work; |
433 | struct usb_serial_port *dp_port; | ||
433 | }; | 434 | }; |
434 | 435 | ||
435 | 436 | ||
436 | /* Local Function Declarations */ | 437 | /* Local Function Declarations */ |
437 | 438 | ||
438 | static void digi_wakeup_write( struct usb_serial_port *port ); | 439 | static void digi_wakeup_write( struct usb_serial_port *port ); |
439 | static void digi_wakeup_write_lock(void *); | 440 | static void digi_wakeup_write_lock(struct work_struct *work); |
440 | static int digi_write_oob_command( struct usb_serial_port *port, | 441 | static int digi_write_oob_command( struct usb_serial_port *port, |
441 | unsigned char *buf, int count, int interruptible ); | 442 | unsigned char *buf, int count, int interruptible ); |
442 | static int digi_write_inb_command( struct usb_serial_port *port, | 443 | static int digi_write_inb_command( struct usb_serial_port *port, |
@@ -598,11 +599,12 @@ static inline long cond_wait_interruptible_timeout_irqrestore( | |||
598 | * on writes. | 599 | * on writes. |
599 | */ | 600 | */ |
600 | 601 | ||
601 | static void digi_wakeup_write_lock(void *arg) | 602 | static void digi_wakeup_write_lock(struct work_struct *work) |
602 | { | 603 | { |
603 | struct usb_serial_port *port = arg; | 604 | struct digi_port *priv = |
605 | container_of(work, struct digi_port, dp_wakeup_work); | ||
606 | struct usb_serial_port *port = priv->dp_port; | ||
604 | unsigned long flags; | 607 | unsigned long flags; |
605 | struct digi_port *priv = usb_get_serial_port_data(port); | ||
606 | 608 | ||
607 | 609 | ||
608 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 610 | spin_lock_irqsave( &priv->dp_port_lock, flags ); |
@@ -1702,8 +1704,8 @@ dbg( "digi_startup: TOP" ); | |||
1702 | init_waitqueue_head( &priv->dp_flush_wait ); | 1704 | init_waitqueue_head( &priv->dp_flush_wait ); |
1703 | priv->dp_in_close = 0; | 1705 | priv->dp_in_close = 0; |
1704 | init_waitqueue_head( &priv->dp_close_wait ); | 1706 | init_waitqueue_head( &priv->dp_close_wait ); |
1705 | INIT_WORK(&priv->dp_wakeup_work, | 1707 | INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); |
1706 | digi_wakeup_write_lock, serial->port[i]); | 1708 | priv->dp_port = serial->port[i]; |
1707 | 1709 | ||
1708 | /* initialize write wait queue for this port */ | 1710 | /* initialize write wait queue for this port */ |
1709 | init_waitqueue_head( &serial->port[i]->write_wait ); | 1711 | init_waitqueue_head( &serial->port[i]->write_wait ); |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 89ce2775be15..72e4d48f51e9 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -559,7 +559,8 @@ struct ftdi_private { | |||
559 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ | 559 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ |
560 | __u8 rx_flags; /* receive state flags (throttling) */ | 560 | __u8 rx_flags; /* receive state flags (throttling) */ |
561 | spinlock_t rx_lock; /* spinlock for receive state */ | 561 | spinlock_t rx_lock; /* spinlock for receive state */ |
562 | struct work_struct rx_work; | 562 | struct delayed_work rx_work; |
563 | struct usb_serial_port *port; | ||
563 | int rx_processed; | 564 | int rx_processed; |
564 | unsigned long rx_bytes; | 565 | unsigned long rx_bytes; |
565 | 566 | ||
@@ -593,7 +594,7 @@ static int ftdi_write_room (struct usb_serial_port *port); | |||
593 | static int ftdi_chars_in_buffer (struct usb_serial_port *port); | 594 | static int ftdi_chars_in_buffer (struct usb_serial_port *port); |
594 | static void ftdi_write_bulk_callback (struct urb *urb); | 595 | static void ftdi_write_bulk_callback (struct urb *urb); |
595 | static void ftdi_read_bulk_callback (struct urb *urb); | 596 | static void ftdi_read_bulk_callback (struct urb *urb); |
596 | static void ftdi_process_read (void *param); | 597 | static void ftdi_process_read (struct work_struct *work); |
597 | static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); | 598 | static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); |
598 | static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); | 599 | static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); |
599 | static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); | 600 | static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); |
@@ -1201,7 +1202,8 @@ static int ftdi_sio_attach (struct usb_serial *serial) | |||
1201 | port->read_urb->transfer_buffer_length = BUFSZ; | 1202 | port->read_urb->transfer_buffer_length = BUFSZ; |
1202 | } | 1203 | } |
1203 | 1204 | ||
1204 | INIT_WORK(&priv->rx_work, ftdi_process_read, port); | 1205 | INIT_DELAYED_WORK(&priv->rx_work, ftdi_process_read); |
1206 | priv->port = port; | ||
1205 | 1207 | ||
1206 | /* Free port's existing write urb and transfer buffer. */ | 1208 | /* Free port's existing write urb and transfer buffer. */ |
1207 | if (port->write_urb) { | 1209 | if (port->write_urb) { |
@@ -1640,17 +1642,18 @@ static void ftdi_read_bulk_callback (struct urb *urb) | |||
1640 | priv->rx_bytes += countread; | 1642 | priv->rx_bytes += countread; |
1641 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 1643 | spin_unlock_irqrestore(&priv->rx_lock, flags); |
1642 | 1644 | ||
1643 | ftdi_process_read(port); | 1645 | ftdi_process_read(&priv->rx_work.work); |
1644 | 1646 | ||
1645 | } /* ftdi_read_bulk_callback */ | 1647 | } /* ftdi_read_bulk_callback */ |
1646 | 1648 | ||
1647 | 1649 | ||
1648 | static void ftdi_process_read (void *param) | 1650 | static void ftdi_process_read (struct work_struct *work) |
1649 | { /* ftdi_process_read */ | 1651 | { /* ftdi_process_read */ |
1650 | struct usb_serial_port *port = (struct usb_serial_port*)param; | 1652 | struct ftdi_private *priv = |
1653 | container_of(work, struct ftdi_private, rx_work.work); | ||
1654 | struct usb_serial_port *port = priv->port; | ||
1651 | struct urb *urb; | 1655 | struct urb *urb; |
1652 | struct tty_struct *tty; | 1656 | struct tty_struct *tty; |
1653 | struct ftdi_private *priv; | ||
1654 | char error_flag; | 1657 | char error_flag; |
1655 | unsigned char *data; | 1658 | unsigned char *data; |
1656 | 1659 | ||
@@ -2179,7 +2182,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port) | |||
2179 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 2182 | spin_unlock_irqrestore(&priv->rx_lock, flags); |
2180 | 2183 | ||
2181 | if (actually_throttled) | 2184 | if (actually_throttled) |
2182 | schedule_work(&priv->rx_work); | 2185 | schedule_delayed_work(&priv->rx_work, 0); |
2183 | } | 2186 | } |
2184 | 2187 | ||
2185 | static int __init ftdi_init (void) | 2188 | static int __init ftdi_init (void) |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 909005107ea2..e09a0bfe6231 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -120,6 +120,8 @@ struct keyspan_pda_private { | |||
120 | int tx_throttled; | 120 | int tx_throttled; |
121 | struct work_struct wakeup_work; | 121 | struct work_struct wakeup_work; |
122 | struct work_struct unthrottle_work; | 122 | struct work_struct unthrottle_work; |
123 | struct usb_serial *serial; | ||
124 | struct usb_serial_port *port; | ||
123 | }; | 125 | }; |
124 | 126 | ||
125 | 127 | ||
@@ -175,9 +177,11 @@ static struct usb_device_id id_table_fake_xircom [] = { | |||
175 | }; | 177 | }; |
176 | #endif | 178 | #endif |
177 | 179 | ||
178 | static void keyspan_pda_wakeup_write( struct usb_serial_port *port ) | 180 | static void keyspan_pda_wakeup_write(struct work_struct *work) |
179 | { | 181 | { |
180 | 182 | struct keyspan_pda_private *priv = | |
183 | container_of(work, struct keyspan_pda_private, wakeup_work); | ||
184 | struct usb_serial_port *port = priv->port; | ||
181 | struct tty_struct *tty = port->tty; | 185 | struct tty_struct *tty = port->tty; |
182 | 186 | ||
183 | /* wake up port processes */ | 187 | /* wake up port processes */ |
@@ -187,8 +191,11 @@ static void keyspan_pda_wakeup_write( struct usb_serial_port *port ) | |||
187 | tty_wakeup(tty); | 191 | tty_wakeup(tty); |
188 | } | 192 | } |
189 | 193 | ||
190 | static void keyspan_pda_request_unthrottle( struct usb_serial *serial ) | 194 | static void keyspan_pda_request_unthrottle(struct work_struct *work) |
191 | { | 195 | { |
196 | struct keyspan_pda_private *priv = | ||
197 | container_of(work, struct keyspan_pda_private, unthrottle_work); | ||
198 | struct usb_serial *serial = priv->serial; | ||
192 | int result; | 199 | int result; |
193 | 200 | ||
194 | dbg(" request_unthrottle"); | 201 | dbg(" request_unthrottle"); |
@@ -765,11 +772,10 @@ static int keyspan_pda_startup (struct usb_serial *serial) | |||
765 | return (1); /* error */ | 772 | return (1); /* error */ |
766 | usb_set_serial_port_data(serial->port[0], priv); | 773 | usb_set_serial_port_data(serial->port[0], priv); |
767 | init_waitqueue_head(&serial->port[0]->write_wait); | 774 | init_waitqueue_head(&serial->port[0]->write_wait); |
768 | INIT_WORK(&priv->wakeup_work, (void *)keyspan_pda_wakeup_write, | 775 | INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write); |
769 | (void *)(serial->port[0])); | 776 | INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle); |
770 | INIT_WORK(&priv->unthrottle_work, | 777 | priv->serial = serial; |
771 | (void *)keyspan_pda_request_unthrottle, | 778 | priv->port = serial->port[0]; |
772 | (void *)(serial)); | ||
773 | return (0); | 779 | return (0); |
774 | } | 780 | } |
775 | 781 | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index c1257d5292f5..3d5072f14b8d 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -533,9 +533,10 @@ void usb_serial_port_softint(struct usb_serial_port *port) | |||
533 | schedule_work(&port->work); | 533 | schedule_work(&port->work); |
534 | } | 534 | } |
535 | 535 | ||
536 | static void usb_serial_port_work(void *private) | 536 | static void usb_serial_port_work(struct work_struct *work) |
537 | { | 537 | { |
538 | struct usb_serial_port *port = private; | 538 | struct usb_serial_port *port = |
539 | container_of(work, struct usb_serial_port, work); | ||
539 | struct tty_struct *tty; | 540 | struct tty_struct *tty; |
540 | 541 | ||
541 | dbg("%s - port %d", __FUNCTION__, port->number); | 542 | dbg("%s - port %d", __FUNCTION__, port->number); |
@@ -799,7 +800,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
799 | port->serial = serial; | 800 | port->serial = serial; |
800 | spin_lock_init(&port->lock); | 801 | spin_lock_init(&port->lock); |
801 | mutex_init(&port->mutex); | 802 | mutex_init(&port->mutex); |
802 | INIT_WORK(&port->work, usb_serial_port_work, port); | 803 | INIT_WORK(&port->work, usb_serial_port_work); |
803 | serial->port[i] = port; | 804 | serial->port[i] = port; |
804 | } | 805 | } |
805 | 806 | ||
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 4d1cd7aeccd3..154c7d290597 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -227,6 +227,7 @@ struct whiteheat_private { | |||
227 | struct list_head rx_urbs_submitted; | 227 | struct list_head rx_urbs_submitted; |
228 | struct list_head rx_urb_q; | 228 | struct list_head rx_urb_q; |
229 | struct work_struct rx_work; | 229 | struct work_struct rx_work; |
230 | struct usb_serial_port *port; | ||
230 | struct list_head tx_urbs_free; | 231 | struct list_head tx_urbs_free; |
231 | struct list_head tx_urbs_submitted; | 232 | struct list_head tx_urbs_submitted; |
232 | }; | 233 | }; |
@@ -241,7 +242,7 @@ static void command_port_read_callback(struct urb *urb); | |||
241 | static int start_port_read(struct usb_serial_port *port); | 242 | static int start_port_read(struct usb_serial_port *port); |
242 | static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, struct list_head *head); | 243 | static struct whiteheat_urb_wrap *urb_to_wrap(struct urb *urb, struct list_head *head); |
243 | static struct list_head *list_first(struct list_head *head); | 244 | static struct list_head *list_first(struct list_head *head); |
244 | static void rx_data_softint(void *private); | 245 | static void rx_data_softint(struct work_struct *work); |
245 | 246 | ||
246 | static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize); | 247 | static int firm_send_command(struct usb_serial_port *port, __u8 command, __u8 *data, __u8 datasize); |
247 | static int firm_open(struct usb_serial_port *port); | 248 | static int firm_open(struct usb_serial_port *port); |
@@ -424,7 +425,8 @@ static int whiteheat_attach (struct usb_serial *serial) | |||
424 | spin_lock_init(&info->lock); | 425 | spin_lock_init(&info->lock); |
425 | info->flags = 0; | 426 | info->flags = 0; |
426 | info->mcr = 0; | 427 | info->mcr = 0; |
427 | INIT_WORK(&info->rx_work, rx_data_softint, port); | 428 | INIT_WORK(&info->rx_work, rx_data_softint); |
429 | info->port = port; | ||
428 | 430 | ||
429 | INIT_LIST_HEAD(&info->rx_urbs_free); | 431 | INIT_LIST_HEAD(&info->rx_urbs_free); |
430 | INIT_LIST_HEAD(&info->rx_urbs_submitted); | 432 | INIT_LIST_HEAD(&info->rx_urbs_submitted); |
@@ -949,7 +951,7 @@ static void whiteheat_unthrottle (struct usb_serial_port *port) | |||
949 | spin_unlock_irqrestore(&info->lock, flags); | 951 | spin_unlock_irqrestore(&info->lock, flags); |
950 | 952 | ||
951 | if (actually_throttled) | 953 | if (actually_throttled) |
952 | rx_data_softint(port); | 954 | rx_data_softint(&info->rx_work); |
953 | 955 | ||
954 | return; | 956 | return; |
955 | } | 957 | } |
@@ -1400,10 +1402,11 @@ static struct list_head *list_first(struct list_head *head) | |||
1400 | } | 1402 | } |
1401 | 1403 | ||
1402 | 1404 | ||
1403 | static void rx_data_softint(void *private) | 1405 | static void rx_data_softint(struct work_struct *work) |
1404 | { | 1406 | { |
1405 | struct usb_serial_port *port = (struct usb_serial_port *)private; | 1407 | struct whiteheat_private *info = |
1406 | struct whiteheat_private *info = usb_get_serial_port_data(port); | 1408 | container_of(work, struct whiteheat_private, rx_work); |
1409 | struct usb_serial_port *port = info->port; | ||
1407 | struct tty_struct *tty = port->tty; | 1410 | struct tty_struct *tty = port->tty; |
1408 | struct whiteheat_urb_wrap *wrap; | 1411 | struct whiteheat_urb_wrap *wrap; |
1409 | struct urb *urb; | 1412 | struct urb *urb; |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 302174b8e477..31f476a64790 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -383,9 +383,9 @@ static void fbcon_update_softback(struct vc_data *vc) | |||
383 | softback_top = 0; | 383 | softback_top = 0; |
384 | } | 384 | } |
385 | 385 | ||
386 | static void fb_flashcursor(void *private) | 386 | static void fb_flashcursor(struct work_struct *work) |
387 | { | 387 | { |
388 | struct fb_info *info = private; | 388 | struct fb_info *info = container_of(work, struct fb_info, queue); |
389 | struct fbcon_ops *ops = info->fbcon_par; | 389 | struct fbcon_ops *ops = info->fbcon_par; |
390 | struct display *p; | 390 | struct display *p; |
391 | struct vc_data *vc = NULL; | 391 | struct vc_data *vc = NULL; |
@@ -442,7 +442,7 @@ static void fbcon_add_cursor_timer(struct fb_info *info) | |||
442 | if ((!info->queue.func || info->queue.func == fb_flashcursor) && | 442 | if ((!info->queue.func || info->queue.func == fb_flashcursor) && |
443 | !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) { | 443 | !(ops->flags & FBCON_FLAGS_CURSOR_TIMER)) { |
444 | if (!info->queue.func) | 444 | if (!info->queue.func) |
445 | INIT_WORK(&info->queue, fb_flashcursor, info); | 445 | INIT_WORK(&info->queue, fb_flashcursor); |
446 | 446 | ||
447 | init_timer(&ops->cursor_timer); | 447 | init_timer(&ops->cursor_timer); |
448 | ops->cursor_timer.function = cursor_timer_handler; | 448 | ops->cursor_timer.function = cursor_timer_handler; |
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index fdb33cd21a27..cb26c6df0583 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/prom.h> | 34 | #include <asm/prom.h> |
35 | #include <asm/pgtable.h> | 35 | #include <asm/pgtable.h> |
36 | #include <asm/of_device.h> | 36 | #include <asm/of_device.h> |
37 | #include <asm/of_platform.h> | ||
37 | 38 | ||
38 | #include "macmodes.h" | 39 | #include "macmodes.h" |
39 | #include "platinumfb.h" | 40 | #include "platinumfb.h" |
@@ -682,14 +683,14 @@ static int __init platinumfb_init(void) | |||
682 | return -ENODEV; | 683 | return -ENODEV; |
683 | platinumfb_setup(option); | 684 | platinumfb_setup(option); |
684 | #endif | 685 | #endif |
685 | of_register_driver(&platinum_driver); | 686 | of_register_platform_driver(&platinum_driver); |
686 | 687 | ||
687 | return 0; | 688 | return 0; |
688 | } | 689 | } |
689 | 690 | ||
690 | static void __exit platinumfb_exit(void) | 691 | static void __exit platinumfb_exit(void) |
691 | { | 692 | { |
692 | of_unregister_driver(&platinum_driver); | 693 | of_unregister_platform_driver(&platinum_driver); |
693 | } | 694 | } |
694 | 695 | ||
695 | MODULE_LICENSE("GPL"); | 696 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 8a8ae55a7403..38eb0b69c2d7 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -964,9 +964,10 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state) | |||
964 | * Our LCD controller task (which is called when we blank or unblank) | 964 | * Our LCD controller task (which is called when we blank or unblank) |
965 | * via keventd. | 965 | * via keventd. |
966 | */ | 966 | */ |
967 | static void pxafb_task(void *dummy) | 967 | static void pxafb_task(struct work_struct *work) |
968 | { | 968 | { |
969 | struct pxafb_info *fbi = dummy; | 969 | struct pxafb_info *fbi = |
970 | container_of(work, struct pxafb_info, task); | ||
970 | u_int state = xchg(&fbi->task_state, -1); | 971 | u_int state = xchg(&fbi->task_state, -1); |
971 | 972 | ||
972 | set_ctrlr_state(fbi, state); | 973 | set_ctrlr_state(fbi, state); |
@@ -1159,7 +1160,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) | |||
1159 | } | 1160 | } |
1160 | 1161 | ||
1161 | init_waitqueue_head(&fbi->ctrlr_wait); | 1162 | init_waitqueue_head(&fbi->ctrlr_wait); |
1162 | INIT_WORK(&fbi->task, pxafb_task, fbi); | 1163 | INIT_WORK(&fbi->task, pxafb_task); |
1163 | init_MUTEX(&fbi->ctrlr_sem); | 1164 | init_MUTEX(&fbi->ctrlr_sem); |
1164 | 1165 | ||
1165 | return fbi; | 1166 | return fbi; |