eata.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,842 行 · 第 1/5 页

C
1,842
字号
 *  interrupts. * *  If you configure multiple boards on the same IRQ, the interrupt must *  be _level_ triggered (not _edge_ triggered). * *  This driver detects EATA boards by probes at fixed port addresses, *  so no BIOS32 or PCI BIOS support is required. *  The suggested way to detect a generic EATA PCI board is to force on it *  any unused EISA address, even if there are other controllers on the EISA *  bus, or even if you system has no EISA bus at all. *  Do not force any ISA address on EATA PCI boards. * *  If PCI bios support is configured into the kernel, BIOS32 is used to *  include in the list of i/o ports to be probed all the PCI SCSI controllers. * *  Due to a DPT BIOS "feature", it might not be possible to force an EISA *  address on more than a single DPT PCI board, so in this case you have to *  let the PCI BIOS assign the addresses. * *  The sequence of detection probes is: * *  - ISA 0x1F0; *  - PCI SCSI controllers (only if BIOS32 is available); *  - EISA/PCI 0x1C88 through 0xFC88 (corresponding to EISA slots 1 to 15); *  - ISA  0x170, 0x230, 0x330. * *  The above list of detection probes can be totally replaced by the *  boot command line option: "eata=port0,port1,port2,...", where the *  port0, port1... arguments are ISA/EISA/PCI addresses to be probed. *  For example using "eata=0x7410,0x7450,0x230", the driver probes *  only the two PCI addresses 0x7410 and 0x7450 and the ISA address 0x230, *  in this order; "eata=0" totally disables this driver. * *  After the optional list of detection probes, other possible command line *  options are: * *  et:y  force use of extended translation (255 heads, 63 sectors); *  et:n  use disk geometry detected by scsicam_bios_param; *  rs:y  reverse scan order while detecting PCI boards; *  rs:n  use BIOS order while detecting PCI boards; *  lc:y  enables linked commands; *  lc:n  disables linked commands; *  tm:0  disables tagged commands (same as tc:n); *  tm:1  use simple queue tags (same as tc:y); *  tm:2  use ordered queue tags (same as tc:2); *  mq:xx set the max queue depth to the value xx (2 <= xx <= 32). * *  The default value is: "eata=lc:n,mq:16,tm:0,et:n,rs:n". *  An example using the list of detection probes could be: *  "eata=0x7410,0x230,lc:y,tm:2,mq:4,et:n". * *  When loading as a module, parameters can be specified as well. *  The above example would be (use 1 in place of y and 0 in place of n): * *  modprobe eata io_port=0x7410,0x230 linked_comm=1 \ *                max_queue_depth=4 ext_tran=0 tag_mode=2 \ *                rev_scan=1 * *  ---------------------------------------------------------------------------- *  In this implementation, linked commands are designed to work with any DISK *  or CD-ROM, since this linking has only the intent of clustering (time-wise) *  and reordering by elevator sorting commands directed to each device, *  without any relation with the actual SCSI protocol between the controller *  and the device. *  If Q is the queue depth reported at boot time for each device (also named *  cmds/lun) and Q > 2, whenever there is already an active command to the *  device all other commands to the same device  (up to Q-1) are kept waiting *  in the elevator sorting queue. When the active command completes, the *  commands in this queue are sorted by sector address. The sort is chosen *  between increasing or decreasing by minimizing the seek distance between *  the sector of the commands just completed and the sector of the first *  command in the list to be sorted. *  Trivial math assures that the unsorted average seek distance when doing *  random seeks over S sectors is S/3. *  When (Q-1) requests are uniformly distributed over S sectors, the average *  distance between two adjacent requests is S/((Q-1) + 1), so the sorted *  average seek distance for (Q-1) random requests over S sectors is S/Q. *  The elevator sorting hence divides the seek distance by a factor Q/3. *  The above pure geometric remarks are valid in all cases and the *  driver effectively reduces the seek distance by the predicted factor *  when there are Q concurrent read i/o operations on the device, but this *  does not necessarily results in a noticeable performance improvement: *  your mileage may vary.... * *  Note: command reordering inside a batch of queued commands could cause *        wrong results only if there is at least one write request and the *        intersection (sector-wise) of all requests is not empty. *        When the driver detects a batch including overlapping requests *        (a really rare event) strict serial (pid) order is enforced. *  ---------------------------------------------------------------------------- *  The extended translation option (et:y) is useful when using large physical *  disks/arrays. It could also be useful when switching between Adaptec boards *  and DPT boards without reformatting the disk. *  When a boot disk is partitioned with extended translation, in order to *  be able to boot it with a DPT board is could be necessary to add to *  lilo.conf additional commands as in the following example: * *  fix-table *  disk=/dev/sda bios=0x80 sectors=63 heads=128 cylindres=546 * *  where the above geometry should be replaced with the one reported at *  power up by the DPT controller. *  ---------------------------------------------------------------------------- * *  The boards are named EATA0, EATA1,... according to the detection order. * *  In order to support multiple ISA boards in a reliable way, *  the driver sets host->wish_block = TRUE for all ISA boards. */#include <linux/config.h>#include <linux/string.h>#include <linux/kernel.h>#include <linux/ioport.h>#include <linux/delay.h>#include <asm/io.h>#include <asm/system.h>#include <asm/byteorder.h>#include <linux/proc_fs.h>#include <linux/blkdev.h>#include <linux/interrupt.h>#include <linux/stat.h>#include <linux/pci.h>#include <linux/init.h>#include <linux/ctype.h>#include <linux/spinlock.h>#include <scsi/scsicam.h>#include "scsi.h"#include <scsi/scsi_host.h>#include <asm/dma.h>#include <asm/irq.h>static int eata2x_detect(Scsi_Host_Template *);static int eata2x_release(struct Scsi_Host *);static int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));static int eata2x_eh_abort(Scsi_Cmnd *);static int eata2x_eh_host_reset(Scsi_Cmnd *);static int eata2x_bios_param(struct scsi_device *, struct block_device *,                             sector_t, int *);static int eata2x_slave_configure(Scsi_Device *);static Scsi_Host_Template driver_template = {                .name                    = "EATA/DMA 2.0x rev. 8.10.00 ",                .detect                  = eata2x_detect,                .release                 = eata2x_release,                .queuecommand            = eata2x_queuecommand,                .eh_abort_handler        = eata2x_eh_abort,                .eh_device_reset_handler = NULL,                .eh_bus_reset_handler    = NULL,                .eh_host_reset_handler   = eata2x_eh_host_reset,                .bios_param              = eata2x_bios_param,                .slave_configure         = eata2x_slave_configure,                .this_id                 = 7,                .unchecked_isa_dma       = 1,                .use_clustering          = ENABLE_CLUSTERING                };#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)#error "Adjust your <asm/byteorder.h> defines"#endif/* Subversion values */#define ISA  0#define ESA 1#undef  FORCE_CONFIG#undef  DEBUG_LINKED_COMMANDS#undef  DEBUG_DETECT#undef  DEBUG_PCI_DETECT#undef  DEBUG_INTERRUPT#undef  DEBUG_RESET#undef  DEBUG_GENERATE_ERRORS#undef  DEBUG_GENERATE_ABORTS#undef  DEBUG_GEOMETRY#define MAX_ISA 4#define MAX_VESA 0#define MAX_EISA 15#define MAX_PCI 16#define MAX_BOARDS (MAX_ISA + MAX_VESA + MAX_EISA + MAX_PCI)#define MAX_CHANNEL 4#define MAX_LUN 32#define MAX_TARGET 32#define MAX_MAILBOXES 64#define MAX_SGLIST 64#define MAX_LARGE_SGLIST 122#define MAX_INTERNAL_RETRIES 64#define MAX_CMD_PER_LUN 2#define MAX_TAGGED_CMD_PER_LUN (MAX_MAILBOXES - MAX_CMD_PER_LUN)#define SKIP ULONG_MAX#define FALSE 0#define TRUE 1#define FREE 0#define IN_USE   1#define LOCKED   2#define IN_RESET 3#define IGNORE   4#define READY    5#define ABORTING 6#define NO_DMA  0xff#define MAXLOOP  10000#define TAG_DISABLED 0#define TAG_SIMPLE   1#define TAG_ORDERED  2#define REG_CMD         7#define REG_STATUS      7#define REG_AUX_STATUS  8#define REG_DATA        0#define REG_DATA2       1#define REG_SEE         6#define REG_LOW         2#define REG_LM          3#define REG_MID         4#define REG_MSB         5#define REGION_SIZE     9UL#define MAX_ISA_ADDR    0x03ff#define MIN_EISA_ADDR   0x1c88#define MAX_EISA_ADDR   0xfc88#define BSY_ASSERTED      0x80#define DRQ_ASSERTED      0x08#define ABSY_ASSERTED     0x01#define IRQ_ASSERTED      0x02#define READ_CONFIG_PIO   0xf0#define SET_CONFIG_PIO    0xf1#define SEND_CP_PIO       0xf2#define RECEIVE_SP_PIO    0xf3#define TRUNCATE_XFR_PIO  0xf4#define RESET_PIO         0xf9#define READ_CONFIG_DMA   0xfd#define SET_CONFIG_DMA    0xfe#define SEND_CP_DMA       0xff#define ASOK              0x00#define ASST              0x01#define YESNO(a) ((a) ? 'y' : 'n')#define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM)/* "EATA", in Big Endian format */#define EATA_SIG_BE 0x45415441/* Number of valid bytes in the board config structure for EATA 2.0x */#define EATA_2_0A_SIZE 28#define EATA_2_0B_SIZE 30#define EATA_2_0C_SIZE 34/* Board info structure */struct eata_info {   u_int32_t data_len;  /* Number of valid bytes after this field */   u_int32_t sign;      /* ASCII "EATA" signature */#if defined(__BIG_ENDIAN_BITFIELD)   unchar version:4, :4;   unchar  haaval:1, ata:1, drqvld:1, dmasup:1, morsup:1, trnxfr:1, tarsup:1,           ocsena:1;#else   unchar        :4,    /* unused low nibble */          version:4;    /* EATA version, should be 0x1 */   unchar  ocsena:1,    /* Overlap Command Support Enabled */           tarsup:1,    /* Target Mode Supported */           trnxfr:1,    /* Truncate Transfer Cmd NOT Necessary */           morsup:1,    /* More Supported */           dmasup:1,    /* DMA Supported */           drqvld:1,    /* DRQ Index (DRQX) is valid */              ata:1,    /* This is an ATA device */           haaval:1;    /* Host Adapter Address Valid */#endif   ushort cp_pad_len;   /* Number of pad bytes after cp_len */   unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */   u_int32_t cp_len;    /* Number of valid bytes in cp */   u_int32_t sp_len;    /* Number of valid bytes in sp */   ushort queue_size;   /* Max number of cp that can be queued */   ushort unused;   ushort scatt_size;   /* Max number of entries in scatter/gather table */#if defined(__BIG_ENDIAN_BITFIELD)   unchar    drqx:2, second:1, irq_tr:1, irq:4;   unchar  sync;   unchar         :4, res1:1, large_sg:1, forcaddr:1, isaena:1;   unchar max_chan:3, max_id:5;   unchar   max_lun;   unchar     eisa:1, pci:1, idquest:1, m1:1, :4;#else   unchar     irq:4,    /* Interrupt Request assigned to this controller */           irq_tr:1,    /* 0 for edge triggered, 1 for level triggered */           second:1,    /* 1 if this is a secondary (not primary) controller */             drqx:2;    /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */   unchar  sync;        /* 1 if scsi target id 7...0 is running sync scsi */   /* Structure extension defined in EATA 2.0B */   unchar  isaena:1,    /* ISA i/o addressing is disabled/enabled */         forcaddr:1,    /* Port address has been forced */         large_sg:1,    /* 1 if large SG lists are supported */             res1:1,                 :4;   unchar  max_id:5,    /* Max SCSI target ID number */         max_chan:3;    /* Max SCSI channel number on this board */   /* Structure extension defined in EATA 2.0C */   unchar   max_lun;    /* Max SCSI LUN number */   unchar        :4,               m1:1,    /* This is a PCI with an M1 chip installed */          idquest:1,    /* RAIDNUM returned is questionable */              pci:1,    /* This board is PCI */             eisa:1;    /* This board is EISA */#endif   unchar   raidnum;    /* Uniquely identifies this HBA in a system */   unchar   notused;   ushort ipad[247];   };/* Board config structure */struct eata_config {   ushort len;          /* Number of bytes following this field */#if defined(__BIG_ENDIAN_BITFIELD)   unchar     :4, tarena:1, mdpena:1, ocena:1, edis:1;#else   unchar edis:1,       /* Disable EATA interface after config command */         ocena:1,       /* Overlapped Commands Enabled */        mdpena:1,       /* Transfer all Modified Data Pointer Messages */        tarena:1,       /* Target Mode Enabled for this controller */              :4;#endif   unchar cpad[511];   };/* Returned status packet structure */struct mssp {#if defined(__BIG_ENDIAN_BITFIELD)   unchar            eoc:1, adapter_status:7;#else   unchar adapter_status:7,    /* State related to current command */                     eoc:1;    /* End Of Command (1 = command completed) */#endif   unchar target_status;       /* SCSI status received after data transfer */   unchar unused[2];   u_int32_t inv_res_len;      /* Number of bytes not transferred */   u_int32_t cpp_index;        /* Index of address set in cp */   char mess[12];   };struct sg_list {   unsigned int address;                /* Segment Address */   unsigned int num_bytes;              /* Segment Length */   };/* MailBox SCSI Command Packet */struct mscp {#if defined(__BIG_ENDIAN_BITFIELD)   unchar     din:1, dout:1, interp:1, :1, sg:1, reqsen:1, init:1, sreset:1;   unchar sense_len;   unchar unused[3];   unchar        :7, fwnest:1;   unchar        :5, hbaci:1, iat:1, phsunit:1;   unchar channel:3, target:5;   unchar     one:1, dispri:1, luntar:1, lun:5;#else   unchar  sreset:1,     /* SCSI Bus Reset Signal should be asserted */             init:1,     /* Re-initialize controller and self test */           reqsen:1,     /* Transfer Request Sense Data to addr using DMA */

⌨️ 快捷键说明

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