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

📄 dac960.c

📁 Linux块设备驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers  Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com>  Portions Copyright 2002 by Mylex (An IBM Business Unit)  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.*/#define DAC960_DriverVersion			"2.5.47"#define DAC960_DriverDate			"14 November 2002"#include <linux/module.h>#include <linux/types.h>#include <linux/miscdevice.h>#include <linux/blkdev.h>#include <linux/bio.h>#include <linux/completion.h>#include <linux/delay.h>#include <linux/genhd.h>#include <linux/hdreg.h>#include <linux/blkpg.h>#include <linux/interrupt.h>#include <linux/ioport.h>#include <linux/mm.h>#include <linux/slab.h>#include <linux/proc_fs.h>#include <linux/reboot.h>#include <linux/spinlock.h>#include <linux/timer.h>#include <linux/pci.h>#include <linux/init.h>#include <asm/io.h>#include <asm/uaccess.h>#include "DAC960.h"#define DAC960_GAM_MINOR	252static DAC960_Controller_T *DAC960_Controllers[DAC960_MaxControllers];static int DAC960_ControllerCount;static struct proc_dir_entry *DAC960_ProcDirectoryEntry;static long disk_size(DAC960_Controller_T *p, int drive_nr){	if (p->FirmwareType == DAC960_V1_Controller) {		if (drive_nr >= p->LogicalDriveCount)			return 0;		return p->V1.LogicalDriveInformation[drive_nr].			LogicalDriveSize;	} else {		DAC960_V2_LogicalDeviceInfo_T *i =			p->V2.LogicalDeviceInformation[drive_nr];		if (i == NULL)			return 0;		return i->ConfigurableDeviceSize;	}}static int DAC960_open(struct inode *inode, struct file *file){	struct gendisk *disk = inode->i_bdev->bd_disk;	DAC960_Controller_T *p = disk->queue->queuedata;	int drive_nr = (long)disk->private_data;	if (p->FirmwareType == DAC960_V1_Controller) {		if (p->V1.LogicalDriveInformation[drive_nr].		    LogicalDriveState == DAC960_V1_LogicalDrive_Offline)			return -ENXIO;	} else {		DAC960_V2_LogicalDeviceInfo_T *i =			p->V2.LogicalDeviceInformation[drive_nr];		if (!i || i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline)			return -ENXIO;	}	check_disk_change(inode->i_bdev);	if (!get_capacity(p->disks[drive_nr]))		return -ENXIO;	return 0;}static int DAC960_ioctl(struct inode *inode, struct file *file,			unsigned int cmd, unsigned long arg){	struct gendisk *disk = inode->i_bdev->bd_disk;	DAC960_Controller_T *p = disk->queue->queuedata;	int drive_nr = (long)disk->private_data;	struct hd_geometry g;	struct hd_geometry __user *loc = (struct hd_geometry __user *)arg;	if (cmd != HDIO_GETGEO || !loc)		return -EINVAL;	if (p->FirmwareType == DAC960_V1_Controller) {		g.heads = p->V1.GeometryTranslationHeads;		g.sectors = p->V1.GeometryTranslationSectors;		g.cylinders = p->V1.LogicalDriveInformation[drive_nr].			LogicalDriveSize / (g.heads * g.sectors);	} else {		DAC960_V2_LogicalDeviceInfo_T *i =			p->V2.LogicalDeviceInformation[drive_nr];		switch (i->DriveGeometry) {		case DAC960_V2_Geometry_128_32:			g.heads = 128;			g.sectors = 32;			break;		case DAC960_V2_Geometry_255_63:			g.heads = 255;			g.sectors = 63;			break;		default:			DAC960_Error("Illegal Logical Device Geometry %d\n",					p, i->DriveGeometry);			return -EINVAL;		}		g.cylinders = i->ConfigurableDeviceSize / (g.heads * g.sectors);	}		g.start = get_start_sect(inode->i_bdev);	return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; }static int DAC960_media_changed(struct gendisk *disk){	DAC960_Controller_T *p = disk->queue->queuedata;	int drive_nr = (long)disk->private_data;	if (!p->LogicalDriveInitiallyAccessible[drive_nr])		return 1;	return 0;}static int DAC960_revalidate_disk(struct gendisk *disk){	DAC960_Controller_T *p = disk->queue->queuedata;	int unit = (long)disk->private_data;	set_capacity(disk, disk_size(p, unit));	return 0;}static struct block_device_operations DAC960_BlockDeviceOperations = {	.owner			= THIS_MODULE,	.open			= DAC960_open,	.ioctl			= DAC960_ioctl,	.media_changed		= DAC960_media_changed,	.revalidate_disk	= DAC960_revalidate_disk,};/*  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-2001 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;}/*  init_dma_loaf() and slice_dma_loaf() are helper functions for  aggregating the dma-mapped memory for a well-known collection of  data structures that are of different lengths.  These routines don't guarantee any alignment.  The caller must  include any space needed for alignment in the sizes of the structures  that are passed in. */static boolean init_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf,								 size_t len){	void *cpu_addr;	dma_addr_t dma_handle;	cpu_addr = pci_alloc_consistent(dev, len, &dma_handle);	if (cpu_addr == NULL)		return false;		loaf->cpu_free = loaf->cpu_base = cpu_addr;	loaf->dma_free =loaf->dma_base = dma_handle;	loaf->length = len;	memset(cpu_addr, 0, len);	return true;}static void *slice_dma_loaf(struct dma_loaf *loaf, size_t len,					dma_addr_t *dma_handle){	void *cpu_end = loaf->cpu_free + len;	void *cpu_addr = loaf->cpu_free;	if (cpu_end > loaf->cpu_base + loaf->length)		BUG();	*dma_handle = loaf->dma_free;	loaf->cpu_free = cpu_end;	loaf->dma_free += len;	return cpu_addr;}static void free_dma_loaf(struct pci_dev *dev, struct dma_loaf *loaf_handle){	if (loaf_handle->cpu_base != NULL)		pci_free_consistent(dev, loaf_handle->length,			loaf_handle->cpu_base, loaf_handle->dma_base);}/*  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;  void *ScatterGatherCPU = NULL;  dma_addr_t ScatterGatherDMA;  struct pci_pool *ScatterGatherPool;  void *RequestSenseCPU = NULL;  dma_addr_t RequestSenseDMA;  struct pci_pool *RequestSensePool = NULL;  if (Controller->FirmwareType == DAC960_V1_Controller)    {      CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker);      CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize;      ScatterGatherPool = pci_pool_create("DAC960_V1_ScatterGather",		Controller->PCIDevice,	DAC960_V1_ScatterGatherLimit * sizeof(DAC960_V1_ScatterGatherSegment_T),	sizeof(DAC960_V1_ScatterGatherSegment_T), 0);      if (ScatterGatherPool == NULL)	    return DAC960_Failure(Controller,			"AUXILIARY STRUCTURE CREATION (SG)");      Controller->ScatterGatherPool = ScatterGatherPool;    }  else    {      CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker);      CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize;      ScatterGatherPool = pci_pool_create("DAC960_V2_ScatterGather",		Controller->PCIDevice,	DAC960_V2_ScatterGatherLimit * sizeof(DAC960_V2_ScatterGatherSegment_T),	sizeof(DAC960_V2_ScatterGatherSegment_T), 0);      if (ScatterGatherPool == NULL)	    return DAC960_Failure(Controller,			"AUXILIARY STRUCTURE CREATION (SG)");      RequestSensePool = pci_pool_create("DAC960_V2_RequestSense",		Controller->PCIDevice, sizeof(DAC960_SCSI_RequestSense_T),		sizeof(int), 0);      if (RequestSensePool == NULL) {	    pci_pool_destroy(ScatterGatherPool);	    return DAC960_Failure(Controller,			"AUXILIARY STRUCTURE CREATION (SG)");      }      Controller->ScatterGatherPool = ScatterGatherPool;      Controller->V2.RequestSensePool = RequestSensePool;    }  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;      ScatterGatherCPU = pci_pool_alloc(ScatterGatherPool, SLAB_ATOMIC,							&ScatterGatherDMA);      if (ScatterGatherCPU == NULL)	  return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");      if (RequestSensePool != NULL) {  	  RequestSenseCPU = pci_pool_alloc(RequestSensePool, SLAB_ATOMIC,						&RequestSenseDMA);  	  if (RequestSenseCPU == NULL) {                pci_pool_free(ScatterGatherPool, ScatterGatherCPU,                                ScatterGatherDMA);    		return DAC960_Failure(Controller,					"AUXILIARY STRUCTURE CREATION");	  }        }     if (Controller->FirmwareType == DAC960_V1_Controller) {        Command->cmd_sglist = Command->V1.ScatterList;

⌨️ 快捷键说明

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