Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] arcmsr: initial driver, version 1.20.00.13

arcmsr is a driver for the Areca Raid controller, a host based RAID
subsystem that speaks SCSI at the firmware level.

This patch is quite a clean up over the initial submission with
contributions from:

Randy Dunlap <rdunlap@xenotime.net>
Christoph Hellwig <hch@lst.de>
Matthew Wilcox <matthew@wil.cx>
Adrian Bunk <bunk@stusta.de>

Signed-off-by: Erich Chen <erich@areca.com.tw>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>

authored by

Erich Chen and committed by
James Bottomley
1c57e86d 0c269e6d

+3028
+56
Documentation/scsi/ChangeLog.arcmsr
··· 1 + ************************************************************************** 2 + ** History 3 + ** 4 + ** REV# DATE NAME DESCRIPTION 5 + ** 1.00.00.00 3/31/2004 Erich Chen First release 6 + ** 1.10.00.04 7/28/2004 Erich Chen modify for ioctl 7 + ** 1.10.00.06 8/28/2004 Erich Chen modify for 2.6.x 8 + ** 1.10.00.08 9/28/2004 Erich Chen modify for x86_64 9 + ** 1.10.00.10 10/10/2004 Erich Chen bug fix for SMP & ioctl 10 + ** 1.20.00.00 11/29/2004 Erich Chen bug fix with arcmsr_bus_reset when PHY error 11 + ** 1.20.00.02 12/09/2004 Erich Chen bug fix with over 2T bytes RAID Volume 12 + ** 1.20.00.04 1/09/2005 Erich Chen fits for Debian linux kernel version 2.2.xx 13 + ** 1.20.00.05 2/20/2005 Erich Chen cleanly as look like a Linux driver at 2.6.x 14 + ** thanks for peoples kindness comment 15 + ** Kornel Wieliczek 16 + ** Christoph Hellwig 17 + ** Adrian Bunk 18 + ** Andrew Morton 19 + ** Christoph Hellwig 20 + ** James Bottomley 21 + ** Arjan van de Ven 22 + ** 1.20.00.06 3/12/2005 Erich Chen fix with arcmsr_pci_unmap_dma "unsigned long" cast, 23 + ** modify PCCB POOL allocated by "dma_alloc_coherent" 24 + ** (Kornel Wieliczek's comment) 25 + ** 1.20.00.07 3/23/2005 Erich Chen bug fix with arcmsr_scsi_host_template_init 26 + ** occur segmentation fault, 27 + ** if RAID adapter does not on PCI slot 28 + ** and modprobe/rmmod this driver twice. 29 + ** bug fix enormous stack usage (Adrian Bunk's comment) 30 + ** 1.20.00.08 6/23/2005 Erich Chen bug fix with abort command, 31 + ** in case of heavy loading when sata cable 32 + ** working on low quality connection 33 + ** 1.20.00.09 9/12/2005 Erich Chen bug fix with abort command handling, firmware version check 34 + ** and firmware update notify for hardware bug fix 35 + ** 1.20.00.10 9/23/2005 Erich Chen enhance sysfs function for change driver's max tag Q number. 36 + ** add DMA_64BIT_MASK for backward compatible with all 2.6.x 37 + ** add some useful message for abort command 38 + ** add ioctl code 'ARCMSR_IOCTL_FLUSH_ADAPTER_CACHE' 39 + ** customer can send this command for sync raid volume data 40 + ** 1.20.00.11 9/29/2005 Erich Chen by comment of Arjan van de Ven fix incorrect msleep redefine 41 + ** cast off sizeof(dma_addr_t) condition for 64bit pci_set_dma_mask 42 + ** 1.20.00.12 9/30/2005 Erich Chen bug fix with 64bit platform's ccbs using if over 4G system memory 43 + ** change 64bit pci_set_consistent_dma_mask into 32bit 44 + ** increcct adapter count if adapter initialize fail. 45 + ** miss edit at arcmsr_build_ccb.... 46 + ** psge += sizeof(struct _SG64ENTRY *) => 47 + ** psge += sizeof(struct _SG64ENTRY) 48 + ** 64 bits sg entry would be incorrectly calculated 49 + ** thanks Kornel Wieliczek give me kindly notify 50 + ** and detail description 51 + ** 1.20.00.13 11/15/2005 Erich Chen scheduling pending ccb with FIFO 52 + ** change the architecture of arcmsr command queue list 53 + ** for linux standard list 54 + ** enable usage of pci message signal interrupt 55 + ** follow Randy.Danlup kindness suggestion cleanup this code 56 + **************************************************************************
+574
Documentation/scsi/arcmsr_spec.txt
··· 1 + ******************************************************************************* 2 + ** ARECA FIRMWARE SPEC 3 + ******************************************************************************* 4 + ** Usage of IOP331 adapter 5 + ** (All In/Out is in IOP331's view) 6 + ** 1. Message 0 --> InitThread message and retrun code 7 + ** 2. Doorbell is used for RS-232 emulation 8 + ** inDoorBell : bit0 -- data in ready 9 + ** (DRIVER DATA WRITE OK) 10 + ** bit1 -- data out has been read 11 + ** (DRIVER DATA READ OK) 12 + ** outDooeBell: bit0 -- data out ready 13 + ** (IOP331 DATA WRITE OK) 14 + ** bit1 -- data in has been read 15 + ** (IOP331 DATA READ OK) 16 + ** 3. Index Memory Usage 17 + ** offset 0xf00 : for RS232 out (request buffer) 18 + ** offset 0xe00 : for RS232 in (scratch buffer) 19 + ** offset 0xa00 : for inbound message code message_rwbuffer 20 + ** (driver send to IOP331) 21 + ** offset 0xa00 : for outbound message code message_rwbuffer 22 + ** (IOP331 send to driver) 23 + ** 4. RS-232 emulation 24 + ** Currently 128 byte buffer is used 25 + ** 1st uint32_t : Data length (1--124) 26 + ** Byte 4--127 : Max 124 bytes of data 27 + ** 5. PostQ 28 + ** All SCSI Command must be sent through postQ: 29 + ** (inbound queue port) Request frame must be 32 bytes aligned 30 + ** #bit27--bit31 => flag for post ccb 31 + ** #bit0--bit26 => real address (bit27--bit31) of post arcmsr_cdb 32 + ** bit31 : 33 + ** 0 : 256 bytes frame 34 + ** 1 : 512 bytes frame 35 + ** bit30 : 36 + ** 0 : normal request 37 + ** 1 : BIOS request 38 + ** bit29 : reserved 39 + ** bit28 : reserved 40 + ** bit27 : reserved 41 + ** --------------------------------------------------------------------------- 42 + ** (outbount queue port) Request reply 43 + ** #bit27--bit31 44 + ** => flag for reply 45 + ** #bit0--bit26 46 + ** => real address (bit27--bit31) of reply arcmsr_cdb 47 + ** bit31 : must be 0 (for this type of reply) 48 + ** bit30 : reserved for BIOS handshake 49 + ** bit29 : reserved 50 + ** bit28 : 51 + ** 0 : no error, ignore AdapStatus/DevStatus/SenseData 52 + ** 1 : Error, error code in AdapStatus/DevStatus/SenseData 53 + ** bit27 : reserved 54 + ** 6. BIOS request 55 + ** All BIOS request is the same with request from PostQ 56 + ** Except : 57 + ** Request frame is sent from configuration space 58 + ** offset: 0x78 : Request Frame (bit30 == 1) 59 + ** offset: 0x18 : writeonly to generate 60 + ** IRQ to IOP331 61 + ** Completion of request: 62 + ** (bit30 == 0, bit28==err flag) 63 + ** 7. Definition of SGL entry (structure) 64 + ** 8. Message1 Out - Diag Status Code (????) 65 + ** 9. Message0 message code : 66 + ** 0x00 : NOP 67 + ** 0x01 : Get Config 68 + ** ->offset 0xa00 :for outbound message code message_rwbuffer 69 + ** (IOP331 send to driver) 70 + ** Signature 0x87974060(4) 71 + ** Request len 0x00000200(4) 72 + ** numbers of queue 0x00000100(4) 73 + ** SDRAM Size 0x00000100(4)-->256 MB 74 + ** IDE Channels 0x00000008(4) 75 + ** vendor 40 bytes char 76 + ** model 8 bytes char 77 + ** FirmVer 16 bytes char 78 + ** Device Map 16 bytes char 79 + ** FirmwareVersion DWORD <== Added for checking of 80 + ** new firmware capability 81 + ** 0x02 : Set Config 82 + ** ->offset 0xa00 :for inbound message code message_rwbuffer 83 + ** (driver send to IOP331) 84 + ** Signature 0x87974063(4) 85 + ** UPPER32 of Request Frame (4)-->Driver Only 86 + ** 0x03 : Reset (Abort all queued Command) 87 + ** 0x04 : Stop Background Activity 88 + ** 0x05 : Flush Cache 89 + ** 0x06 : Start Background Activity 90 + ** (re-start if background is halted) 91 + ** 0x07 : Check If Host Command Pending 92 + ** (Novell May Need This Function) 93 + ** 0x08 : Set controller time 94 + ** ->offset 0xa00 : for inbound message code message_rwbuffer 95 + ** (driver to IOP331) 96 + ** byte 0 : 0xaa <-- signature 97 + ** byte 1 : 0x55 <-- signature 98 + ** byte 2 : year (04) 99 + ** byte 3 : month (1..12) 100 + ** byte 4 : date (1..31) 101 + ** byte 5 : hour (0..23) 102 + ** byte 6 : minute (0..59) 103 + ** byte 7 : second (0..59) 104 + ******************************************************************************* 105 + ******************************************************************************* 106 + ** RS-232 Interface for Areca Raid Controller 107 + ** The low level command interface is exclusive with VT100 terminal 108 + ** -------------------------------------------------------------------- 109 + ** 1. Sequence of command execution 110 + ** -------------------------------------------------------------------- 111 + ** (A) Header : 3 bytes sequence (0x5E, 0x01, 0x61) 112 + ** (B) Command block : variable length of data including length, 113 + ** command code, data and checksum byte 114 + ** (C) Return data : variable length of data 115 + ** -------------------------------------------------------------------- 116 + ** 2. Command block 117 + ** -------------------------------------------------------------------- 118 + ** (A) 1st byte : command block length (low byte) 119 + ** (B) 2nd byte : command block length (high byte) 120 + ** note ..command block length shouldn't > 2040 bytes, 121 + ** length excludes these two bytes 122 + ** (C) 3rd byte : command code 123 + ** (D) 4th and following bytes : variable length data bytes 124 + ** depends on command code 125 + ** (E) last byte : checksum byte (sum of 1st byte until last data byte) 126 + ** -------------------------------------------------------------------- 127 + ** 3. Command code and associated data 128 + ** -------------------------------------------------------------------- 129 + ** The following are command code defined in raid controller Command 130 + ** code 0x10--0x1? are used for system level management, 131 + ** no password checking is needed and should be implemented in separate 132 + ** well controlled utility and not for end user access. 133 + ** Command code 0x20--0x?? always check the password, 134 + ** password must be entered to enable these command. 135 + ** enum 136 + ** { 137 + ** GUI_SET_SERIAL=0x10, 138 + ** GUI_SET_VENDOR, 139 + ** GUI_SET_MODEL, 140 + ** GUI_IDENTIFY, 141 + ** GUI_CHECK_PASSWORD, 142 + ** GUI_LOGOUT, 143 + ** GUI_HTTP, 144 + ** GUI_SET_ETHERNET_ADDR, 145 + ** GUI_SET_LOGO, 146 + ** GUI_POLL_EVENT, 147 + ** GUI_GET_EVENT, 148 + ** GUI_GET_HW_MONITOR, 149 + ** // GUI_QUICK_CREATE=0x20, (function removed) 150 + ** GUI_GET_INFO_R=0x20, 151 + ** GUI_GET_INFO_V, 152 + ** GUI_GET_INFO_P, 153 + ** GUI_GET_INFO_S, 154 + ** GUI_CLEAR_EVENT, 155 + ** GUI_MUTE_BEEPER=0x30, 156 + ** GUI_BEEPER_SETTING, 157 + ** GUI_SET_PASSWORD, 158 + ** GUI_HOST_INTERFACE_MODE, 159 + ** GUI_REBUILD_PRIORITY, 160 + ** GUI_MAX_ATA_MODE, 161 + ** GUI_RESET_CONTROLLER, 162 + ** GUI_COM_PORT_SETTING, 163 + ** GUI_NO_OPERATION, 164 + ** GUI_DHCP_IP, 165 + ** GUI_CREATE_PASS_THROUGH=0x40, 166 + ** GUI_MODIFY_PASS_THROUGH, 167 + ** GUI_DELETE_PASS_THROUGH, 168 + ** GUI_IDENTIFY_DEVICE, 169 + ** GUI_CREATE_RAIDSET=0x50, 170 + ** GUI_DELETE_RAIDSET, 171 + ** GUI_EXPAND_RAIDSET, 172 + ** GUI_ACTIVATE_RAIDSET, 173 + ** GUI_CREATE_HOT_SPARE, 174 + ** GUI_DELETE_HOT_SPARE, 175 + ** GUI_CREATE_VOLUME=0x60, 176 + ** GUI_MODIFY_VOLUME, 177 + ** GUI_DELETE_VOLUME, 178 + ** GUI_START_CHECK_VOLUME, 179 + ** GUI_STOP_CHECK_VOLUME 180 + ** }; 181 + ** Command description : 182 + ** GUI_SET_SERIAL : Set the controller serial# 183 + ** byte 0,1 : length 184 + ** byte 2 : command code 0x10 185 + ** byte 3 : password length (should be 0x0f) 186 + ** byte 4-0x13 : should be "ArEcATecHnoLogY" 187 + ** byte 0x14--0x23 : Serial number string (must be 16 bytes) 188 + ** GUI_SET_VENDOR : Set vendor string for the controller 189 + ** byte 0,1 : length 190 + ** byte 2 : command code 0x11 191 + ** byte 3 : password length (should be 0x08) 192 + ** byte 4-0x13 : should be "ArEcAvAr" 193 + ** byte 0x14--0x3B : vendor string (must be 40 bytes) 194 + ** GUI_SET_MODEL : Set the model name of the controller 195 + ** byte 0,1 : length 196 + ** byte 2 : command code 0x12 197 + ** byte 3 : password length (should be 0x08) 198 + ** byte 4-0x13 : should be "ArEcAvAr" 199 + ** byte 0x14--0x1B : model string (must be 8 bytes) 200 + ** GUI_IDENTIFY : Identify device 201 + ** byte 0,1 : length 202 + ** byte 2 : command code 0x13 203 + ** return "Areca RAID Subsystem " 204 + ** GUI_CHECK_PASSWORD : Verify password 205 + ** byte 0,1 : length 206 + ** byte 2 : command code 0x14 207 + ** byte 3 : password length 208 + ** byte 4-0x?? : user password to be checked 209 + ** GUI_LOGOUT : Logout GUI (force password checking on next command) 210 + ** byte 0,1 : length 211 + ** byte 2 : command code 0x15 212 + ** GUI_HTTP : HTTP interface (reserved for Http proxy service)(0x16) 213 + ** 214 + ** GUI_SET_ETHERNET_ADDR : Set the ethernet MAC address 215 + ** byte 0,1 : length 216 + ** byte 2 : command code 0x17 217 + ** byte 3 : password length (should be 0x08) 218 + ** byte 4-0x13 : should be "ArEcAvAr" 219 + ** byte 0x14--0x19 : Ethernet MAC address (must be 6 bytes) 220 + ** GUI_SET_LOGO : Set logo in HTTP 221 + ** byte 0,1 : length 222 + ** byte 2 : command code 0x18 223 + ** byte 3 : Page# (0/1/2/3) (0xff --> clear OEM logo) 224 + ** byte 4/5/6/7 : 0x55/0xaa/0xa5/0x5a 225 + ** byte 8 : TITLE.JPG data (each page must be 2000 bytes) 226 + ** note page0 1st 2 byte must be 227 + ** actual length of the JPG file 228 + ** GUI_POLL_EVENT : Poll If Event Log Changed 229 + ** byte 0,1 : length 230 + ** byte 2 : command code 0x19 231 + ** GUI_GET_EVENT : Read Event 232 + ** byte 0,1 : length 233 + ** byte 2 : command code 0x1a 234 + ** byte 3 : Event Page (0:1st page/1/2/3:last page) 235 + ** GUI_GET_HW_MONITOR : Get HW monitor data 236 + ** byte 0,1 : length 237 + ** byte 2 : command code 0x1b 238 + ** byte 3 : # of FANs(example 2) 239 + ** byte 4 : # of Voltage sensor(example 3) 240 + ** byte 5 : # of temperature sensor(example 2) 241 + ** byte 6 : # of power 242 + ** byte 7/8 : Fan#0 (RPM) 243 + ** byte 9/10 : Fan#1 244 + ** byte 11/12 : Voltage#0 original value in *1000 245 + ** byte 13/14 : Voltage#0 value 246 + ** byte 15/16 : Voltage#1 org 247 + ** byte 17/18 : Voltage#1 248 + ** byte 19/20 : Voltage#2 org 249 + ** byte 21/22 : Voltage#2 250 + ** byte 23 : Temp#0 251 + ** byte 24 : Temp#1 252 + ** byte 25 : Power indicator (bit0 : power#0, 253 + ** bit1 : power#1) 254 + ** byte 26 : UPS indicator 255 + ** GUI_QUICK_CREATE : Quick create raid/volume set 256 + ** byte 0,1 : length 257 + ** byte 2 : command code 0x20 258 + ** byte 3/4/5/6 : raw capacity 259 + ** byte 7 : raid level 260 + ** byte 8 : stripe size 261 + ** byte 9 : spare 262 + ** byte 10/11/12/13: device mask (the devices to create raid/volume) 263 + ** This function is removed, application like 264 + ** to implement quick create function 265 + ** need to use GUI_CREATE_RAIDSET and GUI_CREATE_VOLUMESET function. 266 + ** GUI_GET_INFO_R : Get Raid Set Information 267 + ** byte 0,1 : length 268 + ** byte 2 : command code 0x20 269 + ** byte 3 : raidset# 270 + ** typedef struct sGUI_RAIDSET 271 + ** { 272 + ** BYTE grsRaidSetName[16]; 273 + ** DWORD grsCapacity; 274 + ** DWORD grsCapacityX; 275 + ** DWORD grsFailMask; 276 + ** BYTE grsDevArray[32]; 277 + ** BYTE grsMemberDevices; 278 + ** BYTE grsNewMemberDevices; 279 + ** BYTE grsRaidState; 280 + ** BYTE grsVolumes; 281 + ** BYTE grsVolumeList[16]; 282 + ** BYTE grsRes1; 283 + ** BYTE grsRes2; 284 + ** BYTE grsRes3; 285 + ** BYTE grsFreeSegments; 286 + ** DWORD grsRawStripes[8]; 287 + ** DWORD grsRes4; 288 + ** DWORD grsRes5; // Total to 128 bytes 289 + ** DWORD grsRes6; // Total to 128 bytes 290 + ** } sGUI_RAIDSET, *pGUI_RAIDSET; 291 + ** GUI_GET_INFO_V : Get Volume Set Information 292 + ** byte 0,1 : length 293 + ** byte 2 : command code 0x21 294 + ** byte 3 : volumeset# 295 + ** typedef struct sGUI_VOLUMESET 296 + ** { 297 + ** BYTE gvsVolumeName[16]; // 16 298 + ** DWORD gvsCapacity; 299 + ** DWORD gvsCapacityX; 300 + ** DWORD gvsFailMask; 301 + ** DWORD gvsStripeSize; 302 + ** DWORD gvsNewFailMask; 303 + ** DWORD gvsNewStripeSize; 304 + ** DWORD gvsVolumeStatus; 305 + ** DWORD gvsProgress; // 32 306 + ** sSCSI_ATTR gvsScsi; 307 + ** BYTE gvsMemberDisks; 308 + ** BYTE gvsRaidLevel; // 8 309 + ** BYTE gvsNewMemberDisks; 310 + ** BYTE gvsNewRaidLevel; 311 + ** BYTE gvsRaidSetNumber; 312 + ** BYTE gvsRes0; // 4 313 + ** BYTE gvsRes1[4]; // 64 bytes 314 + ** } sGUI_VOLUMESET, *pGUI_VOLUMESET; 315 + ** GUI_GET_INFO_P : Get Physical Drive Information 316 + ** byte 0,1 : length 317 + ** byte 2 : command code 0x22 318 + ** byte 3 : drive # (from 0 to max-channels - 1) 319 + ** typedef struct sGUI_PHY_DRV 320 + ** { 321 + ** BYTE gpdModelName[40]; 322 + ** BYTE gpdSerialNumber[20]; 323 + ** BYTE gpdFirmRev[8]; 324 + ** DWORD gpdCapacity; 325 + ** DWORD gpdCapacityX; // Reserved for expansion 326 + ** BYTE gpdDeviceState; 327 + ** BYTE gpdPioMode; 328 + ** BYTE gpdCurrentUdmaMode; 329 + ** BYTE gpdUdmaMode; 330 + ** BYTE gpdDriveSelect; 331 + ** BYTE gpdRaidNumber; // 0xff if not belongs to a raid set 332 + ** sSCSI_ATTR gpdScsi; 333 + ** BYTE gpdReserved[40]; // Total to 128 bytes 334 + ** } sGUI_PHY_DRV, *pGUI_PHY_DRV; 335 + ** GUI_GET_INFO_S : Get System Information 336 + ** byte 0,1 : length 337 + ** byte 2 : command code 0x23 338 + ** typedef struct sCOM_ATTR 339 + ** { 340 + ** BYTE comBaudRate; 341 + ** BYTE comDataBits; 342 + ** BYTE comStopBits; 343 + ** BYTE comParity; 344 + ** BYTE comFlowControl; 345 + ** } sCOM_ATTR, *pCOM_ATTR; 346 + ** typedef struct sSYSTEM_INFO 347 + ** { 348 + ** BYTE gsiVendorName[40]; 349 + ** BYTE gsiSerialNumber[16]; 350 + ** BYTE gsiFirmVersion[16]; 351 + ** BYTE gsiBootVersion[16]; 352 + ** BYTE gsiMbVersion[16]; 353 + ** BYTE gsiModelName[8]; 354 + ** BYTE gsiLocalIp[4]; 355 + ** BYTE gsiCurrentIp[4]; 356 + ** DWORD gsiTimeTick; 357 + ** DWORD gsiCpuSpeed; 358 + ** DWORD gsiICache; 359 + ** DWORD gsiDCache; 360 + ** DWORD gsiScache; 361 + ** DWORD gsiMemorySize; 362 + ** DWORD gsiMemorySpeed; 363 + ** DWORD gsiEvents; 364 + ** BYTE gsiMacAddress[6]; 365 + ** BYTE gsiDhcp; 366 + ** BYTE gsiBeeper; 367 + ** BYTE gsiChannelUsage; 368 + ** BYTE gsiMaxAtaMode; 369 + ** BYTE gsiSdramEcc; // 1:if ECC enabled 370 + ** BYTE gsiRebuildPriority; 371 + ** sCOM_ATTR gsiComA; // 5 bytes 372 + ** sCOM_ATTR gsiComB; // 5 bytes 373 + ** BYTE gsiIdeChannels; 374 + ** BYTE gsiScsiHostChannels; 375 + ** BYTE gsiIdeHostChannels; 376 + ** BYTE gsiMaxVolumeSet; 377 + ** BYTE gsiMaxRaidSet; 378 + ** BYTE gsiEtherPort; // 1:if ether net port supported 379 + ** BYTE gsiRaid6Engine; // 1:Raid6 engine supported 380 + ** BYTE gsiRes[75]; 381 + ** } sSYSTEM_INFO, *pSYSTEM_INFO; 382 + ** GUI_CLEAR_EVENT : Clear System Event 383 + ** byte 0,1 : length 384 + ** byte 2 : command code 0x24 385 + ** GUI_MUTE_BEEPER : Mute current beeper 386 + ** byte 0,1 : length 387 + ** byte 2 : command code 0x30 388 + ** GUI_BEEPER_SETTING : Disable beeper 389 + ** byte 0,1 : length 390 + ** byte 2 : command code 0x31 391 + ** byte 3 : 0->disable, 1->enable 392 + ** GUI_SET_PASSWORD : Change password 393 + ** byte 0,1 : length 394 + ** byte 2 : command code 0x32 395 + ** byte 3 : pass word length ( must <= 15 ) 396 + ** byte 4 : password (must be alpha-numerical) 397 + ** GUI_HOST_INTERFACE_MODE : Set host interface mode 398 + ** byte 0,1 : length 399 + ** byte 2 : command code 0x33 400 + ** byte 3 : 0->Independent, 1->cluster 401 + ** GUI_REBUILD_PRIORITY : Set rebuild priority 402 + ** byte 0,1 : length 403 + ** byte 2 : command code 0x34 404 + ** byte 3 : 0/1/2/3 (low->high) 405 + ** GUI_MAX_ATA_MODE : Set maximum ATA mode to be used 406 + ** byte 0,1 : length 407 + ** byte 2 : command code 0x35 408 + ** byte 3 : 0/1/2/3 (133/100/66/33) 409 + ** GUI_RESET_CONTROLLER : Reset Controller 410 + ** byte 0,1 : length 411 + ** byte 2 : command code 0x36 412 + ** *Response with VT100 screen (discard it) 413 + ** GUI_COM_PORT_SETTING : COM port setting 414 + ** byte 0,1 : length 415 + ** byte 2 : command code 0x37 416 + ** byte 3 : 0->COMA (term port), 417 + ** 1->COMB (debug port) 418 + ** byte 4 : 0/1/2/3/4/5/6/7 419 + ** (1200/2400/4800/9600/19200/38400/57600/115200) 420 + ** byte 5 : data bit 421 + ** (0:7 bit, 1:8 bit : must be 8 bit) 422 + ** byte 6 : stop bit (0:1, 1:2 stop bits) 423 + ** byte 7 : parity (0:none, 1:off, 2:even) 424 + ** byte 8 : flow control 425 + ** (0:none, 1:xon/xoff, 2:hardware => must use none) 426 + ** GUI_NO_OPERATION : No operation 427 + ** byte 0,1 : length 428 + ** byte 2 : command code 0x38 429 + ** GUI_DHCP_IP : Set DHCP option and local IP address 430 + ** byte 0,1 : length 431 + ** byte 2 : command code 0x39 432 + ** byte 3 : 0:dhcp disabled, 1:dhcp enabled 433 + ** byte 4/5/6/7 : IP address 434 + ** GUI_CREATE_PASS_THROUGH : Create pass through disk 435 + ** byte 0,1 : length 436 + ** byte 2 : command code 0x40 437 + ** byte 3 : device # 438 + ** byte 4 : scsi channel (0/1) 439 + ** byte 5 : scsi id (0-->15) 440 + ** byte 6 : scsi lun (0-->7) 441 + ** byte 7 : tagged queue (1 : enabled) 442 + ** byte 8 : cache mode (1 : enabled) 443 + ** byte 9 : max speed (0/1/2/3/4, 444 + ** async/20/40/80/160 for scsi) 445 + ** (0/1/2/3/4, 33/66/100/133/150 for ide ) 446 + ** GUI_MODIFY_PASS_THROUGH : Modify pass through disk 447 + ** byte 0,1 : length 448 + ** byte 2 : command code 0x41 449 + ** byte 3 : device # 450 + ** byte 4 : scsi channel (0/1) 451 + ** byte 5 : scsi id (0-->15) 452 + ** byte 6 : scsi lun (0-->7) 453 + ** byte 7 : tagged queue (1 : enabled) 454 + ** byte 8 : cache mode (1 : enabled) 455 + ** byte 9 : max speed (0/1/2/3/4, 456 + ** async/20/40/80/160 for scsi) 457 + ** (0/1/2/3/4, 33/66/100/133/150 for ide ) 458 + ** GUI_DELETE_PASS_THROUGH : Delete pass through disk 459 + ** byte 0,1 : length 460 + ** byte 2 : command code 0x42 461 + ** byte 3 : device# to be deleted 462 + ** GUI_IDENTIFY_DEVICE : Identify Device 463 + ** byte 0,1 : length 464 + ** byte 2 : command code 0x43 465 + ** byte 3 : Flash Method 466 + ** (0:flash selected, 1:flash not selected) 467 + ** byte 4/5/6/7 : IDE device mask to be flashed 468 + ** note .... no response data available 469 + ** GUI_CREATE_RAIDSET : Create Raid Set 470 + ** byte 0,1 : length 471 + ** byte 2 : command code 0x50 472 + ** byte 3/4/5/6 : device mask 473 + ** byte 7-22 : raidset name (if byte 7 == 0:use default) 474 + ** GUI_DELETE_RAIDSET : Delete Raid Set 475 + ** byte 0,1 : length 476 + ** byte 2 : command code 0x51 477 + ** byte 3 : raidset# 478 + ** GUI_EXPAND_RAIDSET : Expand Raid Set 479 + ** byte 0,1 : length 480 + ** byte 2 : command code 0x52 481 + ** byte 3 : raidset# 482 + ** byte 4/5/6/7 : device mask for expansion 483 + ** byte 8/9/10 : (8:0 no change, 1 change, 0xff:terminate, 484 + ** 9:new raid level, 485 + ** 10:new stripe size 486 + ** 0/1/2/3/4/5->4/8/16/32/64/128K ) 487 + ** byte 11/12/13 : repeat for each volume in the raidset 488 + ** GUI_ACTIVATE_RAIDSET : Activate incomplete raid set 489 + ** byte 0,1 : length 490 + ** byte 2 : command code 0x53 491 + ** byte 3 : raidset# 492 + ** GUI_CREATE_HOT_SPARE : Create hot spare disk 493 + ** byte 0,1 : length 494 + ** byte 2 : command code 0x54 495 + ** byte 3/4/5/6 : device mask for hot spare creation 496 + ** GUI_DELETE_HOT_SPARE : Delete hot spare disk 497 + ** byte 0,1 : length 498 + ** byte 2 : command code 0x55 499 + ** byte 3/4/5/6 : device mask for hot spare deletion 500 + ** GUI_CREATE_VOLUME : Create volume set 501 + ** byte 0,1 : length 502 + ** byte 2 : command code 0x60 503 + ** byte 3 : raidset# 504 + ** byte 4-19 : volume set name 505 + ** (if byte4 == 0, use default) 506 + ** byte 20-27 : volume capacity (blocks) 507 + ** byte 28 : raid level 508 + ** byte 29 : stripe size 509 + ** (0/1/2/3/4/5->4/8/16/32/64/128K) 510 + ** byte 30 : channel 511 + ** byte 31 : ID 512 + ** byte 32 : LUN 513 + ** byte 33 : 1 enable tag 514 + ** byte 34 : 1 enable cache 515 + ** byte 35 : speed 516 + ** (0/1/2/3/4->async/20/40/80/160 for scsi) 517 + ** (0/1/2/3/4->33/66/100/133/150 for IDE ) 518 + ** byte 36 : 1 to select quick init 519 + ** 520 + ** GUI_MODIFY_VOLUME : Modify volume Set 521 + ** byte 0,1 : length 522 + ** byte 2 : command code 0x61 523 + ** byte 3 : volumeset# 524 + ** byte 4-19 : new volume set name 525 + ** (if byte4 == 0, not change) 526 + ** byte 20-27 : new volume capacity (reserved) 527 + ** byte 28 : new raid level 528 + ** byte 29 : new stripe size 529 + ** (0/1/2/3/4/5->4/8/16/32/64/128K) 530 + ** byte 30 : new channel 531 + ** byte 31 : new ID 532 + ** byte 32 : new LUN 533 + ** byte 33 : 1 enable tag 534 + ** byte 34 : 1 enable cache 535 + ** byte 35 : speed 536 + ** (0/1/2/3/4->async/20/40/80/160 for scsi) 537 + ** (0/1/2/3/4->33/66/100/133/150 for IDE ) 538 + ** GUI_DELETE_VOLUME : Delete volume set 539 + ** byte 0,1 : length 540 + ** byte 2 : command code 0x62 541 + ** byte 3 : volumeset# 542 + ** GUI_START_CHECK_VOLUME : Start volume consistency check 543 + ** byte 0,1 : length 544 + ** byte 2 : command code 0x63 545 + ** byte 3 : volumeset# 546 + ** GUI_STOP_CHECK_VOLUME : Stop volume consistency check 547 + ** byte 0,1 : length 548 + ** byte 2 : command code 0x64 549 + ** --------------------------------------------------------------------- 550 + ** 4. Returned data 551 + ** --------------------------------------------------------------------- 552 + ** (A) Header : 3 bytes sequence (0x5E, 0x01, 0x61) 553 + ** (B) Length : 2 bytes 554 + ** (low byte 1st, excludes length and checksum byte) 555 + ** (C) status or data : 556 + ** <1> If length == 1 ==> 1 byte status code 557 + ** #define GUI_OK 0x41 558 + ** #define GUI_RAIDSET_NOT_NORMAL 0x42 559 + ** #define GUI_VOLUMESET_NOT_NORMAL 0x43 560 + ** #define GUI_NO_RAIDSET 0x44 561 + ** #define GUI_NO_VOLUMESET 0x45 562 + ** #define GUI_NO_PHYSICAL_DRIVE 0x46 563 + ** #define GUI_PARAMETER_ERROR 0x47 564 + ** #define GUI_UNSUPPORTED_COMMAND 0x48 565 + ** #define GUI_DISK_CONFIG_CHANGED 0x49 566 + ** #define GUI_INVALID_PASSWORD 0x4a 567 + ** #define GUI_NO_DISK_SPACE 0x4b 568 + ** #define GUI_CHECKSUM_ERROR 0x4c 569 + ** #define GUI_PASSWORD_REQUIRED 0x4d 570 + ** <2> If length > 1 ==> 571 + ** data block returned from controller 572 + ** and the contents depends on the command code 573 + ** (E) Checksum : checksum of length and status or data byte 574 + **************************************************************************
+14
drivers/scsi/Kconfig
··· 469 469 To compile this driver as a module, choose M here: the 470 470 module will be called in2000. 471 471 472 + config SCSI_ARCMSR 473 + tristate "ARECA ARC11X0[PCI-X]/ARC12X0[PCI-EXPRESS] SATA-RAID support" 474 + depends on PCI && SCSI 475 + help 476 + This driver supports all of ARECA's SATA RAID controller cards. 477 + This is an ARECA-maintained driver by Erich Chen. 478 + If you have any problems, please mail to: < erich@areca.com.tw > 479 + Areca supports Linux RAID config tools. 480 + 481 + < http://www.areca.com.tw > 482 + 483 + To compile this driver as a module, choose M here: the 484 + module will be called arcmsr (modprobe arcmsr). 485 + 472 486 source "drivers/scsi/megaraid/Kconfig.megaraid" 473 487 474 488 config SCSI_SATA
+1
drivers/scsi/Makefile
··· 59 59 obj-$(CONFIG_SCSI_BUSLOGIC) += BusLogic.o 60 60 obj-$(CONFIG_SCSI_DPT_I2O) += dpt_i2o.o 61 61 obj-$(CONFIG_SCSI_U14_34F) += u14-34f.o 62 + obj-$(CONFIG_SCSI_ARCMSR) += arcmsr/ 62 63 obj-$(CONFIG_SCSI_ULTRASTOR) += ultrastor.o 63 64 obj-$(CONFIG_SCSI_AHA152X) += aha152x.o 64 65 obj-$(CONFIG_SCSI_AHA1542) += aha1542.o
+6
drivers/scsi/arcmsr/Makefile
··· 1 + # File: drivers/arcmsr/Makefile 2 + # Makefile for the ARECA PCI-X PCI-EXPRESS SATA RAID controllers SCSI driver. 3 + 4 + arcmsr-objs := arcmsr_attr.o arcmsr_hba.o 5 + 6 + obj-$(CONFIG_SCSI_ARCMSR) := arcmsr.o
+472
drivers/scsi/arcmsr/arcmsr.h
··· 1 + /* 2 + ******************************************************************************* 3 + ** O.S : Linux 4 + ** FILE NAME : arcmsr.h 5 + ** BY : Erich Chen 6 + ** Description: SCSI RAID Device Driver for 7 + ** ARECA RAID Host adapter 8 + ******************************************************************************* 9 + ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved. 10 + ** 11 + ** Web site: www.areca.com.tw 12 + ** E-mail: erich@areca.com.tw 13 + ** 14 + ** This program is free software; you can redistribute it and/or modify 15 + ** it under the terms of the GNU General Public License version 2 as 16 + ** published by the Free Software Foundation. 17 + ** This program is distributed in the hope that it will be useful, 18 + ** but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + ** GNU General Public License for more details. 21 + ******************************************************************************* 22 + ** Redistribution and use in source and binary forms, with or without 23 + ** modification, are permitted provided that the following conditions 24 + ** are met: 25 + ** 1. Redistributions of source code must retain the above copyright 26 + ** notice, this list of conditions and the following disclaimer. 27 + ** 2. Redistributions in binary form must reproduce the above copyright 28 + ** notice, this list of conditions and the following disclaimer in the 29 + ** documentation and/or other materials provided with the distribution. 30 + ** 3. The name of the author may not be used to endorse or promote products 31 + ** derived from this software without specific prior written permission. 32 + ** 33 + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 34 + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 35 + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36 + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 37 + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT 38 + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 39 + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY 40 + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41 + **(INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF 42 + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 + ******************************************************************************* 44 + */ 45 + #include <linux/interrupt.h> 46 + 47 + struct class_device_attribute; 48 + 49 + #define ARCMSR_MAX_OUTSTANDING_CMD 256 50 + #define ARCMSR_MAX_FREECCB_NUM 288 51 + #define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.13" 52 + #define ARCMSR_SCSI_INITIATOR_ID 255 53 + #define ARCMSR_MAX_XFER_SECTORS 512 54 + #define ARCMSR_MAX_TARGETID 17 55 + #define ARCMSR_MAX_TARGETLUN 8 56 + #define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD 57 + #define ARCMSR_MAX_QBUFFER 4096 58 + #define ARCMSR_MAX_SG_ENTRIES 38 59 + 60 + /* 61 + ******************************************************************************* 62 + ** split 64bits dma addressing 63 + ******************************************************************************* 64 + */ 65 + #define dma_addr_hi32(addr) (uint32_t) ((addr>>16)>>16) 66 + #define dma_addr_lo32(addr) (uint32_t) (addr & 0xffffffff) 67 + /* 68 + ******************************************************************************* 69 + ** MESSAGE CONTROL CODE 70 + ******************************************************************************* 71 + */ 72 + struct CMD_MESSAGE 73 + { 74 + uint32_t HeaderLength; 75 + uint8_t Signature[8]; 76 + uint32_t Timeout; 77 + uint32_t ControlCode; 78 + uint32_t ReturnCode; 79 + uint32_t Length; 80 + }; 81 + /* 82 + ******************************************************************************* 83 + ** IOP Message Transfer Data for user space 84 + ******************************************************************************* 85 + */ 86 + struct CMD_MESSAGE_FIELD 87 + { 88 + struct CMD_MESSAGE cmdmessage; 89 + uint8_t messagedatabuffer[1032]; 90 + }; 91 + /* IOP message transfer */ 92 + #define ARCMSR_MESSAGE_FAIL 0x0001 93 + /* DeviceType */ 94 + #define ARECA_SATA_RAID 0x90000000 95 + /* FunctionCode */ 96 + #define FUNCTION_READ_RQBUFFER 0x0801 97 + #define FUNCTION_WRITE_WQBUFFER 0x0802 98 + #define FUNCTION_CLEAR_RQBUFFER 0x0803 99 + #define FUNCTION_CLEAR_WQBUFFER 0x0804 100 + #define FUNCTION_CLEAR_ALLQBUFFER 0x0805 101 + #define FUNCTION_RETURN_CODE_3F 0x0806 102 + #define FUNCTION_SAY_HELLO 0x0807 103 + #define FUNCTION_SAY_GOODBYE 0x0808 104 + #define FUNCTION_FLUSH_ADAPTER_CACHE 0x0809 105 + /* ARECA IO CONTROL CODE*/ 106 + #define ARCMSR_MESSAGE_READ_RQBUFFER \ 107 + ARECA_SATA_RAID | FUNCTION_READ_RQBUFFER 108 + #define ARCMSR_MESSAGE_WRITE_WQBUFFER \ 109 + ARECA_SATA_RAID | FUNCTION_WRITE_WQBUFFER 110 + #define ARCMSR_MESSAGE_CLEAR_RQBUFFER \ 111 + ARECA_SATA_RAID | FUNCTION_CLEAR_RQBUFFER 112 + #define ARCMSR_MESSAGE_CLEAR_WQBUFFER \ 113 + ARECA_SATA_RAID | FUNCTION_CLEAR_WQBUFFER 114 + #define ARCMSR_MESSAGE_CLEAR_ALLQBUFFER \ 115 + ARECA_SATA_RAID | FUNCTION_CLEAR_ALLQBUFFER 116 + #define ARCMSR_MESSAGE_RETURN_CODE_3F \ 117 + ARECA_SATA_RAID | FUNCTION_RETURN_CODE_3F 118 + #define ARCMSR_MESSAGE_SAY_HELLO \ 119 + ARECA_SATA_RAID | FUNCTION_SAY_HELLO 120 + #define ARCMSR_MESSAGE_SAY_GOODBYE \ 121 + ARECA_SATA_RAID | FUNCTION_SAY_GOODBYE 122 + #define ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE \ 123 + ARECA_SATA_RAID | FUNCTION_FLUSH_ADAPTER_CACHE 124 + /* ARECA IOCTL ReturnCode */ 125 + #define ARCMSR_MESSAGE_RETURNCODE_OK 0x00000001 126 + #define ARCMSR_MESSAGE_RETURNCODE_ERROR 0x00000006 127 + #define ARCMSR_MESSAGE_RETURNCODE_3F 0x0000003F 128 + /* 129 + ************************************************************* 130 + ** structure for holding DMA address data 131 + ************************************************************* 132 + */ 133 + #define IS_SG64_ADDR 0x01000000 /* bit24 */ 134 + struct SG32ENTRY 135 + { 136 + uint32_t length; 137 + uint32_t address; 138 + }; 139 + struct SG64ENTRY 140 + { 141 + uint32_t length; 142 + uint32_t address; 143 + uint32_t addresshigh; 144 + }; 145 + struct SGENTRY_UNION 146 + { 147 + union 148 + { 149 + struct SG32ENTRY sg32entry; 150 + struct SG64ENTRY sg64entry; 151 + }u; 152 + }; 153 + /* 154 + ******************************************************************** 155 + ** Q Buffer of IOP Message Transfer 156 + ******************************************************************** 157 + */ 158 + struct QBUFFER 159 + { 160 + uint32_t data_len; 161 + uint8_t data[124]; 162 + }; 163 + /* 164 + ******************************************************************************* 165 + ** FIRMWARE INFO 166 + ******************************************************************************* 167 + */ 168 + struct FIRMWARE_INFO 169 + { 170 + uint32_t signature; /*0, 00-03*/ 171 + uint32_t request_len; /*1, 04-07*/ 172 + uint32_t numbers_queue; /*2, 08-11*/ 173 + uint32_t sdram_size; /*3, 12-15*/ 174 + uint32_t ide_channels; /*4, 16-19*/ 175 + char vendor[40]; /*5, 20-59*/ 176 + char model[8]; /*15, 60-67*/ 177 + char firmware_ver[16]; /*17, 68-83*/ 178 + char device_map[16]; /*21, 84-99*/ 179 + }; 180 + /* signature of set and get firmware config */ 181 + #define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 182 + #define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063 183 + /* message code of inbound message register */ 184 + #define ARCMSR_INBOUND_MESG0_NOP 0x00000000 185 + #define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001 186 + #define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002 187 + #define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003 188 + #define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004 189 + #define ARCMSR_INBOUND_MESG0_FLUSH_CACHE 0x00000005 190 + #define ARCMSR_INBOUND_MESG0_START_BGRB 0x00000006 191 + #define ARCMSR_INBOUND_MESG0_CHK331PENDING 0x00000007 192 + #define ARCMSR_INBOUND_MESG0_SYNC_TIMER 0x00000008 193 + /* doorbell interrupt generator */ 194 + #define ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK 0x00000001 195 + #define ARCMSR_INBOUND_DRIVER_DATA_READ_OK 0x00000002 196 + #define ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK 0x00000001 197 + #define ARCMSR_OUTBOUND_IOP331_DATA_READ_OK 0x00000002 198 + /* ccb areca cdb flag */ 199 + #define ARCMSR_CCBPOST_FLAG_SGL_BSIZE 0x80000000 200 + #define ARCMSR_CCBPOST_FLAG_IAM_BIOS 0x40000000 201 + #define ARCMSR_CCBREPLY_FLAG_IAM_BIOS 0x40000000 202 + #define ARCMSR_CCBREPLY_FLAG_ERROR 0x10000000 203 + /* outbound firmware ok */ 204 + #define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000 205 + /* 206 + ******************************************************************************* 207 + ** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504) 208 + ******************************************************************************* 209 + */ 210 + struct ARCMSR_CDB 211 + { 212 + uint8_t Bus; 213 + uint8_t TargetID; 214 + uint8_t LUN; 215 + uint8_t Function; 216 + 217 + uint8_t CdbLength; 218 + uint8_t sgcount; 219 + uint8_t Flags; 220 + #define ARCMSR_CDB_FLAG_SGL_BSIZE 0x01 221 + #define ARCMSR_CDB_FLAG_BIOS 0x02 222 + #define ARCMSR_CDB_FLAG_WRITE 0x04 223 + #define ARCMSR_CDB_FLAG_SIMPLEQ 0x00 224 + #define ARCMSR_CDB_FLAG_HEADQ 0x08 225 + #define ARCMSR_CDB_FLAG_ORDEREDQ 0x10 226 + uint8_t Reserved1; 227 + 228 + uint32_t Context; 229 + uint32_t DataLength; 230 + 231 + uint8_t Cdb[16]; 232 + 233 + uint8_t DeviceStatus; 234 + #define ARCMSR_DEV_CHECK_CONDITION 0x02 235 + #define ARCMSR_DEV_SELECT_TIMEOUT 0xF0 236 + #define ARCMSR_DEV_ABORTED 0xF1 237 + #define ARCMSR_DEV_INIT_FAIL 0xF2 238 + uint8_t SenseData[15]; 239 + 240 + union 241 + { 242 + struct SG32ENTRY sg32entry[ARCMSR_MAX_SG_ENTRIES]; 243 + struct SG64ENTRY sg64entry[ARCMSR_MAX_SG_ENTRIES]; 244 + } u; 245 + }; 246 + /* 247 + ******************************************************************************* 248 + ** Messaging Unit (MU) of the Intel R 80331 I/O processor (80331) 249 + ******************************************************************************* 250 + */ 251 + struct MessageUnit 252 + { 253 + uint32_t resrved0[4]; /*0000 000F*/ 254 + uint32_t inbound_msgaddr0; /*0010 0013*/ 255 + uint32_t inbound_msgaddr1; /*0014 0017*/ 256 + uint32_t outbound_msgaddr0; /*0018 001B*/ 257 + uint32_t outbound_msgaddr1; /*001C 001F*/ 258 + uint32_t inbound_doorbell; /*0020 0023*/ 259 + uint32_t inbound_intstatus; /*0024 0027*/ 260 + uint32_t inbound_intmask; /*0028 002B*/ 261 + uint32_t outbound_doorbell; /*002C 002F*/ 262 + uint32_t outbound_intstatus; /*0030 0033*/ 263 + uint32_t outbound_intmask; /*0034 0037*/ 264 + uint32_t reserved1[2]; /*0038 003F*/ 265 + uint32_t inbound_queueport; /*0040 0043*/ 266 + uint32_t outbound_queueport; /*0044 0047*/ 267 + uint32_t reserved2[2]; /*0048 004F*/ 268 + uint32_t reserved3[492]; /*0050 07FF 492*/ 269 + uint32_t reserved4[128]; /*0800 09FF 128*/ 270 + uint32_t message_rwbuffer[256]; /*0a00 0DFF 256*/ 271 + uint32_t message_wbuffer[32]; /*0E00 0E7F 32*/ 272 + uint32_t reserved5[32]; /*0E80 0EFF 32*/ 273 + uint32_t message_rbuffer[32]; /*0F00 0F7F 32*/ 274 + uint32_t reserved6[32]; /*0F80 0FFF 32*/ 275 + }; 276 + /* 277 + ******************************************************************************* 278 + ** Adapter Control Block 279 + ******************************************************************************* 280 + */ 281 + struct AdapterControlBlock 282 + { 283 + struct pci_dev * pdev; 284 + struct Scsi_Host * host; 285 + unsigned long vir2phy_offset; 286 + /* Offset is used in making arc cdb physical to virtual calculations */ 287 + uint32_t outbound_int_enable; 288 + 289 + struct MessageUnit __iomem * pmu; 290 + /* message unit ATU inbound base address0 */ 291 + 292 + uint32_t acb_flags; 293 + #define ACB_F_SCSISTOPADAPTER 0x0001 294 + #define ACB_F_MSG_STOP_BGRB 0x0002 295 + /* stop RAID background rebuild */ 296 + #define ACB_F_MSG_START_BGRB 0x0004 297 + /* stop RAID background rebuild */ 298 + #define ACB_F_IOPDATA_OVERFLOW 0x0008 299 + /* iop message data rqbuffer overflow */ 300 + #define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010 301 + /* message clear wqbuffer */ 302 + #define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020 303 + /* message clear rqbuffer */ 304 + #define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 305 + #define ACB_F_BUS_RESET 0x0080 306 + #define ACB_F_IOP_INITED 0x0100 307 + /* iop init */ 308 + 309 + struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; 310 + /* used for memory free */ 311 + struct list_head ccb_free_list; 312 + /* head of free ccb list */ 313 + atomic_t ccboutstandingcount; 314 + 315 + void * dma_coherent; 316 + /* dma_coherent used for memory free */ 317 + dma_addr_t dma_coherent_handle; 318 + /* dma_coherent_handle used for memory free */ 319 + 320 + uint8_t rqbuffer[ARCMSR_MAX_QBUFFER]; 321 + /* data collection buffer for read from 80331 */ 322 + int32_t rqbuf_firstindex; 323 + /* first of read buffer */ 324 + int32_t rqbuf_lastindex; 325 + /* last of read buffer */ 326 + uint8_t wqbuffer[ARCMSR_MAX_QBUFFER]; 327 + /* data collection buffer for write to 80331 */ 328 + int32_t wqbuf_firstindex; 329 + /* first of write buffer */ 330 + int32_t wqbuf_lastindex; 331 + /* last of write buffer */ 332 + uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; 333 + /* id0 ..... id15, lun0...lun7 */ 334 + #define ARECA_RAID_GONE 0x55 335 + #define ARECA_RAID_GOOD 0xaa 336 + uint32_t num_resets; 337 + uint32_t num_aborts; 338 + uint32_t firm_request_len; 339 + uint32_t firm_numbers_queue; 340 + uint32_t firm_sdram_size; 341 + uint32_t firm_hd_channels; 342 + char firm_model[12]; 343 + char firm_version[20]; 344 + };/* HW_DEVICE_EXTENSION */ 345 + /* 346 + ******************************************************************************* 347 + ** Command Control Block 348 + ** this CCB length must be 32 bytes boundary 349 + ******************************************************************************* 350 + */ 351 + struct CommandControlBlock 352 + { 353 + struct ARCMSR_CDB arcmsr_cdb; 354 + /* 355 + ** 0-503 (size of CDB=504): 356 + ** arcmsr messenger scsi command descriptor size 504 bytes 357 + */ 358 + uint32_t cdb_shifted_phyaddr; 359 + /* 504-507 */ 360 + uint32_t reserved1; 361 + /* 508-511 */ 362 + #if BITS_PER_LONG == 64 363 + /* ======================512+64 bytes======================== */ 364 + struct list_head list; 365 + /* 512-527 16 bytes next/prev ptrs for ccb lists */ 366 + struct scsi_cmnd * pcmd; 367 + /* 528-535 8 bytes pointer of linux scsi command */ 368 + struct AdapterControlBlock * acb; 369 + /* 536-543 8 bytes pointer of acb */ 370 + 371 + uint16_t ccb_flags; 372 + /* 544-545 */ 373 + #define CCB_FLAG_READ 0x0000 374 + #define CCB_FLAG_WRITE 0x0001 375 + #define CCB_FLAG_ERROR 0x0002 376 + #define CCB_FLAG_FLUSHCACHE 0x0004 377 + #define CCB_FLAG_MASTER_ABORTED 0x0008 378 + uint16_t startdone; 379 + /* 546-547 */ 380 + #define ARCMSR_CCB_DONE 0x0000 381 + #define ARCMSR_CCB_START 0x55AA 382 + #define ARCMSR_CCB_ABORTED 0xAA55 383 + #define ARCMSR_CCB_ILLEGAL 0xFFFF 384 + uint32_t reserved2[7]; 385 + /* 548-551 552-555 556-559 560-563 564-567 568-571 572-575 */ 386 + #else 387 + /* ======================512+32 bytes======================== */ 388 + struct list_head list; 389 + /* 512-519 8 bytes next/prev ptrs for ccb lists */ 390 + struct scsi_cmnd * pcmd; 391 + /* 520-523 4 bytes pointer of linux scsi command */ 392 + struct AdapterControlBlock * acb; 393 + /* 524-527 4 bytes pointer of acb */ 394 + 395 + uint16_t ccb_flags; 396 + /* 528-529 */ 397 + #define CCB_FLAG_READ 0x0000 398 + #define CCB_FLAG_WRITE 0x0001 399 + #define CCB_FLAG_ERROR 0x0002 400 + #define CCB_FLAG_FLUSHCACHE 0x0004 401 + #define CCB_FLAG_MASTER_ABORTED 0x0008 402 + uint16_t startdone; 403 + /* 530-531 */ 404 + #define ARCMSR_CCB_DONE 0x0000 405 + #define ARCMSR_CCB_START 0x55AA 406 + #define ARCMSR_CCB_ABORTED 0xAA55 407 + #define ARCMSR_CCB_ILLEGAL 0xFFFF 408 + uint32_t reserved2[3]; 409 + /* 532-535 536-539 540-543 */ 410 + #endif 411 + /* ========================================================== */ 412 + }; 413 + /* 414 + ******************************************************************************* 415 + ** ARECA SCSI sense data 416 + ******************************************************************************* 417 + */ 418 + struct SENSE_DATA 419 + { 420 + uint8_t ErrorCode:7; 421 + #define SCSI_SENSE_CURRENT_ERRORS 0x70 422 + #define SCSI_SENSE_DEFERRED_ERRORS 0x71 423 + uint8_t Valid:1; 424 + uint8_t SegmentNumber; 425 + uint8_t SenseKey:4; 426 + uint8_t Reserved:1; 427 + uint8_t IncorrectLength:1; 428 + uint8_t EndOfMedia:1; 429 + uint8_t FileMark:1; 430 + uint8_t Information[4]; 431 + uint8_t AdditionalSenseLength; 432 + uint8_t CommandSpecificInformation[4]; 433 + uint8_t AdditionalSenseCode; 434 + uint8_t AdditionalSenseCodeQualifier; 435 + uint8_t FieldReplaceableUnitCode; 436 + uint8_t SenseKeySpecific[3]; 437 + }; 438 + /* 439 + ******************************************************************************* 440 + ** Outbound Interrupt Status Register - OISR 441 + ******************************************************************************* 442 + */ 443 + #define ARCMSR_MU_OUTBOUND_INTERRUPT_STATUS_REG 0x30 444 + #define ARCMSR_MU_OUTBOUND_PCI_INT 0x10 445 + #define ARCMSR_MU_OUTBOUND_POSTQUEUE_INT 0x08 446 + #define ARCMSR_MU_OUTBOUND_DOORBELL_INT 0x04 447 + #define ARCMSR_MU_OUTBOUND_MESSAGE1_INT 0x02 448 + #define ARCMSR_MU_OUTBOUND_MESSAGE0_INT 0x01 449 + #define ARCMSR_MU_OUTBOUND_HANDLE_INT \ 450 + (ARCMSR_MU_OUTBOUND_MESSAGE0_INT \ 451 + |ARCMSR_MU_OUTBOUND_MESSAGE1_INT \ 452 + |ARCMSR_MU_OUTBOUND_DOORBELL_INT \ 453 + |ARCMSR_MU_OUTBOUND_POSTQUEUE_INT \ 454 + |ARCMSR_MU_OUTBOUND_PCI_INT) 455 + /* 456 + ******************************************************************************* 457 + ** Outbound Interrupt Mask Register - OIMR 458 + ******************************************************************************* 459 + */ 460 + #define ARCMSR_MU_OUTBOUND_INTERRUPT_MASK_REG 0x34 461 + #define ARCMSR_MU_OUTBOUND_PCI_INTMASKENABLE 0x10 462 + #define ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE 0x08 463 + #define ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE 0x04 464 + #define ARCMSR_MU_OUTBOUND_MESSAGE1_INTMASKENABLE 0x02 465 + #define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01 466 + #define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F 467 + 468 + extern void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb); 469 + extern struct class_device_attribute *arcmsr_host_attrs[]; 470 + extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb); 471 + void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb); 472 +
+392
drivers/scsi/arcmsr/arcmsr_attr.c
··· 1 + /* 2 + ******************************************************************************* 3 + ** O.S : Linux 4 + ** FILE NAME : arcmsr_attr.c 5 + ** BY : Erich Chen 6 + ** Description: attributes exported to sysfs and device host 7 + ******************************************************************************* 8 + ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved 9 + ** 10 + ** Web site: www.areca.com.tw 11 + ** E-mail: erich@areca.com.tw 12 + ** 13 + ** This program is free software; you can redistribute it and/or modify 14 + ** it under the terms of the GNU General Public License version 2 as 15 + ** published by the Free Software Foundation. 16 + ** This program is distributed in the hope that it will be useful, 17 + ** but WITHOUT ANY WARRANTY; without even the implied warranty of 18 + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 + ** GNU General Public License for more details. 20 + ******************************************************************************* 21 + ** Redistribution and use in source and binary forms, with or without 22 + ** modification, are permitted provided that the following conditions 23 + ** are met: 24 + ** 1. Redistributions of source code must retain the above copyright 25 + ** notice, this list of conditions and the following disclaimer. 26 + ** 2. Redistributions in binary form must reproduce the above copyright 27 + ** notice, this list of conditions and the following disclaimer in the 28 + ** documentation and/or other materials provided with the distribution. 29 + ** 3. The name of the author may not be used to endorse or promote products 30 + ** derived from this software without specific prior written permission. 31 + ** 32 + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 33 + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 34 + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35 + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 36 + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING,BUT 37 + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38 + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY 39 + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 + ** (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF 41 + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 + ******************************************************************************* 43 + ** For history of changes, see Documentation/scsi/ChangeLog.arcmsr 44 + ** Firmware Specification, see Documentation/scsi/arcmsr_spec.txt 45 + ******************************************************************************* 46 + */ 47 + #include <linux/module.h> 48 + #include <linux/kernel.h> 49 + #include <linux/init.h> 50 + #include <linux/errno.h> 51 + #include <linux/delay.h> 52 + #include <linux/pci.h> 53 + 54 + #include <scsi/scsi_cmnd.h> 55 + #include <scsi/scsi_device.h> 56 + #include <scsi/scsi_host.h> 57 + #include <scsi/scsi_transport.h> 58 + #include "arcmsr.h" 59 + 60 + struct class_device_attribute *arcmsr_host_attrs[]; 61 + 62 + static ssize_t 63 + arcmsr_sysfs_iop_message_read(struct kobject *kobj, char *buf, loff_t off, 64 + size_t count) 65 + { 66 + struct class_device *cdev = container_of(kobj,struct class_device,kobj); 67 + struct Scsi_Host *host = class_to_shost(cdev); 68 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 69 + struct MessageUnit __iomem *reg = acb->pmu; 70 + uint8_t *pQbuffer,*ptmpQbuffer; 71 + int32_t allxfer_len = 0; 72 + 73 + if (!capable(CAP_SYS_ADMIN)) 74 + return -EACCES; 75 + 76 + /* do message unit read. */ 77 + ptmpQbuffer = (uint8_t *)buf; 78 + while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) 79 + && (allxfer_len < 1031)) { 80 + pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; 81 + memcpy(ptmpQbuffer, pQbuffer, 1); 82 + acb->rqbuf_firstindex++; 83 + acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; 84 + ptmpQbuffer++; 85 + allxfer_len++; 86 + } 87 + if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 88 + struct QBUFFER __iomem * prbuffer = (struct QBUFFER __iomem *) 89 + &reg->message_rbuffer; 90 + uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; 91 + int32_t iop_len; 92 + 93 + acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; 94 + iop_len = readl(&prbuffer->data_len); 95 + while (iop_len > 0) { 96 + acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); 97 + acb->rqbuf_lastindex++; 98 + acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; 99 + iop_data++; 100 + iop_len--; 101 + } 102 + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, 103 + &reg->inbound_doorbell); 104 + } 105 + return (allxfer_len); 106 + } 107 + 108 + static ssize_t 109 + arcmsr_sysfs_iop_message_write(struct kobject *kobj, char *buf, loff_t off, 110 + size_t count) 111 + { 112 + struct class_device *cdev = container_of(kobj,struct class_device,kobj); 113 + struct Scsi_Host *host = class_to_shost(cdev); 114 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 115 + int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; 116 + uint8_t *pQbuffer, *ptmpuserbuffer; 117 + 118 + if (!capable(CAP_SYS_ADMIN)) 119 + return -EACCES; 120 + if (count > 1032) 121 + return -EINVAL; 122 + /* do message unit write. */ 123 + ptmpuserbuffer = (uint8_t *)buf; 124 + user_len = (int32_t)count; 125 + wqbuf_lastindex = acb->wqbuf_lastindex; 126 + wqbuf_firstindex = acb->wqbuf_firstindex; 127 + if (wqbuf_lastindex != wqbuf_firstindex) { 128 + arcmsr_post_Qbuffer(acb); 129 + return 0; /*need retry*/ 130 + } else { 131 + my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) 132 + &(ARCMSR_MAX_QBUFFER - 1); 133 + if (my_empty_len >= user_len) { 134 + while (user_len > 0) { 135 + pQbuffer = 136 + &acb->wqbuffer[acb->wqbuf_lastindex]; 137 + memcpy(pQbuffer, ptmpuserbuffer, 1); 138 + acb->wqbuf_lastindex++; 139 + acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; 140 + ptmpuserbuffer++; 141 + user_len--; 142 + } 143 + if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { 144 + acb->acb_flags &= 145 + ~ACB_F_MESSAGE_WQBUFFER_CLEARED; 146 + arcmsr_post_Qbuffer(acb); 147 + } 148 + return count; 149 + } else { 150 + return 0; /*need retry*/ 151 + } 152 + } 153 + } 154 + 155 + static ssize_t 156 + arcmsr_sysfs_iop_message_clear(struct kobject *kobj, char *buf, loff_t off, 157 + size_t count) 158 + { 159 + struct class_device *cdev = container_of(kobj,struct class_device,kobj); 160 + struct Scsi_Host *host = class_to_shost(cdev); 161 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 162 + struct MessageUnit __iomem *reg = acb->pmu; 163 + uint8_t *pQbuffer; 164 + 165 + if (!capable(CAP_SYS_ADMIN)) 166 + return -EACCES; 167 + 168 + if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 169 + acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; 170 + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK 171 + , &reg->inbound_doorbell); 172 + } 173 + acb->acb_flags |= 174 + (ACB_F_MESSAGE_WQBUFFER_CLEARED 175 + | ACB_F_MESSAGE_RQBUFFER_CLEARED 176 + | ACB_F_MESSAGE_WQBUFFER_READED); 177 + acb->rqbuf_firstindex = 0; 178 + acb->rqbuf_lastindex = 0; 179 + acb->wqbuf_firstindex = 0; 180 + acb->wqbuf_lastindex = 0; 181 + pQbuffer = acb->rqbuffer; 182 + memset(pQbuffer, 0, sizeof (struct QBUFFER)); 183 + pQbuffer = acb->wqbuffer; 184 + memset(pQbuffer, 0, sizeof (struct QBUFFER)); 185 + return 1; 186 + } 187 + 188 + static struct bin_attribute arcmsr_sysfs_message_read_attr = { 189 + .attr = { 190 + .name = "mu_read", 191 + .mode = S_IRUSR , 192 + .owner = THIS_MODULE, 193 + }, 194 + .size = 1032, 195 + .read = arcmsr_sysfs_iop_message_read, 196 + }; 197 + 198 + static struct bin_attribute arcmsr_sysfs_message_write_attr = { 199 + .attr = { 200 + .name = "mu_write", 201 + .mode = S_IWUSR, 202 + .owner = THIS_MODULE, 203 + }, 204 + .size = 1032, 205 + .write = arcmsr_sysfs_iop_message_write, 206 + }; 207 + 208 + static struct bin_attribute arcmsr_sysfs_message_clear_attr = { 209 + .attr = { 210 + .name = "mu_clear", 211 + .mode = S_IWUSR, 212 + .owner = THIS_MODULE, 213 + }, 214 + .size = 1, 215 + .write = arcmsr_sysfs_iop_message_clear, 216 + }; 217 + 218 + int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb) 219 + { 220 + struct Scsi_Host *host = acb->host; 221 + int error; 222 + 223 + error = sysfs_create_bin_file(&host->shost_classdev.kobj, 224 + &arcmsr_sysfs_message_read_attr); 225 + if (error) { 226 + printk(KERN_ERR "arcmsr: alloc sysfs mu_read failed\n"); 227 + goto error_bin_file_message_read; 228 + } 229 + error = sysfs_create_bin_file(&host->shost_classdev.kobj, 230 + &arcmsr_sysfs_message_write_attr); 231 + if (error) { 232 + printk(KERN_ERR "arcmsr: alloc sysfs mu_write failed\n"); 233 + goto error_bin_file_message_write; 234 + } 235 + error = sysfs_create_bin_file(&host->shost_classdev.kobj, 236 + &arcmsr_sysfs_message_clear_attr); 237 + if (error) { 238 + printk(KERN_ERR "arcmsr: alloc sysfs mu_clear failed\n"); 239 + goto error_bin_file_message_clear; 240 + } 241 + return 0; 242 + error_bin_file_message_clear: 243 + error = sysfs_remove_bin_file(&host->shost_classdev.kobj, 244 + &arcmsr_sysfs_message_write_attr); 245 + if (error) 246 + printk(KERN_ERR "arcmsr: sysfs_remove_bin_file mu_write failed\n"); 247 + error_bin_file_message_write: 248 + error = sysfs_remove_bin_file(&host->shost_classdev.kobj, 249 + &arcmsr_sysfs_message_read_attr); 250 + if (error) 251 + printk(KERN_ERR "arcmsr: sysfs_remove_bin_file mu_read failed\n"); 252 + error_bin_file_message_read: 253 + return error; 254 + } 255 + 256 + void 257 + arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) { 258 + struct Scsi_Host *host = acb->host; 259 + int error; 260 + 261 + error = sysfs_remove_bin_file(&host->shost_classdev.kobj, 262 + &arcmsr_sysfs_message_clear_attr); 263 + if (error) 264 + printk(KERN_ERR "arcmsr: free sysfs mu_clear failed\n"); 265 + error = sysfs_remove_bin_file(&host->shost_classdev.kobj, 266 + &arcmsr_sysfs_message_write_attr); 267 + if (error) 268 + printk(KERN_ERR "arcmsr: free sysfs mu_write failed\n"); 269 + error = sysfs_remove_bin_file(&host->shost_classdev.kobj, 270 + &arcmsr_sysfs_message_read_attr); 271 + if (error) 272 + printk(KERN_ERR "arcmsr: free sysfss mu_read failed\n"); 273 + } 274 + 275 + 276 + static ssize_t 277 + arcmsr_attr_host_driver_version(struct class_device *cdev, char *buf) { 278 + return snprintf(buf, PAGE_SIZE, 279 + "ARCMSR: %s\n", 280 + ARCMSR_DRIVER_VERSION); 281 + } 282 + 283 + static ssize_t 284 + arcmsr_attr_host_driver_posted_cmd(struct class_device *cdev, char *buf) { 285 + struct Scsi_Host *host = class_to_shost(cdev); 286 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 287 + return snprintf(buf, PAGE_SIZE, 288 + "Current commands posted: %4d\n", 289 + atomic_read(&acb->ccboutstandingcount)); 290 + } 291 + 292 + static ssize_t 293 + arcmsr_attr_host_driver_reset(struct class_device *cdev, char *buf) { 294 + struct Scsi_Host *host = class_to_shost(cdev); 295 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 296 + return snprintf(buf, PAGE_SIZE, 297 + "SCSI Host Resets: %4d\n", 298 + acb->num_resets); 299 + } 300 + 301 + static ssize_t 302 + arcmsr_attr_host_driver_abort(struct class_device *cdev, char *buf) { 303 + struct Scsi_Host *host = class_to_shost(cdev); 304 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 305 + return snprintf(buf, PAGE_SIZE, 306 + "SCSI Aborts/Timeouts: %4d\n", 307 + acb->num_aborts); 308 + } 309 + 310 + static ssize_t 311 + arcmsr_attr_host_fw_model(struct class_device *cdev, char *buf) { 312 + struct Scsi_Host *host = class_to_shost(cdev); 313 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 314 + return snprintf(buf, PAGE_SIZE, 315 + "Adapter Model: %s\n", 316 + acb->firm_model); 317 + } 318 + 319 + static ssize_t 320 + arcmsr_attr_host_fw_version(struct class_device *cdev, char *buf) { 321 + struct Scsi_Host *host = class_to_shost(cdev); 322 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 323 + 324 + return snprintf(buf, PAGE_SIZE, 325 + "Firmware Version: %s\n", 326 + acb->firm_version); 327 + } 328 + 329 + static ssize_t 330 + arcmsr_attr_host_fw_request_len(struct class_device *cdev, char *buf) { 331 + struct Scsi_Host *host = class_to_shost(cdev); 332 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 333 + 334 + return snprintf(buf, PAGE_SIZE, 335 + "Reguest Lenth: %4d\n", 336 + acb->firm_request_len); 337 + } 338 + 339 + static ssize_t 340 + arcmsr_attr_host_fw_numbers_queue(struct class_device *cdev, char *buf) { 341 + struct Scsi_Host *host = class_to_shost(cdev); 342 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 343 + 344 + return snprintf(buf, PAGE_SIZE, 345 + "Numbers of Queue: %4d\n", 346 + acb->firm_numbers_queue); 347 + } 348 + 349 + static ssize_t 350 + arcmsr_attr_host_fw_sdram_size(struct class_device *cdev, char *buf) { 351 + struct Scsi_Host *host = class_to_shost(cdev); 352 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 353 + 354 + return snprintf(buf, PAGE_SIZE, 355 + "SDRAM Size: %4d\n", 356 + acb->firm_sdram_size); 357 + } 358 + 359 + static ssize_t 360 + arcmsr_attr_host_fw_hd_channels(struct class_device *cdev, char *buf) { 361 + struct Scsi_Host *host = class_to_shost(cdev); 362 + struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; 363 + 364 + return snprintf(buf, PAGE_SIZE, 365 + "Hard Disk Channels: %4d\n", 366 + acb->firm_hd_channels); 367 + } 368 + 369 + static CLASS_DEVICE_ATTR(host_driver_version, S_IRUGO, arcmsr_attr_host_driver_version, NULL); 370 + static CLASS_DEVICE_ATTR(host_driver_posted_cmd, S_IRUGO, arcmsr_attr_host_driver_posted_cmd, NULL); 371 + static CLASS_DEVICE_ATTR(host_driver_reset, S_IRUGO, arcmsr_attr_host_driver_reset, NULL); 372 + static CLASS_DEVICE_ATTR(host_driver_abort, S_IRUGO, arcmsr_attr_host_driver_abort, NULL); 373 + static CLASS_DEVICE_ATTR(host_fw_model, S_IRUGO, arcmsr_attr_host_fw_model, NULL); 374 + static CLASS_DEVICE_ATTR(host_fw_version, S_IRUGO, arcmsr_attr_host_fw_version, NULL); 375 + static CLASS_DEVICE_ATTR(host_fw_request_len, S_IRUGO, arcmsr_attr_host_fw_request_len, NULL); 376 + static CLASS_DEVICE_ATTR(host_fw_numbers_queue, S_IRUGO, arcmsr_attr_host_fw_numbers_queue, NULL); 377 + static CLASS_DEVICE_ATTR(host_fw_sdram_size, S_IRUGO, arcmsr_attr_host_fw_sdram_size, NULL); 378 + static CLASS_DEVICE_ATTR(host_fw_hd_channels, S_IRUGO, arcmsr_attr_host_fw_hd_channels, NULL); 379 + 380 + struct class_device_attribute *arcmsr_host_attrs[] = { 381 + &class_device_attr_host_driver_version, 382 + &class_device_attr_host_driver_posted_cmd, 383 + &class_device_attr_host_driver_reset, 384 + &class_device_attr_host_driver_abort, 385 + &class_device_attr_host_fw_model, 386 + &class_device_attr_host_fw_version, 387 + &class_device_attr_host_fw_request_len, 388 + &class_device_attr_host_fw_numbers_queue, 389 + &class_device_attr_host_fw_sdram_size, 390 + &class_device_attr_host_fw_hd_channels, 391 + NULL, 392 + };
+1496
drivers/scsi/arcmsr/arcmsr_hba.c
··· 1 + /* 2 + ******************************************************************************* 3 + ** O.S : Linux 4 + ** FILE NAME : arcmsr_hba.c 5 + ** BY : Erich Chen 6 + ** Description: SCSI RAID Device Driver for 7 + ** ARECA RAID Host adapter 8 + ******************************************************************************* 9 + ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved 10 + ** 11 + ** Web site: www.areca.com.tw 12 + ** E-mail: erich@areca.com.tw 13 + ** 14 + ** This program is free software; you can redistribute it and/or modify 15 + ** it under the terms of the GNU General Public License version 2 as 16 + ** published by the Free Software Foundation. 17 + ** This program is distributed in the hope that it will be useful, 18 + ** but WITHOUT ANY WARRANTY; without even the implied warranty of 19 + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 + ** GNU General Public License for more details. 21 + ******************************************************************************* 22 + ** Redistribution and use in source and binary forms, with or without 23 + ** modification, are permitted provided that the following conditions 24 + ** are met: 25 + ** 1. Redistributions of source code must retain the above copyright 26 + ** notice, this list of conditions and the following disclaimer. 27 + ** 2. Redistributions in binary form must reproduce the above copyright 28 + ** notice, this list of conditions and the following disclaimer in the 29 + ** documentation and/or other materials provided with the distribution. 30 + ** 3. The name of the author may not be used to endorse or promote products 31 + ** derived from this software without specific prior written permission. 32 + ** 33 + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 34 + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 35 + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36 + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 37 + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING,BUT 38 + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 39 + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION)HOWEVER CAUSED AND ON ANY 40 + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41 + ** (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF 42 + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 + ******************************************************************************* 44 + ** For history of changes, see Documentation/scsi/ChangeLog.arcmsr 45 + ** Firmware Specification, see Documentation/scsi/arcmsr_spec.txt 46 + ******************************************************************************* 47 + */ 48 + #include <linux/module.h> 49 + #include <linux/reboot.h> 50 + #include <linux/spinlock.h> 51 + #include <linux/pci_ids.h> 52 + #include <linux/interrupt.h> 53 + #include <linux/moduleparam.h> 54 + #include <linux/errno.h> 55 + #include <linux/types.h> 56 + #include <linux/delay.h> 57 + #include <linux/dma-mapping.h> 58 + #include <linux/timer.h> 59 + #include <linux/pci.h> 60 + #include <asm/dma.h> 61 + #include <asm/io.h> 62 + #include <asm/system.h> 63 + #include <asm/uaccess.h> 64 + #include <scsi/scsi_host.h> 65 + #include <scsi/scsi.h> 66 + #include <scsi/scsi_cmnd.h> 67 + #include <scsi/scsi_tcq.h> 68 + #include <scsi/scsi_device.h> 69 + #include <scsi/scsi_transport.h> 70 + #include <scsi/scsicam.h> 71 + #include "arcmsr.h" 72 + 73 + MODULE_AUTHOR("Erich Chen <erich@areca.com.tw>"); 74 + MODULE_DESCRIPTION("ARECA (ARC11xx/12xx) SATA RAID HOST Adapter"); 75 + MODULE_LICENSE("Dual BSD/GPL"); 76 + MODULE_VERSION(ARCMSR_DRIVER_VERSION); 77 + 78 + static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd); 79 + static int arcmsr_abort(struct scsi_cmnd *); 80 + static int arcmsr_bus_reset(struct scsi_cmnd *); 81 + static int arcmsr_bios_param(struct scsi_device *sdev, 82 + struct block_device *bdev, sector_t capacity, int *info); 83 + static int arcmsr_queue_command(struct scsi_cmnd * cmd, 84 + void (*done) (struct scsi_cmnd *)); 85 + static int arcmsr_probe(struct pci_dev *pdev, 86 + const struct pci_device_id *id); 87 + static void arcmsr_remove(struct pci_dev *pdev); 88 + static void arcmsr_shutdown(struct pci_dev *pdev); 89 + static void arcmsr_iop_init(struct AdapterControlBlock *acb); 90 + static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb); 91 + static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); 92 + static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb); 93 + static uint8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb); 94 + static const char *arcmsr_info(struct Scsi_Host *); 95 + static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); 96 + 97 + static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) 98 + { 99 + if (queue_depth > ARCMSR_MAX_CMD_PERLUN) 100 + queue_depth = ARCMSR_MAX_CMD_PERLUN; 101 + scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, queue_depth); 102 + return queue_depth; 103 + } 104 + 105 + static struct scsi_host_template arcmsr_scsi_host_template = { 106 + .module = THIS_MODULE, 107 + .name = "ARCMSR ARECA SATA RAID HOST Adapter" ARCMSR_DRIVER_VERSION, 108 + .info = arcmsr_info, 109 + .queuecommand = arcmsr_queue_command, 110 + .eh_abort_handler = arcmsr_abort, 111 + .eh_bus_reset_handler = arcmsr_bus_reset, 112 + .bios_param = arcmsr_bios_param, 113 + .change_queue_depth = arcmsr_adjust_disk_queue_depth, 114 + .can_queue = ARCMSR_MAX_OUTSTANDING_CMD, 115 + .this_id = ARCMSR_SCSI_INITIATOR_ID, 116 + .sg_tablesize = ARCMSR_MAX_SG_ENTRIES, 117 + .max_sectors = ARCMSR_MAX_XFER_SECTORS, 118 + .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN, 119 + .use_clustering = ENABLE_CLUSTERING, 120 + .shost_attrs = arcmsr_host_attrs, 121 + }; 122 + 123 + static struct pci_device_id arcmsr_device_id_table[] = { 124 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, 125 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1120)}, 126 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1130)}, 127 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1160)}, 128 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1170)}, 129 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210)}, 130 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1220)}, 131 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1230)}, 132 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1260)}, 133 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1270)}, 134 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1280)}, 135 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1380)}, 136 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1381)}, 137 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1680)}, 138 + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1681)}, 139 + {0, 0}, /* Terminating entry */ 140 + }; 141 + MODULE_DEVICE_TABLE(pci, arcmsr_device_id_table); 142 + static struct pci_driver arcmsr_pci_driver = { 143 + .name = "arcmsr", 144 + .id_table = arcmsr_device_id_table, 145 + .probe = arcmsr_probe, 146 + .remove = arcmsr_remove, 147 + .shutdown = arcmsr_shutdown 148 + }; 149 + 150 + static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id, 151 + struct pt_regs *regs) 152 + { 153 + irqreturn_t handle_state; 154 + struct AdapterControlBlock *acb; 155 + unsigned long flags; 156 + 157 + acb = (struct AdapterControlBlock *)dev_id; 158 + 159 + spin_lock_irqsave(acb->host->host_lock, flags); 160 + handle_state = arcmsr_interrupt(acb); 161 + spin_unlock_irqrestore(acb->host->host_lock, flags); 162 + return handle_state; 163 + } 164 + 165 + static int arcmsr_bios_param(struct scsi_device *sdev, 166 + struct block_device *bdev, sector_t capacity, int *geom) 167 + { 168 + int ret, heads, sectors, cylinders, total_capacity; 169 + unsigned char *buffer;/* return copy of block device's partition table */ 170 + 171 + buffer = scsi_bios_ptable(bdev); 172 + if (buffer) { 173 + ret = scsi_partsize(buffer, capacity, &geom[2], &geom[0], &geom[1]); 174 + kfree(buffer); 175 + if (ret != -1) 176 + return ret; 177 + } 178 + total_capacity = capacity; 179 + heads = 64; 180 + sectors = 32; 181 + cylinders = total_capacity / (heads * sectors); 182 + if (cylinders > 1024) { 183 + heads = 255; 184 + sectors = 63; 185 + cylinders = total_capacity / (heads * sectors); 186 + } 187 + geom[0] = heads; 188 + geom[1] = sectors; 189 + geom[2] = cylinders; 190 + return 0; 191 + } 192 + 193 + static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) 194 + { 195 + struct pci_dev *pdev = acb->pdev; 196 + struct MessageUnit __iomem *reg = acb->pmu; 197 + u32 ccb_phyaddr_hi32; 198 + void *dma_coherent; 199 + dma_addr_t dma_coherent_handle, dma_addr; 200 + struct CommandControlBlock *ccb_tmp; 201 + int i, j; 202 + 203 + dma_coherent = dma_alloc_coherent(&pdev->dev, 204 + ARCMSR_MAX_FREECCB_NUM * 205 + sizeof (struct CommandControlBlock) + 0x20, 206 + &dma_coherent_handle, GFP_KERNEL); 207 + if (!dma_coherent) 208 + return -ENOMEM; 209 + 210 + acb->dma_coherent = dma_coherent; 211 + acb->dma_coherent_handle = dma_coherent_handle; 212 + 213 + if (((unsigned long)dma_coherent & 0x1F)) { 214 + dma_coherent = dma_coherent + 215 + (0x20 - ((unsigned long)dma_coherent & 0x1F)); 216 + dma_coherent_handle = dma_coherent_handle + 217 + (0x20 - ((unsigned long)dma_coherent_handle & 0x1F)); 218 + } 219 + 220 + dma_addr = dma_coherent_handle; 221 + ccb_tmp = (struct CommandControlBlock *)dma_coherent; 222 + for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { 223 + ccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5; 224 + ccb_tmp->acb = acb; 225 + acb->pccb_pool[i] = ccb_tmp; 226 + list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); 227 + dma_addr = dma_addr + sizeof (struct CommandControlBlock); 228 + ccb_tmp++; 229 + } 230 + 231 + acb->vir2phy_offset = (unsigned long)ccb_tmp - 232 + (unsigned long)dma_addr; 233 + for (i = 0; i < ARCMSR_MAX_TARGETID; i++) 234 + for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) 235 + acb->devstate[i][j] = ARECA_RAID_GOOD; 236 + 237 + /* 238 + ** here we need to tell iop 331 our ccb_tmp.HighPart 239 + ** if ccb_tmp.HighPart is not zero 240 + */ 241 + ccb_phyaddr_hi32 = (uint32_t) ((dma_coherent_handle >> 16) >> 16); 242 + if (ccb_phyaddr_hi32 != 0) { 243 + writel(ARCMSR_SIGNATURE_SET_CONFIG, &reg->message_rwbuffer[0]); 244 + writel(ccb_phyaddr_hi32, &reg->message_rwbuffer[1]); 245 + writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, &reg->inbound_msgaddr0); 246 + if (arcmsr_wait_msgint_ready(acb)) 247 + printk(KERN_NOTICE "arcmsr%d: " 248 + "'set ccb high part physical address' timeout\n", 249 + acb->host->host_no); 250 + } 251 + 252 + writel(readl(&reg->outbound_intmask) | 253 + ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, 254 + &reg->outbound_intmask); 255 + return 0; 256 + } 257 + 258 + static int arcmsr_probe(struct pci_dev *pdev, 259 + const struct pci_device_id *id) 260 + { 261 + struct Scsi_Host *host; 262 + struct AdapterControlBlock *acb; 263 + uint8_t bus, dev_fun; 264 + int error; 265 + 266 + error = pci_enable_device(pdev); 267 + if (error) 268 + goto out; 269 + pci_set_master(pdev); 270 + 271 + host = scsi_host_alloc(&arcmsr_scsi_host_template, 272 + sizeof(struct AdapterControlBlock)); 273 + if (!host) { 274 + error = -ENOMEM; 275 + goto out_disable_device; 276 + } 277 + acb = (struct AdapterControlBlock *)host->hostdata; 278 + memset(acb, 0, sizeof (struct AdapterControlBlock)); 279 + 280 + error = pci_set_dma_mask(pdev, DMA_64BIT_MASK); 281 + if (error) { 282 + error = pci_set_dma_mask(pdev, DMA_32BIT_MASK); 283 + if (error) { 284 + printk(KERN_WARNING 285 + "scsi%d: No suitable DMA mask available\n", 286 + host->host_no); 287 + goto out_host_put; 288 + } 289 + } 290 + bus = pdev->bus->number; 291 + dev_fun = pdev->devfn; 292 + acb->host = host; 293 + acb->pdev = pdev; 294 + host->max_sectors = ARCMSR_MAX_XFER_SECTORS; 295 + host->max_lun = ARCMSR_MAX_TARGETLUN; 296 + host->max_id = ARCMSR_MAX_TARGETID;/*16:8*/ 297 + host->max_cmd_len = 16; /*this is issue of 64bit LBA, over 2T byte*/ 298 + host->sg_tablesize = ARCMSR_MAX_SG_ENTRIES; 299 + host->can_queue = ARCMSR_MAX_FREECCB_NUM; /* max simultaneous cmds */ 300 + host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN; 301 + host->this_id = ARCMSR_SCSI_INITIATOR_ID; 302 + host->unique_id = (bus << 8) | dev_fun; 303 + host->irq = pdev->irq; 304 + error = pci_request_regions(pdev, "arcmsr"); 305 + if (error) 306 + goto out_host_put; 307 + 308 + acb->pmu = ioremap(pci_resource_start(pdev, 0), 309 + pci_resource_len(pdev, 0)); 310 + if (!acb->pmu) { 311 + printk(KERN_NOTICE "arcmsr%d: memory" 312 + " mapping region fail \n", acb->host->host_no); 313 + goto out_release_regions; 314 + } 315 + acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | 316 + ACB_F_MESSAGE_RQBUFFER_CLEARED | 317 + ACB_F_MESSAGE_WQBUFFER_READED); 318 + acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER; 319 + INIT_LIST_HEAD(&acb->ccb_free_list); 320 + 321 + error = arcmsr_alloc_ccb_pool(acb); 322 + if (error) 323 + goto out_iounmap; 324 + 325 + error = request_irq(pdev->irq, arcmsr_do_interrupt, 326 + SA_INTERRUPT | SA_SHIRQ, "arcmsr", acb); 327 + if (error) 328 + goto out_free_ccb_pool; 329 + 330 + arcmsr_iop_init(acb); 331 + pci_set_drvdata(pdev, host); 332 + 333 + error = scsi_add_host(host, &pdev->dev); 334 + if (error) 335 + goto out_free_irq; 336 + 337 + error = arcmsr_alloc_sysfs_attr(acb); 338 + if (error) 339 + goto out_free_sysfs; 340 + 341 + scsi_scan_host(host); 342 + return 0; 343 + out_free_sysfs: 344 + out_free_irq: 345 + free_irq(pdev->irq, acb); 346 + out_free_ccb_pool: 347 + arcmsr_free_ccb_pool(acb); 348 + out_iounmap: 349 + iounmap(acb->pmu); 350 + out_release_regions: 351 + pci_release_regions(pdev); 352 + out_host_put: 353 + scsi_host_put(host); 354 + out_disable_device: 355 + pci_disable_device(pdev); 356 + out: 357 + return error; 358 + } 359 + 360 + static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) 361 + { 362 + struct MessageUnit __iomem *reg = acb->pmu; 363 + 364 + writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, &reg->inbound_msgaddr0); 365 + if (arcmsr_wait_msgint_ready(acb)) 366 + printk(KERN_NOTICE 367 + "arcmsr%d: wait 'abort all outstanding command' timeout \n" 368 + , acb->host->host_no); 369 + } 370 + 371 + static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb) 372 + { 373 + struct AdapterControlBlock *acb = ccb->acb; 374 + struct scsi_cmnd *pcmd = ccb->pcmd; 375 + 376 + if (pcmd->use_sg != 0) { 377 + struct scatterlist *sl; 378 + 379 + sl = (struct scatterlist *)pcmd->request_buffer; 380 + pci_unmap_sg(acb->pdev, sl, pcmd->use_sg, pcmd->sc_data_direction); 381 + } 382 + else if (pcmd->request_bufflen != 0) 383 + pci_unmap_single(acb->pdev, 384 + pcmd->SCp.dma_handle, 385 + pcmd->request_bufflen, pcmd->sc_data_direction); 386 + } 387 + 388 + static void arcmsr_ccb_complete(struct CommandControlBlock *ccb, int stand_flag) 389 + { 390 + struct AdapterControlBlock *acb = ccb->acb; 391 + struct scsi_cmnd *pcmd = ccb->pcmd; 392 + 393 + arcmsr_pci_unmap_dma(ccb); 394 + if (stand_flag == 1) 395 + atomic_dec(&acb->ccboutstandingcount); 396 + ccb->startdone = ARCMSR_CCB_DONE; 397 + ccb->ccb_flags = 0; 398 + list_add_tail(&ccb->list, &acb->ccb_free_list); 399 + pcmd->scsi_done(pcmd); 400 + } 401 + 402 + static void arcmsr_remove(struct pci_dev *pdev) 403 + { 404 + struct Scsi_Host *host = pci_get_drvdata(pdev); 405 + struct AdapterControlBlock *acb = 406 + (struct AdapterControlBlock *) host->hostdata; 407 + struct MessageUnit __iomem *reg = acb->pmu; 408 + int poll_count = 0; 409 + 410 + arcmsr_free_sysfs_attr(acb); 411 + scsi_remove_host(host); 412 + arcmsr_stop_adapter_bgrb(acb); 413 + arcmsr_flush_adapter_cache(acb); 414 + writel(readl(&reg->outbound_intmask) | 415 + ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, 416 + &reg->outbound_intmask); 417 + acb->acb_flags |= ACB_F_SCSISTOPADAPTER; 418 + acb->acb_flags &= ~ACB_F_IOP_INITED; 419 + 420 + for (poll_count = 0; poll_count < 256; poll_count++) { 421 + if (!atomic_read(&acb->ccboutstandingcount)) 422 + break; 423 + arcmsr_interrupt(acb); 424 + msleep(25); 425 + } 426 + 427 + if (atomic_read(&acb->ccboutstandingcount)) { 428 + int i; 429 + 430 + arcmsr_abort_allcmd(acb); 431 + for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) 432 + readl(&reg->outbound_queueport); 433 + for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { 434 + struct CommandControlBlock *ccb = acb->pccb_pool[i]; 435 + if (ccb->startdone == ARCMSR_CCB_START) { 436 + ccb->startdone = ARCMSR_CCB_ABORTED; 437 + ccb->pcmd->result = DID_ABORT << 16; 438 + arcmsr_ccb_complete(ccb, 1); 439 + } 440 + } 441 + } 442 + 443 + free_irq(pdev->irq, acb); 444 + iounmap(acb->pmu); 445 + arcmsr_free_ccb_pool(acb); 446 + pci_release_regions(pdev); 447 + 448 + scsi_host_put(host); 449 + 450 + pci_disable_device(pdev); 451 + pci_set_drvdata(pdev, NULL); 452 + } 453 + 454 + static void arcmsr_shutdown(struct pci_dev *pdev) 455 + { 456 + struct Scsi_Host *host = pci_get_drvdata(pdev); 457 + struct AdapterControlBlock *acb = 458 + (struct AdapterControlBlock *)host->hostdata; 459 + 460 + arcmsr_stop_adapter_bgrb(acb); 461 + arcmsr_flush_adapter_cache(acb); 462 + } 463 + 464 + static int arcmsr_module_init(void) 465 + { 466 + int error = 0; 467 + 468 + error = pci_register_driver(&arcmsr_pci_driver); 469 + return error; 470 + } 471 + 472 + static void arcmsr_module_exit(void) 473 + { 474 + pci_unregister_driver(&arcmsr_pci_driver); 475 + } 476 + module_init(arcmsr_module_init); 477 + module_exit(arcmsr_module_exit); 478 + 479 + static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) 480 + { 481 + struct MessageUnit __iomem *reg = acb->pmu; 482 + u32 orig_mask = readl(&reg->outbound_intmask); 483 + 484 + writel(orig_mask | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, 485 + &reg->outbound_intmask); 486 + return orig_mask; 487 + } 488 + 489 + static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, 490 + u32 orig_mask) 491 + { 492 + struct MessageUnit __iomem *reg = acb->pmu; 493 + u32 mask; 494 + 495 + mask = orig_mask & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | 496 + ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); 497 + writel(mask, &reg->outbound_intmask); 498 + } 499 + 500 + static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) 501 + { 502 + struct MessageUnit __iomem *reg=acb->pmu; 503 + 504 + writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, &reg->inbound_msgaddr0); 505 + if (arcmsr_wait_msgint_ready(acb)) 506 + printk(KERN_NOTICE 507 + "arcmsr%d: wait 'flush adapter cache' timeout \n" 508 + , acb->host->host_no); 509 + } 510 + 511 + static void arcmsr_report_sense_info(struct CommandControlBlock *ccb) 512 + { 513 + struct scsi_cmnd *pcmd = ccb->pcmd; 514 + struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer; 515 + 516 + pcmd->result = DID_OK << 16; 517 + if (sensebuffer) { 518 + int sense_data_length = 519 + sizeof (struct SENSE_DATA) < sizeof (pcmd->sense_buffer) 520 + ? sizeof (struct SENSE_DATA) : sizeof (pcmd->sense_buffer); 521 + memset(sensebuffer, 0, sizeof (pcmd->sense_buffer)); 522 + memcpy(sensebuffer, ccb->arcmsr_cdb.SenseData, sense_data_length); 523 + sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS; 524 + sensebuffer->Valid = 1; 525 + } 526 + } 527 + 528 + static uint8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb) 529 + { 530 + struct MessageUnit __iomem *reg = acb->pmu; 531 + uint32_t Index; 532 + uint8_t Retries = 0x00; 533 + 534 + do { 535 + for (Index = 0; Index < 100; Index++) { 536 + if (readl(&reg->outbound_intstatus) 537 + & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { 538 + writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT 539 + , &reg->outbound_intstatus); 540 + return 0x00; 541 + } 542 + msleep_interruptible(10); 543 + }/*max 1 seconds*/ 544 + } while (Retries++ < 20);/*max 20 sec*/ 545 + return 0xff; 546 + } 547 + 548 + static void arcmsr_build_ccb(struct AdapterControlBlock *acb, 549 + struct CommandControlBlock *ccb, struct scsi_cmnd *pcmd) 550 + { 551 + struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; 552 + int8_t *psge = (int8_t *)&arcmsr_cdb->u; 553 + uint32_t address_lo, address_hi; 554 + int arccdbsize = 0x30; 555 + 556 + ccb->pcmd = pcmd; 557 + memset(arcmsr_cdb, 0, sizeof (struct ARCMSR_CDB)); 558 + arcmsr_cdb->Bus = 0; 559 + arcmsr_cdb->TargetID = pcmd->device->id; 560 + arcmsr_cdb->LUN = pcmd->device->lun; 561 + arcmsr_cdb->Function = 1; 562 + arcmsr_cdb->CdbLength = (uint8_t)pcmd->cmd_len; 563 + arcmsr_cdb->Context = (unsigned long)arcmsr_cdb; 564 + memcpy(arcmsr_cdb->Cdb, pcmd->cmnd, pcmd->cmd_len); 565 + if (pcmd->use_sg) { 566 + int length, sgcount, i, cdb_sgcount = 0; 567 + struct scatterlist *sl; 568 + 569 + /* Get Scatter Gather List from scsiport. */ 570 + sl = (struct scatterlist *) pcmd->request_buffer; 571 + sgcount = pci_map_sg(acb->pdev, sl, pcmd->use_sg, 572 + pcmd->sc_data_direction); 573 + /* map stor port SG list to our iop SG List. */ 574 + for (i = 0; i < sgcount; i++) { 575 + /* Get the physical address of the current data pointer */ 576 + length = cpu_to_le32(sg_dma_len(sl)); 577 + address_lo = cpu_to_le32(dma_addr_lo32(sg_dma_address(sl))); 578 + address_hi = cpu_to_le32(dma_addr_hi32(sg_dma_address(sl))); 579 + if (address_hi == 0) { 580 + struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge; 581 + 582 + pdma_sg->address = address_lo; 583 + pdma_sg->length = length; 584 + psge += sizeof (struct SG32ENTRY); 585 + arccdbsize += sizeof (struct SG32ENTRY); 586 + } else { 587 + struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge; 588 + 589 + pdma_sg->addresshigh = address_hi; 590 + pdma_sg->address = address_lo; 591 + pdma_sg->length = length|IS_SG64_ADDR; 592 + psge += sizeof (struct SG64ENTRY); 593 + arccdbsize += sizeof (struct SG64ENTRY); 594 + } 595 + sl++; 596 + cdb_sgcount++; 597 + } 598 + arcmsr_cdb->sgcount = (uint8_t)cdb_sgcount; 599 + arcmsr_cdb->DataLength = pcmd->request_bufflen; 600 + if ( arccdbsize > 256) 601 + arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_SGL_BSIZE; 602 + } else if (pcmd->request_bufflen) { 603 + dma_addr_t dma_addr; 604 + dma_addr = pci_map_single(acb->pdev, pcmd->request_buffer, 605 + pcmd->request_bufflen, pcmd->sc_data_direction); 606 + pcmd->SCp.dma_handle = dma_addr; 607 + address_lo = cpu_to_le32(dma_addr_lo32(dma_addr)); 608 + address_hi = cpu_to_le32(dma_addr_hi32(dma_addr)); 609 + if (address_hi == 0) { 610 + struct SG32ENTRY *pdma_sg = (struct SG32ENTRY *)psge; 611 + pdma_sg->address = address_lo; 612 + pdma_sg->length = pcmd->request_bufflen; 613 + } else { 614 + struct SG64ENTRY *pdma_sg = (struct SG64ENTRY *)psge; 615 + pdma_sg->addresshigh = address_hi; 616 + pdma_sg->address = address_lo; 617 + pdma_sg->length = pcmd->request_bufflen|IS_SG64_ADDR; 618 + } 619 + arcmsr_cdb->sgcount = 1; 620 + arcmsr_cdb->DataLength = pcmd->request_bufflen; 621 + } 622 + if (pcmd->sc_data_direction == DMA_TO_DEVICE ) { 623 + arcmsr_cdb->Flags |= ARCMSR_CDB_FLAG_WRITE; 624 + ccb->ccb_flags |= CCB_FLAG_WRITE; 625 + } 626 + } 627 + 628 + static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb) 629 + { 630 + struct MessageUnit __iomem *reg = acb->pmu; 631 + uint32_t cdb_shifted_phyaddr = ccb->cdb_shifted_phyaddr; 632 + struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; 633 + 634 + atomic_inc(&acb->ccboutstandingcount); 635 + ccb->startdone = ARCMSR_CCB_START; 636 + if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) 637 + writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE, 638 + &reg->inbound_queueport); 639 + else 640 + writel(cdb_shifted_phyaddr, &reg->inbound_queueport); 641 + } 642 + 643 + void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb) 644 + { 645 + struct MessageUnit __iomem *reg = acb->pmu; 646 + struct QBUFFER __iomem *pwbuffer = (struct QBUFFER __iomem *) &reg->message_wbuffer; 647 + uint8_t __iomem *iop_data = (uint8_t __iomem *) pwbuffer->data; 648 + int32_t allxfer_len = 0; 649 + 650 + if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) { 651 + acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); 652 + while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) 653 + && (allxfer_len < 124)) { 654 + writeb(acb->wqbuffer[acb->wqbuf_firstindex], iop_data); 655 + acb->wqbuf_firstindex++; 656 + acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; 657 + iop_data++; 658 + allxfer_len++; 659 + } 660 + writel(allxfer_len, &pwbuffer->data_len); 661 + writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK 662 + , &reg->inbound_doorbell); 663 + } 664 + } 665 + 666 + static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) 667 + { 668 + struct MessageUnit __iomem *reg = acb->pmu; 669 + 670 + acb->acb_flags &= ~ACB_F_MSG_START_BGRB; 671 + writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, &reg->inbound_msgaddr0); 672 + if (arcmsr_wait_msgint_ready(acb)) 673 + printk(KERN_NOTICE 674 + "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" 675 + , acb->host->host_no); 676 + } 677 + 678 + static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) 679 + { 680 + dma_free_coherent(&acb->pdev->dev, 681 + ARCMSR_MAX_FREECCB_NUM * sizeof (struct CommandControlBlock) + 0x20, 682 + acb->dma_coherent, 683 + acb->dma_coherent_handle); 684 + } 685 + 686 + static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) 687 + { 688 + struct MessageUnit __iomem *reg = acb->pmu; 689 + struct CommandControlBlock *ccb; 690 + uint32_t flag_ccb, outbound_intstatus, outbound_doorbell; 691 + 692 + outbound_intstatus = readl(&reg->outbound_intstatus) 693 + & acb->outbound_int_enable; 694 + writel(outbound_intstatus, &reg->outbound_intstatus); 695 + if (outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) { 696 + outbound_doorbell = readl(&reg->outbound_doorbell); 697 + writel(outbound_doorbell, &reg->outbound_doorbell); 698 + if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) { 699 + struct QBUFFER __iomem * prbuffer = 700 + (struct QBUFFER __iomem *) &reg->message_rbuffer; 701 + uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; 702 + int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex; 703 + 704 + rqbuf_lastindex = acb->rqbuf_lastindex; 705 + rqbuf_firstindex = acb->rqbuf_firstindex; 706 + iop_len = readl(&prbuffer->data_len); 707 + my_empty_len = (rqbuf_firstindex - rqbuf_lastindex - 1) 708 + &(ARCMSR_MAX_QBUFFER - 1); 709 + if (my_empty_len >= iop_len) { 710 + while (iop_len > 0) { 711 + acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); 712 + acb->rqbuf_lastindex++; 713 + acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; 714 + iop_data++; 715 + iop_len--; 716 + } 717 + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, 718 + &reg->inbound_doorbell); 719 + } else 720 + acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW; 721 + } 722 + if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) { 723 + acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; 724 + if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) { 725 + struct QBUFFER __iomem * pwbuffer = 726 + (struct QBUFFER __iomem *) &reg->message_wbuffer; 727 + uint8_t __iomem * iop_data = (uint8_t __iomem *) pwbuffer->data; 728 + int32_t allxfer_len = 0; 729 + 730 + acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); 731 + while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) 732 + && (allxfer_len < 124)) { 733 + writeb(acb->wqbuffer[acb->wqbuf_firstindex], iop_data); 734 + acb->wqbuf_firstindex++; 735 + acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; 736 + iop_data++; 737 + allxfer_len++; 738 + } 739 + writel(allxfer_len, &pwbuffer->data_len); 740 + writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK, 741 + &reg->inbound_doorbell); 742 + } 743 + if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) 744 + acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; 745 + } 746 + } 747 + if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) { 748 + int id, lun; 749 + /* 750 + **************************************************************** 751 + ** areca cdb command done 752 + **************************************************************** 753 + */ 754 + while (1) { 755 + if ((flag_ccb = readl(&reg->outbound_queueport)) == 0xFFFFFFFF) 756 + break;/*chip FIFO no ccb for completion already*/ 757 + /* check if command done with no error*/ 758 + ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + 759 + (flag_ccb << 5)); 760 + if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { 761 + if (ccb->startdone == ARCMSR_CCB_ABORTED) { 762 + struct scsi_cmnd *abortcmd=ccb->pcmd; 763 + if (abortcmd) { 764 + abortcmd->result |= DID_ABORT >> 16; 765 + arcmsr_ccb_complete(ccb, 1); 766 + printk(KERN_NOTICE 767 + "arcmsr%d: ccb='0x%p' isr got aborted command \n" 768 + , acb->host->host_no, ccb); 769 + } 770 + continue; 771 + } 772 + printk(KERN_NOTICE 773 + "arcmsr%d: isr get an illegal ccb command done acb='0x%p'" 774 + "ccb='0x%p' ccbacb='0x%p' startdone = 0x%x" 775 + " ccboutstandingcount=%d \n" 776 + , acb->host->host_no 777 + , acb 778 + , ccb 779 + , ccb->acb 780 + , ccb->startdone 781 + , atomic_read(&acb->ccboutstandingcount)); 782 + continue; 783 + } 784 + id = ccb->pcmd->device->id; 785 + lun = ccb->pcmd->device->lun; 786 + if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { 787 + if (acb->devstate[id][lun] == ARECA_RAID_GONE) 788 + acb->devstate[id][lun] = ARECA_RAID_GOOD; 789 + ccb->pcmd->result = DID_OK << 16; 790 + arcmsr_ccb_complete(ccb, 1); 791 + } else { 792 + switch(ccb->arcmsr_cdb.DeviceStatus) { 793 + case ARCMSR_DEV_SELECT_TIMEOUT: { 794 + acb->devstate[id][lun] = ARECA_RAID_GONE; 795 + ccb->pcmd->result = DID_TIME_OUT << 16; 796 + arcmsr_ccb_complete(ccb, 1); 797 + } 798 + break; 799 + case ARCMSR_DEV_ABORTED: 800 + case ARCMSR_DEV_INIT_FAIL: { 801 + acb->devstate[id][lun] = ARECA_RAID_GONE; 802 + ccb->pcmd->result = DID_BAD_TARGET << 16; 803 + arcmsr_ccb_complete(ccb, 1); 804 + } 805 + break; 806 + case ARCMSR_DEV_CHECK_CONDITION: { 807 + acb->devstate[id][lun] = ARECA_RAID_GOOD; 808 + arcmsr_report_sense_info(ccb); 809 + arcmsr_ccb_complete(ccb, 1); 810 + } 811 + break; 812 + default: 813 + printk(KERN_NOTICE 814 + "arcmsr%d: scsi id=%d lun=%d" 815 + " isr get command error done," 816 + "but got unknown DeviceStatus = 0x%x \n" 817 + , acb->host->host_no 818 + , id 819 + , lun 820 + , ccb->arcmsr_cdb.DeviceStatus); 821 + acb->devstate[id][lun] = ARECA_RAID_GONE; 822 + ccb->pcmd->result = DID_NO_CONNECT << 16; 823 + arcmsr_ccb_complete(ccb, 1); 824 + break; 825 + } 826 + } 827 + }/*drain reply FIFO*/ 828 + } 829 + if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) 830 + return IRQ_NONE; 831 + return IRQ_HANDLED; 832 + } 833 + 834 + static void arcmsr_iop_parking(struct AdapterControlBlock *acb) 835 + { 836 + if (acb) { 837 + /* stop adapter background rebuild */ 838 + if (acb->acb_flags & ACB_F_MSG_START_BGRB) { 839 + acb->acb_flags &= ~ACB_F_MSG_START_BGRB; 840 + arcmsr_stop_adapter_bgrb(acb); 841 + arcmsr_flush_adapter_cache(acb); 842 + } 843 + } 844 + } 845 + 846 + static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd) 847 + { 848 + struct MessageUnit __iomem *reg = acb->pmu; 849 + struct CMD_MESSAGE_FIELD *pcmdmessagefld; 850 + int retvalue = 0, transfer_len = 0; 851 + char *buffer; 852 + uint32_t controlcode = (uint32_t ) cmd->cmnd[5] << 24 | 853 + (uint32_t ) cmd->cmnd[6] << 16 | 854 + (uint32_t ) cmd->cmnd[7] << 8 | 855 + (uint32_t ) cmd->cmnd[8]; 856 + /* 4 bytes: Areca io control code */ 857 + if (cmd->use_sg) { 858 + struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer; 859 + 860 + buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; 861 + if (cmd->use_sg > 1) { 862 + retvalue = ARCMSR_MESSAGE_FAIL; 863 + goto message_out; 864 + } 865 + transfer_len += sg->length; 866 + } else { 867 + buffer = cmd->request_buffer; 868 + transfer_len = cmd->request_bufflen; 869 + } 870 + if (transfer_len > sizeof(struct CMD_MESSAGE_FIELD)) { 871 + retvalue = ARCMSR_MESSAGE_FAIL; 872 + goto message_out; 873 + } 874 + pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) buffer; 875 + switch(controlcode) { 876 + case ARCMSR_MESSAGE_READ_RQBUFFER: { 877 + unsigned long *ver_addr; 878 + dma_addr_t buf_handle; 879 + uint8_t *pQbuffer, *ptmpQbuffer; 880 + int32_t allxfer_len = 0; 881 + 882 + ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); 883 + if (!ver_addr) { 884 + retvalue = ARCMSR_MESSAGE_FAIL; 885 + goto message_out; 886 + } 887 + ptmpQbuffer = (uint8_t *) ver_addr; 888 + while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) 889 + && (allxfer_len < 1031)) { 890 + pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; 891 + memcpy(ptmpQbuffer, pQbuffer, 1); 892 + acb->rqbuf_firstindex++; 893 + acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; 894 + ptmpQbuffer++; 895 + allxfer_len++; 896 + } 897 + if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 898 + struct QBUFFER __iomem * prbuffer = (struct QBUFFER __iomem *) 899 + &reg->message_rbuffer; 900 + uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; 901 + int32_t iop_len; 902 + 903 + acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; 904 + iop_len = readl(&prbuffer->data_len); 905 + while (iop_len > 0) { 906 + acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); 907 + acb->rqbuf_lastindex++; 908 + acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; 909 + iop_data++; 910 + iop_len--; 911 + } 912 + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, 913 + &reg->inbound_doorbell); 914 + } 915 + memcpy(pcmdmessagefld->messagedatabuffer, 916 + (uint8_t *)ver_addr, allxfer_len); 917 + pcmdmessagefld->cmdmessage.Length = allxfer_len; 918 + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; 919 + pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); 920 + } 921 + break; 922 + case ARCMSR_MESSAGE_WRITE_WQBUFFER: { 923 + unsigned long *ver_addr; 924 + dma_addr_t buf_handle; 925 + int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; 926 + uint8_t *pQbuffer, *ptmpuserbuffer; 927 + 928 + ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); 929 + if (!ver_addr) { 930 + retvalue = ARCMSR_MESSAGE_FAIL; 931 + goto message_out; 932 + } 933 + ptmpuserbuffer = (uint8_t *)ver_addr; 934 + user_len = pcmdmessagefld->cmdmessage.Length; 935 + memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); 936 + wqbuf_lastindex = acb->wqbuf_lastindex; 937 + wqbuf_firstindex = acb->wqbuf_firstindex; 938 + if (wqbuf_lastindex != wqbuf_firstindex) { 939 + struct SENSE_DATA *sensebuffer = 940 + (struct SENSE_DATA *)cmd->sense_buffer; 941 + arcmsr_post_Qbuffer(acb); 942 + /* has error report sensedata */ 943 + sensebuffer->ErrorCode = 0x70; 944 + sensebuffer->SenseKey = ILLEGAL_REQUEST; 945 + sensebuffer->AdditionalSenseLength = 0x0A; 946 + sensebuffer->AdditionalSenseCode = 0x20; 947 + sensebuffer->Valid = 1; 948 + retvalue = ARCMSR_MESSAGE_FAIL; 949 + } else { 950 + my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) 951 + &(ARCMSR_MAX_QBUFFER - 1); 952 + if (my_empty_len >= user_len) { 953 + while (user_len > 0) { 954 + pQbuffer = 955 + &acb->wqbuffer[acb->wqbuf_lastindex]; 956 + memcpy(pQbuffer, ptmpuserbuffer, 1); 957 + acb->wqbuf_lastindex++; 958 + acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; 959 + ptmpuserbuffer++; 960 + user_len--; 961 + } 962 + if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { 963 + acb->acb_flags &= 964 + ~ACB_F_MESSAGE_WQBUFFER_CLEARED; 965 + arcmsr_post_Qbuffer(acb); 966 + } 967 + } else { 968 + /* has error report sensedata */ 969 + struct SENSE_DATA *sensebuffer = 970 + (struct SENSE_DATA *)cmd->sense_buffer; 971 + sensebuffer->ErrorCode = 0x70; 972 + sensebuffer->SenseKey = ILLEGAL_REQUEST; 973 + sensebuffer->AdditionalSenseLength = 0x0A; 974 + sensebuffer->AdditionalSenseCode = 0x20; 975 + sensebuffer->Valid = 1; 976 + retvalue = ARCMSR_MESSAGE_FAIL; 977 + } 978 + } 979 + pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); 980 + } 981 + break; 982 + case ARCMSR_MESSAGE_CLEAR_RQBUFFER: { 983 + uint8_t *pQbuffer = acb->rqbuffer; 984 + 985 + if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 986 + acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; 987 + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, 988 + &reg->inbound_doorbell); 989 + } 990 + acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED; 991 + acb->rqbuf_firstindex = 0; 992 + acb->rqbuf_lastindex = 0; 993 + memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); 994 + pcmdmessagefld->cmdmessage.ReturnCode = 995 + ARCMSR_MESSAGE_RETURNCODE_OK; 996 + } 997 + break; 998 + case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { 999 + uint8_t *pQbuffer = acb->wqbuffer; 1000 + 1001 + if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 1002 + acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; 1003 + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK 1004 + , &reg->inbound_doorbell); 1005 + } 1006 + acb->acb_flags |= 1007 + (ACB_F_MESSAGE_WQBUFFER_CLEARED | 1008 + ACB_F_MESSAGE_WQBUFFER_READED); 1009 + acb->wqbuf_firstindex = 0; 1010 + acb->wqbuf_lastindex = 0; 1011 + memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); 1012 + pcmdmessagefld->cmdmessage.ReturnCode = 1013 + ARCMSR_MESSAGE_RETURNCODE_OK; 1014 + } 1015 + break; 1016 + case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: { 1017 + uint8_t *pQbuffer; 1018 + 1019 + if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { 1020 + acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; 1021 + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK 1022 + , &reg->inbound_doorbell); 1023 + } 1024 + acb->acb_flags |= 1025 + (ACB_F_MESSAGE_WQBUFFER_CLEARED 1026 + | ACB_F_MESSAGE_RQBUFFER_CLEARED 1027 + | ACB_F_MESSAGE_WQBUFFER_READED); 1028 + acb->rqbuf_firstindex = 0; 1029 + acb->rqbuf_lastindex = 0; 1030 + acb->wqbuf_firstindex = 0; 1031 + acb->wqbuf_lastindex = 0; 1032 + pQbuffer = acb->rqbuffer; 1033 + memset(pQbuffer, 0, sizeof (struct QBUFFER)); 1034 + pQbuffer = acb->wqbuffer; 1035 + memset(pQbuffer, 0, sizeof (struct QBUFFER)); 1036 + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; 1037 + } 1038 + break; 1039 + case ARCMSR_MESSAGE_RETURN_CODE_3F: { 1040 + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F; 1041 + } 1042 + break; 1043 + case ARCMSR_MESSAGE_SAY_HELLO: { 1044 + int8_t * hello_string = "Hello! I am ARCMSR"; 1045 + 1046 + memcpy(pcmdmessagefld->messagedatabuffer, hello_string 1047 + , (int16_t)strlen(hello_string)); 1048 + pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; 1049 + } 1050 + break; 1051 + case ARCMSR_MESSAGE_SAY_GOODBYE: 1052 + arcmsr_iop_parking(acb); 1053 + break; 1054 + case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: 1055 + arcmsr_flush_adapter_cache(acb); 1056 + break; 1057 + default: 1058 + retvalue = ARCMSR_MESSAGE_FAIL; 1059 + } 1060 + message_out: 1061 + if (cmd->use_sg) { 1062 + struct scatterlist *sg; 1063 + 1064 + sg = (struct scatterlist *) cmd->request_buffer; 1065 + kunmap_atomic(buffer - sg->offset, KM_IRQ0); 1066 + } 1067 + return retvalue; 1068 + } 1069 + 1070 + static struct CommandControlBlock *arcmsr_get_freeccb(struct AdapterControlBlock *acb) 1071 + { 1072 + struct list_head *head = &acb->ccb_free_list; 1073 + struct CommandControlBlock *ccb = NULL; 1074 + 1075 + if (!list_empty(head)) { 1076 + ccb = list_entry(head->next, struct CommandControlBlock, list); 1077 + list_del(head->next); 1078 + } 1079 + return ccb; 1080 + } 1081 + 1082 + static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb, 1083 + struct scsi_cmnd *cmd) 1084 + { 1085 + switch (cmd->cmnd[0]) { 1086 + case INQUIRY: { 1087 + unsigned char inqdata[36]; 1088 + char *buffer; 1089 + 1090 + if (cmd->device->lun) { 1091 + cmd->result = (DID_TIME_OUT << 16); 1092 + cmd->scsi_done(cmd); 1093 + return; 1094 + } 1095 + inqdata[0] = TYPE_PROCESSOR; 1096 + /* Periph Qualifier & Periph Dev Type */ 1097 + inqdata[1] = 0; 1098 + /* rem media bit & Dev Type Modifier */ 1099 + inqdata[2] = 0; 1100 + /* ISO,ECMA,& ANSI versions */ 1101 + inqdata[4] = 31; 1102 + /* length of additional data */ 1103 + strncpy(&inqdata[8], "Areca ", 8); 1104 + /* Vendor Identification */ 1105 + strncpy(&inqdata[16], "RAID controller ", 16); 1106 + /* Product Identification */ 1107 + strncpy(&inqdata[32], "R001", 4); /* Product Revision */ 1108 + if (cmd->use_sg) { 1109 + struct scatterlist *sg; 1110 + 1111 + sg = (struct scatterlist *) cmd->request_buffer; 1112 + buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; 1113 + } else { 1114 + buffer = cmd->request_buffer; 1115 + } 1116 + memcpy(buffer, inqdata, sizeof(inqdata)); 1117 + if (cmd->use_sg) { 1118 + struct scatterlist *sg; 1119 + 1120 + sg = (struct scatterlist *) cmd->request_buffer; 1121 + kunmap_atomic(buffer - sg->offset, KM_IRQ0); 1122 + } 1123 + cmd->scsi_done(cmd); 1124 + } 1125 + break; 1126 + case WRITE_BUFFER: 1127 + case READ_BUFFER: { 1128 + if (arcmsr_iop_message_xfer(acb, cmd)) 1129 + cmd->result = (DID_ERROR << 16); 1130 + cmd->scsi_done(cmd); 1131 + } 1132 + break; 1133 + default: 1134 + cmd->scsi_done(cmd); 1135 + } 1136 + } 1137 + 1138 + static int arcmsr_queue_command(struct scsi_cmnd *cmd, 1139 + void (* done)(struct scsi_cmnd *)) 1140 + { 1141 + struct Scsi_Host *host = cmd->device->host; 1142 + struct AdapterControlBlock *acb = 1143 + (struct AdapterControlBlock *) host->hostdata; 1144 + struct CommandControlBlock *ccb; 1145 + int target = cmd->device->id; 1146 + int lun = cmd->device->lun; 1147 + 1148 + cmd->scsi_done = done; 1149 + cmd->host_scribble = NULL; 1150 + cmd->result = 0; 1151 + if (acb->acb_flags & ACB_F_BUS_RESET) { 1152 + printk(KERN_NOTICE "arcmsr%d: bus reset" 1153 + " and return busy \n" 1154 + , acb->host->host_no); 1155 + return SCSI_MLQUEUE_HOST_BUSY; 1156 + } 1157 + if(target == 16) { 1158 + /* virtual device for iop message transfer */ 1159 + arcmsr_handle_virtual_command(acb, cmd); 1160 + return 0; 1161 + } 1162 + if (acb->devstate[target][lun] == ARECA_RAID_GONE) { 1163 + uint8_t block_cmd; 1164 + 1165 + block_cmd = cmd->cmnd[0] & 0x0f; 1166 + if (block_cmd == 0x08 || block_cmd == 0x0a) { 1167 + printk(KERN_NOTICE 1168 + "arcmsr%d: block 'read/write'" 1169 + "command with gone raid volume" 1170 + " Cmd=%2x, TargetId=%d, Lun=%d \n" 1171 + , acb->host->host_no 1172 + , cmd->cmnd[0] 1173 + , target, lun); 1174 + cmd->result = (DID_NO_CONNECT << 16); 1175 + cmd->scsi_done(cmd); 1176 + return 0; 1177 + } 1178 + } 1179 + if (atomic_read(&acb->ccboutstandingcount) >= 1180 + ARCMSR_MAX_OUTSTANDING_CMD) 1181 + return SCSI_MLQUEUE_HOST_BUSY; 1182 + 1183 + ccb = arcmsr_get_freeccb(acb); 1184 + if (!ccb) 1185 + return SCSI_MLQUEUE_HOST_BUSY; 1186 + arcmsr_build_ccb(acb, ccb, cmd); 1187 + arcmsr_post_ccb(acb, ccb); 1188 + return 0; 1189 + } 1190 + 1191 + static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) 1192 + { 1193 + struct MessageUnit __iomem *reg = acb->pmu; 1194 + char *acb_firm_model = acb->firm_model; 1195 + char *acb_firm_version = acb->firm_version; 1196 + char __iomem *iop_firm_model = (char __iomem *) &reg->message_rwbuffer[15]; 1197 + char __iomem *iop_firm_version = (char __iomem *) &reg->message_rwbuffer[17]; 1198 + int count; 1199 + 1200 + writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, &reg->inbound_msgaddr0); 1201 + if (arcmsr_wait_msgint_ready(acb)) 1202 + printk(KERN_NOTICE 1203 + "arcmsr%d: wait " 1204 + "'get adapter firmware miscellaneous data' timeout \n" 1205 + , acb->host->host_no); 1206 + count = 8; 1207 + while (count) { 1208 + *acb_firm_model = readb(iop_firm_model); 1209 + acb_firm_model++; 1210 + iop_firm_model++; 1211 + count--; 1212 + } 1213 + count = 16; 1214 + while (count) { 1215 + *acb_firm_version = readb(iop_firm_version); 1216 + acb_firm_version++; 1217 + iop_firm_version++; 1218 + count--; 1219 + } 1220 + printk(KERN_INFO 1221 + "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n" 1222 + , acb->host->host_no 1223 + , acb->firm_version); 1224 + acb->firm_request_len = readl(&reg->message_rwbuffer[1]); 1225 + acb->firm_numbers_queue = readl(&reg->message_rwbuffer[2]); 1226 + acb->firm_sdram_size = readl(&reg->message_rwbuffer[3]); 1227 + acb->firm_hd_channels = readl(&reg->message_rwbuffer[4]); 1228 + } 1229 + 1230 + static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, 1231 + struct CommandControlBlock *poll_ccb) 1232 + { 1233 + struct MessageUnit __iomem *reg = acb->pmu; 1234 + struct CommandControlBlock *ccb; 1235 + uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 0; 1236 + int id, lun; 1237 + 1238 + polling_ccb_retry: 1239 + poll_count++; 1240 + outbound_intstatus = readl(&reg->outbound_intstatus) 1241 + & acb->outbound_int_enable; 1242 + writel(outbound_intstatus, &reg->outbound_intstatus);/*clear interrupt*/ 1243 + while (1) { 1244 + if ((flag_ccb = readl(&reg->outbound_queueport)) == 0xFFFFFFFF) { 1245 + if (poll_ccb_done) 1246 + break; 1247 + else { 1248 + msleep(25); 1249 + if (poll_count > 100) 1250 + break; 1251 + goto polling_ccb_retry; 1252 + } 1253 + } 1254 + ccb = (struct CommandControlBlock *) 1255 + (acb->vir2phy_offset + (flag_ccb << 5)); 1256 + if ((ccb->acb != acb) || 1257 + (ccb->startdone != ARCMSR_CCB_START)) { 1258 + if ((ccb->startdone == ARCMSR_CCB_ABORTED) || 1259 + (ccb == poll_ccb)) { 1260 + printk(KERN_NOTICE 1261 + "arcmsr%d: scsi id=%d lun=%d ccb='0x%p'" 1262 + " poll command abort successfully \n" 1263 + , acb->host->host_no 1264 + , ccb->pcmd->device->id 1265 + , ccb->pcmd->device->lun 1266 + , ccb); 1267 + ccb->pcmd->result = DID_ABORT << 16; 1268 + arcmsr_ccb_complete(ccb, 1); 1269 + poll_ccb_done = 1; 1270 + continue; 1271 + } 1272 + printk(KERN_NOTICE 1273 + "arcmsr%d: polling get an illegal ccb" 1274 + " command done ccb='0x%p'" 1275 + "ccboutstandingcount=%d \n" 1276 + , acb->host->host_no 1277 + , ccb 1278 + , atomic_read(&acb->ccboutstandingcount)); 1279 + continue; 1280 + } 1281 + id = ccb->pcmd->device->id; 1282 + lun = ccb->pcmd->device->lun; 1283 + if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { 1284 + if (acb->devstate[id][lun] == ARECA_RAID_GONE) 1285 + acb->devstate[id][lun] = ARECA_RAID_GOOD; 1286 + ccb->pcmd->result = DID_OK << 16; 1287 + arcmsr_ccb_complete(ccb, 1); 1288 + } else { 1289 + switch(ccb->arcmsr_cdb.DeviceStatus) { 1290 + case ARCMSR_DEV_SELECT_TIMEOUT: { 1291 + acb->devstate[id][lun] = ARECA_RAID_GONE; 1292 + ccb->pcmd->result = DID_TIME_OUT << 16; 1293 + arcmsr_ccb_complete(ccb, 1); 1294 + } 1295 + break; 1296 + case ARCMSR_DEV_ABORTED: 1297 + case ARCMSR_DEV_INIT_FAIL: { 1298 + acb->devstate[id][lun] = ARECA_RAID_GONE; 1299 + ccb->pcmd->result = DID_BAD_TARGET << 16; 1300 + arcmsr_ccb_complete(ccb, 1); 1301 + } 1302 + break; 1303 + case ARCMSR_DEV_CHECK_CONDITION: { 1304 + acb->devstate[id][lun] = ARECA_RAID_GOOD; 1305 + arcmsr_report_sense_info(ccb); 1306 + arcmsr_ccb_complete(ccb, 1); 1307 + } 1308 + break; 1309 + default: 1310 + printk(KERN_NOTICE 1311 + "arcmsr%d: scsi id=%d lun=%d" 1312 + " polling and getting command error done" 1313 + "but got unknown DeviceStatus = 0x%x \n" 1314 + , acb->host->host_no 1315 + , id 1316 + , lun 1317 + , ccb->arcmsr_cdb.DeviceStatus); 1318 + acb->devstate[id][lun] = ARECA_RAID_GONE; 1319 + ccb->pcmd->result = DID_BAD_TARGET << 16; 1320 + arcmsr_ccb_complete(ccb, 1); 1321 + break; 1322 + } 1323 + } 1324 + } 1325 + } 1326 + 1327 + static void arcmsr_iop_init(struct AdapterControlBlock *acb) 1328 + { 1329 + struct MessageUnit __iomem *reg = acb->pmu; 1330 + uint32_t intmask_org, mask, outbound_doorbell, firmware_state = 0; 1331 + 1332 + do { 1333 + firmware_state = readl(&reg->outbound_msgaddr1); 1334 + } while (!(firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK)); 1335 + intmask_org = readl(&reg->outbound_intmask) 1336 + | ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE; 1337 + arcmsr_get_firmware_spec(acb); 1338 + 1339 + acb->acb_flags |= ACB_F_MSG_START_BGRB; 1340 + writel(ARCMSR_INBOUND_MESG0_START_BGRB, &reg->inbound_msgaddr0); 1341 + if (arcmsr_wait_msgint_ready(acb)) { 1342 + printk(KERN_NOTICE "arcmsr%d: " 1343 + "wait 'start adapter background rebulid' timeout\n", 1344 + acb->host->host_no); 1345 + } 1346 + 1347 + outbound_doorbell = readl(&reg->outbound_doorbell); 1348 + writel(outbound_doorbell, &reg->outbound_doorbell); 1349 + writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, &reg->inbound_doorbell); 1350 + mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE 1351 + | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); 1352 + writel(intmask_org & mask, &reg->outbound_intmask); 1353 + acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff; 1354 + acb->acb_flags |= ACB_F_IOP_INITED; 1355 + } 1356 + 1357 + static void arcmsr_iop_reset(struct AdapterControlBlock *acb) 1358 + { 1359 + struct MessageUnit __iomem *reg = acb->pmu; 1360 + struct CommandControlBlock *ccb; 1361 + uint32_t intmask_org; 1362 + int i = 0; 1363 + 1364 + if (atomic_read(&acb->ccboutstandingcount) != 0) { 1365 + /* talk to iop 331 outstanding command aborted */ 1366 + arcmsr_abort_allcmd(acb); 1367 + /* wait for 3 sec for all command aborted*/ 1368 + msleep_interruptible(3000); 1369 + /* disable all outbound interrupt */ 1370 + intmask_org = arcmsr_disable_outbound_ints(acb); 1371 + /* clear all outbound posted Q */ 1372 + for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) 1373 + readl(&reg->outbound_queueport); 1374 + for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { 1375 + ccb = acb->pccb_pool[i]; 1376 + if ((ccb->startdone == ARCMSR_CCB_START) || 1377 + (ccb->startdone == ARCMSR_CCB_ABORTED)) { 1378 + ccb->startdone = ARCMSR_CCB_ABORTED; 1379 + ccb->pcmd->result = DID_ABORT << 16; 1380 + arcmsr_ccb_complete(ccb, 1); 1381 + } 1382 + } 1383 + /* enable all outbound interrupt */ 1384 + arcmsr_enable_outbound_ints(acb, intmask_org); 1385 + } 1386 + atomic_set(&acb->ccboutstandingcount, 0); 1387 + } 1388 + 1389 + static int arcmsr_bus_reset(struct scsi_cmnd *cmd) 1390 + { 1391 + struct AdapterControlBlock *acb = 1392 + (struct AdapterControlBlock *)cmd->device->host->hostdata; 1393 + int i; 1394 + 1395 + acb->num_resets++; 1396 + acb->acb_flags |= ACB_F_BUS_RESET; 1397 + for (i = 0; i < 400; i++) { 1398 + if (!atomic_read(&acb->ccboutstandingcount)) 1399 + break; 1400 + arcmsr_interrupt(acb); 1401 + msleep(25); 1402 + } 1403 + arcmsr_iop_reset(acb); 1404 + acb->acb_flags &= ~ACB_F_BUS_RESET; 1405 + return SUCCESS; 1406 + } 1407 + 1408 + static void arcmsr_abort_one_cmd(struct AdapterControlBlock *acb, 1409 + struct CommandControlBlock *ccb) 1410 + { 1411 + u32 intmask; 1412 + 1413 + ccb->startdone = ARCMSR_CCB_ABORTED; 1414 + 1415 + /* 1416 + ** Wait for 3 sec for all command done. 1417 + */ 1418 + msleep_interruptible(3000); 1419 + 1420 + intmask = arcmsr_disable_outbound_ints(acb); 1421 + arcmsr_polling_ccbdone(acb, ccb); 1422 + arcmsr_enable_outbound_ints(acb, intmask); 1423 + } 1424 + 1425 + static int arcmsr_abort(struct scsi_cmnd *cmd) 1426 + { 1427 + struct AdapterControlBlock *acb = 1428 + (struct AdapterControlBlock *)cmd->device->host->hostdata; 1429 + int i = 0; 1430 + 1431 + printk(KERN_NOTICE 1432 + "arcmsr%d: abort device command of scsi id=%d lun=%d \n", 1433 + acb->host->host_no, cmd->device->id, cmd->device->lun); 1434 + acb->num_aborts++; 1435 + 1436 + /* 1437 + ************************************************ 1438 + ** the all interrupt service routine is locked 1439 + ** we need to handle it as soon as possible and exit 1440 + ************************************************ 1441 + */ 1442 + if (!atomic_read(&acb->ccboutstandingcount)) 1443 + return SUCCESS; 1444 + 1445 + for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { 1446 + struct CommandControlBlock *ccb = acb->pccb_pool[i]; 1447 + if (ccb->startdone == ARCMSR_CCB_START && ccb->pcmd == cmd) { 1448 + arcmsr_abort_one_cmd(acb, ccb); 1449 + break; 1450 + } 1451 + } 1452 + 1453 + return SUCCESS; 1454 + } 1455 + 1456 + static const char *arcmsr_info(struct Scsi_Host *host) 1457 + { 1458 + struct AdapterControlBlock *acb = 1459 + (struct AdapterControlBlock *) host->hostdata; 1460 + static char buf[256]; 1461 + char *type; 1462 + int raid6 = 1; 1463 + 1464 + switch (acb->pdev->device) { 1465 + case PCI_DEVICE_ID_ARECA_1110: 1466 + case PCI_DEVICE_ID_ARECA_1210: 1467 + raid6 = 0; 1468 + /*FALLTHRU*/ 1469 + case PCI_DEVICE_ID_ARECA_1120: 1470 + case PCI_DEVICE_ID_ARECA_1130: 1471 + case PCI_DEVICE_ID_ARECA_1160: 1472 + case PCI_DEVICE_ID_ARECA_1170: 1473 + case PCI_DEVICE_ID_ARECA_1220: 1474 + case PCI_DEVICE_ID_ARECA_1230: 1475 + case PCI_DEVICE_ID_ARECA_1260: 1476 + case PCI_DEVICE_ID_ARECA_1270: 1477 + case PCI_DEVICE_ID_ARECA_1280: 1478 + type = "SATA"; 1479 + break; 1480 + case PCI_DEVICE_ID_ARECA_1380: 1481 + case PCI_DEVICE_ID_ARECA_1381: 1482 + case PCI_DEVICE_ID_ARECA_1680: 1483 + case PCI_DEVICE_ID_ARECA_1681: 1484 + type = "SAS"; 1485 + break; 1486 + default: 1487 + type = "X-TYPE"; 1488 + break; 1489 + } 1490 + sprintf(buf, "Areca %s Host Adapter RAID Controller%s\n %s", 1491 + type, raid6 ? "( RAID6 capable)" : "", 1492 + ARCMSR_DRIVER_VERSION); 1493 + return buf; 1494 + } 1495 + 1496 +
+17
include/linux/pci_ids.h
··· 2004 2004 #define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea 2005 2005 #define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb 2006 2006 2007 + #define PCI_VENDOR_ID_ARECA 0x17d3 2008 + #define PCI_DEVICE_ID_ARECA_1110 0x1110 2009 + #define PCI_DEVICE_ID_ARECA_1120 0x1120 2010 + #define PCI_DEVICE_ID_ARECA_1130 0x1130 2011 + #define PCI_DEVICE_ID_ARECA_1160 0x1160 2012 + #define PCI_DEVICE_ID_ARECA_1170 0x1170 2013 + #define PCI_DEVICE_ID_ARECA_1210 0x1210 2014 + #define PCI_DEVICE_ID_ARECA_1220 0x1220 2015 + #define PCI_DEVICE_ID_ARECA_1230 0x1230 2016 + #define PCI_DEVICE_ID_ARECA_1260 0x1260 2017 + #define PCI_DEVICE_ID_ARECA_1270 0x1270 2018 + #define PCI_DEVICE_ID_ARECA_1280 0x1280 2019 + #define PCI_DEVICE_ID_ARECA_1380 0x1380 2020 + #define PCI_DEVICE_ID_ARECA_1381 0x1381 2021 + #define PCI_DEVICE_ID_ARECA_1680 0x1680 2022 + #define PCI_DEVICE_ID_ARECA_1681 0x1681 2023 + 2007 2024 #define PCI_VENDOR_ID_S2IO 0x17d5 2008 2025 #define PCI_DEVICE_ID_S2IO_WIN 0x5731 2009 2026 #define PCI_DEVICE_ID_S2IO_UNI 0x5831