⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dac960.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers  Copyright 1998-2000 by Leonard N. Zubkoff <lnz@dandelion.com>  This program is free software; you may redistribute and/or modify it under  the terms of the GNU General Public License Version 2 as published by the  Free Software Foundation.  This program is distributed in the hope that it will be useful, but  WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License  for complete details.  The author respectfully requests that any modifications to this software be  sent directly to him for evaluation and testing.*/#define DAC960_DriverVersion			"2.4.9"#define DAC960_DriverDate			"7 September 2000"#include <linux/version.h>#include <linux/module.h>#include <linux/types.h>#include <linux/blk.h>#include <linux/blkdev.h>#include <linux/delay.h>#include <linux/hdreg.h>#include <linux/interrupt.h>#include <linux/ioport.h>#include <linux/locks.h>#include <linux/mm.h>#include <linux/malloc.h>#include <linux/proc_fs.h>#include <linux/reboot.h>#include <linux/spinlock.h>#include <linux/timer.h>#include <linux/pci.h>#include <asm/io.h>#include <asm/segment.h>#include <asm/uaccess.h>#include "DAC960.h"/*  DAC960_ControllerCount is the number of DAC960 Controllers detected.*/static int  DAC960_ControllerCount;/*  DAC960_ActiveControllerCount is the number of active DAC960 Controllers  detected.*/static int  DAC960_ActiveControllerCount;/*  DAC960_Controllers is an array of pointers to the DAC960 Controller  structures.*/static DAC960_Controller_T  *DAC960_Controllers[DAC960_MaxControllers];/*  DAC960_BlockDeviceOperations is the Block Device Operations structure for  DAC960 Logical Disk Devices.*/static BlockDeviceOperations_T  DAC960_BlockDeviceOperations =    { open:		    DAC960_Open,      release:		    DAC960_Release,      ioctl:		    DAC960_IOCTL };/*  DAC960_ProcDirectoryEntry is the DAC960 /proc/rd directory entry.*/static PROC_DirectoryEntry_T  *DAC960_ProcDirectoryEntry;/*  DAC960_NotifierBlock is the Notifier Block structure for DAC960 Driver.*/static NotifierBlock_T  DAC960_NotifierBlock =    { DAC960_Finalize, NULL, 0 };/*  DAC960_AnnounceDriver announces the Driver Version and Date, Author's Name,  Copyright Notice, and Electronic Mail Address.*/static void DAC960_AnnounceDriver(DAC960_Controller_T *Controller){  DAC960_Announce("***** DAC960 RAID Driver Version "		  DAC960_DriverVersion " of "		  DAC960_DriverDate " *****\n", Controller);  DAC960_Announce("Copyright 1998-2000 by Leonard N. Zubkoff "		  "<lnz@dandelion.com>\n", Controller);}/*  DAC960_Failure prints a standardized error message, and then returns false.*/static boolean DAC960_Failure(DAC960_Controller_T *Controller,			      unsigned char *ErrorMessage){  DAC960_Error("While configuring DAC960 PCI RAID Controller at\n",	       Controller);  if (Controller->IO_Address == 0)    DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "		 "PCI Address 0x%X\n", Controller,		 Controller->Bus, Controller->Device,		 Controller->Function, Controller->PCI_Address);  else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "		    "0x%X PCI Address 0x%X\n", Controller,		    Controller->Bus, Controller->Device,		    Controller->Function, Controller->IO_Address,		    Controller->PCI_Address);  DAC960_Error("%s FAILED - DETACHING\n", Controller, ErrorMessage);  return false;}/*  DAC960_CreateAuxiliaryStructures allocates and initializes the auxiliary  data structures for Controller.  It returns true on success and false on  failure.*/static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller){  int CommandAllocationLength, CommandAllocationGroupSize;  int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount;  void *AllocationPointer = NULL;  if (Controller->FirmwareType == DAC960_V1_Controller)    {      CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker);      CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize;    }  else    {      CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker);      CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize;    }  Controller->CommandAllocationGroupSize = CommandAllocationGroupSize;  Controller->FreeCommands = NULL;  for (CommandIdentifier = 1;       CommandIdentifier <= Controller->DriverQueueDepth;       CommandIdentifier++)    {      DAC960_Command_T *Command;      if (--CommandsRemaining <= 0)	{	  CommandsRemaining =	    Controller->DriverQueueDepth - CommandIdentifier + 1;	  if (CommandsRemaining > CommandAllocationGroupSize)	    CommandsRemaining = CommandAllocationGroupSize;	  CommandGroupByteCount =	    CommandsRemaining * CommandAllocationLength;	  AllocationPointer = kmalloc(CommandGroupByteCount, GFP_ATOMIC);	  if (AllocationPointer == NULL)	    return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");	  memset(AllocationPointer, 0, CommandGroupByteCount);	}      Command = (DAC960_Command_T *) AllocationPointer;      AllocationPointer += CommandAllocationLength;      Command->CommandIdentifier = CommandIdentifier;      Command->Controller = Controller;      Command->Next = Controller->FreeCommands;      Controller->FreeCommands = Command;      Controller->Commands[CommandIdentifier-1] = Command;    }  return true;}/*  DAC960_DestroyAuxiliaryStructures deallocates the auxiliary data  structures for Controller.*/static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller){  int i;  Controller->FreeCommands = NULL;  for (i = 0; i < Controller->DriverQueueDepth; i++)    {      DAC960_Command_T *Command = Controller->Commands[i];      if (Command != NULL &&	  (Command->CommandIdentifier	   % Controller->CommandAllocationGroupSize) == 1)	kfree(Command);      Controller->Commands[i] = NULL;    }  if (Controller->CombinedStatusBuffer != NULL)    {      kfree(Controller->CombinedStatusBuffer);      Controller->CombinedStatusBuffer = NULL;      Controller->CurrentStatusBuffer = NULL;    }  if (Controller->FirmwareType == DAC960_V1_Controller) return;  for (i = 0; i < DAC960_MaxLogicalDrives; i++)    if (Controller->V2.LogicalDeviceInformation[i] != NULL)      {	kfree(Controller->V2.LogicalDeviceInformation[i]);	Controller->V2.LogicalDeviceInformation[i] = NULL;      }  for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)    {      if (Controller->V2.PhysicalDeviceInformation[i] != NULL)	{	  kfree(Controller->V2.PhysicalDeviceInformation[i]);	  Controller->V2.PhysicalDeviceInformation[i] = NULL;	}      if (Controller->V2.InquiryUnitSerialNumber[i] != NULL)	{	  kfree(Controller->V2.InquiryUnitSerialNumber[i]);	  Controller->V2.InquiryUnitSerialNumber[i] = NULL;	}    }}/*  DAC960_V1_ClearCommand clears critical fields of Command for DAC960 V1  Firmware Controllers.*/static inline void DAC960_V1_ClearCommand(DAC960_Command_T *Command){  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;  memset(CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T));  Command->V1.CommandStatus = 0;}/*  DAC960_V2_ClearCommand clears critical fields of Command for DAC960 V2  Firmware Controllers.*/static inline void DAC960_V2_ClearCommand(DAC960_Command_T *Command){  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;  memset(CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));  Command->V2.CommandStatus = 0;}/*  DAC960_AllocateCommand allocates a Command structure from Controller's  free list.*/static inline DAC960_Command_T *DAC960_AllocateCommand(DAC960_Controller_T						       *Controller){  DAC960_Command_T *Command = Controller->FreeCommands;  if (Command == NULL) return NULL;  Controller->FreeCommands = Command->Next;  Command->Next = NULL;  return Command;}/*  DAC960_DeallocateCommand deallocates Command, returning it to Controller's  free list.*/static inline void DAC960_DeallocateCommand(DAC960_Command_T *Command){  DAC960_Controller_T *Controller = Command->Controller;  Command->Next = Controller->FreeCommands;  Controller->FreeCommands = Command;}/*  DAC960_WaitForCommand waits for a wake_up on Controller's Command Wait Queue.*/static void DAC960_WaitForCommand(DAC960_Controller_T *Controller){  spin_unlock_irq(&io_request_lock);  __wait_event(Controller->CommandWaitQueue, Controller->FreeCommands);  spin_lock_irq(&io_request_lock);}/*  DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers.*/static void DAC960_BA_QueueCommand(DAC960_Command_T *Command){  DAC960_Controller_T *Controller = Command->Controller;  void *ControllerBaseAddress = Controller->BaseAddress;  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;  DAC960_V2_CommandMailbox_T *NextCommandMailbox =    Controller->V2.NextCommandMailbox;  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;  DAC960_BA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);  if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||      Controller->V2.PreviousCommandMailbox2->Words[0] == 0)    DAC960_BA_MemoryMailboxNewCommand(ControllerBaseAddress);  Controller->V2.PreviousCommandMailbox2 =    Controller->V2.PreviousCommandMailbox1;  Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;  if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)    NextCommandMailbox = Controller->V2.FirstCommandMailbox;  Controller->V2.NextCommandMailbox = NextCommandMailbox;}/*  DAC960_LP_QueueCommand queues Command for DAC960 LP Series Controllers.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -