diff -Ncr linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid100/atapi.h linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid100/atapi.h *** linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid100/atapi.h 2003-11-27 11:18:33.000000000 +0900 --- linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid100/atapi.h 2003-12-03 00:34:32.000000000 +0900 *************** *** 46,60 **** #define IDE_COMMAND_ENABLE_MEDIA_STATUS 0xEF // Feature Set #define IDE_COMMAND_IDENTIFY 0xEC // <--- #define IDE_COMMAND_MEDIA_EJECT 0xED ! ! ! //////////////////////////////////KHG133s_Big////////////////////////////////////// ! #define IDE_COMMAND_READ_DMA_EXT 0x25 ! #define IDE_COMMAND_WRITE_DMA_EXT 0x35 ! #define IDE_COMMAND_READ_SECTORS 0x20 ! #define IDE_COMMAND_WRITE_SECTORS 0x30 ! #define IDE_COMMAND_READ_SECTORS_EXT 0x24 ! #define IDE_COMMAND_WRITE_SECTORS_EXT 0x34 /////////////////////////////////////////////////////////////////////////////////// // //DmaCommand bits definition --- 46,60 ---- #define IDE_COMMAND_ENABLE_MEDIA_STATUS 0xEF // Feature Set #define IDE_COMMAND_IDENTIFY 0xEC // <--- #define IDE_COMMAND_MEDIA_EJECT 0xED ! ! ! //////////////////////////////////KHG133s_Big////////////////////////////////////// ! #define IDE_COMMAND_READ_DMA_EXT 0x25 ! #define IDE_COMMAND_WRITE_DMA_EXT 0x35 ! #define IDE_COMMAND_READ_SECTORS 0x20 ! #define IDE_COMMAND_WRITE_SECTORS 0x30 ! #define IDE_COMMAND_READ_SECTORS_EXT 0x24 ! #define IDE_COMMAND_WRITE_SECTORS_EXT 0x34 /////////////////////////////////////////////////////////////////////////////////// // //DmaCommand bits definition *************** *** 225,238 **** USHORT ReleaseTimeOverlapped; // 71 USHORT ReleaseTimeServiceCommand; // 72 USHORT MajorRevision; // 73 ! USHORT MinorRevision; // 74 ! ! //////////////////////////////////KHG-133s_Big//////////////////////////////// ! USHORT Reserved6[8]; // 75-82 ! USHORT BIT48; // 83 USHORT Reserved6_1[4]; // 84-87 ////////////////////////////////////////////////////////////////////////////// ! UCHAR UDMASupport; // 88 UCHAR UDMASelected; // /* --- 225,238 ---- USHORT ReleaseTimeOverlapped; // 71 USHORT ReleaseTimeServiceCommand; // 72 USHORT MajorRevision; // 73 ! USHORT MinorRevision; // 74 ! ! //////////////////////////////////KHG-133s_Big//////////////////////////////// ! USHORT Reserved6[8]; // 75-82 ! USHORT BIT48; // 83 USHORT Reserved6_1[4]; // 84-87 ////////////////////////////////////////////////////////////////////////////// ! UCHAR UDMASupport; // 88 UCHAR UDMASelected; // /* diff -Ncr linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid100/scsi_module.c linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid100/scsi_module.c *** linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid100/scsi_module.c 2003-11-27 11:18:33.000000000 +0900 --- linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid100/scsi_module.c 1970-01-01 09:00:00.000000000 +0900 *************** *** 1,71 **** - /* - * scsi_module.c Copyright (1994, 1995) Eric Youngdale. - * - * Support for loading low-level scsi drivers using the linux kernel loadable - * module interface. - * - * To use, the host adapter should first define and initialize the variable - * driver_template (datatype Scsi_Host_Template), and then include this file. - * This should also be wrapped in a #ifdef MODULE/#endif. - * - * The low -level driver must also define a release function which will - * free any irq assignments, release any dma channels, release any I/O - * address space that might be reserved, and otherwise clean up after itself. - * The idea is that the same driver should be able to be reloaded without - * any difficulty. This makes debugging new drivers easier, as you should - * be able to load the driver, test it, unload, modify and reload. - * - * One *very* important caveat. If the driver may need to do DMA on the - * ISA bus, you must have unchecked_isa_dma set in the device template, - * even if this might be changed during the detect routine. This is - * because the shpnt structure will be allocated in a special way so that - * it will be below the appropriate DMA limit - thus if your driver uses - * the hostdata field of shpnt, and the board must be able to access this - * via DMA, the shpnt structure must be in a DMA accessible region of - * memory. This comment would be relevant for something like the buslogic - * driver where there are many boards, only some of which do DMA onto the - * ISA bus. There is no convenient way of specifying whether the host - * needs to be in a ISA DMA accessible region of memory when you call - * scsi_register. - */ - - #include - #include - - static int __init init_this_scsi_driver(void) - { - driver_template.module = THIS_MODULE; - scsi_register_module(MODULE_SCSI_HA, &driver_template); - if (driver_template.present) - return 0; - - scsi_unregister_module(MODULE_SCSI_HA, &driver_template); - return -ENODEV; - } - - static void __exit exit_this_scsi_driver(void) - { - scsi_unregister_module(MODULE_SCSI_HA, &driver_template); - } - - module_init(init_this_scsi_driver); - module_exit(exit_this_scsi_driver); - - /* - * Overrides for Emacs so that we almost follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil - * tab-width: 8 - * End: - */ --- 0 ---- diff -Ncr linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid100/scsi_obsolete.h linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid100/scsi_obsolete.h *** linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid100/scsi_obsolete.h 2003-11-27 11:18:33.000000000 +0900 --- linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid100/scsi_obsolete.h 1970-01-01 09:00:00.000000000 +0900 *************** *** 1,106 **** - /* - * scsi_obsolete.h Copyright (C) 1997 Eric Youngdale - * - */ - - #ifndef _SCSI_OBSOLETE_H - #define _SCSI_OBSOLETE_H - - /* - * These are the return codes for the abort and reset functions. The mid-level - * code uses these to decide what to do next. Each of the low level abort - * and reset functions must correctly indicate what it has done. - * The descriptions are written from the point of view of the mid-level code, - * so that the return code is telling the mid-level drivers exactly what - * the low level driver has already done, and what remains to be done. - */ - - /* We did not do anything. - * Wait some more for this command to complete, and if this does not work, - * try something more serious. */ - #define SCSI_ABORT_SNOOZE 0 - - /* This means that we were able to abort the command. We have already - * called the mid-level done function, and do not expect an interrupt that - * will lead to another call to the mid-level done function for this command */ - #define SCSI_ABORT_SUCCESS 1 - - /* We called for an abort of this command, and we should get an interrupt - * when this succeeds. Thus we should not restore the timer for this - * command in the mid-level abort function. */ - #define SCSI_ABORT_PENDING 2 - - /* Unable to abort - command is currently on the bus. Grin and bear it. */ - #define SCSI_ABORT_BUSY 3 - - /* The command is not active in the low level code. Command probably - * finished. */ - #define SCSI_ABORT_NOT_RUNNING 4 - - /* Something went wrong. The low level driver will indicate the correct - * error condition when it calls scsi_done, so the mid-level abort function - * can simply wait until this comes through */ - #define SCSI_ABORT_ERROR 5 - - /* We do not know how to reset the bus, or we do not want to. Bummer. - * Anyway, just wait a little more for the command in question, and hope that - * it eventually finishes. If it never finishes, the SCSI device could - * hang, so use this with caution. */ - #define SCSI_RESET_SNOOZE 0 - - /* We do not know how to reset the bus, or we do not want to. Bummer. - * We have given up on this ever completing. The mid-level code will - * request sense information to decide how to proceed from here. */ - #define SCSI_RESET_PUNT 1 - - /* This means that we were able to reset the bus. We have restarted all of - * the commands that should be restarted, and we should be able to continue - * on normally from here. We do not expect any interrupts that will return - * DID_RESET to any of the other commands in the host_queue, and the mid-level - * code does not need to do anything special to keep the commands alive. - * If a hard reset was performed then all outstanding commands on the - * bus have been restarted. */ - #define SCSI_RESET_SUCCESS 2 - - /* We called for a reset of this bus, and we should get an interrupt - * when this succeeds. Each command should get its own status - * passed up to scsi_done, but this has not happened yet. - * If a hard reset was performed, then we expect an interrupt - * for *each* of the outstanding commands that will have the - * effect of restarting the commands. - */ - #define SCSI_RESET_PENDING 3 - - /* We did a reset, but do not expect an interrupt to signal DID_RESET. - * This tells the upper level code to request the sense info, and this - * should keep the command alive. */ - #define SCSI_RESET_WAKEUP 4 - - /* The command is not active in the low level code. Command probably - finished. */ - #define SCSI_RESET_NOT_RUNNING 5 - - /* Something went wrong, and we do not know how to fix it. */ - #define SCSI_RESET_ERROR 6 - - #define SCSI_RESET_SYNCHRONOUS 0x01 - #define SCSI_RESET_ASYNCHRONOUS 0x02 - #define SCSI_RESET_SUGGEST_BUS_RESET 0x04 - #define SCSI_RESET_SUGGEST_HOST_RESET 0x08 - /* - * This is a bitmask that is ored with one of the above codes. - * It tells the mid-level code that we did a hard reset. - */ - #define SCSI_RESET_BUS_RESET 0x100 - /* - * This is a bitmask that is ored with one of the above codes. - * It tells the mid-level code that we did a host adapter reset. - */ - #define SCSI_RESET_HOST_RESET 0x200 - /* - * Used to mask off bits and to obtain the basic action that was - * performed. - */ - #define SCSI_RESET_ACTION 0xff - - #endif /* SCSI_OBSOLETE_H */ --- 0 ---- diff -Ncr linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid100/ultima.c linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid100/ultima.c *** linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid100/ultima.c 2003-11-27 11:18:33.000000000 +0900 --- linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid100/ultima.c 2003-12-03 00:34:32.000000000 +0900 *************** *** 1,2134 **** ! /******************************************************************* ! ! Aralion Ultima ATA100 IDE Raid Controller ! Linux Device Driver source, programmed by soonsoo@hitel.net ! ! *******************************************************************/ ! //#define __BOOT_KERNEL_BOOT 1 ! ! //#define DEBUG1 1 ! //#define DEBUG2 1 ! //#define DEBUG3 1 ! //#define DEBUG4 1 ! ! #include ! #include ! #include ! #include ! #include ! #include "/usr/src/linux-2.4/drivers/scsi/scsi.h" ! #include "/usr/src/linux-2.4/drivers/scsi/hosts.h" ! #include "ultima.h" ! #include "atapi.h" ! #include ! #include ! #include ! #include ! #include ! #include ! #include ! #include ! #include /* for CONFIG_PCI */ ! #include ! #include /* for put_user_byte */ ! #include ! #include ! #include ! #include ! //#include "iocontrol.h" ! //#include "flash.h" ! ! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) ! #define KERNEL240 ! #else ! #define KERNEL220 ! #endif ! ! #define S_BOARD(x) (DiskID[x].DiskStatus.BoardID) ! #define S_CHAN(x) (DiskID[x].DiskStatus.Channel) ! #define S_DRV(x) (DiskID[x].DiskStatus.Drive) ! #define RAID(x) (DiskID[x].RaidStatus) ! ! //////////////////////////////////////////////////////////////////////////////////////// ! ! static void print_banner(struct Scsi_Host *shpnt); ! char * GetCmdName(char code); ! static void print_banner(struct Scsi_Host *shpnt); ! static void do_pause(ULONG amount); ! static int aralion_pci_bios_detect(int *irq); ! ULONG GetBlockCount(int BoardID,int channel,int drive); ! void SetBlockCount(int BoardID,int channel,int drive,ULONG nCount); ! int RequestAllIrq(); ! int PutOneDriveToDiskSet(int board,int disk,_DiskIDTable *DiskID,V6BDISKINFO *DiskInfo); ! void PutLBAvalue( ! ULONG IOPort1, ! ULONG lba, ! ULONG numsectors, ! ULONG DriveSelect); ! void DisableInterrupt(int BoardID); ! void EnableInterrupt(int BoardID); ! ULONG SetBoardInterruptFlag(int BoardID,int Channel,DWORD Status); ! ULONG SetScatterList( ! Scsi_Cmnd * SCpnt, ! ULONG lba, ! ULONG numsectors, ! ULONG ReadWrite); ! void SetIOPort(DISKLIST *pList,USHORT DmaRW,DWORD OrderFlag); ! void SetIOInformation(int tid,USHORT DmaRW,DWORD OrderFlag); ! ULONG PutOneScatterList( ! ULONG CurrentID, ! DWORD PrimaryDiskArrayCount, ! DISKLIST *PrimaryDiskArray, ! ULONG lba, ! ULONG buffer, ! USHORT length); ! void SetIDECommand(DWORD Command, DWORD order); ! DWORD BigDiskCommand (DWORD cmnd); ! void SetDMACommand(USHORT DmaRW,DWORD OrderFlag); ! void FillDump( Scsi_Cmnd * SCpnt); ! static int ReadDMA( ! Scsi_Cmnd * SCpnt, ! ULONG lba, ! ULONG numsectors); ! static int WriteDMA( ! Scsi_Cmnd * SCpnt, ! ULONG lba, ! ULONG numsectors); ! void GetUDMAMode( ! USHORT *mode, ! USHORT *Timing, ! IDENTIFY_DATA * IdentifyData); ! void SetUDMAMode( ! int BoardID, ! int Channel, ! int DriveSelect, ! IDENTIFY_DATA * IdentifyData); ! static int IdentifyDisk( ! int BoardID, ! int Channel, ! int DriveSelect, ! IDENTIFY_DATA * IdentifyData); ! static void my_done(int error); ! int CheckScsiError(ULONG Channel,ULONG IOPort1,UCHAR statusByte); ! void CheckJobFinished(ULONG BoardID,ULONG Channel); ! int IsSplitter(char c); ! int ultima_1cardreset(int BoardID); ! int ultima_cardreset(); ! void do_ultima_intr(int irq, void *dev_id, struct pt_regs *regs); ! void internal_done(Scsi_Cmnd * SCpnt); ! void print_info(Scsi_Cmnd * SCpnt); ! ! //////////////////////////////////////////////////////////////////////////////////////// ! ! struct proc_dir_entry proc_scsi_aralion = { ! 0x10, 7, "aralion", ! S_IFDIR | S_IRUGO | S_IXUGO, 2 ! }; ! ! Scsi_Host_Template driver_template = ULTIMA_DMA100; ! ! #define VERSION "$Revision: LV2.01X-X86-ATA $" ! ! ! enum { ! in_arbitration = 0x02, ! in_selection = 0x04, ! in_other = 0x08, ! disconnect = 0x10, ! aborted = 0x20, ! sent_ident = 0x40, ! }; ! ! typedef struct { ! char name[23]; ! char code; ! } CMDNAME; ! ! CMDNAME CmdName[] = ! { ! {"TEST_UNIT_READY",0x00}, ! {"REZERO_UNIT",0x01}, ! {"REQUEST_SENSE",0x03}, ! {"FORMAT_UNIT",0x04}, ! {"READ_BLOCK_LIMITS",0x05}, ! {"REASSIGN_BLOCKS",0x07}, ! {"READ_6",0x08}, ! {"WRITE_6",0x0a}, ! {"SEEK_6",0x0b}, ! {"READ_REVERSE",0x0f}, ! {"WRITE_FILEMARKS",0x10}, ! {"SPACE",0x11}, ! {"INQUIRY",0x12}, ! {"RECOVER_BUFFERED_DATA",0x14}, ! {"MODE_SELECT",0x15}, ! {"RESERVE",0x16}, ! {"RELEASE",0x17}, ! {"COPY",0x18}, ! {"ERASE",0x19}, ! {"MODE_SENSE",0x1a}, ! {"START_STOP",0x1b}, ! {"RECEIVE_DIAGNOSTIC",0x1c}, ! {"SEND_DIAGNOSTIC",0x1d}, ! {"ALLOW_MEDIUM_REMOVAL",0x1e}, ! {"SET_WINDOW",0x24}, ! {"READ_CAPACITY",0x25}, ! {"READ_10",0x28}, ! {"WRITE_10",0x2a}, ! {"SEEK_10",0x2b}, ! {"WRITE_VERIFY",0x2e}, ! {"VERIFY",0x2f}, ! {"SEARCH_HIGH",0x30}, ! {"SEARCH_EQUAL",0x31}, ! {"SEARCH_LOW",0x32}, ! {"SET_LIMITS",0x33}, ! {"PRE_FETCH",0x34}, ! {"READ_POSITION",0x34}, ! {"SYNCHRONIZE_CACHE",0x35}, ! {"LOCK_UNLOCK_CACHE",0x36}, ! {"READ_DEFECT_DATA",0x37}, ! {"MEDIUM_SCAN",0x38}, ! {"COMPARE",0x39}, ! {"COPY_VERIFY",0x3a}, ! {"WRITE_BUFFER",0x3b}, ! {"READ_BUFFER",0x3c}, ! {"UPDATE_BLOCK",0x3d}, ! {"READ_LONG",0x3e}, ! {"WRITE_LONG",0x3f}, ! {"CHANGE_DEFINITION",0x40}, ! {"WRITE_SAME",0x41}, ! {"READ_TOC",0x43}, ! {"LOG_SELECT",0x4c}, ! {"LOG_SENSE",0x4d}, ! {"MODE_SELECT_10",0x55}, ! {"RESERVE_10",0x56}, ! {"RELEASE_10",0x57}, ! {"MODE_SENSE_10",0x5a}, ! {"PERSISTENT_RESERVE_IN",0x5e}, ! {"PERSISTENT_RESERVE_OUT",0x5f}, ! {"MOVE_MEDIUM",0xa5}, ! {"READ_12",0xa8}, ! {"WRITE_12",0xaa}, ! {"WRITE_VERIFY_12",0xae}, ! {"SEARCH_HIGH_12",0xb0}, ! {"SEARCH_EQUAL_12",0xb1}, ! {"SEARCH_LOW_12",0xb2}, ! {"READ_ELEMENT_STATUS",0xb8}, ! {"SEND_VOLUME_TAG",0xb6}, ! {"WRITE_LONG_2",0xea} ! }; ! ! /////////////////////////////////////////////////////////////////////// ! static volatile int internal_done_flag = 0; ! static volatile int internal_done_errcode = 0; ! static Scsi_Cmnd *current_SC = NULL; ! static int this_id = 31; ! V6INTERFACEB V6; ! static _DiskIDTable DiskID[16]; ! static DISKRWINFO DiskRWInfo[MAXBOARD][2][2]; ! static IDENTIFY_DATA DiskIdentifyData[MAXBOARD][2][2]; ! static int gBoardCount = 0; ! IrqID ultimaID[MAXBOARD]; ! BOARDTABLE BoardInfo[MAXBOARD]; ! static int IrqFlag[16] = {0,}; ! static int DriverInit = 0; ! static int DiskCount = 0; ! ULONG LastErrorBlock,LastErrorCode; ! static ULONG RWStatus; ! static ULONG OrderStatus; ! static ULONG CurrentDisk; ! static int interrupt_level = 0; ! ///////////////////////////////////////////////// ! #define IOCTL_LOCK 1 ! static int in_ioctl = 0; ! static int ClearReady = 0; ! static int in_command = 0; ! unsigned long LockValue = 0; ! static DECLARE_WAIT_QUEUE_HEAD (WaitingQ); ! static int HddConnected[MAXBOARD][2][2]; ! ///////////////////////////////////////////////// ! DWORD gResetFlag = 0; ! char * GetCmdName(char code) ! { ! int i; ! int count; ! char *s = "unknown function"; ! ! count = sizeof(CmdName) / sizeof(CMDNAME); ! ! for(i=0;ithis_id); ! ! if (interrupt_level) ! printk(" int %d", interrupt_level); ! else ! printk(""); ! ! printk("\n"); ! } ! ! static void aralion_setup(char *str, int *ints) ! { ! this_id = 31; ! } ! ! ! /* Pause for amount*10 milliseconds */ ! static void do_pause(ULONG amount) ! { ! do ! { ! udelay(10 * 1000); ! } ! while (--amount); ! } ! ! inline static void aralion_make_bus_idle(void) ! { ! } ! ! static int aralion_is_valid_port(int port) ! { ! return 0; ! } ! ! static int aralion_test_loopback(void) ! { ! return 0; ! } ! ! static int aralion_pci_bios_detect(int *irq) ! { ! struct pci_dev *pdev = NULL; ! ! if (!pci_present()) ! return 0; ! ! memset(BoardInfo,0,sizeof(BoardInfo)); ! ! do { ! if ((pdev = pci_find_device(ARALION_VENDOR, ULTIMA_DEVICE, pdev)) != NULL) { ! #ifdef KERNEL240 ! BoardInfo[gBoardCount].PrimaryIO ! = (ULONG) pci_resource_start(pdev,0); ! BoardInfo[gBoardCount].SecondaryIO ! = (ULONG) pci_resource_start(pdev,1); ! BoardInfo[gBoardCount].PrimaryDmaIO ! = (ULONG) pci_resource_start(pdev,2); ! BoardInfo[gBoardCount].SecondaryDmaIO ! = (ULONG) pci_resource_start(pdev,3); ! BoardInfo[gBoardCount].ControlRegister ! = (ULONG) pci_resource_start(pdev,4); ! #else ! BoardInfo[gBoardCount].PrimaryIO ! = (ULONG) pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; ! BoardInfo[gBoardCount].SecondaryIO ! = (ULONG) pdev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK; ! BoardInfo[gBoardCount].PrimaryDmaIO ! = (ULONG) pdev->base_address[2] & PCI_BASE_ADDRESS_IO_MASK; ! BoardInfo[gBoardCount].SecondaryDmaIO ! = (ULONG) pdev->base_address[3] & PCI_BASE_ADDRESS_IO_MASK; ! BoardInfo[gBoardCount].ControlRegister ! = (ULONG) pdev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK; ! #endif ! BoardInfo[gBoardCount].interrupt_level = pdev->irq; ! ! request_region(BoardInfo[gBoardCount].PrimaryIO, 0x10, "aralion"); ! request_region(BoardInfo[gBoardCount].SecondaryIO, 0x10, "aralion"); ! request_region(BoardInfo[gBoardCount].PrimaryDmaIO, 0x10, "aralion"); ! request_region(BoardInfo[gBoardCount].SecondaryDmaIO, 0x10, "aralion"); ! request_region(BoardInfo[gBoardCount].ControlRegister, 0x10, "aralion"); ! if (!gBoardCount) ! *irq = pdev->irq; ! ! gBoardCount++; ! } ! } while(pdev != NULL); ! ! ! if (!gBoardCount) { ! printk("Ultima Board not found\n"); ! return 0; ! } ! ! interrupt_level = BoardInfo[0].interrupt_level; ! ! // printk("%d's Board found :",gBoardCount); ! ! return 1; ! } ! ! ULONG GetBlockCount(int BoardID,int channel,int drive) ! { ! int i; ! ULONG nCount; ! UCHAR *p; ! p = (char *) &(DiskIdentifyData[BoardID][channel][drive]); ! if(DiskIdentifyData[BoardID][channel][drive].BIT48 & 0x0400) ! nCount = *((ULONG *) (p + 200)); ! else ! nCount = *((ULONG *) (p + 120)); ! // printk("BCD=%d,%d,%d Size = %u \n",BoardID,channel,drive,nCount); ! return nCount; ! } ! ! ! void SetBlockCount(int BoardID,int channel,int drive,ULONG nCount) ! { ! UCHAR *p; ! ! p = (char *) &(DiskIdentifyData[BoardID][channel][drive]); ! if(DiskIdentifyData[BoardID][channel][drive].BIT48 & 0x0400) ! *((ULONG *) (p + 200)) = nCount; ! else ! *((ULONG *) (p + 120)) = nCount; ! } ! ! ////////////////// ! int RequestAllIrq() ! { ! int i; ! int irq; ! int retcode; ! ! for(i=0;i IRQ %d is bad!\n", irq); ! printk(" This shouldn't happen!\n"); ! printk(" Send mail to faith@acm.org\n"); ! } else if (retcode == -EBUSY) { ! printk("scsi: IRQ %d is already in use!\n",irq); ! printk(" Please use another IRQ!\n"); ! } else { ! printk("scsi: Error getting IRQ %d\n",irq); ! printk(" This shouldn't happen!\n"); ! printk(" Send mail to faith@acm.org\n"); ! } ! printk("scsi: Detected, but driver not loaded (IRQ)\n"); ! ! return retcode; ! } ! } ! } ! return 0; ! } ! ! ! int ultima_detect(Scsi_Host_Template * tpnt) ! { ! int retcode; ! struct Scsi_Host *shpnt; ! int i, j; ! int flag = 0; ! ! tpnt->proc_dir = &proc_scsi_aralion; ! ! flag = aralion_pci_bios_detect(&interrupt_level); ! ! if (!flag) { ! printk("scsi: Ultima not found\n"); ! return 0; ! } ! ! ! memset(&DiskID,0,sizeof(DiskID)); ! memset(&DiskRWInfo,0,sizeof(DiskRWInfo)); ! memset(&DiskIdentifyData,0,sizeof(DiskIdentifyData)); ! DiskCount = 0; ! ! ! for(i=0;ithis_id = (this_id & 0x1f); ! ! /* Print out a banner here in case we can't ! get resources. */ ! shpnt = scsi_register(tpnt, 0); ! shpnt->irq = interrupt_level; ! shpnt->io_port = BoardInfo[0].ControlRegister; ! shpnt->n_io_port = 0x10; ! // print_banner(shpnt); ! ! if (!interrupt_level) ! { ! printk("scsi: " ! " Card Detected, but driver not loaded (no IRQ)\n"); ! return 0; ! } else ! { ! /* Register the IRQ with the kernel */ ! if (RequestAllIrq()) ! return 0; ! } ! DriverInit = 0; ! ! for(i=0;i ",i,d1); ! } ! printk("\n"); ! } ! #endif ! ! inline DISKRWINFO *GetRWInfoPointer(DISKLIST *pDiskList) ! { ! return (DISKRWINFO *) &DiskRWInfo[pDiskList->BoardID][pDiskList->Channel][pDiskList->Drive]; ! } ! ! void PutLBAvalue(ULONG IOPort1,ULONG lba,ULONG numsectors, ! ULONG DriveSelect) ! { ! UCHAR Data[4]; ! if(lba >= 0x10000000){ ! Data[0] = (lba & 0xff000000 ) >> 24; ! Data[1] = 0; ! Data[2] = 0; ! outb(0,IOPort1 + BlockCountPort); ! outb(Data[0],IOPort1 + BlockNumberPort); ! outb(Data[1],IOPort1 + CylinderLowPort); ! outb(Data[2],IOPort1 + CylinderHighPort); ! Data[0] = (lba & 0x000000ff); ! Data[1] = (lba & 0x0000ff00) >> 8; ! Data[2] = (lba & 0x00ff0000) >> 16; ! Data[3] = (DriveSelect << 4) | 0xe0; ! outb(numsectors,IOPort1 + BlockCountPort); ! outb(Data[0],IOPort1 + BlockNumberPort); ! outb(Data[1],IOPort1 + CylinderLowPort); ! outb(Data[2],IOPort1 + CylinderHighPort); ! outb(Data[3],IOPort1 + DriveSelectPort); ! } ! else{ ! Data[0] = (lba & 0x000000ff); ! Data[1] = (lba & 0x0000ff00) >> 8; ! Data[2] = (lba & 0x00ff0000) >> 16; ! Data[3] = (lba & 0x0f000000) >> 24; ! Data[3] = Data[3] | 0x40 | (DriveSelect << 4) | 0xa0; ! ! outb(numsectors,IOPort1 + BlockCountPort); ! outb(Data[0],IOPort1 + BlockNumberPort); ! outb(Data[1],IOPort1 + CylinderLowPort); ! outb(Data[2],IOPort1 + CylinderHighPort); ! outb(Data[3],IOPort1 + DriveSelectPort); ! } ! } ! ! void DisableInterrupt(int BoardID) ! { ! USHORT Intena; ! Intena = 0; ! outw(Intena,BoardInfo[BoardID].ControlRegister + INTENA); ! } ! ! void EnableInterrupt(int BoardID) ! { ! USHORT Intena; ! Intena = 0x03; ! outw(Intena,BoardInfo[BoardID].ControlRegister + INTENA); ! } ! ! ULONG SetBoardInterruptFlag(int BoardID,int Channel,DWORD Status) ! { ! ULONG TempStatus; ! ! if (BoardInfo[BoardID].InterruptFlag[Channel] & Status) { ! TempStatus = BoardInfo[BoardID].InterruptFlag[Channel] & 0x00001111; ! if(TempStatus & 0x00001100){ ! BoardInfo[BoardID].InterruptFlag[Channel] |= 0x00001000; ! return 0x00001000; ! } ! else if(TempStatus & 0x00000010){ ! BoardInfo[BoardID].InterruptFlag[Channel] |= 0x00000100; ! return 0x00000100; ! } ! else { ! BoardInfo[BoardID].InterruptFlag[Channel] |= 0x00000010; ! return 0x000000010; ! } ! ! ! #ifdef DEBUG1 ! printk("SL:[%d,%d] - %08x ", ! BoardID,Channel, ! BoardInfo[BoardID].InterruptFlag[Channel]); ! #endif ! } ! else { ! BoardInfo[BoardID].InterruptFlag[Channel] = (Status | ORDER_ONE); ! ! #ifdef DEBUG1 ! printk("SF:[%d,%d] - %08x ", ! BoardID,Channel, ! BoardInfo[BoardID].InterruptFlag[Channel]); ! #endif ! return 0; ! } ! } ! ! ULONG SetScatterList( Scsi_Cmnd * SCpnt, ! ULONG lba, ! ULONG numsectors, ! ULONG ReadWrite) ! { ! struct scatterlist *slp; ! int i,j; ! PPDT_TABLE pPDTTable; ! DISKRWINFO *pRWInfo,*pRWInfo2; ! int tid = SCpnt->target; ! DWORD RaidStatus; ! ULONG TempFlag; ! ! RaidStatus = RAID(tid); ! ! pRWInfo = (DISKRWINFO *) &DiskRWInfo[S_BOARD(tid)][S_CHAN(tid)][S_DRV(tid)]; ! pRWInfo->StartLba = lba; ! pRWInfo->ListCount = 0; ! pRWInfo->NumSectors = 0; ! pPDTTable = pRWInfo->ScatterList; ! ! if (SCpnt->use_sg) ! { ! slp = (struct scatterlist *) SCpnt->request_buffer; ! for(i=0;iuse_sg;i++,slp++) { ! pPDTTable[i].address = virt_to_bus(slp->address); ! pPDTTable[i].length = slp->length; ! pPDTTable[i].EndOfChain = 0; ! pRWInfo->NumSectors += slp->length; ! } ! pPDTTable[i - 1].EndOfChain = 0x80; ! pRWInfo->ListCount = SCpnt->use_sg; ! } ! else ! { ! pPDTTable[0].address = virt_to_bus(SCpnt->request_buffer); ! pPDTTable[0].length = SCpnt->request_bufflen; ! pPDTTable[0].EndOfChain = 0x80; ! pRWInfo->NumSectors = SCpnt->request_bufflen; ! pRWInfo->ListCount = 1; ! } ! ! pRWInfo->NumSectors /= 512; ! ! pRWInfo->InterruptFlag = ReadWrite | ORDER_ONE; ! SetBoardInterruptFlag(S_BOARD(tid),S_CHAN(tid),ReadWrite); ! ! } ! ! void PrintPDT(PPDT_TABLE pPDTTable,int count) ! { ! int i; ! ! for(i=0;iBoardID; ! Channel = pList->Channel; ! Drive = pList->Drive; ! ! pRWInfo = (DISKRWINFO *) &DiskRWInfo[pList->BoardID][pList->Channel][pList->Drive]; ! ! ! #ifdef DEBUG1 ! /* ! printk("SetIOPort : [B:%d,C:%d,D:%d,F:%08x,O:%08x]\n", ! BoardID, ! Channel, ! Drive, ! pRWInfo->InterruptFlag, ! OrderFlag); ! */ ! #endif ! ! ! if (!(OrderFlag & pRWInfo->InterruptFlag)) { ! #ifdef DEBUG1 ! printk("Order Invalid\n"); ! #endif ! return ; ! } ! ! if (Channel == 0) ! { ! pPDTTable = BoardInfo[BoardID].PriScatterList; ! IOPort1 = BoardInfo[BoardID].PrimaryIO; ! DmaIO = BoardInfo[BoardID].PrimaryDmaIO; ! } ! else ! { ! pPDTTable = BoardInfo[BoardID].SecScatterList; ! IOPort1 = BoardInfo[BoardID].SecondaryIO; ! DmaIO = BoardInfo[BoardID].SecondaryDmaIO; ! } ! memcpy(pPDTTable,pRWInfo->ScatterList,pRWInfo->ListCount * sizeof(PDT_TABLE)); ! BoardInfo[BoardID].ListCount = pRWInfo->ListCount; ! BoardInfo[BoardID].NumSectors = pRWInfo->NumSectors; ! BoardInfo[BoardID].StartLba = pRWInfo->StartLba; ! ! AddressLow = virt_to_bus(pPDTTable) & 0x0000ffff; ! AddressHi = (virt_to_bus(pPDTTable) & 0xffff0000) >> 16; ! ! outw(AddressLow,DmaIO + PDTLAR); ! outw(AddressHi,DmaIO + PDTHAR); ! PutLBAvalue( ! IOPort1, ! BoardInfo[BoardID].StartLba, ! BoardInfo[BoardID].NumSectors, ! Drive); ! ! } ! ! void SetIOInformation(int tid,USHORT DmaRW,DWORD OrderFlag) ! { ! struct scatterlist *slp; ! int i,j,k; ! PPDT_TABLE pPDTTable; ! DISKRWINFO *pRWInfo = GetRWInfoPointer(&DiskID[tid].DiskStatus); ! if (pRWInfo->ListCount) { ! SetIOPort(&DiskID[tid].DiskStatus,DmaRW,OrderFlag); ! } ! ! } ! ! void SetIDECommand(DWORD Command, DWORD OrderFlag) ! { ! int i,j; ! ! for(i=0;i= 0x10000000) ! Command=BigDiskCommand(Command); ! outb(Command,BoardInfo[i].PrimaryIO + CommandPort); ! } ! if (BoardInfo[i].InterruptFlag[1] & OrderFlag) { ! if(BoardInfo[i].StartLba >= 0x10000000) ! Command=BigDiskCommand(Command); ! outb(Command,BoardInfo[i].SecondaryIO + CommandPort); ! } ! ! } ! } ! ! DWORD BigDiskCommand (DWORD cmnd) ! { ! switch(cmnd){ ! case IDE_COMMAND_READ_DMA: ! return IDE_COMMAND_READ_DMA_EXT; ! case IDE_COMMAND_WRITE_DMA: ! return IDE_COMMAND_WRITE_DMA_EXT; ! } ! } ! ! void SetDMACommand(USHORT DmaRW,DWORD OrderFlag) ! { ! ULONG DmaIO; ! int i,j,k; ! ! for(i=0;itarget].RaidStatus) { ! case NORMALIDE: ! SetScatterList(SCpnt,lba,numsectors,READ_STATUS); ! break; ! default: ! printk("Not Supported Mode!!\n"); ! return -1; ! } ! SetIOInformation(SCpnt->target,DMA_READ,ORDER_ONE); ! RWStatus = READ_STATUS; ! OrderStatus = ORDER_ONE; ! SetIDECommand(IDE_COMMAND_READ_DMA,ORDER_ONE); ! SetDMACommand(DMA_READ,ORDER_ONE); ! return 0; ! } ! ! static int WriteDMA( ! Scsi_Cmnd * SCpnt, ! ULONG lba, ! ULONG numsectors) ! { ! int i; ! unsigned long flags; ! ! if (numsectors == 0) { ! my_done(DID_ABORT << 16); ! return ERROR_INVALID_SECTORCOUNT; ! } ! ! switch(DiskID[SCpnt->target].RaidStatus) { ! case NORMALIDE: ! SetScatterList(SCpnt,lba,numsectors,WRITE_STATUS); ! break; ! default: ! printk("Not Supported Mode!!\n"); ! return -1; ! ! } ! SetIOInformation(SCpnt->target,DMA_WRITE,ORDER_ONE); ! RWStatus = WRITE_STATUS; ! OrderStatus = ORDER_ONE; ! SetIDECommand(IDE_COMMAND_WRITE_DMA,ORDER_ONE); ! SetDMACommand(DMA_WRITE,ORDER_ONE); ! return 0; ! } ! ! void GetUDMAMode(USHORT *mode,USHORT *Timing, ! IDENTIFY_DATA * IdentifyData) ! { ! ! if(IdentifyData->UDMASupport & 0x20){ ! *mode = 0x45; // mode 5 ! *Timing = 0xff22; // mode 5 ! } ! else if(IdentifyData->UDMASupport & 0x10){ ! *mode = 0x44; // mode 4 ! *Timing = 0xff33; // mode 4 ! } ! else if(IdentifyData->UDMASupport & 0x08){ ! *mode = 0x43; // mode 3 ! *Timing = 0xff55; // mode 3 ! } ! else if(IdentifyData->UDMASupport & 0x04){ ! *mode = 0x42; // mode 2 ! *Timing = 0xff66; // mode 2 ! } ! else if(IdentifyData->UDMASupport & 0x02){ ! *mode = 0x41; // mode 1 ! *Timing = 0xff88; // mode 1 ! } ! else if(IdentifyData->UDMASupport & 0x01){ ! *mode = 0x40; // mode 0 ! *Timing = 0xffcc; // mode 0 ! } ! #ifdef _7878_ ! *mode = 0x44; // mode 4 ! *Timing = 0x7878; // safe mode ! #endif ! } ! ! void SetUDMAMode( int BoardID, ! int Channel, ! int DriveSelect, ! IDENTIFY_DATA * IdentifyData) ! { ! USHORT mode[2],Timing[2]; ! ULONG IOPort1; ! ULONG DmaIO; ! char statusByte; ! int i; ! if (Channel == 0) { ! IOPort1 = BoardInfo[BoardID].PrimaryIO; ! DmaIO = BoardInfo[BoardID].PrimaryDmaIO; ! } ! else { ! IOPort1 = BoardInfo[BoardID].SecondaryIO; ! DmaIO = BoardInfo[BoardID].SecondaryDmaIO; ! } ! outb(0x03,IOPort1 + ErrorPort); ! ! for(i=0;i<4;i++) ! { ! mode[i] = 0xffff; ! } ! ! if (HddConnected[BoardID][Channel][0]) ! GetUDMAMode(&mode[0],&Timing[0],&DiskIdentifyData[BoardID][Channel][0]); ! if (HddConnected[BoardID][Channel][1]) ! GetUDMAMode(&mode[1],&Timing[1],&DiskIdentifyData[BoardID][Channel][1]); ! if(mode[0] > mode[1]) ! { ! mode[0] = mode[1]; ! Timing[0] = Timing[1]; ! } ! ! outw(0x0001,DmaIO + DMAMODE); ! ! outb(mode[0],IOPort1 + BlockCountPort); ! if (HddConnected[BoardID][Channel][0]) ! { ! outb(0xA0,IOPort1 + DriveSelectPort); ! outb(IDE_COMMAND_ENABLE_MEDIA_STATUS,IOPort1 + CommandPort); ! outw(Timing[0],DmaIO + UDM_TIM); ! } ! if (HddConnected[BoardID][Channel][1]) ! { ! outb(0xB0,IOPort1 + DriveSelectPort); ! outb(IDE_COMMAND_ENABLE_MEDIA_STATUS,IOPort1 + CommandPort); ! outw(Timing[0],DmaIO + UDM_TIM); ! } ! ! statusByte = 0; ! mdelay(5); ! while(!(statusByte & IDE_STATUS_IDLE)) ! { ! GetBaseStatus(IOPort1, statusByte); ! } ! } ! ! static int IdentifyDisk( ! int BoardID, ! int Channel, ! int DriveSelect, ! IDENTIFY_DATA * IdentifyData) ! { ! ULONG IOPort1,DmaIO,ControlRegister; ! UCHAR statusByte; ! USHORT *pIdentifyData; ! int i, j; ! int flag = 0; ! ! HddConnected[BoardID][Channel][DriveSelect] = 0; ! mdelay(100); ! ! if (Channel == 0) ! { ! IOPort1 = BoardInfo[BoardID].PrimaryIO; ! DmaIO = BoardInfo[BoardID].PrimaryDmaIO; ! } ! else ! { ! IOPort1 = BoardInfo[BoardID].SecondaryIO; ! DmaIO = BoardInfo[BoardID].SecondaryDmaIO; ! } ! ! ControlRegister = BoardInfo[BoardID].ControlRegister; ! ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! ! for (i=0;i<100;i++) { ! udelay(10); ! GetBaseStatus(IOPort1, statusByte); ! ! if (!(statusByte & 0x80)) ! break; ! } ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! mdelay(50); ! GetBaseStatus(IOPort1, statusByte); ! ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! mdelay(50); ! GetBaseStatus(IOPort1, statusByte); ! ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! mdelay(50); ! GetBaseStatus(IOPort1, statusByte); ! mdelay(50); ! if(statusByte != 0x50) ! { ! if((statusByte & 0xF0) != 0x50) ! return 0; ! outb(0x08,IOPort1+CommandPort); ! mdelay(100); ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! GetBaseStatus(IOPort1, statusByte); ! for(i=0;i<3;i++) ! { ! mdelay(100); ! outb(0x04, IOPort1 + 0x0E); ! mdelay(100); ! outb(0x00, IOPort1 + 0x0E); ! GetBaseStatus(IOPort1, statusByte); ! if(statusByte == 0x50) ! break; ! } ! if(i >= 3) ! return 0; ! } ! ! ! statusByte = statusByte & 0xc9; ! ! // printk("Identify: After Masking with 0xC9! Status == %x\n", ! // statusByte); ! ! if (statusByte != IDE_STATUS_DRDY) ! { ! // printk(" ---- Identify: DRDY is NOT asserted!\n"); ! // printk(" ---- Identify: return FALSE.\n"); ! // printk("IdentifyDisk Fail bd=%d,ch=%d, drv=%d :\n",BoardID,Channel,DriveSelect); ! return 0; ! } ! ! ! label1: ! for (j = 0; j < 2; j++) ! { ! ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! mdelay(10); ! GetBaseStatus(IOPort1, statusByte); ! ! // printk("Status3 = %x\n", (UCHAR) statusByte); ! ! WaitOnBusy(IOPort1, statusByte); ! outb(IDE_COMMAND_IDENTIFY, IOPort1 + CommandPort); ! ! for (i = 0; i < 4; i++) ! { ! WaitForDrq(IOPort1, statusByte); ! if (statusByte & IDE_STATUS_DRQ) ! { ! // Read status to acknowledge any interrupts generated. ! GetBaseStatus(IOPort1, statusByte); ! break; ! } ! ! WaitOnBusy(IOPort1, statusByte); ! } // end of for (i = 0; i < 4; i++) ! ! if (i == 4 && j == 0) ! { ! // printk(" ---- Identify: DRQ never asserted (%x). Error reg (%x)\n", ! // statusByte, inb(IOPort1 + 1)); ! // printk(" ---- Identify: return FALSE.\n"); ! return 0; ! } else ! { ! break; ! } ! } // end of for (j = 0; j < 2; j++) ! ! ! if (statusByte & IDE_STATUS_ERROR) ! { ! // printk(" ---- Identify: Status %x\n", statusByte); ! // printk(" ---- Identify: return FALSE.\n"); ! return 0; ! } ! ! WaitOnBusy(IOPort1, statusByte); ! ! ! if (!(statusByte & IDE_STATUS_DRQ)) ! { ! // printk(" ---- Identify: DRQ is NOT asserted!\n"); ! // printk(" ---- Identify: return FALSE.\n"); ! return 0; ! } ! ! // DiskPresent |= (1 << (Channel * 2 + DriveSelect + 4)); ! pIdentifyData = (USHORT *) IdentifyData; ! ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! mdelay(50); ! GetBaseStatus(IOPort1, statusByte); ! // printk("S3=%02x ", (UCHAR) statusByte); ! // printk("IdentifyDisk bd=%d,ch=%d, drv=%d \n",BoardID,Channel,DriveSelect); ! for (i = 0; i < 256; i++) ! { ! pIdentifyData[i] = inw(IOPort1 + DataPort); ! } ! ! // printk("\n"); ! ! for(i=0; i<256; i++) ! { ! // printk("%0.4x ",pIdentifyData[i]); ! } ! // printk("\n"); ! ! { ! char *p,c; ! p = (char *) &(IdentifyData->VendorUnique1); ! ! for (i = 0; i < 26; i+=2) ! { ! c = p[i]; ! p[i] = p[i+1]; ! p[i+1] = c; ! // printk("[%02x]<%02x>",(unsigned char)p[i],(unsigned char)p[i+1]); ! } ! // printk("\n"); ! ! p = (char *) &(IdentifyData->ModelNumber); ! ! for (i = 0; i < 40; i+=2) ! { ! c = p[i]; ! p[i] = p[i+1]; ! p[i+1] = c; ! // printk("%c",c); ! } ! } ! HddConnected[BoardID][Channel][DriveSelect] = 1; ! SetUDMAMode(BoardID,Channel,DriveSelect,IdentifyData); ! ! { ! int mm = 0; ! ! for (i = 0; i < 0x1000; i++) ! { ! ! GetStatus(IOPort1, statusByte); ! ! if ((statusByte & IDE_STATUS_DRQ) ! || (statusByte & IDE_STATUS_BUSY) ! || (statusByte & 1) ) ! { ! inw(IOPort1 + DataPort); ! } else ! break; ! } // end of for ! } ! // printk("IdentifyDisk Success!\n"); ! return 1; ! } ! ! char *ultima_info(struct Scsi_Host *ignore) ! { ! static char buffer[128]; ! char *pt; ! ! // printk("[ ultima_info ]\n"); ! strcpy(buffer, "Aralion Ultima ATA100 IDE RAID MultiCard Driver Version"); ! if (strchr(VERSION, ':')) ! { /* Assume VERSION is an RCS Revision string */ ! strcat(buffer, strchr(VERSION, ':') + 1); ! pt = strrchr(buffer, '$') - 1; ! if (!pt) /* Stripped RCS Revision string? */ ! pt = buffer + strlen(buffer) - 1; ! if (*pt != ' ') ! ++pt; ! *pt = '\0'; ! } else ! { /* Assume VERSION is a number */ ! strcat(buffer, " " VERSION); ! } ! ! return buffer; ! } ! ! ! ! int ultima_ioctl (Scsi_Device *dev, int cmd, void *arg) ! { ! return 0; ! } ! ! int init_module(void) { ! driver_template.module = &__this_module; ! scsi_register_module(MODULE_SCSI_HA, &driver_template); ! if (driver_template.present) { ! return 0; ! } ! ! scsi_unregister_module(MODULE_SCSI_HA, &driver_template); ! return -1; ! } ! ! void cleanup_module( void) { ! scsi_unregister_module(MODULE_SCSI_HA, &driver_template); ! } ! /* First pass at /proc information routine. */ ! ! int ultima_proc_info(char *buffer, char **start, off_t offset, ! int length, int hostno, int inout) ! { ! const char *info = ultima_info(NULL); ! int len; ! int pos; ! int begin; ! ! if (inout) ! return (-ENOSYS); ! ! begin = 0; ! strcpy(buffer, info); ! strcat(buffer, "\n"); ! ! pos = len = strlen(buffer); ! ! if (pos < offset) ! { ! len = 0; ! begin = pos; ! } ! ! *start = buffer + (offset - begin); /* Start of wanted data */ ! len -= (offset - begin); ! if (len > length) ! len = length; ! ! return (len); ! } ! ! static int aralion_arbitrate(void) ! { ! int status = 0; ! ULONG timeout; ! ! printk("[ aralion_arbitrate ]\n"); ! ! return 0; ! } ! ! static int aralion_select(int target) ! { ! int status; ! ULONG timeout; ! static int flag = 0; ! ! ! printk("[ aralion_select - %d ]\n",target); ! return 0; ! } ! ! static void my_done(int error) ! { ! if (in_command) ! { ! in_command = 0; ! // printk("{C}"); ! if (test_and_clear_bit(IOCTL_LOCK,&LockValue) == 0) ! printk("misc clear...\n"); ! current_SC->result = error; ! if (current_SC->scsi_done) { ! current_SC->scsi_done(current_SC); ! } ! else ! panic("scsi: current_SC->scsi_done() == NULL"); ! } else ! { ! panic("scsi: my_done() called outside of command\n"); ! } ! } ! ! int CheckScsiError(ULONG Channel,ULONG IOPort1,UCHAR statusByte) ! { ! ULONG lba; ! UCHAR Data[4]; ! UCHAR errorByte; ! ULONG scsiStatus = 0; ! ! if (statusByte & 0x1) { ! ! errorByte = inb(IOPort1 + ErrorPort); ! ! if (errorByte & IDE_ERROR_BAD_BLOCK) ! scsiStatus = DID_PARITY; ! else if (errorByte & IDE_ERROR_DATA_ERROR) ! scsiStatus = DID_ERROR; ! else if (errorByte & IDE_ERROR_ID_NOT_FOUND) ! scsiStatus = DID_NO_CONNECT; ! else if (errorByte & IDE_ERROR_COMMAND_ABORTED) ! scsiStatus = DID_ABORT; ! else if (errorByte & IDE_ERROR_ILLEGAL_LENGTH ) ! scsiStatus = DID_ERROR; ! ! Data[3] = inb(IOPort1 + BlockNumberPort); ! Data[2] = inb(IOPort1 + CylinderLowPort); ! Data[1] = inb(IOPort1 + CylinderHighPort); ! Data[0] = inb(IOPort1 + DriveSelectPort) & 0x0f; ! ! lba = (Data[0] << 24) + (Data[1] << 16) ! + (Data[2] << 8) + Data[0]; ! ! LastErrorBlock = lba; ! LastErrorCode = errorByte & 0x000f; ! ! printk("Error! Ch:%d, %02x , %0d\n",Channel, ! (UCHAR) errorByte,lba); ! ! // my_done(scsiStatus << 16); ! return scsiStatus; ! } ! else ! return 0; ! } ! ! void CheckJobFinished(ULONG BoardID,ULONG Channel) ! { ! ULONG DmaIO; ! USHORT Stat; ! DWORD i = 0; ! ! // printk("CheckJobFinished = <%d,%d>\n",BoardID,Channel); ! ! if (Channel == 1) { ! DmaIO = BoardInfo[BoardID].PrimaryDmaIO; ! } ! else ! DmaIO = BoardInfo[BoardID].SecondaryDmaIO; ! ! do { ! Stat = inw(DmaIO + CONSR); ! i++; ! } while ((Stat & 0x01) && (i < 80000000)); ! // printk("Check End : %u\n",i); ! } ! void ClearAllIrq() ! { ! ULONG Channel; ! UCHAR statusByte = 0; ! UCHAR statusByte2 = 0; ! ULONG IOPort1,IOPort2; ! ULONG scsiStatus = 0; ! int i; ! ! for(i=0;i\n"); ! ! if (!pIntID) { ! #ifdef DEBUG ! printk("It is not ultima_irq1\n"); ! #endif ! spin_unlock_irqrestore(&io_request_lock, flags); ! return ; ! } ! ! if (gResetFlag) { ! for (i=0;iresult; ! ++internal_done_flag; ! } ! ! int IsSplitter(char c) ! { ! if (c == ' ' || c == '-' || c == '_') ! return 1; ! else if (c >= '0' && c <= '9') ! return 1; ! ! return 0; ! } ! ! int ultima_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) ! { ! char *buf; ! int board,channel,drive; ! ULONG result; ! /* ! printk("[c=%x : %s,I=%x],DiskCount = %d\n", ! (UCHAR) SCpnt->cmnd[0], ! GetCmdName((UCHAR) SCpnt->cmnd[0]), ! SCpnt->target, ! DiskCount); ! */ ! if (in_command) { ! printk("[ ultima_queue c=%x : %s,I=%x]\n", ! (UCHAR) SCpnt->cmnd[0], ! GetCmdName((UCHAR) SCpnt->cmnd[0]), ! SCpnt->target); ! panic("Error! in_command == 1\n"); ! return ; ! } ! ! while(test_and_set_bit(IOCTL_LOCK,&LockValue) != 0) { ! printk("QW "); ! schedule(); ! udelay(1); ! } ! while(in_ioctl) { ! // printk("in_ioctl = 1\n"); ! udelay(1); ! } ! in_command = 1; ! current_SC = SCpnt; ! current_SC->scsi_done = done; ! ! current_SC->SCp.Status = 0; ! current_SC->SCp.Message = 0; ! current_SC->SCp.have_data_in = 0; ! current_SC->SCp.sent_command = 0; ! current_SC->SCp.phase = in_arbitration; ! ! if ( SCpnt->lun > 0) { ! my_done(DID_ABORT << 16); ! return 0; ! } ! board = DiskID[current_SC->target].DiskStatus.BoardID; ! channel = DiskID[current_SC->target].DiskStatus.Channel; ! drive = DiskID[current_SC->target].DiskStatus.Drive; ! ! ! switch(current_SC->cmnd[0]) { ! case TEST_UNIT_READY: ! case REQUEST_SENSE : ! my_done(0); ! return 0; ! ! case MODE_SENSE : ! buf = (char *) current_SC->buffer; ! buf[2] = 0x0; ! my_done(0); ! break; ! ! case INQUIRY : ! if(hotplug_check(current_SC->target) == 0) ! { ! my_done(DID_ABORT << 16); ! return 0; ! } ! ! board = DiskID[current_SC->target].DiskStatus.BoardID; ! channel = DiskID[current_SC->target].DiskStatus.Channel; ! drive = DiskID[current_SC->target].DiskStatus.Drive; ! buf = (char *) current_SC->buffer; ! { ! PINQUIRYDATA inquiryData ! = (PINQUIRYDATA) current_SC->buffer; ! PIDENTIFY_DATA identifyData = ! &DiskIdentifyData[board][channel][drive]; ! int i; ! ! memset(buf,0,current_SC->bufflen); ! ! buf[4] = sizeof(INQUIRYDATA); ! ! // ! // Standard IDE interface only supports disks. ! inquiryData->DeviceType = DIRECT_ACCESS_DEVICE; ! ! // ! // Fill in vendor identification fields. ! { ! unsigned char *p; ! int i,j; ! ! for (i = 0; i < 24; i ++) { ! inquiryData->VendorId[i] = 0; ! } ! p = (UCHAR *) identifyData->ModelNumber; ! i = 0; ! ! while(!IsSplitter(p[i])) { ! inquiryData->VendorId[i] = p[i++]; ! } ! inquiryData->VendorId[i] = 0; ! ! i++; ! j = 0; ! while (p[i] != ' ' && i < 24) ! inquiryData->ProductId[j++] = p[i++]; ! inquiryData->ProductId[j] = 0; ! ! } ! // ! // Initialize unused portion of product id. ! for (i = 0; i < 4; i++) { ! inquiryData->ProductId[12+i] = ' '; ! } ! ! // ! // Move firmware revision from IDENTIFY data to ! // product revision in INQUIRY data. ! for (i = 0; i < 4; i += 2) { ! inquiryData->ProductRevisionLevel[i] = ! ((UCHAR *)identifyData->FirmwareRevision)[i+1]; ! inquiryData->ProductRevisionLevel[i+1] = ! ((UCHAR *)identifyData->FirmwareRevision)[i]; ! } ! } ! // printk("Inquiry Success!"); ! my_done(0); ! break; ! case READ_6 : ! case READ_10 : ! case WRITE_6 : ! case WRITE_10 : ! ! { ! ULONG numsectors,lba,i ; ! ! // SDptr->disconnect = 0; ! if (*current_SC->cmnd == READ_6 || *current_SC->cmnd == WRITE_6) { ! numsectors = (u_long) current_SC->cmnd[4]; ! lba = ((u_long) current_SC->cmnd[1] << 16) | ! ((u_long) current_SC->cmnd[2] << 8) | ! (u_long) current_SC->cmnd[3]; ! lba &= 0x1FFFFF; ! } ! if (*current_SC->cmnd == READ_10 || *current_SC->cmnd == WRITE_10) { ! numsectors = (u_long) current_SC->cmnd[8] | ! ((u_long) current_SC->cmnd[7] << 8); ! lba = ((u_long) current_SC->cmnd[2] << 24) | ! ((u_long) current_SC->cmnd[3] << 16) | ! ((u_long) current_SC->cmnd[4] << 8) | ! (u_long) current_SC->cmnd[5]; ! } ! ! memset(DiskRWInfo,0,sizeof(DiskRWInfo)); ! for(i=0;itarget; ! ! if (*current_SC->cmnd == READ_6 || *current_SC->cmnd == READ_10) { ! ! // printk("R:[%03d,%08x]", numsectors,lba); ! ReadDMA(current_SC,lba,numsectors); ! } ! else { ! // printk("W:[%03d,%08x]", numsectors,lba); ! WriteDMA(current_SC,lba,numsectors); ! } ! } ! // printk("RW Success!\n"); ! break; ! ! case READ_CAPACITY : ! { ! ULONG block,size; ! IDENTIFY_DATA * IdentifyData; ! ! block = DiskID[current_SC->target].DiskStatus.Size; ! // printk("Block Size = %x\n",block); ! buf = (char *) current_SC->buffer; ! size = 512; ! ! *((ULONG *) buf) = htonl(block - 1); ! *((ULONG *) (buf + 4)) = htonl(size); ! } ! ! my_done(0); ! // printk("Read_Cap Success!\n"); ! break; ! default: ! my_done(0); ! break; ! ! } ! return 0; ! } ! ! ! void FillDump( Scsi_Cmnd * SCpnt) ! { ! struct scatterlist *slp; ! int i,j; ! ULONG TempFlag; ! ! if (SCpnt->use_sg) ! { ! slp = (struct scatterlist *) SCpnt->request_buffer; ! for(i=0;iuse_sg;i++,slp++) { ! memset(&(slp->address),0,slp->length); ! } ! } ! else ! { ! memset(&(slp->address),0,SCpnt->request_bufflen); ! } ! } ! ! int hotplug_check(int target) ! { ! int i, j, k; ! UCHAR statusByte; ! ULONG IOPort1; ! // printk("targetID=%d, DiskCount=%d\n",target,DiskCount); ! if(target == DiskCount) ! { ! for(i=0;ihost) ! { ! printk("scsi: Cannot provide detailed information\n"); ! return; ! } ! ! printk("%s\n", ultima_info(SCpnt->host)); ! return ; ! print_banner(SCpnt->host); ! ! printk("(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n", ! SCpnt->SCp.phase, ! SCpnt->target, ! *(UCHAR *) SCpnt->cmnd, ! SCpnt->use_sg, SCpnt->request_bufflen); ! printk("sent_command = %d, have_data_in = %d, timeout = %d\n", ! SCpnt->SCp.sent_command, ! SCpnt->SCp.have_data_in, SCpnt->timeout); ! } ! ! int ultima_handle(Scsi_Cmnd * SCpnt) ! { ! // printk("\n"); ! } ! ! int ultima_abort(Scsi_Cmnd * SCpnt) ! { ! ULONG flags; ! ! // printk("ultima_abort ---- \n"); ! if (!in_command) ! { ! return SCSI_ABORT_NOT_RUNNING; ! } ! ultima_cardreset(); ! ! //#if DEBUG ! print_info(SCpnt); ! //#endif ! ! current_SC->SCp.phase |= aborted; ! ! current_SC->result = DID_ABORT << 16; ! // current_SC->result = DID_BUS_BUSY << 16; ! ! /* Aborts are not done well. . . */ ! if (in_command) ! my_done(DID_ABORT << 16); ! // my_done(DID_BUS_BUSY << 16); ! ! return SCSI_ABORT_SUCCESS; ! } ! ! int ultima_reset(Scsi_Cmnd * SCpnt, unsigned int ignored) ! { ! // printk("ultima_reset ---- \n"); ! ultima_cardreset(); ! ! return SCSI_RESET_WAKEUP; ! } ! ! // ! // KHG-20020719 ! // ! ! int ultima_1channelreset(int BoardID, int Channel) ! { ! int i; ! UCHAR statusByte,statusByte2; ! // printk("%d board reset\n",BoardID); ! if(Channel == 0) ! { ! outw(0x8000,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x4000,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x0,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0xff8f,BoardInfo[BoardID].ControlRegister + 0x0c); ! /* ! for (i=0;i<200;i++) ! { ! mdelay(5); ! outb(0xA0, BoardInfo[BoardID].PrimaryIO + DriveSelectPort); ! GetBaseStatus(BoardInfo[BoardID].PrimaryIO, statusByte); ! outb(0xB0, BoardInfo[BoardID].PrimaryIO + DriveSelectPort); ! GetBaseStatus(BoardInfo[BoardID].PrimaryIO, statusByte2); ! if (!(statusByte & 0x80) && !(statusByte2 & 0x80)) ! break; ! } ! */ ! } ! else ! { ! outw(0x8000,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x4000,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x0,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! mdelay(20); ! outw(0xff8f,BoardInfo[BoardID].ControlRegister + 0x0e); ! /* ! for (i=0;i<200;i++) ! { ! mdelay(5); ! outb(0xA0, BoardInfo[BoardID].SecondaryIO + DriveSelectPort); ! GetBaseStatus(BoardInfo[BoardID].SecondaryIO, statusByte); ! outb(0xB0, BoardInfo[BoardID].SecondaryIO + DriveSelectPort); ! GetBaseStatus(BoardInfo[BoardID].SecondaryIO, statusByte2); ! if (!(statusByte & 0x80) && !(statusByte2 & 0x80)) ! break; ! } ! */ ! } ! for(i=0;i<125;i++) ! { ! mdelay(10); ! } ! } ! ! int ultima_1cardreset(int BoardID) ! { ! int i,j; ! UCHAR statusByte,statusByte2; ! UCHAR statusByte3,statusByte4; ! ! mdelay(20); ! outw(0x8000,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x4000,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x0,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x8000,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x4000,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x0,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! for(i=0;i<125;i++) ! { ! mdelay(20); ! } ! } ! ! ! int ultima_cardreset() ! { ! int i,j,k; ! ! RWStatus = RESET_STATUS; ! // printk("ultima cardreset\n"); ! gResetFlag = 1; ! for(i=0;i> 4; ! // printk("BiosParam = %d,%d\n",board,channel); ! ! info_array[0] = 16; ! info_array[1] = 63; ! ! // size = info_array[0] * info_array[1] * info_array[2]; ! ! size = DiskID[target].DiskStatus.Size; ! info_array[2] = size / (info_array[0] * info_array[1]); ! ! if (info_array[2] > 1024) { ! info_array[0] = 0xff; ! info_array[2] = ! (ULONG) size / (info_array[0] * info_array[1]); ! } ! ! return 0; ! } ! --- 1,2134 ---- ! /******************************************************************* ! ! Aralion Ultima ATA100 IDE Raid Controller ! Linux Device Driver source, programmed by soonsoo@hitel.net ! ! *******************************************************************/ ! //#define __BOOT_KERNEL_BOOT 1 ! ! //#define DEBUG1 1 ! //#define DEBUG2 1 ! //#define DEBUG3 1 ! //#define DEBUG4 1 ! ! #include ! #include ! #include ! #include ! #include ! #include "../scsi.h" ! #include "../hosts.h" ! #include "../sd.h" ! #include "ultima.h" ! #include "atapi.h" ! #include ! #include ! #include ! #include ! #include ! #include ! #include ! #include ! #include /* for CONFIG_PCI */ ! #include ! #include /* for put_user_byte */ ! #include ! #include ! #include ! #include ! //#include "iocontrol.h" ! //#include "flash.h" ! ! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) ! #define KERNEL240 ! #else ! #define KERNEL220 ! #endif ! ! #define S_BOARD(x) (DiskID[x].DiskStatus.BoardID) ! #define S_CHAN(x) (DiskID[x].DiskStatus.Channel) ! #define S_DRV(x) (DiskID[x].DiskStatus.Drive) ! #define RAID(x) (DiskID[x].RaidStatus) ! ! //////////////////////////////////////////////////////////////////////////////////////// ! ! static void print_banner(struct Scsi_Host *shpnt); ! char * GetCmdName(char code); ! static void print_banner(struct Scsi_Host *shpnt); ! static void do_pause(ULONG amount); ! static int aralion_pci_bios_detect(int *irq); ! ULONG GetBlockCount(int BoardID,int channel,int drive); ! void SetBlockCount(int BoardID,int channel,int drive,ULONG nCount); ! int RequestAllIrq(void); ! int PutOneDriveToDiskSet(int board,int disk,_DiskIDTable *DiskID,V6BDISKINFO *DiskInfo); ! void PutLBAvalue( ! ULONG IOPort1, ! ULONG lba, ! ULONG numsectors, ! ULONG DriveSelect); ! void DisableInterrupt(int BoardID); ! void EnableInterrupt(int BoardID); ! ULONG SetBoardInterruptFlag(int BoardID,int Channel,DWORD Status); ! ULONG SetScatterList( ! Scsi_Cmnd * SCpnt, ! ULONG lba, ! ULONG numsectors, ! ULONG ReadWrite); ! void SetIOPort(DISKLIST *pList,USHORT DmaRW,DWORD OrderFlag); ! void SetIOInformation(int tid,USHORT DmaRW,DWORD OrderFlag); ! ULONG PutOneScatterList( ! ULONG CurrentID, ! DWORD PrimaryDiskArrayCount, ! DISKLIST *PrimaryDiskArray, ! ULONG lba, ! ULONG buffer, ! USHORT length); ! void SetIDECommand(DWORD Command, DWORD order); ! DWORD BigDiskCommand (DWORD cmnd); ! void SetDMACommand(USHORT DmaRW,DWORD OrderFlag); ! void FillDump( Scsi_Cmnd * SCpnt); ! static int ReadDMA( ! Scsi_Cmnd * SCpnt, ! ULONG lba, ! ULONG numsectors); ! static int WriteDMA( ! Scsi_Cmnd * SCpnt, ! ULONG lba, ! ULONG numsectors); ! void GetUDMAMode( ! USHORT *mode, ! USHORT *Timing, ! IDENTIFY_DATA * IdentifyData); ! void SetUDMAMode( ! int BoardID, ! int Channel, ! int DriveSelect, ! IDENTIFY_DATA * IdentifyData); ! static int IdentifyDisk( ! int BoardID, ! int Channel, ! int DriveSelect, ! IDENTIFY_DATA * IdentifyData); ! static void my_done(int error); ! int CheckScsiError(ULONG Channel,ULONG IOPort1,UCHAR statusByte); ! void CheckJobFinished(ULONG BoardID,ULONG Channel); ! int IsSplitter(char c); ! int ultima_1cardreset(int BoardID); ! int ultima_cardreset(void); ! void do_ultima_intr(int irq, void *dev_id, struct pt_regs *regs); ! void internal_done(Scsi_Cmnd * SCpnt); ! void print_info(Scsi_Cmnd * SCpnt); ! ! //////////////////////////////////////////////////////////////////////////////////////// ! ! struct proc_dir_entry proc_scsi_aralion = { ! 0x10, 7, "aralion", ! S_IFDIR | S_IRUGO | S_IXUGO, 2 ! }; ! ! Scsi_Host_Template driver_template = ULTIMA_DMA100; ! ! #define VERSION "$Revision: LV2.01X-X86-ATA $" ! ! ! enum { ! in_arbitration = 0x02, ! in_selection = 0x04, ! in_other = 0x08, ! disconnect = 0x10, ! aborted = 0x20, ! sent_ident = 0x40, ! }; ! ! typedef struct { ! char name[23]; ! char code; ! } CMDNAME; ! ! CMDNAME CmdName[] = ! { ! {"TEST_UNIT_READY",0x00}, ! {"REZERO_UNIT",0x01}, ! {"REQUEST_SENSE",0x03}, ! {"FORMAT_UNIT",0x04}, ! {"READ_BLOCK_LIMITS",0x05}, ! {"REASSIGN_BLOCKS",0x07}, ! {"READ_6",0x08}, ! {"WRITE_6",0x0a}, ! {"SEEK_6",0x0b}, ! {"READ_REVERSE",0x0f}, ! {"WRITE_FILEMARKS",0x10}, ! {"SPACE",0x11}, ! {"INQUIRY",0x12}, ! {"RECOVER_BUFFERED_DATA",0x14}, ! {"MODE_SELECT",0x15}, ! {"RESERVE",0x16}, ! {"RELEASE",0x17}, ! {"COPY",0x18}, ! {"ERASE",0x19}, ! {"MODE_SENSE",0x1a}, ! {"START_STOP",0x1b}, ! {"RECEIVE_DIAGNOSTIC",0x1c}, ! {"SEND_DIAGNOSTIC",0x1d}, ! {"ALLOW_MEDIUM_REMOVAL",0x1e}, ! {"SET_WINDOW",0x24}, ! {"READ_CAPACITY",0x25}, ! {"READ_10",0x28}, ! {"WRITE_10",0x2a}, ! {"SEEK_10",0x2b}, ! {"WRITE_VERIFY",0x2e}, ! {"VERIFY",0x2f}, ! {"SEARCH_HIGH",0x30}, ! {"SEARCH_EQUAL",0x31}, ! {"SEARCH_LOW",0x32}, ! {"SET_LIMITS",0x33}, ! {"PRE_FETCH",0x34}, ! {"READ_POSITION",0x34}, ! {"SYNCHRONIZE_CACHE",0x35}, ! {"LOCK_UNLOCK_CACHE",0x36}, ! {"READ_DEFECT_DATA",0x37}, ! {"MEDIUM_SCAN",0x38}, ! {"COMPARE",0x39}, ! {"COPY_VERIFY",0x3a}, ! {"WRITE_BUFFER",0x3b}, ! {"READ_BUFFER",0x3c}, ! {"UPDATE_BLOCK",0x3d}, ! {"READ_LONG",0x3e}, ! {"WRITE_LONG",0x3f}, ! {"CHANGE_DEFINITION",0x40}, ! {"WRITE_SAME",0x41}, ! {"READ_TOC",0x43}, ! {"LOG_SELECT",0x4c}, ! {"LOG_SENSE",0x4d}, ! {"MODE_SELECT_10",0x55}, ! {"RESERVE_10",0x56}, ! {"RELEASE_10",0x57}, ! {"MODE_SENSE_10",0x5a}, ! {"PERSISTENT_RESERVE_IN",0x5e}, ! {"PERSISTENT_RESERVE_OUT",0x5f}, ! {"MOVE_MEDIUM",0xa5}, ! {"READ_12",0xa8}, ! {"WRITE_12",0xaa}, ! {"WRITE_VERIFY_12",0xae}, ! {"SEARCH_HIGH_12",0xb0}, ! {"SEARCH_EQUAL_12",0xb1}, ! {"SEARCH_LOW_12",0xb2}, ! {"READ_ELEMENT_STATUS",0xb8}, ! {"SEND_VOLUME_TAG",0xb6}, ! {"WRITE_LONG_2",0xea} ! }; ! ! /////////////////////////////////////////////////////////////////////// ! static volatile int internal_done_flag = 0; ! static volatile int internal_done_errcode = 0; ! static Scsi_Cmnd *current_SC = NULL; ! static int this_id = 31; ! V6INTERFACEB V6; ! static _DiskIDTable DiskID[16]; ! static DISKRWINFO DiskRWInfo[MAXBOARD][2][2]; ! static IDENTIFY_DATA DiskIdentifyData[MAXBOARD][2][2]; ! static int gBoardCount = 0; ! IrqID ultimaID[MAXBOARD]; ! BOARDTABLE BoardInfo[MAXBOARD]; ! static int IrqFlag[16] = {0,}; ! static int DriverInit = 0; ! static int DiskCount = 0; ! ULONG LastErrorBlock,LastErrorCode; ! static ULONG RWStatus; ! static ULONG OrderStatus; ! static ULONG CurrentDisk; ! static int interrupt_level = 0; ! ///////////////////////////////////////////////// ! #define IOCTL_LOCK 1 ! static int in_ioctl = 0; ! static int ClearReady = 0; ! static int in_command = 0; ! unsigned long LockValue = 0; ! static DECLARE_WAIT_QUEUE_HEAD (WaitingQ); ! static int HddConnected[MAXBOARD][2][2]; ! ///////////////////////////////////////////////// ! DWORD gResetFlag = 0; ! char * GetCmdName(char code) ! { ! int i; ! int count; ! char *s = "unknown function"; ! ! count = sizeof(CmdName) / sizeof(CMDNAME); ! ! for(i=0;ithis_id); ! ! if (interrupt_level) ! printk(" int %d", interrupt_level); ! else ! printk(""); ! ! printk("\n"); ! } ! ! static void aralion_setup(char *str, int *ints) ! { ! this_id = 31; ! } ! ! ! /* Pause for amount*10 milliseconds */ ! static void do_pause(ULONG amount) ! { ! do ! { ! udelay(10 * 1000); ! } ! while (--amount); ! } ! ! inline static void aralion_make_bus_idle(void) ! { ! } ! ! static int aralion_is_valid_port(int port) ! { ! return 0; ! } ! ! static int aralion_test_loopback(void) ! { ! return 0; ! } ! ! static int aralion_pci_bios_detect(int *irq) ! { ! struct pci_dev *pdev = NULL; ! ! if (!pci_present()) ! return 0; ! ! memset(BoardInfo,0,sizeof(BoardInfo)); ! ! do { ! if ((pdev = pci_find_device(ARALION_VENDOR, ULTIMA_DEVICE, pdev)) != NULL) { ! #ifdef KERNEL240 ! BoardInfo[gBoardCount].PrimaryIO ! = (ULONG) pci_resource_start(pdev,0); ! BoardInfo[gBoardCount].SecondaryIO ! = (ULONG) pci_resource_start(pdev,1); ! BoardInfo[gBoardCount].PrimaryDmaIO ! = (ULONG) pci_resource_start(pdev,2); ! BoardInfo[gBoardCount].SecondaryDmaIO ! = (ULONG) pci_resource_start(pdev,3); ! BoardInfo[gBoardCount].ControlRegister ! = (ULONG) pci_resource_start(pdev,4); ! #else ! BoardInfo[gBoardCount].PrimaryIO ! = (ULONG) pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK; ! BoardInfo[gBoardCount].SecondaryIO ! = (ULONG) pdev->base_address[1] & PCI_BASE_ADDRESS_IO_MASK; ! BoardInfo[gBoardCount].PrimaryDmaIO ! = (ULONG) pdev->base_address[2] & PCI_BASE_ADDRESS_IO_MASK; ! BoardInfo[gBoardCount].SecondaryDmaIO ! = (ULONG) pdev->base_address[3] & PCI_BASE_ADDRESS_IO_MASK; ! BoardInfo[gBoardCount].ControlRegister ! = (ULONG) pdev->base_address[4] & PCI_BASE_ADDRESS_IO_MASK; ! #endif ! BoardInfo[gBoardCount].interrupt_level = pdev->irq; ! ! request_region(BoardInfo[gBoardCount].PrimaryIO, 0x10, "aralion"); ! request_region(BoardInfo[gBoardCount].SecondaryIO, 0x10, "aralion"); ! request_region(BoardInfo[gBoardCount].PrimaryDmaIO, 0x10, "aralion"); ! request_region(BoardInfo[gBoardCount].SecondaryDmaIO, 0x10, "aralion"); ! request_region(BoardInfo[gBoardCount].ControlRegister, 0x10, "aralion"); ! if (!gBoardCount) ! *irq = pdev->irq; ! ! gBoardCount++; ! } ! } while(pdev != NULL); ! ! ! if (!gBoardCount) { ! printk("Ultima Board not found\n"); ! return 0; ! } ! ! interrupt_level = BoardInfo[0].interrupt_level; ! ! // printk("%d's Board found :",gBoardCount); ! ! return 1; ! } ! ! ULONG GetBlockCount(int BoardID,int channel,int drive) ! { ! int i; ! ULONG nCount; ! UCHAR *p; ! p = (char *) &(DiskIdentifyData[BoardID][channel][drive]); ! if(DiskIdentifyData[BoardID][channel][drive].BIT48 & 0x0400) ! nCount = *((ULONG *) (p + 200)); ! else ! nCount = *((ULONG *) (p + 120)); ! // printk("BCD=%d,%d,%d Size = %u \n",BoardID,channel,drive,nCount); ! return nCount; ! } ! ! ! void SetBlockCount(int BoardID,int channel,int drive,ULONG nCount) ! { ! UCHAR *p; ! ! p = (char *) &(DiskIdentifyData[BoardID][channel][drive]); ! if(DiskIdentifyData[BoardID][channel][drive].BIT48 & 0x0400) ! *((ULONG *) (p + 200)) = nCount; ! else ! *((ULONG *) (p + 120)) = nCount; ! } ! ! ////////////////// ! int RequestAllIrq(void) ! { ! int i; ! int irq; ! int retcode; ! ! for(i=0;i IRQ %d is bad!\n", irq); ! printk(" This shouldn't happen!\n"); ! printk(" Send mail to faith@acm.org\n"); ! } else if (retcode == -EBUSY) { ! printk("scsi: IRQ %d is already in use!\n",irq); ! printk(" Please use another IRQ!\n"); ! } else { ! printk("scsi: Error getting IRQ %d\n",irq); ! printk(" This shouldn't happen!\n"); ! printk(" Send mail to faith@acm.org\n"); ! } ! printk("scsi: Detected, but driver not loaded (IRQ)\n"); ! ! return retcode; ! } ! } ! } ! return 0; ! } ! ! ! int ultima_detect(Scsi_Host_Template * tpnt) ! { ! int retcode; ! struct Scsi_Host *shpnt; ! int i, j; ! int flag = 0; ! ! tpnt->proc_dir = &proc_scsi_aralion; ! ! flag = aralion_pci_bios_detect(&interrupt_level); ! ! if (!flag) { ! printk("scsi: Ultima not found\n"); ! return 0; ! } ! ! ! memset(&DiskID,0,sizeof(DiskID)); ! memset(&DiskRWInfo,0,sizeof(DiskRWInfo)); ! memset(&DiskIdentifyData,0,sizeof(DiskIdentifyData)); ! DiskCount = 0; ! ! ! for(i=0;ithis_id = (this_id & 0x1f); ! ! /* Print out a banner here in case we can't ! get resources. */ ! shpnt = scsi_register(tpnt, 0); ! shpnt->irq = interrupt_level; ! shpnt->io_port = BoardInfo[0].ControlRegister; ! shpnt->n_io_port = 0x10; ! // print_banner(shpnt); ! ! if (!interrupt_level) ! { ! printk("scsi: " ! " Card Detected, but driver not loaded (no IRQ)\n"); ! return 0; ! } else ! { ! /* Register the IRQ with the kernel */ ! if (RequestAllIrq()) ! return 0; ! } ! DriverInit = 0; ! ! for(i=0;i ",i,d1); ! } ! printk("\n"); ! } ! #endif ! ! inline DISKRWINFO *GetRWInfoPointer(DISKLIST *pDiskList) ! { ! return (DISKRWINFO *) &DiskRWInfo[pDiskList->BoardID][pDiskList->Channel][pDiskList->Drive]; ! } ! ! void PutLBAvalue(ULONG IOPort1,ULONG lba,ULONG numsectors, ! ULONG DriveSelect) ! { ! UCHAR Data[4]; ! if(lba >= 0x10000000){ ! Data[0] = (lba & 0xff000000 ) >> 24; ! Data[1] = 0; ! Data[2] = 0; ! outb(0,IOPort1 + BlockCountPort); ! outb(Data[0],IOPort1 + BlockNumberPort); ! outb(Data[1],IOPort1 + CylinderLowPort); ! outb(Data[2],IOPort1 + CylinderHighPort); ! Data[0] = (lba & 0x000000ff); ! Data[1] = (lba & 0x0000ff00) >> 8; ! Data[2] = (lba & 0x00ff0000) >> 16; ! Data[3] = (DriveSelect << 4) | 0xe0; ! outb(numsectors,IOPort1 + BlockCountPort); ! outb(Data[0],IOPort1 + BlockNumberPort); ! outb(Data[1],IOPort1 + CylinderLowPort); ! outb(Data[2],IOPort1 + CylinderHighPort); ! outb(Data[3],IOPort1 + DriveSelectPort); ! } ! else{ ! Data[0] = (lba & 0x000000ff); ! Data[1] = (lba & 0x0000ff00) >> 8; ! Data[2] = (lba & 0x00ff0000) >> 16; ! Data[3] = (lba & 0x0f000000) >> 24; ! Data[3] = Data[3] | 0x40 | (DriveSelect << 4) | 0xa0; ! ! outb(numsectors,IOPort1 + BlockCountPort); ! outb(Data[0],IOPort1 + BlockNumberPort); ! outb(Data[1],IOPort1 + CylinderLowPort); ! outb(Data[2],IOPort1 + CylinderHighPort); ! outb(Data[3],IOPort1 + DriveSelectPort); ! } ! } ! ! void DisableInterrupt(int BoardID) ! { ! USHORT Intena; ! Intena = 0; ! outw(Intena,BoardInfo[BoardID].ControlRegister + INTENA); ! } ! ! void EnableInterrupt(int BoardID) ! { ! USHORT Intena; ! Intena = 0x03; ! outw(Intena,BoardInfo[BoardID].ControlRegister + INTENA); ! } ! ! ULONG SetBoardInterruptFlag(int BoardID,int Channel,DWORD Status) ! { ! ULONG TempStatus; ! ! if (BoardInfo[BoardID].InterruptFlag[Channel] & Status) { ! TempStatus = BoardInfo[BoardID].InterruptFlag[Channel] & 0x00001111; ! if(TempStatus & 0x00001100){ ! BoardInfo[BoardID].InterruptFlag[Channel] |= 0x00001000; ! return 0x00001000; ! } ! else if(TempStatus & 0x00000010){ ! BoardInfo[BoardID].InterruptFlag[Channel] |= 0x00000100; ! return 0x00000100; ! } ! else { ! BoardInfo[BoardID].InterruptFlag[Channel] |= 0x00000010; ! return 0x000000010; ! } ! ! ! #ifdef DEBUG1 ! printk("SL:[%d,%d] - %08x ", ! BoardID,Channel, ! BoardInfo[BoardID].InterruptFlag[Channel]); ! #endif ! } ! else { ! BoardInfo[BoardID].InterruptFlag[Channel] = (Status | ORDER_ONE); ! ! #ifdef DEBUG1 ! printk("SF:[%d,%d] - %08x ", ! BoardID,Channel, ! BoardInfo[BoardID].InterruptFlag[Channel]); ! #endif ! return 0; ! } ! } ! ! ULONG SetScatterList( Scsi_Cmnd * SCpnt, ! ULONG lba, ! ULONG numsectors, ! ULONG ReadWrite) ! { ! struct scatterlist *slp; ! int i,j; ! PPDT_TABLE pPDTTable; ! DISKRWINFO *pRWInfo,*pRWInfo2; ! int tid = SCpnt->target; ! DWORD RaidStatus; ! ULONG TempFlag; ! ! RaidStatus = RAID(tid); ! ! pRWInfo = (DISKRWINFO *) &DiskRWInfo[S_BOARD(tid)][S_CHAN(tid)][S_DRV(tid)]; ! pRWInfo->StartLba = lba; ! pRWInfo->ListCount = 0; ! pRWInfo->NumSectors = 0; ! pPDTTable = pRWInfo->ScatterList; ! ! if (SCpnt->use_sg) ! { ! slp = (struct scatterlist *) SCpnt->request_buffer; ! for(i=0;iuse_sg;i++,slp++) { ! pPDTTable[i].address = virt_to_bus(slp->address); ! pPDTTable[i].length = slp->length; ! pPDTTable[i].EndOfChain = 0; ! pRWInfo->NumSectors += slp->length; ! } ! pPDTTable[i - 1].EndOfChain = 0x80; ! pRWInfo->ListCount = SCpnt->use_sg; ! } ! else ! { ! pPDTTable[0].address = virt_to_bus(SCpnt->request_buffer); ! pPDTTable[0].length = SCpnt->request_bufflen; ! pPDTTable[0].EndOfChain = 0x80; ! pRWInfo->NumSectors = SCpnt->request_bufflen; ! pRWInfo->ListCount = 1; ! } ! ! pRWInfo->NumSectors /= 512; ! ! pRWInfo->InterruptFlag = ReadWrite | ORDER_ONE; ! SetBoardInterruptFlag(S_BOARD(tid),S_CHAN(tid),ReadWrite); ! ! } ! ! void PrintPDT(PPDT_TABLE pPDTTable,int count) ! { ! int i; ! ! for(i=0;iBoardID; ! Channel = pList->Channel; ! Drive = pList->Drive; ! ! pRWInfo = (DISKRWINFO *) &DiskRWInfo[pList->BoardID][pList->Channel][pList->Drive]; ! ! ! #ifdef DEBUG1 ! /* ! printk("SetIOPort : [B:%d,C:%d,D:%d,F:%08x,O:%08x]\n", ! BoardID, ! Channel, ! Drive, ! pRWInfo->InterruptFlag, ! OrderFlag); ! */ ! #endif ! ! ! if (!(OrderFlag & pRWInfo->InterruptFlag)) { ! #ifdef DEBUG1 ! printk("Order Invalid\n"); ! #endif ! return ; ! } ! ! if (Channel == 0) ! { ! pPDTTable = BoardInfo[BoardID].PriScatterList; ! IOPort1 = BoardInfo[BoardID].PrimaryIO; ! DmaIO = BoardInfo[BoardID].PrimaryDmaIO; ! } ! else ! { ! pPDTTable = BoardInfo[BoardID].SecScatterList; ! IOPort1 = BoardInfo[BoardID].SecondaryIO; ! DmaIO = BoardInfo[BoardID].SecondaryDmaIO; ! } ! memcpy(pPDTTable,pRWInfo->ScatterList,pRWInfo->ListCount * sizeof(PDT_TABLE)); ! BoardInfo[BoardID].ListCount = pRWInfo->ListCount; ! BoardInfo[BoardID].NumSectors = pRWInfo->NumSectors; ! BoardInfo[BoardID].StartLba = pRWInfo->StartLba; ! ! AddressLow = virt_to_bus(pPDTTable) & 0x0000ffff; ! AddressHi = (virt_to_bus(pPDTTable) & 0xffff0000) >> 16; ! ! outw(AddressLow,DmaIO + PDTLAR); ! outw(AddressHi,DmaIO + PDTHAR); ! PutLBAvalue( ! IOPort1, ! BoardInfo[BoardID].StartLba, ! BoardInfo[BoardID].NumSectors, ! Drive); ! ! } ! ! void SetIOInformation(int tid,USHORT DmaRW,DWORD OrderFlag) ! { ! struct scatterlist *slp; ! int i,j,k; ! PPDT_TABLE pPDTTable; ! DISKRWINFO *pRWInfo = GetRWInfoPointer(&DiskID[tid].DiskStatus); ! if (pRWInfo->ListCount) { ! SetIOPort(&DiskID[tid].DiskStatus,DmaRW,OrderFlag); ! } ! ! } ! ! void SetIDECommand(DWORD Command, DWORD OrderFlag) ! { ! int i,j; ! ! for(i=0;i= 0x10000000) ! Command=BigDiskCommand(Command); ! outb(Command,BoardInfo[i].PrimaryIO + CommandPort); ! } ! if (BoardInfo[i].InterruptFlag[1] & OrderFlag) { ! if(BoardInfo[i].StartLba >= 0x10000000) ! Command=BigDiskCommand(Command); ! outb(Command,BoardInfo[i].SecondaryIO + CommandPort); ! } ! ! } ! } ! ! DWORD BigDiskCommand (DWORD cmnd) ! { ! switch(cmnd){ ! case IDE_COMMAND_READ_DMA: ! return IDE_COMMAND_READ_DMA_EXT; ! case IDE_COMMAND_WRITE_DMA: ! return IDE_COMMAND_WRITE_DMA_EXT; ! } ! } ! ! void SetDMACommand(USHORT DmaRW,DWORD OrderFlag) ! { ! ULONG DmaIO; ! int i,j,k; ! ! for(i=0;itarget].RaidStatus) { ! case NORMALIDE: ! SetScatterList(SCpnt,lba,numsectors,READ_STATUS); ! break; ! default: ! printk("Not Supported Mode!!\n"); ! return -1; ! } ! SetIOInformation(SCpnt->target,DMA_READ,ORDER_ONE); ! RWStatus = READ_STATUS; ! OrderStatus = ORDER_ONE; ! SetIDECommand(IDE_COMMAND_READ_DMA,ORDER_ONE); ! SetDMACommand(DMA_READ,ORDER_ONE); ! return 0; ! } ! ! static int WriteDMA( ! Scsi_Cmnd * SCpnt, ! ULONG lba, ! ULONG numsectors) ! { ! int i; ! unsigned long flags; ! ! if (numsectors == 0) { ! my_done(DID_ABORT << 16); ! return ERROR_INVALID_SECTORCOUNT; ! } ! ! switch(DiskID[SCpnt->target].RaidStatus) { ! case NORMALIDE: ! SetScatterList(SCpnt,lba,numsectors,WRITE_STATUS); ! break; ! default: ! printk("Not Supported Mode!!\n"); ! return -1; ! ! } ! SetIOInformation(SCpnt->target,DMA_WRITE,ORDER_ONE); ! RWStatus = WRITE_STATUS; ! OrderStatus = ORDER_ONE; ! SetIDECommand(IDE_COMMAND_WRITE_DMA,ORDER_ONE); ! SetDMACommand(DMA_WRITE,ORDER_ONE); ! return 0; ! } ! ! void GetUDMAMode(USHORT *mode,USHORT *Timing, ! IDENTIFY_DATA * IdentifyData) ! { ! ! if(IdentifyData->UDMASupport & 0x20){ ! *mode = 0x45; // mode 5 ! *Timing = 0xff22; // mode 5 ! } ! else if(IdentifyData->UDMASupport & 0x10){ ! *mode = 0x44; // mode 4 ! *Timing = 0xff33; // mode 4 ! } ! else if(IdentifyData->UDMASupport & 0x08){ ! *mode = 0x43; // mode 3 ! *Timing = 0xff55; // mode 3 ! } ! else if(IdentifyData->UDMASupport & 0x04){ ! *mode = 0x42; // mode 2 ! *Timing = 0xff66; // mode 2 ! } ! else if(IdentifyData->UDMASupport & 0x02){ ! *mode = 0x41; // mode 1 ! *Timing = 0xff88; // mode 1 ! } ! else if(IdentifyData->UDMASupport & 0x01){ ! *mode = 0x40; // mode 0 ! *Timing = 0xffcc; // mode 0 ! } ! #ifdef _7878_ ! *mode = 0x44; // mode 4 ! *Timing = 0x7878; // safe mode ! #endif ! } ! ! void SetUDMAMode( int BoardID, ! int Channel, ! int DriveSelect, ! IDENTIFY_DATA * IdentifyData) ! { ! USHORT mode[2],Timing[2]; ! ULONG IOPort1; ! ULONG DmaIO; ! char statusByte; ! int i; ! if (Channel == 0) { ! IOPort1 = BoardInfo[BoardID].PrimaryIO; ! DmaIO = BoardInfo[BoardID].PrimaryDmaIO; ! } ! else { ! IOPort1 = BoardInfo[BoardID].SecondaryIO; ! DmaIO = BoardInfo[BoardID].SecondaryDmaIO; ! } ! outb(0x03,IOPort1 + ErrorPort); ! ! for(i=0;i<4;i++) ! { ! mode[i] = 0xffff; ! } ! ! if (HddConnected[BoardID][Channel][0]) ! GetUDMAMode(&mode[0],&Timing[0],&DiskIdentifyData[BoardID][Channel][0]); ! if (HddConnected[BoardID][Channel][1]) ! GetUDMAMode(&mode[1],&Timing[1],&DiskIdentifyData[BoardID][Channel][1]); ! if(mode[0] > mode[1]) ! { ! mode[0] = mode[1]; ! Timing[0] = Timing[1]; ! } ! ! outw(0x0001,DmaIO + DMAMODE); ! ! outb(mode[0],IOPort1 + BlockCountPort); ! if (HddConnected[BoardID][Channel][0]) ! { ! outb(0xA0,IOPort1 + DriveSelectPort); ! outb(IDE_COMMAND_ENABLE_MEDIA_STATUS,IOPort1 + CommandPort); ! outw(Timing[0],DmaIO + UDM_TIM); ! } ! if (HddConnected[BoardID][Channel][1]) ! { ! outb(0xB0,IOPort1 + DriveSelectPort); ! outb(IDE_COMMAND_ENABLE_MEDIA_STATUS,IOPort1 + CommandPort); ! outw(Timing[0],DmaIO + UDM_TIM); ! } ! ! statusByte = 0; ! mdelay(5); ! while(!(statusByte & IDE_STATUS_IDLE)) ! { ! GetBaseStatus(IOPort1, statusByte); ! } ! } ! ! static int IdentifyDisk( ! int BoardID, ! int Channel, ! int DriveSelect, ! IDENTIFY_DATA * IdentifyData) ! { ! ULONG IOPort1,DmaIO,ControlRegister; ! UCHAR statusByte; ! USHORT *pIdentifyData; ! int i, j; ! int flag = 0; ! ! HddConnected[BoardID][Channel][DriveSelect] = 0; ! mdelay(100); ! ! if (Channel == 0) ! { ! IOPort1 = BoardInfo[BoardID].PrimaryIO; ! DmaIO = BoardInfo[BoardID].PrimaryDmaIO; ! } ! else ! { ! IOPort1 = BoardInfo[BoardID].SecondaryIO; ! DmaIO = BoardInfo[BoardID].SecondaryDmaIO; ! } ! ! ControlRegister = BoardInfo[BoardID].ControlRegister; ! ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! ! for (i=0;i<100;i++) { ! udelay(10); ! GetBaseStatus(IOPort1, statusByte); ! ! if (!(statusByte & 0x80)) ! break; ! } ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! mdelay(50); ! GetBaseStatus(IOPort1, statusByte); ! ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! mdelay(50); ! GetBaseStatus(IOPort1, statusByte); ! ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! mdelay(50); ! GetBaseStatus(IOPort1, statusByte); ! mdelay(50); ! if(statusByte != 0x50) ! { ! if((statusByte & 0xF0) != 0x50) ! return 0; ! outb(0x08,IOPort1+CommandPort); ! mdelay(100); ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! GetBaseStatus(IOPort1, statusByte); ! for(i=0;i<3;i++) ! { ! mdelay(100); ! outb(0x04, IOPort1 + 0x0E); ! mdelay(100); ! outb(0x00, IOPort1 + 0x0E); ! GetBaseStatus(IOPort1, statusByte); ! if(statusByte == 0x50) ! break; ! } ! if(i >= 3) ! return 0; ! } ! ! ! statusByte = statusByte & 0xc9; ! ! // printk("Identify: After Masking with 0xC9! Status == %x\n", ! // statusByte); ! ! if (statusByte != IDE_STATUS_DRDY) ! { ! // printk(" ---- Identify: DRDY is NOT asserted!\n"); ! // printk(" ---- Identify: return FALSE.\n"); ! // printk("IdentifyDisk Fail bd=%d,ch=%d, drv=%d :\n",BoardID,Channel,DriveSelect); ! return 0; ! } ! ! ! label1: ! for (j = 0; j < 2; j++) ! { ! ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! mdelay(10); ! GetBaseStatus(IOPort1, statusByte); ! ! // printk("Status3 = %x\n", (UCHAR) statusByte); ! ! WaitOnBusy(IOPort1, statusByte); ! outb(IDE_COMMAND_IDENTIFY, IOPort1 + CommandPort); ! ! for (i = 0; i < 4; i++) ! { ! WaitForDrq(IOPort1, statusByte); ! if (statusByte & IDE_STATUS_DRQ) ! { ! // Read status to acknowledge any interrupts generated. ! GetBaseStatus(IOPort1, statusByte); ! break; ! } ! ! WaitOnBusy(IOPort1, statusByte); ! } // end of for (i = 0; i < 4; i++) ! ! if (i == 4 && j == 0) ! { ! // printk(" ---- Identify: DRQ never asserted (%x). Error reg (%x)\n", ! // statusByte, inb(IOPort1 + 1)); ! // printk(" ---- Identify: return FALSE.\n"); ! return 0; ! } else ! { ! break; ! } ! } // end of for (j = 0; j < 2; j++) ! ! ! if (statusByte & IDE_STATUS_ERROR) ! { ! // printk(" ---- Identify: Status %x\n", statusByte); ! // printk(" ---- Identify: return FALSE.\n"); ! return 0; ! } ! ! WaitOnBusy(IOPort1, statusByte); ! ! ! if (!(statusByte & IDE_STATUS_DRQ)) ! { ! // printk(" ---- Identify: DRQ is NOT asserted!\n"); ! // printk(" ---- Identify: return FALSE.\n"); ! return 0; ! } ! ! // DiskPresent |= (1 << (Channel * 2 + DriveSelect + 4)); ! pIdentifyData = (USHORT *) IdentifyData; ! ! outb(((DriveSelect << 4) | 0xA0), IOPort1 + DriveSelectPort); ! mdelay(50); ! GetBaseStatus(IOPort1, statusByte); ! // printk("S3=%02x ", (UCHAR) statusByte); ! // printk("IdentifyDisk bd=%d,ch=%d, drv=%d \n",BoardID,Channel,DriveSelect); ! for (i = 0; i < 256; i++) ! { ! pIdentifyData[i] = inw(IOPort1 + DataPort); ! } ! ! // printk("\n"); ! ! for(i=0; i<256; i++) ! { ! // printk("%0.4x ",pIdentifyData[i]); ! } ! // printk("\n"); ! ! { ! char *p,c; ! p = (char *) &(IdentifyData->VendorUnique1); ! ! for (i = 0; i < 26; i+=2) ! { ! c = p[i]; ! p[i] = p[i+1]; ! p[i+1] = c; ! // printk("[%02x]<%02x>",(unsigned char)p[i],(unsigned char)p[i+1]); ! } ! // printk("\n"); ! ! p = (char *) &(IdentifyData->ModelNumber); ! ! for (i = 0; i < 40; i+=2) ! { ! c = p[i]; ! p[i] = p[i+1]; ! p[i+1] = c; ! // printk("%c",c); ! } ! } ! HddConnected[BoardID][Channel][DriveSelect] = 1; ! SetUDMAMode(BoardID,Channel,DriveSelect,IdentifyData); ! ! { ! int mm = 0; ! ! for (i = 0; i < 0x1000; i++) ! { ! ! GetStatus(IOPort1, statusByte); ! ! if ((statusByte & IDE_STATUS_DRQ) ! || (statusByte & IDE_STATUS_BUSY) ! || (statusByte & 1) ) ! { ! inw(IOPort1 + DataPort); ! } else ! break; ! } // end of for ! } ! // printk("IdentifyDisk Success!\n"); ! return 1; ! } ! ! char *ultima_info(struct Scsi_Host *ignore) ! { ! static char buffer[128]; ! char *pt; ! ! // printk("[ ultima_info ]\n"); ! strcpy(buffer, "Aralion Ultima ATA100 IDE RAID MultiCard Driver Version"); ! if (strchr(VERSION, ':')) ! { /* Assume VERSION is an RCS Revision string */ ! strcat(buffer, strchr(VERSION, ':') + 1); ! pt = strrchr(buffer, '$') - 1; ! if (!pt) /* Stripped RCS Revision string? */ ! pt = buffer + strlen(buffer) - 1; ! if (*pt != ' ') ! ++pt; ! *pt = '\0'; ! } else ! { /* Assume VERSION is a number */ ! strcat(buffer, " " VERSION); ! } ! ! return buffer; ! } ! ! ! ! int ultima_ioctl (Scsi_Device *dev, int cmd, void *arg) ! { ! return 0; ! } ! ! int init_module(void) { ! driver_template.module = &__this_module; ! scsi_register_module(MODULE_SCSI_HA, &driver_template); ! if (driver_template.present) { ! return 0; ! } ! ! scsi_unregister_module(MODULE_SCSI_HA, &driver_template); ! return -1; ! } ! ! void cleanup_module( void) { ! scsi_unregister_module(MODULE_SCSI_HA, &driver_template); ! } ! /* First pass at /proc information routine. */ ! ! int ultima_proc_info(char *buffer, char **start, off_t offset, ! int length, int hostno, int inout) ! { ! const char *info = ultima_info(NULL); ! int len; ! int pos; ! int begin; ! ! if (inout) ! return (-ENOSYS); ! ! begin = 0; ! strcpy(buffer, info); ! strcat(buffer, "\n"); ! ! pos = len = strlen(buffer); ! ! if (pos < offset) ! { ! len = 0; ! begin = pos; ! } ! ! *start = buffer + (offset - begin); /* Start of wanted data */ ! len -= (offset - begin); ! if (len > length) ! len = length; ! ! return (len); ! } ! ! static int aralion_arbitrate(void) ! { ! int status = 0; ! ULONG timeout; ! ! printk("[ aralion_arbitrate ]\n"); ! ! return 0; ! } ! ! static int aralion_select(int target) ! { ! int status; ! ULONG timeout; ! static int flag = 0; ! ! ! printk("[ aralion_select - %d ]\n",target); ! return 0; ! } ! ! static void my_done(int error) ! { ! if (in_command) ! { ! in_command = 0; ! // printk("{C}"); ! if (test_and_clear_bit(IOCTL_LOCK,&LockValue) == 0) ! printk("misc clear...\n"); ! current_SC->result = error; ! if (current_SC->scsi_done) { ! current_SC->scsi_done(current_SC); ! } ! else ! panic("scsi: current_SC->scsi_done() == NULL"); ! } else ! { ! panic("scsi: my_done() called outside of command\n"); ! } ! } ! ! int CheckScsiError(ULONG Channel,ULONG IOPort1,UCHAR statusByte) ! { ! ULONG lba; ! UCHAR Data[4]; ! UCHAR errorByte; ! ULONG scsiStatus = 0; ! ! if (statusByte & 0x1) { ! ! errorByte = inb(IOPort1 + ErrorPort); ! ! if (errorByte & IDE_ERROR_BAD_BLOCK) ! scsiStatus = DID_PARITY; ! else if (errorByte & IDE_ERROR_DATA_ERROR) ! scsiStatus = DID_ERROR; ! else if (errorByte & IDE_ERROR_ID_NOT_FOUND) ! scsiStatus = DID_NO_CONNECT; ! else if (errorByte & IDE_ERROR_COMMAND_ABORTED) ! scsiStatus = DID_ABORT; ! else if (errorByte & IDE_ERROR_ILLEGAL_LENGTH ) ! scsiStatus = DID_ERROR; ! ! Data[3] = inb(IOPort1 + BlockNumberPort); ! Data[2] = inb(IOPort1 + CylinderLowPort); ! Data[1] = inb(IOPort1 + CylinderHighPort); ! Data[0] = inb(IOPort1 + DriveSelectPort) & 0x0f; ! ! lba = (Data[0] << 24) + (Data[1] << 16) ! + (Data[2] << 8) + Data[0]; ! ! LastErrorBlock = lba; ! LastErrorCode = errorByte & 0x000f; ! ! printk("Error! Ch:%d, %02x , %0d\n",Channel, ! (UCHAR) errorByte,lba); ! ! // my_done(scsiStatus << 16); ! return scsiStatus; ! } ! else ! return 0; ! } ! ! void CheckJobFinished(ULONG BoardID,ULONG Channel) ! { ! ULONG DmaIO; ! USHORT Stat; ! DWORD i = 0; ! ! // printk("CheckJobFinished = <%d,%d>\n",BoardID,Channel); ! ! if (Channel == 1) { ! DmaIO = BoardInfo[BoardID].PrimaryDmaIO; ! } ! else ! DmaIO = BoardInfo[BoardID].SecondaryDmaIO; ! ! do { ! Stat = inw(DmaIO + CONSR); ! i++; ! } while ((Stat & 0x01) && (i < 80000000)); ! // printk("Check End : %u\n",i); ! } ! void ClearAllIrq(void) ! { ! ULONG Channel; ! UCHAR statusByte = 0; ! UCHAR statusByte2 = 0; ! ULONG IOPort1,IOPort2; ! ULONG scsiStatus = 0; ! int i; ! ! for(i=0;i\n"); ! ! if (!pIntID) { ! #ifdef DEBUG ! printk("It is not ultima_irq1\n"); ! #endif ! spin_unlock_irqrestore(&io_request_lock, flags); ! return ; ! } ! ! if (gResetFlag) { ! for (i=0;iresult; ! ++internal_done_flag; ! } ! ! int IsSplitter(char c) ! { ! if (c == ' ' || c == '-' || c == '_') ! return 1; ! else if (c >= '0' && c <= '9') ! return 1; ! ! return 0; ! } ! ! int ultima_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) ! { ! char *buf; ! int board,channel,drive; ! ULONG result; ! /* ! printk("[c=%x : %s,I=%x],DiskCount = %d\n", ! (UCHAR) SCpnt->cmnd[0], ! GetCmdName((UCHAR) SCpnt->cmnd[0]), ! SCpnt->target, ! DiskCount); ! */ ! if (in_command) { ! printk("[ ultima_queue c=%x : %s,I=%x]\n", ! (UCHAR) SCpnt->cmnd[0], ! GetCmdName((UCHAR) SCpnt->cmnd[0]), ! SCpnt->target); ! panic("Error! in_command == 1\n"); ! return ; ! } ! ! while(test_and_set_bit(IOCTL_LOCK,&LockValue) != 0) { ! printk("QW "); ! schedule(); ! udelay(1); ! } ! while(in_ioctl) { ! // printk("in_ioctl = 1\n"); ! udelay(1); ! } ! in_command = 1; ! current_SC = SCpnt; ! current_SC->scsi_done = done; ! ! current_SC->SCp.Status = 0; ! current_SC->SCp.Message = 0; ! current_SC->SCp.have_data_in = 0; ! current_SC->SCp.sent_command = 0; ! current_SC->SCp.phase = in_arbitration; ! ! if ( SCpnt->lun > 0) { ! my_done(DID_ABORT << 16); ! return 0; ! } ! board = DiskID[current_SC->target].DiskStatus.BoardID; ! channel = DiskID[current_SC->target].DiskStatus.Channel; ! drive = DiskID[current_SC->target].DiskStatus.Drive; ! ! ! switch(current_SC->cmnd[0]) { ! case TEST_UNIT_READY: ! case REQUEST_SENSE : ! my_done(0); ! return 0; ! ! case MODE_SENSE : ! buf = (char *) current_SC->buffer; ! buf[2] = 0x0; ! my_done(0); ! break; ! ! case INQUIRY : ! if(hotplug_check(current_SC->target) == 0) ! { ! my_done(DID_ABORT << 16); ! return 0; ! } ! ! board = DiskID[current_SC->target].DiskStatus.BoardID; ! channel = DiskID[current_SC->target].DiskStatus.Channel; ! drive = DiskID[current_SC->target].DiskStatus.Drive; ! buf = (char *) current_SC->buffer; ! { ! PINQUIRYDATA inquiryData ! = (PINQUIRYDATA) current_SC->buffer; ! PIDENTIFY_DATA identifyData = ! &DiskIdentifyData[board][channel][drive]; ! int i; ! ! memset(buf,0,current_SC->bufflen); ! ! buf[4] = sizeof(INQUIRYDATA); ! ! // ! // Standard IDE interface only supports disks. ! inquiryData->DeviceType = DIRECT_ACCESS_DEVICE; ! ! // ! // Fill in vendor identification fields. ! { ! unsigned char *p; ! int i,j; ! ! for (i = 0; i < 24; i ++) { ! inquiryData->VendorId[i] = 0; ! } ! p = (UCHAR *) identifyData->ModelNumber; ! i = 0; ! ! while(!IsSplitter(p[i])) { ! inquiryData->VendorId[i] = p[i++]; ! } ! inquiryData->VendorId[i] = 0; ! ! i++; ! j = 0; ! while (p[i] != ' ' && i < 24) ! inquiryData->ProductId[j++] = p[i++]; ! inquiryData->ProductId[j] = 0; ! ! } ! // ! // Initialize unused portion of product id. ! for (i = 0; i < 4; i++) { ! inquiryData->ProductId[12+i] = ' '; ! } ! ! // ! // Move firmware revision from IDENTIFY data to ! // product revision in INQUIRY data. ! for (i = 0; i < 4; i += 2) { ! inquiryData->ProductRevisionLevel[i] = ! ((UCHAR *)identifyData->FirmwareRevision)[i+1]; ! inquiryData->ProductRevisionLevel[i+1] = ! ((UCHAR *)identifyData->FirmwareRevision)[i]; ! } ! } ! // printk("Inquiry Success!"); ! my_done(0); ! break; ! case READ_6 : ! case READ_10 : ! case WRITE_6 : ! case WRITE_10 : ! ! { ! ULONG numsectors,lba,i ; ! ! // SDptr->disconnect = 0; ! if (*current_SC->cmnd == READ_6 || *current_SC->cmnd == WRITE_6) { ! numsectors = (u_long) current_SC->cmnd[4]; ! lba = ((u_long) current_SC->cmnd[1] << 16) | ! ((u_long) current_SC->cmnd[2] << 8) | ! (u_long) current_SC->cmnd[3]; ! lba &= 0x1FFFFF; ! } ! if (*current_SC->cmnd == READ_10 || *current_SC->cmnd == WRITE_10) { ! numsectors = (u_long) current_SC->cmnd[8] | ! ((u_long) current_SC->cmnd[7] << 8); ! lba = ((u_long) current_SC->cmnd[2] << 24) | ! ((u_long) current_SC->cmnd[3] << 16) | ! ((u_long) current_SC->cmnd[4] << 8) | ! (u_long) current_SC->cmnd[5]; ! } ! ! memset(DiskRWInfo,0,sizeof(DiskRWInfo)); ! for(i=0;itarget; ! ! if (*current_SC->cmnd == READ_6 || *current_SC->cmnd == READ_10) { ! ! // printk("R:[%03d,%08x]", numsectors,lba); ! ReadDMA(current_SC,lba,numsectors); ! } ! else { ! // printk("W:[%03d,%08x]", numsectors,lba); ! WriteDMA(current_SC,lba,numsectors); ! } ! } ! // printk("RW Success!\n"); ! break; ! ! case READ_CAPACITY : ! { ! ULONG block,size; ! IDENTIFY_DATA * IdentifyData; ! ! block = DiskID[current_SC->target].DiskStatus.Size; ! // printk("Block Size = %x\n",block); ! buf = (char *) current_SC->buffer; ! size = 512; ! ! *((ULONG *) buf) = htonl(block - 1); ! *((ULONG *) (buf + 4)) = htonl(size); ! } ! ! my_done(0); ! // printk("Read_Cap Success!\n"); ! break; ! default: ! my_done(0); ! break; ! ! } ! return 0; ! } ! ! ! void FillDump( Scsi_Cmnd * SCpnt) ! { ! struct scatterlist *slp; ! int i,j; ! ULONG TempFlag; ! ! if (SCpnt->use_sg) ! { ! slp = (struct scatterlist *) SCpnt->request_buffer; ! for(i=0;iuse_sg;i++,slp++) { ! memset(&(slp->address),0,slp->length); ! } ! } ! else ! { ! memset(&(slp->address),0,SCpnt->request_bufflen); ! } ! } ! ! int hotplug_check(int target) ! { ! int i, j, k; ! UCHAR statusByte; ! ULONG IOPort1; ! // printk("targetID=%d, DiskCount=%d\n",target,DiskCount); ! if(target == DiskCount) ! { ! for(i=0;ihost) ! { ! printk("scsi: Cannot provide detailed information\n"); ! return; ! } ! ! printk("%s\n", ultima_info(SCpnt->host)); ! return ; ! print_banner(SCpnt->host); ! ! printk("(%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n", ! SCpnt->SCp.phase, ! SCpnt->target, ! *(UCHAR *) SCpnt->cmnd, ! SCpnt->use_sg, SCpnt->request_bufflen); ! printk("sent_command = %d, have_data_in = %d, timeout = %d\n", ! SCpnt->SCp.sent_command, ! SCpnt->SCp.have_data_in, SCpnt->timeout); ! } ! ! int ultima_handle(Scsi_Cmnd * SCpnt) ! { ! // printk("\n"); ! } ! ! int ultima_abort(Scsi_Cmnd * SCpnt) ! { ! ULONG flags; ! ! // printk("ultima_abort ---- \n"); ! if (!in_command) ! { ! return SCSI_ABORT_NOT_RUNNING; ! } ! ultima_cardreset(); ! ! //#if DEBUG ! print_info(SCpnt); ! //#endif ! ! current_SC->SCp.phase |= aborted; ! ! current_SC->result = DID_ABORT << 16; ! // current_SC->result = DID_BUS_BUSY << 16; ! ! /* Aborts are not done well. . . */ ! if (in_command) ! my_done(DID_ABORT << 16); ! // my_done(DID_BUS_BUSY << 16); ! ! return SCSI_ABORT_SUCCESS; ! } ! ! int ultima_reset(Scsi_Cmnd * SCpnt, unsigned int ignored) ! { ! // printk("ultima_reset ---- \n"); ! ultima_cardreset(); ! ! return SCSI_RESET_WAKEUP; ! } ! ! // ! // KHG-20020719 ! // ! ! int ultima_1channelreset(int BoardID, int Channel) ! { ! int i; ! UCHAR statusByte,statusByte2; ! // printk("%d board reset\n",BoardID); ! if(Channel == 0) ! { ! outw(0x8000,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x4000,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x0,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0xff8f,BoardInfo[BoardID].ControlRegister + 0x0c); ! /* ! for (i=0;i<200;i++) ! { ! mdelay(5); ! outb(0xA0, BoardInfo[BoardID].PrimaryIO + DriveSelectPort); ! GetBaseStatus(BoardInfo[BoardID].PrimaryIO, statusByte); ! outb(0xB0, BoardInfo[BoardID].PrimaryIO + DriveSelectPort); ! GetBaseStatus(BoardInfo[BoardID].PrimaryIO, statusByte2); ! if (!(statusByte & 0x80) && !(statusByte2 & 0x80)) ! break; ! } ! */ ! } ! else ! { ! outw(0x8000,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x4000,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x0,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! mdelay(20); ! outw(0xff8f,BoardInfo[BoardID].ControlRegister + 0x0e); ! /* ! for (i=0;i<200;i++) ! { ! mdelay(5); ! outb(0xA0, BoardInfo[BoardID].SecondaryIO + DriveSelectPort); ! GetBaseStatus(BoardInfo[BoardID].SecondaryIO, statusByte); ! outb(0xB0, BoardInfo[BoardID].SecondaryIO + DriveSelectPort); ! GetBaseStatus(BoardInfo[BoardID].SecondaryIO, statusByte2); ! if (!(statusByte & 0x80) && !(statusByte2 & 0x80)) ! break; ! } ! */ ! } ! for(i=0;i<125;i++) ! { ! mdelay(10); ! } ! } ! ! int ultima_1cardreset(int BoardID) ! { ! int i,j; ! UCHAR statusByte,statusByte2; ! UCHAR statusByte3,statusByte4; ! ! mdelay(20); ! outw(0x8000,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x4000,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x0,BoardInfo[BoardID].PrimaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x8000,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x4000,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! mdelay(20); ! outw(0x0,BoardInfo[BoardID].SecondaryDmaIO + 0x0e); ! for(i=0;i<125;i++) ! { ! mdelay(20); ! } ! } ! ! ! int ultima_cardreset(void) ! { ! int i,j,k; ! ! RWStatus = RESET_STATUS; ! // printk("ultima cardreset\n"); ! gResetFlag = 1; ! for(i=0;i> 4; ! // printk("BiosParam = %d,%d\n",board,channel); ! ! info_array[0] = 16; ! info_array[1] = 63; ! ! // size = info_array[0] * info_array[1] * info_array[2]; ! ! size = DiskID[target].DiskStatus.Size; ! info_array[2] = size / (info_array[0] * info_array[1]); ! ! if (info_array[2] > 1024) { ! info_array[0] = 0xff; ! info_array[2] = ! (ULONG) size / (info_array[0] * info_array[1]); ! } ! ! return 0; ! } ! diff -Ncr linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid100/ultima.h linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid100/ultima.h *** linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid100/ultima.h 2003-11-27 11:18:33.000000000 +0900 --- linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid100/ultima.h 2003-12-03 00:34:32.000000000 +0900 *************** *** 78,84 **** extern int ultima_biosparam( Disk *, kdev_t, int * ); extern int ultima_handle( Scsi_Cmnd * ); extern char * ultima_info( struct Scsi_Host * ); ! extern int ultima_cardreset(); extern int ultima_proc_info( char *buffer, char **start, off_t offset, int length, int hostno, int inout ); extern int ultima_ioctl(Scsi_Device *dev, int cmd, void *arg); --- 78,84 ---- extern int ultima_biosparam( Disk *, kdev_t, int * ); extern int ultima_handle( Scsi_Cmnd * ); extern char * ultima_info( struct Scsi_Host * ); ! extern int ultima_cardreset(void); extern int ultima_proc_info( char *buffer, char **start, off_t offset, int length, int hostno, int inout ); extern int ultima_ioctl(Scsi_Device *dev, int cmd, void *arg); diff -Ncr linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid133/atapi.h linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid133/atapi.h *** linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid133/atapi.h 2003-11-27 11:18:33.000000000 +0900 --- linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid133/atapi.h 2003-12-03 00:34:32.000000000 +0900 *************** *** 46,60 **** #define IDE_COMMAND_ENABLE_MEDIA_STATUS 0xEF // Feature Set #define IDE_COMMAND_IDENTIFY 0xEC // <--- #define IDE_COMMAND_MEDIA_EJECT 0xED ! ! ! //////////////////////////////////KHG133s_Big////////////////////////////////////// ! #define IDE_COMMAND_READ_DMA_EXT 0x25 ! #define IDE_COMMAND_WRITE_DMA_EXT 0x35 ! #define IDE_COMMAND_READ_SECTORS 0x20 ! #define IDE_COMMAND_WRITE_SECTORS 0x30 ! #define IDE_COMMAND_READ_SECTORS_EXT 0x24 ! #define IDE_COMMAND_WRITE_SECTORS_EXT 0x34 /////////////////////////////////////////////////////////////////////////////////// // //DmaCommand bits definition --- 46,60 ---- #define IDE_COMMAND_ENABLE_MEDIA_STATUS 0xEF // Feature Set #define IDE_COMMAND_IDENTIFY 0xEC // <--- #define IDE_COMMAND_MEDIA_EJECT 0xED ! ! ! //////////////////////////////////KHG133s_Big////////////////////////////////////// ! #define IDE_COMMAND_READ_DMA_EXT 0x25 ! #define IDE_COMMAND_WRITE_DMA_EXT 0x35 ! #define IDE_COMMAND_READ_SECTORS 0x20 ! #define IDE_COMMAND_WRITE_SECTORS 0x30 ! #define IDE_COMMAND_READ_SECTORS_EXT 0x24 ! #define IDE_COMMAND_WRITE_SECTORS_EXT 0x34 /////////////////////////////////////////////////////////////////////////////////// // //DmaCommand bits definition *************** *** 225,238 **** USHORT ReleaseTimeOverlapped; // 71 USHORT ReleaseTimeServiceCommand; // 72 USHORT MajorRevision; // 73 ! USHORT MinorRevision; // 74 ! ! //////////////////////////////////KHG-133s_Big//////////////////////////////// ! USHORT Reserved6[8]; // 75-82 ! USHORT BIT48; // 83 USHORT Reserved6_1[4]; // 84-87 ////////////////////////////////////////////////////////////////////////////// ! UCHAR UDMASupport; // 88 UCHAR UDMASelected; // /* --- 225,238 ---- USHORT ReleaseTimeOverlapped; // 71 USHORT ReleaseTimeServiceCommand; // 72 USHORT MajorRevision; // 73 ! USHORT MinorRevision; // 74 ! ! //////////////////////////////////KHG-133s_Big//////////////////////////////// ! USHORT Reserved6[8]; // 75-82 ! USHORT BIT48; // 83 USHORT Reserved6_1[4]; // 84-87 ////////////////////////////////////////////////////////////////////////////// ! UCHAR UDMASupport; // 88 UCHAR UDMASelected; // /* diff -Ncr linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid133/iocontrol.h linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid133/iocontrol.h *** linux-2.4.20-20.9.ashuaria2/drivers/scsi/ultimaraid133/iocontrol.h 2003-11-27 11:18:33.000000000 +0900 --- linux-2.4.20-20.9.ashuaria3/drivers/scsi/ultimaraid133/iocontrol.h 2003-12-03 00:34:32.000000000 +0900 *************** *** 1,146 **** ! ///////////////////////// Ioctl start ! /* IoControl.h */ ! /* ! This header is defined for RAID monitor Util and ! should be shared with the App's header. ! */ ! ! // REQUESTs to ULTIMA from GUI. ! #define IOCTL_ULTIMA_PRESENT 0x80018001 // ~ ~ ~ ~ 1000 0000 0000 0001 ! #define IOCTL_GET_ULTIMA_STATUS 0x80018002 // ~ ~ ~ ~ 1000 0000 0000 0010 ! #define IOCTL_EXECUTIVE_COMMAND 0x80018004 // ~ ~ ~ ~ 1000 0000 0000 0100 ! #define IOCTL_GET_HDD_FLAGS 0x80018008 // ~ ~ ~ ~ 1000 0000 0000 1000 ! #define IOCTL_ULTIMA_RESET 0x80018010 // ~ ~ ~ ~ 1000 0000 0001 0000 ! #define IOCTL_GET_ERROR_STATUS 0x80018020 // ~ ~ ~ ~ 1000 0000 0010 0000 ! #define IOCTL_UPDATE_IDENTIFY 0x80018040 // ~ ~ ~ ~ 1000 0000 0010 0000 ~~ 2000/06/20 ! #define IOCTL_ULTIMA_REBUILD_COMPLETE 0x80018080 // ~~2000/08/02 ! #define IOCTL_ULTIMA_REBUILD_CANCEL 0x80018100 // ~~2000/08/11 ! #define IOCTL_ULTIMA_MOVE_DATA 0x80018101 // ~~2000/08/11 ! #define IOCTL_FLASH_READ 0x80018200 // ~~2000/08/11 ! #define IOCTL_FLASH_WRITE 0x80018400 // ~~2000/08/11 ! #define IOCTL_TEST_EVENT 0x80018800 ! ! ! typedef struct _SRB_IO_CONTROL { ! ULONG HeaderLength; ! UCHAR Signature[8]; ! ULONG Timeout; ! ULONG ControlCode; ! ULONG ReturnCode; ! ULONG Length; ! } SRB_IO_CONTROL, *PSRB_IO_CONTROL; ! ! typedef struct _SRB_BUFFER { ! SRB_IO_CONTROL sic; ! UCHAR ucDataBuffer[512]; // Extended DATA BUFFER ! } SRB_BUFFER, *PSRB_BUFFER; ! ! typedef struct _REBUILDSIZE { ! DWORD DiskID; ! DWORD Size; ! } REBUILDSIZE; ! ! typedef struct _HDD_STATUS { ! ! USHORT NumberOfCylinders; ! USHORT NumberOfHeads; ! USHORT SectorsPerTrack; ! USHORT VendorUnique1[3]; ! USHORT SerialNumber[10]; ! USHORT FirmwareRevision[4]; ! USHORT ModelNumber[20]; ! // USHORT UserAddressableSectors[2]; ! DWORD BlockSize; ! UCHAR UDMASupport; ! UCHAR UDMAPresentMode; ! ! } HDD_STATUS, *PHDD_STATUS; ! ! typedef struct _GUI_INTERFACE_B ! { ! V6INTERFACEB Interface; ! HDD_STATUS HddStatus[4][4]; ! UCHAR BiosDeviceNum; ! UCHAR BiosManufacNum; ! } GuiInterface, *PGuiInterface; ! ! ! typedef struct _GUI_INTERFACE_B2 ! { ! SRB_IO_CONTROL sic; ! V6INTERFACEB Interface; ! HDD_STATUS HddStatus[4][4]; ! UCHAR BiosDeviceNum; ! UCHAR BiosManufacNum; ! ! } GuiInterface2, *PGuiInterface2; ! ! typedef struct _GUI_FLAG ! { ! UCHAR IsActingHdd[4][2][2]; ! UCHAR IsHereHdd[4][2][2]; ! UCHAR RemovedHdd[4][2][2]; ! UCHAR RebuildHdd[4][2][2]; ! UCHAR SourceHdd[4][2][2]; ! ULONG DiskID[4][2][2]; ! ULONG Order[4][2][2]; ! ULONG RunRebuildTime[16]; ! ULONG Reserved; ! } GUI_FLAG,*PGUI_FLAG; ! ! /* ! UI Interface´Â À§ ±¸Á¶Ã¼·Î Àü´ÞÇÕ´Ï´Ù.(1Ãʸ¶´Ù °»½Å) ! ! UCHAR IsActingHdd[CardNumber][TargerId] : Hdd Read/Write Working status ! UCHAR IsHereHdd[CardNumber][TargerId] : Hdd Á¸Àç À¯¹« Ç÷¡±×. ! UCHAR RebuildHdd[CardNumber][TargerId] : Rebuild´çÇÏ´Â Hdd ! UCHAR SourceHdd[CardNumber][TargerId] : Source Hdd ! ULONG RunRebuildTime; : RebuildÇØ¾ßÇÒ ½ÃÁ¡¿¡ TRUE¼ÂÆÃ. ! */ ! ! ! typedef struct _GUI_FLAG2 ! { ! SRB_IO_CONTROL sic; ! UCHAR IsActingHdd[4][4]; ! UCHAR IsHereHdd[4][4]; ! UCHAR RebuildHdd[4][4]; ! UCHAR SourceHdd[4][4]; ! ULONG RunRebuildTime; ! ULONG Reserved; ! } GUI_FLAG2,*PGUI_FLAG2; ! ! typedef struct _MOVEDATA_ ! { ! DWORD DiskID; ! UCHAR SourceCard; ! UCHAR SourceTargetId; ! UCHAR TargetCard; ! UCHAR TargetTargetId; ! ULONG LbaAddress; ! ULONG Size; ! }MOVEDATA,*PMOVEDATA; ! ! ! // ! // Define SCSI maximum configuration parameters. ! // ! ! #define SCSI_MAXIMUM_LOGICAL_UNITS 8 ! #define SCSI_MAXIMUM_TARGETS_PER_BUS 32 ! #define SCSI_MAXIMUM_BUSES 8 ! #define SCSI_MINIMUM_PHYSICAL_BREAKS 16 ! #define SCSI_MAXIMUM_PHYSICAL_BREAKS 255 ! ! // ! // This constant is for backward compatibility. ! // This use to be the maximum number of targets supported. ! // ! ! #define SCSI_MAXIMUM_TARGETS 8 ! ! // begin_ntminitape ! ! #define MAXIMUM_CDB_SIZE 12 ! ! // end_ntminitape --- 1,146 ---- ! ///////////////////////// Ioctl start ! /* IoControl.h */ ! /* ! This header is defined for RAID monitor Util and ! should be shared with the App's header. ! */ ! ! // REQUESTs to ULTIMA from GUI. ! #define IOCTL_ULTIMA_PRESENT 0x80018001 // ~ ~ ~ ~ 1000 0000 0000 0001 ! #define IOCTL_GET_ULTIMA_STATUS 0x80018002 // ~ ~ ~ ~ 1000 0000 0000 0010 ! #define IOCTL_EXECUTIVE_COMMAND 0x80018004 // ~ ~ ~ ~ 1000 0000 0000 0100 ! #define IOCTL_GET_HDD_FLAGS 0x80018008 // ~ ~ ~ ~ 1000 0000 0000 1000 ! #define IOCTL_ULTIMA_RESET 0x80018010 // ~ ~ ~ ~ 1000 0000 0001 0000 ! #define IOCTL_GET_ERROR_STATUS 0x80018020 // ~ ~ ~ ~ 1000 0000 0010 0000 ! #define IOCTL_UPDATE_IDENTIFY 0x80018040 // ~ ~ ~ ~ 1000 0000 0010 0000 ~~ 2000/06/20 ! #define IOCTL_ULTIMA_REBUILD_COMPLETE 0x80018080 // ~~2000/08/02 ! #define IOCTL_ULTIMA_REBUILD_CANCEL 0x80018100 // ~~2000/08/11 ! #define IOCTL_ULTIMA_MOVE_DATA 0x80018101 // ~~2000/08/11 ! #define IOCTL_FLASH_READ 0x80018200 // ~~2000/08/11 ! #define IOCTL_FLASH_WRITE 0x80018400 // ~~2000/08/11 ! #define IOCTL_TEST_EVENT 0x80018800 ! ! ! typedef struct _SRB_IO_CONTROL { ! ULONG HeaderLength; ! UCHAR Signature[8]; ! ULONG Timeout; ! ULONG ControlCode; ! ULONG ReturnCode; ! ULONG Length; ! } SRB_IO_CONTROL, *PSRB_IO_CONTROL; ! ! typedef struct _SRB_BUFFER { ! SRB_IO_CONTROL sic; ! UCHAR ucDataBuffer[512]; // Extended DATA BUFFER ! } SRB_BUFFER, *PSRB_BUFFER; ! ! typedef struct _REBUILDSIZE { ! DWORD DiskID; ! DWORD Size; ! } REBUILDSIZE; ! ! typedef struct _HDD_STATUS { ! ! USHORT NumberOfCylinders; ! USHORT NumberOfHeads; ! USHORT SectorsPerTrack; ! USHORT VendorUnique1[3]; ! USHORT SerialNumber[10]; ! USHORT FirmwareRevision[4]; ! USHORT ModelNumber[20]; ! // USHORT UserAddressableSectors[2]; ! DWORD BlockSize; ! UCHAR UDMASupport; ! UCHAR UDMAPresentMode; ! ! } HDD_STATUS, *PHDD_STATUS; ! ! typedef struct _GUI_INTERFACE_B ! { ! V6INTERFACEB Interface; ! HDD_STATUS HddStatus[4][4]; ! UCHAR BiosDeviceNum; ! UCHAR BiosManufacNum; ! } GuiInterface, *PGuiInterface; ! ! ! typedef struct _GUI_INTERFACE_B2 ! { ! SRB_IO_CONTROL sic; ! V6INTERFACEB Interface; ! HDD_STATUS HddStatus[4][4]; ! UCHAR BiosDeviceNum; ! UCHAR BiosManufacNum; ! ! } GuiInterface2, *PGuiInterface2; ! ! typedef struct _GUI_FLAG ! { ! UCHAR IsActingHdd[4][2][2]; ! UCHAR IsHereHdd[4][2][2]; ! UCHAR RemovedHdd[4][2][2]; ! UCHAR RebuildHdd[4][2][2]; ! UCHAR SourceHdd[4][2][2]; ! ULONG DiskID[4][2][2]; ! ULONG Order[4][2][2]; ! ULONG RunRebuildTime[16]; ! ULONG Reserved; ! } GUI_FLAG,*PGUI_FLAG; ! ! /* ! UI Interface´Â À§ ±¸Á¶Ã¼·Î Àü´ÞÇÕ´Ï´Ù.(1Ãʸ¶´Ù °»½Å) ! ! UCHAR IsActingHdd[CardNumber][TargerId] : Hdd Read/Write Working status ! UCHAR IsHereHdd[CardNumber][TargerId] : Hdd Á¸Àç À¯¹« Ç÷¡±×. ! UCHAR RebuildHdd[CardNumber][TargerId] : Rebuild´çÇÏ´Â Hdd ! UCHAR SourceHdd[CardNumber][TargerId] : Source Hdd ! ULONG RunRebuildTime; : RebuildÇØ¾ßÇÒ ½ÃÁ¡¿¡ TRUE¼ÂÆÃ. ! */ ! ! ! typedef struct _GUI_FLAG2 ! { ! SRB_IO_CONTROL sic; ! UCHAR IsActingHdd[4][4]; ! UCHAR IsHereHdd[4][4]; ! UCHAR RebuildHdd[4][4]; ! UCHAR SourceHdd[4][4]; ! ULONG RunRebuildTime; ! ULONG Reserved; ! } GUI_FLAG2,*PGUI_FLAG2; ! ! typedef struct _MOVEDATA_ ! { ! DWORD DiskID; ! UCHAR SourceCard; ! UCHAR SourceTargetId; ! UCHAR TargetCard; ! UCHAR TargetTargetId; ! ULONG LbaAddress; ! ULONG Size; ! }MOVEDATA,*PMOVEDATA; ! ! ! // ! // Define SCSI maximum configuration parameters. ! // ! ! #define SCSI_MAXIMUM_LOGICAL_UNITS 8 ! #define SCSI_MAXIMUM_TARGETS_PER_BUS 32 ! #define SCSI_MAXIMUM_BUSES 8 ! #define SCSI_MINIMUM_PHYSICAL_BREAKS 16 ! #define SCSI_MAXIMUM_PHYSICAL_BREAKS 255 ! ! // ! // This constant is for backward compatibility. ! // This use to be the maximum number of targets supported. ! // ! ! #define SCSI_MAXIMUM_TARGETS 8 ! ! // begin_ntminitape ! ! #define MAXIMUM_CDB_SIZE 12 ! ! // end_ntminitape