aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/DAC960.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/DAC960.c')
-rw-r--r--drivers/block/DAC960.c132
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
540static 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
5273static 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
7082static 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
6965static struct DAC960_privdata DAC960_BA_privdata = { 7090static 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 = {
7007static struct pci_device_id DAC960_id_table[] = { 7132static 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,