diff options
Diffstat (limited to 'drivers/block/DAC960.c')
-rw-r--r-- | drivers/block/DAC960.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 423bbf2000d2..3760edfdc65c 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -3,6 +3,7 @@ | |||
3 | Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers | 3 | Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers |
4 | 4 | ||
5 | Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com> | 5 | Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com> |
6 | Portions Copyright 2002 by Mylex (An IBM Business Unit) | ||
6 | 7 | ||
7 | This program is free software; you may redistribute and/or modify it under | 8 | This program is free software; you may redistribute and/or modify it under |
8 | the terms of the GNU General Public License Version 2 as published by the | 9 | the terms of the GNU General Public License Version 2 as published by the |
@@ -532,6 +533,34 @@ static void DAC960_WaitForCommand(DAC960_Controller_T *Controller) | |||
532 | spin_lock_irq(&Controller->queue_lock); | 533 | spin_lock_irq(&Controller->queue_lock); |
533 | } | 534 | } |
534 | 535 | ||
536 | /* | ||
537 | DAC960_GEM_QueueCommand queues Command for DAC960 GEM Series Controllers. | ||
538 | */ | ||
539 | |||
540 | static void DAC960_GEM_QueueCommand(DAC960_Command_T *Command) | ||
541 | { | ||
542 | DAC960_Controller_T *Controller = Command->Controller; | ||
543 | void __iomem *ControllerBaseAddress = Controller->BaseAddress; | ||
544 | DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; | ||
545 | DAC960_V2_CommandMailbox_T *NextCommandMailbox = | ||
546 | Controller->V2.NextCommandMailbox; | ||
547 | |||
548 | CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; | ||
549 | DAC960_GEM_WriteCommandMailbox(NextCommandMailbox, CommandMailbox); | ||
550 | |||
551 | if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 || | ||
552 | Controller->V2.PreviousCommandMailbox2->Words[0] == 0) | ||
553 | DAC960_GEM_MemoryMailboxNewCommand(ControllerBaseAddress); | ||
554 | |||
555 | Controller->V2.PreviousCommandMailbox2 = | ||
556 | Controller->V2.PreviousCommandMailbox1; | ||
557 | Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox; | ||
558 | |||
559 | if (++NextCommandMailbox > Controller->V2.LastCommandMailbox) | ||
560 | NextCommandMailbox = Controller->V2.FirstCommandMailbox; | ||
561 | |||
562 | Controller->V2.NextCommandMailbox = NextCommandMailbox; | ||
563 | } | ||
535 | 564 | ||
536 | /* | 565 | /* |
537 | DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers. | 566 | DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers. |
@@ -1464,6 +1493,17 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T | |||
1464 | Controller->V2.FirstStatusMailboxDMA; | 1493 | Controller->V2.FirstStatusMailboxDMA; |
1465 | switch (Controller->HardwareType) | 1494 | switch (Controller->HardwareType) |
1466 | { | 1495 | { |
1496 | case DAC960_GEM_Controller: | ||
1497 | while (DAC960_GEM_HardwareMailboxFullP(ControllerBaseAddress)) | ||
1498 | udelay(1); | ||
1499 | DAC960_GEM_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA); | ||
1500 | DAC960_GEM_HardwareMailboxNewCommand(ControllerBaseAddress); | ||
1501 | while (!DAC960_GEM_HardwareMailboxStatusAvailableP(ControllerBaseAddress)) | ||
1502 | udelay(1); | ||
1503 | CommandStatus = DAC960_GEM_ReadCommandStatus(ControllerBaseAddress); | ||
1504 | DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); | ||
1505 | DAC960_GEM_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); | ||
1506 | break; | ||
1467 | case DAC960_BA_Controller: | 1507 | case DAC960_BA_Controller: |
1468 | while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress)) | 1508 | while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress)) |
1469 | udelay(1); | 1509 | udelay(1); |
@@ -2627,6 +2667,9 @@ static void DAC960_DetectCleanup(DAC960_Controller_T *Controller) | |||
2627 | if (Controller->MemoryMappedAddress) { | 2667 | if (Controller->MemoryMappedAddress) { |
2628 | switch(Controller->HardwareType) | 2668 | switch(Controller->HardwareType) |
2629 | { | 2669 | { |
2670 | case DAC960_GEM_Controller: | ||
2671 | DAC960_GEM_DisableInterrupts(Controller->BaseAddress); | ||
2672 | break; | ||
2630 | case DAC960_BA_Controller: | 2673 | case DAC960_BA_Controller: |
2631 | DAC960_BA_DisableInterrupts(Controller->BaseAddress); | 2674 | DAC960_BA_DisableInterrupts(Controller->BaseAddress); |
2632 | break; | 2675 | break; |
@@ -2705,6 +2748,9 @@ DAC960_DetectController(struct pci_dev *PCI_Device, | |||
2705 | 2748 | ||
2706 | switch (Controller->HardwareType) | 2749 | switch (Controller->HardwareType) |
2707 | { | 2750 | { |
2751 | case DAC960_GEM_Controller: | ||
2752 | Controller->PCI_Address = pci_resource_start(PCI_Device, 0); | ||
2753 | break; | ||
2708 | case DAC960_BA_Controller: | 2754 | case DAC960_BA_Controller: |
2709 | Controller->PCI_Address = pci_resource_start(PCI_Device, 0); | 2755 | Controller->PCI_Address = pci_resource_start(PCI_Device, 0); |
2710 | break; | 2756 | break; |
@@ -2756,6 +2802,36 @@ DAC960_DetectController(struct pci_dev *PCI_Device, | |||
2756 | BaseAddress = Controller->BaseAddress; | 2802 | BaseAddress = Controller->BaseAddress; |
2757 | switch (Controller->HardwareType) | 2803 | switch (Controller->HardwareType) |
2758 | { | 2804 | { |
2805 | case DAC960_GEM_Controller: | ||
2806 | DAC960_GEM_DisableInterrupts(BaseAddress); | ||
2807 | DAC960_GEM_AcknowledgeHardwareMailboxStatus(BaseAddress); | ||
2808 | udelay(1000); | ||
2809 | while (DAC960_GEM_InitializationInProgressP(BaseAddress)) | ||
2810 | { | ||
2811 | if (DAC960_GEM_ReadErrorStatus(BaseAddress, &ErrorStatus, | ||
2812 | &Parameter0, &Parameter1) && | ||
2813 | DAC960_ReportErrorStatus(Controller, ErrorStatus, | ||
2814 | Parameter0, Parameter1)) | ||
2815 | goto Failure; | ||
2816 | udelay(10); | ||
2817 | } | ||
2818 | if (!DAC960_V2_EnableMemoryMailboxInterface(Controller)) | ||
2819 | { | ||
2820 | DAC960_Error("Unable to Enable Memory Mailbox Interface " | ||
2821 | "for Controller at\n", Controller); | ||
2822 | goto Failure; | ||
2823 | } | ||
2824 | DAC960_GEM_EnableInterrupts(BaseAddress); | ||
2825 | Controller->QueueCommand = DAC960_GEM_QueueCommand; | ||
2826 | Controller->ReadControllerConfiguration = | ||
2827 | DAC960_V2_ReadControllerConfiguration; | ||
2828 | Controller->ReadDeviceConfiguration = | ||
2829 | DAC960_V2_ReadDeviceConfiguration; | ||
2830 | Controller->ReportDeviceConfiguration = | ||
2831 | DAC960_V2_ReportDeviceConfiguration; | ||
2832 | Controller->QueueReadWriteCommand = | ||
2833 | DAC960_V2_QueueReadWriteCommand; | ||
2834 | break; | ||
2759 | case DAC960_BA_Controller: | 2835 | case DAC960_BA_Controller: |
2760 | DAC960_BA_DisableInterrupts(BaseAddress); | 2836 | DAC960_BA_DisableInterrupts(BaseAddress); |
2761 | DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress); | 2837 | DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress); |
@@ -5189,6 +5265,47 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) | |||
5189 | wake_up(&Controller->CommandWaitQueue); | 5265 | wake_up(&Controller->CommandWaitQueue); |
5190 | } | 5266 | } |
5191 | 5267 | ||
5268 | /* | ||
5269 | DAC960_GEM_InterruptHandler handles hardware interrupts from DAC960 GEM Series | ||
5270 | Controllers. | ||
5271 | */ | ||
5272 | |||
5273 | static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel, | ||
5274 | void *DeviceIdentifier, | ||
5275 | struct pt_regs *InterruptRegisters) | ||
5276 | { | ||
5277 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier; | ||
5278 | void __iomem *ControllerBaseAddress = Controller->BaseAddress; | ||
5279 | DAC960_V2_StatusMailbox_T *NextStatusMailbox; | ||
5280 | unsigned long flags; | ||
5281 | |||
5282 | spin_lock_irqsave(&Controller->queue_lock, flags); | ||
5283 | DAC960_GEM_AcknowledgeInterrupt(ControllerBaseAddress); | ||
5284 | NextStatusMailbox = Controller->V2.NextStatusMailbox; | ||
5285 | while (NextStatusMailbox->Fields.CommandIdentifier > 0) | ||
5286 | { | ||
5287 | DAC960_V2_CommandIdentifier_T CommandIdentifier = | ||
5288 | NextStatusMailbox->Fields.CommandIdentifier; | ||
5289 | DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1]; | ||
5290 | Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus; | ||
5291 | Command->V2.RequestSenseLength = | ||
5292 | NextStatusMailbox->Fields.RequestSenseLength; | ||
5293 | Command->V2.DataTransferResidue = | ||
5294 | NextStatusMailbox->Fields.DataTransferResidue; | ||
5295 | NextStatusMailbox->Words[0] = 0; | ||
5296 | if (++NextStatusMailbox > Controller->V2.LastStatusMailbox) | ||
5297 | NextStatusMailbox = Controller->V2.FirstStatusMailbox; | ||
5298 | DAC960_V2_ProcessCompletedCommand(Command); | ||
5299 | } | ||
5300 | Controller->V2.NextStatusMailbox = NextStatusMailbox; | ||
5301 | /* | ||
5302 | Attempt to remove additional I/O Requests from the Controller's | ||
5303 | I/O Request Queue and queue them to the Controller. | ||
5304 | */ | ||
5305 | DAC960_ProcessRequest(Controller); | ||
5306 | spin_unlock_irqrestore(&Controller->queue_lock, flags); | ||
5307 | return IRQ_HANDLED; | ||
5308 | } | ||
5192 | 5309 | ||
5193 | /* | 5310 | /* |
5194 | DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series | 5311 | DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series |
@@ -6962,6 +7079,14 @@ static void DAC960_gam_cleanup(void) | |||
6962 | 7079 | ||
6963 | #endif /* DAC960_GAM_MINOR */ | 7080 | #endif /* DAC960_GAM_MINOR */ |
6964 | 7081 | ||
7082 | static struct DAC960_privdata DAC960_GEM_privdata = { | ||
7083 | .HardwareType = DAC960_GEM_Controller, | ||
7084 | .FirmwareType = DAC960_V2_Controller, | ||
7085 | .InterruptHandler = DAC960_GEM_InterruptHandler, | ||
7086 | .MemoryWindowSize = DAC960_GEM_RegisterWindowSize, | ||
7087 | }; | ||
7088 | |||
7089 | |||
6965 | static struct DAC960_privdata DAC960_BA_privdata = { | 7090 | static struct DAC960_privdata DAC960_BA_privdata = { |
6966 | .HardwareType = DAC960_BA_Controller, | 7091 | .HardwareType = DAC960_BA_Controller, |
6967 | .FirmwareType = DAC960_V2_Controller, | 7092 | .FirmwareType = DAC960_V2_Controller, |
@@ -7007,6 +7132,13 @@ static struct DAC960_privdata DAC960_P_privdata = { | |||
7007 | static struct pci_device_id DAC960_id_table[] = { | 7132 | static struct pci_device_id DAC960_id_table[] = { |
7008 | { | 7133 | { |
7009 | .vendor = PCI_VENDOR_ID_MYLEX, | 7134 | .vendor = PCI_VENDOR_ID_MYLEX, |
7135 | .device = PCI_DEVICE_ID_MYLEX_DAC960_GEM, | ||
7136 | .subvendor = PCI_ANY_ID, | ||
7137 | .subdevice = PCI_ANY_ID, | ||
7138 | .driver_data = (unsigned long) &DAC960_GEM_privdata, | ||
7139 | }, | ||
7140 | { | ||
7141 | .vendor = PCI_VENDOR_ID_MYLEX, | ||
7010 | .device = PCI_DEVICE_ID_MYLEX_DAC960_BA, | 7142 | .device = PCI_DEVICE_ID_MYLEX_DAC960_BA, |
7011 | .subvendor = PCI_ANY_ID, | 7143 | .subvendor = PCI_ANY_ID, |
7012 | .subdevice = PCI_ANY_ID, | 7144 | .subdevice = PCI_ANY_ID, |