Code/Resource
Windows Develop
Linux-Unix program
Internet-Socket-Network
Web Server
Browser Client
Ftp Server
Ftp Client
Browser Plugins
Proxy Server
Email Server
Email Client
WEB Mail
Firewall-Security
Telnet Server
Telnet Client
ICQ-IM-Chat
Search Engine
Sniffer Package capture
Remote Control
xml-soap-webservice
P2P
WEB(ASP,PHP,...)
TCP/IP Stack
SNMP
Grid Computing
SilverLight
DNS
Cluster Service
Network Security
Communication-Mobile
Game Program
Editor
Multimedia program
Graph program
Compiler program
Compress-Decompress algrithms
Crypt_Decrypt algrithms
Mathimatics-Numerical algorithms
MultiLanguage
Disk/Storage
Java Develop
assembly language
Applications
Other systems
Database system
Embeded-SCM Develop
FlashMX/Flex
source in ebook
Delphi VCL
OS Develop
MiddleWare
MPI
MacOS develop
LabView
ELanguage
Software/Tools
E-Books
Artical/Document
ips.c
Package: linux-2.4.20.tar.gz [view]
Upload User: jlfgdled
Upload Date: 2013-04-10
Package Size: 33168k
Code Size: 274k
Category:
Linux-Unix program
Development Platform:
Unix_Linux
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_free_scb */
- /* */
- /* Routine Description: */
- /* */
- /* Return an unused CCB back to the free list */
- /* */
- /* ASSUMED to be called from within a lock */
- /* */
- /****************************************************************************/
- static void
- ips_freescb(ips_ha_t *ha, ips_scb_t *scb) {
- unsigned long cpu_flags;
- METHOD_TRACE("ips_freescb", 1);
- if(scb->flags & IPS_SCB_MAP_SG)
- pci_unmap_sg(ha->pcidev,scb->scsi_cmd->request_buffer, scb->scsi_cmd->use_sg, PCI_DMA_BIDIRECTIONAL);
- else if(scb->flags & IPS_SCB_MAP_SINGLE)
- pci_unmap_single(ha->pcidev,scb->cmd.basic_io.sg_addr, scb->data_len, PCI_DMA_BIDIRECTIONAL);
- /* check to make sure this is not our "special" scb */
- if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
- IPS_SCB_LOCK(cpu_flags);
- scb->q_next = ha->scb_freelist;
- ha->scb_freelist = scb;
- IPS_SCB_UNLOCK(cpu_flags);
- }
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_isinit_copperhead */
- /* */
- /* Routine Description: */
- /* */
- /* Is controller initialized ? */
- /* */
- /****************************************************************************/
- static int
- ips_isinit_copperhead(ips_ha_t *ha) {
- uint8_t scpr;
- uint8_t isr;
- METHOD_TRACE("ips_isinit_copperhead", 1);
- isr = inb(ha->io_addr + IPS_REG_HISR);
- scpr = inb(ha->io_addr + IPS_REG_SCPR);
- if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
- return (0);
- else
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_isinit_copperhead_memio */
- /* */
- /* Routine Description: */
- /* */
- /* Is controller initialized ? */
- /* */
- /****************************************************************************/
- static int
- ips_isinit_copperhead_memio(ips_ha_t *ha) {
- uint8_t isr=0;
- uint8_t scpr;
- METHOD_TRACE("ips_is_init_copperhead_memio", 1);
- isr = readb(ha->mem_ptr + IPS_REG_HISR);
- scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
- if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
- return (0);
- else
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_isinit_morpheus */
- /* */
- /* Routine Description: */
- /* */
- /* Is controller initialized ? */
- /* */
- /****************************************************************************/
- static int
- ips_isinit_morpheus(ips_ha_t *ha) {
- uint32_t post;
- uint32_t bits;
- METHOD_TRACE("ips_is_init_morpheus", 1);
- post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
- bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
- if (post == 0)
- return (0);
- else if (bits & 0x3)
- return (0);
- else
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_enable_int_copperhead */
- /* */
- /* Routine Description: */
- /* Turn on interrupts */
- /* */
- /****************************************************************************/
- static void
- ips_enable_int_copperhead(ips_ha_t *ha) {
- METHOD_TRACE("ips_enable_int_copperhead", 1);
- outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_enable_int_copperhead_memio */
- /* */
- /* Routine Description: */
- /* Turn on interrupts */
- /* */
- /****************************************************************************/
- static void
- ips_enable_int_copperhead_memio(ips_ha_t *ha) {
- METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
- writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_enable_int_morpheus */
- /* */
- /* Routine Description: */
- /* Turn on interrupts */
- /* */
- /****************************************************************************/
- static void
- ips_enable_int_morpheus(ips_ha_t *ha) {
- uint32_t Oimr;
- METHOD_TRACE("ips_enable_int_morpheus", 1);
- Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
- Oimr &= ~0x08;
- writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_init_copperhead */
- /* */
- /* Routine Description: */
- /* */
- /* Initialize a copperhead controller */
- /* */
- /****************************************************************************/
- static int
- ips_init_copperhead(ips_ha_t *ha) {
- uint8_t Isr;
- uint8_t Cbsp;
- uint8_t PostByte[IPS_MAX_POST_BYTES];
- uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
- int i, j;
- METHOD_TRACE("ips_init_copperhead", 1);
- for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
- for (j = 0; j < 45; j++) {
- Isr = inb(ha->io_addr + IPS_REG_HISR);
- if (Isr & IPS_BIT_GHI)
- break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
- if (j >= 45)
- /* error occurred */
- return (0);
- PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
- outb(Isr, ha->io_addr + IPS_REG_HISR);
- }
- if (PostByte[0] < IPS_GOOD_POST_STATUS) {
- printk(KERN_WARNING "(%s%d) reset controller fails (post status %x %x).n",
- ips_name, ha->host_num, PostByte[0], PostByte[1]);
- return (0);
- }
- for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
- for (j = 0; j < 240; j++) {
- Isr = inb(ha->io_addr + IPS_REG_HISR);
- if (Isr & IPS_BIT_GHI)
- break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
- if (j >= 240)
- /* error occurred */
- return (0);
- ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
- outb(Isr, ha->io_addr + IPS_REG_HISR);
- }
- for (i = 0; i < 240; i++) {
- Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
- if ((Cbsp & IPS_BIT_OP) == 0)
- break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
- if (i >= 240)
- /* reset failed */
- return (0);
- /* setup CCCR */
- outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR);
- /* Enable busmastering */
- outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- /* fix for anaconda64 */
- outl(0, ha->io_addr + IPS_REG_NDAE);
- /* Enable interrupts */
- outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_init_copperhead_memio */
- /* */
- /* Routine Description: */
- /* */
- /* Initialize a copperhead controller with memory mapped I/O */
- /* */
- /****************************************************************************/
- static int
- ips_init_copperhead_memio(ips_ha_t *ha) {
- uint8_t Isr=0;
- uint8_t Cbsp;
- uint8_t PostByte[IPS_MAX_POST_BYTES];
- uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
- int i, j;
- METHOD_TRACE("ips_init_copperhead_memio", 1);
- for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
- for (j = 0; j < 45; j++) {
- Isr = readb(ha->mem_ptr + IPS_REG_HISR);
- if (Isr & IPS_BIT_GHI)
- break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
- if (j >= 45)
- /* error occurred */
- return (0);
- PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
- writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
- }
- if (PostByte[0] < IPS_GOOD_POST_STATUS) {
- printk(KERN_WARNING "(%s%d) reset controller fails (post status %x %x).n",
- ips_name, ha->host_num, PostByte[0], PostByte[1]);
- return (0);
- }
- for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
- for (j = 0; j < 240; j++) {
- Isr = readb(ha->mem_ptr + IPS_REG_HISR);
- if (Isr & IPS_BIT_GHI)
- break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
- if (j >= 240)
- /* error occurred */
- return (0);
- ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
- writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
- }
- for (i = 0; i < 240; i++) {
- Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
- if ((Cbsp & IPS_BIT_OP) == 0)
- break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
- if (i >= 240)
- /* error occurred */
- return (0);
- /* setup CCCR */
- writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
- /* Enable busmastering */
- writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- /* fix for anaconda64 */
- writel(0, ha->mem_ptr + IPS_REG_NDAE);
- /* Enable interrupts */
- writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
- /* if we get here then everything went OK */
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_init_morpheus */
- /* */
- /* Routine Description: */
- /* */
- /* Initialize a morpheus controller */
- /* */
- /****************************************************************************/
- static int
- ips_init_morpheus(ips_ha_t *ha) {
- uint32_t Post;
- uint32_t Config;
- uint32_t Isr;
- uint32_t Oimr;
- int i;
- METHOD_TRACE("ips_init_morpheus", 1);
- /* Wait up to 45 secs for Post */
- for (i = 0; i < 45; i++) {
- Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
- if (Isr & IPS_BIT_I960_MSG0I)
- break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
- if (i >= 45) {
- /* error occurred */
- printk(KERN_WARNING "(%s%d) timeout waiting for post.n",
- ips_name, ha->host_num);
- return (0);
- }
- Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
- /* Clear the interrupt bit */
- Isr = (uint32_t) IPS_BIT_I960_MSG0I;
- writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
- if (Post < (IPS_GOOD_POST_STATUS << 8)) {
- printk(KERN_WARNING "(%s%d) reset controller fails (post status %x).n",
- ips_name, ha->host_num, Post);
- return (0);
- }
- /* Wait up to 240 secs for config bytes */
- for (i = 0; i < 240; i++) {
- Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
- if (Isr & IPS_BIT_I960_MSG1I)
- break;
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- }
- if (i >= 240) {
- /* error occurred */
- printk(KERN_WARNING "(%s%d) timeout waiting for config.n",
- ips_name, ha->host_num);
- return (0);
- }
- Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
- /* Clear interrupt bit */
- Isr = (uint32_t) IPS_BIT_I960_MSG1I;
- writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
- /* Turn on the interrupts */
- Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
- Oimr &= ~0x8;
- writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
- /* if we get here then everything went OK */
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_reset_copperhead */
- /* */
- /* Routine Description: */
- /* */
- /* Reset the controller */
- /* */
- /****************************************************************************/
- static int
- ips_reset_copperhead(ips_ha_t *ha) {
- int reset_counter;
- unsigned long cpu_flags;
- METHOD_TRACE("ips_reset_copperhead", 1);
- DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
- ips_name, ha->host_num, ha->io_addr, ha->irq);
- IPS_HA_LOCK(cpu_flags);
- reset_counter = 0;
- while (reset_counter < 2) {
- reset_counter++;
- outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- outb(0, ha->io_addr + IPS_REG_SCPR);
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- if ((*ha->func.init)(ha))
- break;
- else if (reset_counter >= 2) {
- IPS_HA_UNLOCK(cpu_flags);
- return (0);
- }
- }
- IPS_HA_UNLOCK(cpu_flags);
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_reset_copperhead_memio */
- /* */
- /* Routine Description: */
- /* */
- /* Reset the controller */
- /* */
- /****************************************************************************/
- static int
- ips_reset_copperhead_memio(ips_ha_t *ha) {
- int reset_counter;
- unsigned long cpu_flags;
- METHOD_TRACE("ips_reset_copperhead_memio", 1);
- DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
- ips_name, ha->host_num, ha->mem_addr, ha->irq);
- IPS_HA_LOCK(cpu_flags);
- reset_counter = 0;
- while (reset_counter < 2) {
- reset_counter++;
- writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- writeb(0, ha->mem_ptr + IPS_REG_SCPR);
- /* Delay for 1 Second */
- MDELAY(IPS_ONE_SEC);
- if ((*ha->func.init)(ha))
- break;
- else if (reset_counter >= 2) {
- IPS_HA_UNLOCK(cpu_flags);
- return (0);
- }
- }
- IPS_HA_UNLOCK(cpu_flags);
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_reset_morpheus */
- /* */
- /* Routine Description: */
- /* */
- /* Reset the controller */
- /* */
- /****************************************************************************/
- static int
- ips_reset_morpheus(ips_ha_t *ha) {
- int reset_counter;
- uint8_t junk;
- unsigned long cpu_flags;
- METHOD_TRACE("ips_reset_morpheus", 1);
- DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
- ips_name, ha->host_num, ha->mem_addr, ha->irq);
- IPS_HA_LOCK(cpu_flags);
- reset_counter = 0;
- while (reset_counter < 2) {
- reset_counter++;
- writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
- /* Delay for 5 Seconds */
- MDELAY(5 * IPS_ONE_SEC);
- /* Do a PCI config read to wait for adapter */
- pci_read_config_byte(ha->pcidev, 4, &junk);
- if ((*ha->func.init)(ha))
- break;
- else if (reset_counter >= 2) {
- IPS_HA_UNLOCK(cpu_flags);
- return (0);
- }
- }
- IPS_HA_UNLOCK(cpu_flags);
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_statinit */
- /* */
- /* Routine Description: */
- /* */
- /* Initialize the status queues on the controller */
- /* */
- /****************************************************************************/
- static void
- ips_statinit(ips_ha_t *ha) {
- uint32_t phys_status_start;
- METHOD_TRACE("ips_statinit", 1);
- ha->adapt->p_status_start = ha->adapt->status;
- ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
- ha->adapt->p_status_tail = ha->adapt->status;
- phys_status_start = VIRT_TO_BUS(ha->adapt->status);
- outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR);
- outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->io_addr + IPS_REG_SQER);
- outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->io_addr + IPS_REG_SQHR);
- outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR);
- ha->adapt->hw_status_start = phys_status_start;
- ha->adapt->hw_status_tail = phys_status_start;
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_statinit_memio */
- /* */
- /* Routine Description: */
- /* */
- /* Initialize the status queues on the controller */
- /* */
- /****************************************************************************/
- static void
- ips_statinit_memio(ips_ha_t *ha) {
- uint32_t phys_status_start;
- METHOD_TRACE("ips_statinit_memio", 1);
- ha->adapt->p_status_start = ha->adapt->status;
- ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
- ha->adapt->p_status_tail = ha->adapt->status;
- phys_status_start = VIRT_TO_BUS(ha->adapt->status);
- writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
- writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER);
- writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
- writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
- ha->adapt->hw_status_start = phys_status_start;
- ha->adapt->hw_status_tail = phys_status_start;
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_statupd_copperhead */
- /* */
- /* Routine Description: */
- /* */
- /* Remove an element from the status queue */
- /* */
- /****************************************************************************/
- static uint32_t
- ips_statupd_copperhead(ips_ha_t *ha) {
- METHOD_TRACE("ips_statupd_copperhead", 1);
- if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
- ha->adapt->p_status_tail++;
- ha->adapt->hw_status_tail += sizeof(IPS_STATUS);
- } else {
- ha->adapt->p_status_tail = ha->adapt->p_status_start;
- ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
- }
- outl(cpu_to_le32(ha->adapt->hw_status_tail), ha->io_addr + IPS_REG_SQTR);
- return (ha->adapt->p_status_tail->value);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_statupd_copperhead_memio */
- /* */
- /* Routine Description: */
- /* */
- /* Remove an element from the status queue */
- /* */
- /****************************************************************************/
- static uint32_t
- ips_statupd_copperhead_memio(ips_ha_t *ha) {
- METHOD_TRACE("ips_statupd_copperhead_memio", 1);
- if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
- ha->adapt->p_status_tail++;
- ha->adapt->hw_status_tail += sizeof(IPS_STATUS);
- } else {
- ha->adapt->p_status_tail = ha->adapt->p_status_start;
- ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
- }
- writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
- return (ha->adapt->p_status_tail->value);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_statupd_morpheus */
- /* */
- /* Routine Description: */
- /* */
- /* Remove an element from the status queue */
- /* */
- /****************************************************************************/
- static uint32_t
- ips_statupd_morpheus(ips_ha_t *ha) {
- uint32_t val;
- METHOD_TRACE("ips_statupd_morpheus", 1);
- val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
- return (val);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_issue_copperhead */
- /* */
- /* Routine Description: */
- /* */
- /* Send a command down to the controller */
- /* */
- /****************************************************************************/
- static int
- ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
- uint32_t TimeOut;
- uint32_t val;
- unsigned long cpu_flags;
- METHOD_TRACE("ips_issue_copperhead", 1);
- if (scb->scsi_cmd) {
- DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
- ips_name,
- ha->host_num,
- scb->cdb[0],
- scb->cmd.basic_io.command_id,
- scb->bus,
- scb->target_id,
- scb->lun);
- } else {
- DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d",
- ips_name,
- ha->host_num,
- scb->cmd.basic_io.command_id);
- }
- IPS_HA_LOCK(cpu_flags);
- TimeOut = 0;
- while ((val = le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
- udelay(1000);
- if (++TimeOut >= IPS_SEM_TIMEOUT) {
- if (!(val & IPS_BIT_START_STOP))
- break;
- printk(KERN_WARNING "(%s%d) ips_issue val [0x%x].n",
- ips_name, ha->host_num, val);
- printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.n",
- ips_name, ha->host_num);
- IPS_HA_UNLOCK(cpu_flags);
- return (IPS_FAILURE);
- } /* end if */
- } /* end while */
- outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR);
- outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR);
- IPS_HA_UNLOCK(cpu_flags);
- return (IPS_SUCCESS);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_issue_copperhead_memio */
- /* */
- /* Routine Description: */
- /* */
- /* Send a command down to the controller */
- /* */
- /****************************************************************************/
- static int
- ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
- uint32_t TimeOut;
- uint32_t val;
- unsigned long cpu_flags;
- METHOD_TRACE("ips_issue_copperhead_memio", 1);
- if (scb->scsi_cmd) {
- DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
- ips_name,
- ha->host_num,
- scb->cdb[0],
- scb->cmd.basic_io.command_id,
- scb->bus,
- scb->target_id,
- scb->lun);
- } else {
- DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
- ips_name,
- ha->host_num,
- scb->cmd.basic_io.command_id);
- }
- IPS_HA_LOCK(cpu_flags);
- TimeOut = 0;
- while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
- udelay(1000);
- if (++TimeOut >= IPS_SEM_TIMEOUT) {
- if (!(val & IPS_BIT_START_STOP))
- break;
- printk(KERN_WARNING "(%s%d) ips_issue val [0x%x].n",
- ips_name, ha->host_num, val);
- printk(KERN_WARNING "(%s%d) ips_issue semaphore chk timeout.n",
- ips_name, ha->host_num);
- IPS_HA_UNLOCK(cpu_flags);
- return (IPS_FAILURE);
- } /* end if */
- } /* end while */
- writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
- writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
- IPS_HA_UNLOCK(cpu_flags);
- return (IPS_SUCCESS);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_issue_i2o */
- /* */
- /* Routine Description: */
- /* */
- /* Send a command down to the controller */
- /* */
- /****************************************************************************/
- static int
- ips_issue_i2o(ips_ha_t *ha, ips_scb_t *scb) {
- unsigned long cpu_flags;
- METHOD_TRACE("ips_issue_i2o", 1);
- if (scb->scsi_cmd) {
- DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
- ips_name,
- ha->host_num,
- scb->cdb[0],
- scb->cmd.basic_io.command_id,
- scb->bus,
- scb->target_id,
- scb->lun);
- } else {
- DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
- ips_name,
- ha->host_num,
- scb->cmd.basic_io.command_id);
- }
- IPS_HA_LOCK(cpu_flags);
- outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ);
- IPS_HA_UNLOCK(cpu_flags);
- return (IPS_SUCCESS);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_issue_i2o_memio */
- /* */
- /* Routine Description: */
- /* */
- /* Send a command down to the controller */
- /* */
- /****************************************************************************/
- static int
- ips_issue_i2o_memio(ips_ha_t *ha, ips_scb_t *scb) {
- unsigned long cpu_flags;
- METHOD_TRACE("ips_issue_i2o_memio", 1);
- if (scb->scsi_cmd) {
- DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
- ips_name,
- ha->host_num,
- scb->cdb[0],
- scb->cmd.basic_io.command_id,
- scb->bus,
- scb->target_id,
- scb->lun);
- } else {
- DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
- ips_name,
- ha->host_num,
- scb->cmd.basic_io.command_id);
- }
- IPS_HA_LOCK(cpu_flags);
- writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
- IPS_HA_UNLOCK(cpu_flags);
- return (IPS_SUCCESS);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_isintr_copperhead */
- /* */
- /* Routine Description: */
- /* */
- /* Test to see if an interrupt is for us */
- /* */
- /****************************************************************************/
- static int
- ips_isintr_copperhead(ips_ha_t *ha) {
- uint8_t Isr;
- METHOD_TRACE("ips_isintr_copperhead", 2);
- Isr = inb(ha->io_addr + IPS_REG_HISR);
- if (Isr == 0xFF)
- /* ?!?! Nothing really there */
- return (0);
- if (Isr & IPS_BIT_SCE)
- return (1);
- else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
- /* status queue overflow or GHI */
- /* just clear the interrupt */
- outb(Isr, ha->io_addr + IPS_REG_HISR);
- }
- return (0);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_isintr_copperhead_memio */
- /* */
- /* Routine Description: */
- /* */
- /* Test to see if an interrupt is for us */
- /* */
- /****************************************************************************/
- static int
- ips_isintr_copperhead_memio(ips_ha_t *ha) {
- uint8_t Isr;
- METHOD_TRACE("ips_isintr_memio", 2);
- Isr = readb(ha->mem_ptr + IPS_REG_HISR);
- if (Isr == 0xFF)
- /* ?!?! Nothing really there */
- return (0);
- if (Isr & IPS_BIT_SCE)
- return (1);
- else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
- /* status queue overflow or GHI */
- /* just clear the interrupt */
- writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
- }
- return (0);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_isintr_morpheus */
- /* */
- /* Routine Description: */
- /* */
- /* Test to see if an interrupt is for us */
- /* */
- /****************************************************************************/
- static int
- ips_isintr_morpheus(ips_ha_t *ha) {
- uint32_t Isr;
- METHOD_TRACE("ips_isintr_morpheus", 2);
- Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
- if (Isr & IPS_BIT_I2O_OPQI)
- return (1);
- else
- return (0);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_wait */
- /* */
- /* Routine Description: */
- /* */
- /* Wait for a command to complete */
- /* */
- /****************************************************************************/
- static int
- ips_wait(ips_ha_t *ha, int time, int intr) {
- int ret;
- int done;
- METHOD_TRACE("ips_wait", 1);
- ret = IPS_FAILURE;
- done = FALSE;
- time *= IPS_ONE_SEC; /* convert seconds */
- while ((time > 0) && (!done)) {
- if (intr == IPS_INTR_ON) {
- if (ha->waitflag == FALSE) {
- ret = IPS_SUCCESS;
- done = TRUE;
- break;
- }
- } else if (intr == IPS_INTR_IORL) {
- if (ha->waitflag == FALSE) {
- /*
- * controller generated an interrupt to
- * acknowledge completion of the command
- * and ips_intr() has serviced the interrupt.
- */
- ret = IPS_SUCCESS;
- done = TRUE;
- break;
- }
- /*
- * NOTE: we already have the io_request_lock so
- * even if we get an interrupt it won't get serviced
- * until after we finish.
- */
- while (test_and_set_bit(IPS_IN_INTR, &ha->flags))
- udelay(1000);
- (*ha->func.intr)(ha);
- clear_bit(IPS_IN_INTR, &ha->flags);
- }
- /* This looks like a very evil loop, but it only does this during start-up */
- udelay(1000);
- time--;
- }
- return (ret);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_write_driver_status */
- /* */
- /* Routine Description: */
- /* */
- /* Write OS/Driver version to Page 5 of the nvram on the controller */
- /* */
- /****************************************************************************/
- static int
- ips_write_driver_status(ips_ha_t *ha, int intr) {
- METHOD_TRACE("ips_write_driver_status", 1);
- if (!ips_readwrite_page5(ha, FALSE, intr)) {
- printk(KERN_WARNING "(%s%d) unable to read NVRAM page 5.n",
- ips_name, ha->host_num);
- return (0);
- }
- /* check to make sure the page has a valid */
- /* signature */
- if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) {
- DEBUG_VAR(1, "(%s%d) NVRAM page 5 has an invalid signature: %X.",
- ips_name, ha->host_num, ha->nvram->signature);
- return (1);
- }
- DEBUG_VAR(2, "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
- ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type),
- ha->nvram->adapter_slot,
- ha->nvram->bios_high[0], ha->nvram->bios_high[1],
- ha->nvram->bios_high[2], ha->nvram->bios_high[3],
- ha->nvram->bios_low[0], ha->nvram->bios_low[1],
- ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
- ips_get_bios_version(ha, intr);
- /* change values (as needed) */
- ha->nvram->operating_system = IPS_OS_LINUX;
- ha->nvram->adapter_type = ha->ad_type;
- strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4);
- strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4);
- strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4);
- strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4);
- ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */
- /* now update the page */
- if (!ips_readwrite_page5(ha, TRUE, intr)) {
- printk(KERN_WARNING "(%s%d) unable to write NVRAM page 5.n",
- ips_name, ha->host_num);
- return (0);
- }
- /* IF NVRAM Page 5 is OK, Use it for Slot Number Info Because Linux Doesn't Do Slots */
- ha->slot_num = ha->nvram->adapter_slot;
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_read_adapter_status */
- /* */
- /* Routine Description: */
- /* */
- /* Do an Inquiry command to the adapter */
- /* */
- /****************************************************************************/
- static int
- ips_read_adapter_status(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- int ret;
- METHOD_TRACE("ips_read_adapter_status", 1);
- scb = &ha->scbs[ha->max_cmds-1];
- ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_ENQUIRY;
- scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.basic_io.sg_count = 0;
- scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->enq));
- scb->cmd.basic_io.lba = 0;
- scb->cmd.basic_io.sector_count = 0;
- scb->cmd.basic_io.log_drv = 0;
- scb->cmd.basic_io.reserved = 0;
- /* send command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
- return (0);
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_read_subsystem_parameters */
- /* */
- /* Routine Description: */
- /* */
- /* Read subsystem parameters from the adapter */
- /* */
- /****************************************************************************/
- static int
- ips_read_subsystem_parameters(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- int ret;
- METHOD_TRACE("ips_read_subsystem_parameters", 1);
- scb = &ha->scbs[ha->max_cmds-1];
- ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_GET_SUBSYS;
- scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.basic_io.sg_count = 0;
- scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->subsys));
- scb->cmd.basic_io.lba = 0;
- scb->cmd.basic_io.sector_count = 0;
- scb->cmd.basic_io.log_drv = 0;
- scb->cmd.basic_io.reserved = 0;
- /* send command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
- return (0);
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_read_config */
- /* */
- /* Routine Description: */
- /* */
- /* Read the configuration on the adapter */
- /* */
- /****************************************************************************/
- static int
- ips_read_config(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- int i;
- int ret;
- METHOD_TRACE("ips_read_config", 1);
- /* set defaults for initiator IDs */
- for (i = 0; i < 4; i++)
- ha->conf->init_id[i] = 7;
- scb = &ha->scbs[ha->max_cmds-1];
- ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_READ_CONF;
- scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF;
- scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->conf));
- /* send command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
- memset(ha->conf, 0, sizeof(IPS_CONF));
- /* reset initiator IDs */
- for (i = 0; i < 4; i++)
- ha->conf->init_id[i] = 7;
- /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */
- if ((scb->basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_CMPLT_WERROR)
- return (1);
- return (0);
- }
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_readwrite_page5 */
- /* */
- /* Routine Description: */
- /* */
- /* Read nvram page 5 from the adapter */
- /* */
- /****************************************************************************/
- static int
- ips_readwrite_page5(ips_ha_t *ha, int write, int intr) {
- ips_scb_t *scb;
- int ret;
- METHOD_TRACE("ips_readwrite_page5", 1);
- scb = &ha->scbs[ha->max_cmds-1];
- ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE;
- scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE;
- scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.nvram.page = 5;
- scb->cmd.nvram.write = write;
- scb->cmd.nvram.buffer_addr = cpu_to_le32(VIRT_TO_BUS(ha->nvram));
- scb->cmd.nvram.reserved = 0;
- scb->cmd.nvram.reserved2 = 0;
- /* issue the command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
- memset(ha->nvram, 0, sizeof(IPS_NVRAM_P5));
- return (0);
- }
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_clear_adapter */
- /* */
- /* Routine Description: */
- /* */
- /* Clear the stripe lock tables */
- /* */
- /****************************************************************************/
- static int
- ips_clear_adapter(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- int ret;
- METHOD_TRACE("ips_clear_adapter", 1);
- scb = &ha->scbs[ha->max_cmds-1];
- ips_init_scb(ha, scb);
- scb->timeout = ips_reset_timeout;
- scb->cdb[0] = IPS_CMD_CONFIG_SYNC;
- scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC;
- scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.config_sync.channel = 0;
- scb->cmd.config_sync.source_target = IPS_POCL;
- scb->cmd.config_sync.reserved = 0;
- scb->cmd.config_sync.reserved2 = 0;
- scb->cmd.config_sync.reserved3 = 0;
- /* issue command */
- if (((ret = ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
- return (0);
- /* send unlock stripe command */
- ips_init_scb(ha, scb);
- scb->cdb[0] = IPS_CMD_ERROR_TABLE;
- scb->timeout = ips_reset_timeout;
- scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE;
- scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.unlock_stripe.log_drv = 0;
- scb->cmd.unlock_stripe.control = IPS_CSL;
- scb->cmd.unlock_stripe.reserved = 0;
- scb->cmd.unlock_stripe.reserved2 = 0;
- scb->cmd.unlock_stripe.reserved3 = 0;
- /* issue command */
- if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
- (ret == IPS_SUCCESS_IMM) ||
- ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
- return (0);
- return (1);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_ffdc_reset */
- /* */
- /* Routine Description: */
- /* */
- /* FFDC: write reset info */
- /* */
- /****************************************************************************/
- static void
- ips_ffdc_reset(ips_ha_t *ha, int intr) {
- ips_scb_t *scb;
- METHOD_TRACE("ips_ffdc_reset", 1);
- scb = &ha->scbs[ha->max_cmds-1];
- ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_FFDC;
- scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
- scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.ffdc.reset_count = ha->reset_count;
- scb->cmd.ffdc.reset_type = 0x80;
- /* convert time to what the card wants */
- ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
- /* issue command */
- ips_send_wait(ha, scb, ips_cmd_timeout, intr);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_ffdc_time */
- /* */
- /* Routine Description: */
- /* */
- /* FFDC: write time info */
- /* */
- /****************************************************************************/
- static void
- ips_ffdc_time(ips_ha_t *ha) {
- ips_scb_t *scb;
- METHOD_TRACE("ips_ffdc_time", 1);
- DEBUG_VAR(1, "(%s%d) Sending time update.",
- ips_name, ha->host_num);
- scb = &ha->scbs[ha->max_cmds-1];
- ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_FFDC;
- scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
- scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.ffdc.reset_count = 0;
- scb->cmd.ffdc.reset_type = 0x80;
- /* convert time to what the card wants */
- ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
- /* issue command */
- ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_fix_ffdc_time */
- /* */
- /* Routine Description: */
- /* Adjust time_t to what the card wants */
- /* */
- /****************************************************************************/
- static void
- ips_fix_ffdc_time(ips_ha_t *ha, ips_scb_t *scb, time_t current_time) {
- long days;
- long rem;
- int i;
- int year;
- int yleap;
- int year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR };
- int month_lengths[12][2] = { {31, 31},
- {28, 29},
- {31, 31},
- {30, 30},
- {31, 31},
- {30, 30},
- {31, 31},
- {31, 31},
- {30, 30},
- {31, 31},
- {30, 30},
- {31, 31} };
- METHOD_TRACE("ips_fix_ffdc_time", 1);
- days = current_time / IPS_SECS_DAY;
- rem = current_time % IPS_SECS_DAY;
- scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR);
- rem = rem % IPS_SECS_HOUR;
- scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN);
- scb->cmd.ffdc.second = (rem % IPS_SECS_MIN);
- year = IPS_EPOCH_YEAR;
- while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) {
- int newy;
- newy = year + (days / IPS_DAYS_NORMAL_YEAR);
- if (days < 0)
- --newy;
- days -= (newy - year) * IPS_DAYS_NORMAL_YEAR +
- IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) -
- IPS_NUM_LEAP_YEARS_THROUGH(year - 1);
- year = newy;
- }
- scb->cmd.ffdc.yearH = year / 100;
- scb->cmd.ffdc.yearL = year % 100;
- for (i = 0; days >= month_lengths[i][yleap]; ++i)
- days -= month_lengths[i][yleap];
- scb->cmd.ffdc.month = i + 1;
- scb->cmd.ffdc.day = days + 1;
- }
- /****************************************************************************
- * BIOS Flash Routines *
- ****************************************************************************/
- /****************************************************************************/
- /* */
- /* Routine Name: ips_erase_bios */
- /* */
- /* Routine Description: */
- /* Erase the BIOS on the adapter */
- /* */
- /****************************************************************************/
- static int
- ips_erase_bios(ips_ha_t *ha) {
- int timeout;
- uint8_t status=0;
- METHOD_TRACE("ips_erase_bios", 1);
- status = 0;
- /* Clear the status register */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- outb(0x50, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* Erase Setup */
- outb(0x20, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* Erase Confirm */
- outb(0xD0, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* Erase Status */
- outb(0x70, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- timeout = 80000; /* 80 seconds */
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- outl(0, ha->io_addr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
- status = inb(ha->io_addr + IPS_REG_FLDP);
- if (status & 0x80)
- break;
- MDELAY(1);
- timeout--;
- }
- /* check for timeout */
- if (timeout <= 0) {
- /* timeout */
- /* try to suspend the erase */
- outb(0xB0, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* wait for 10 seconds */
- timeout = 10000;
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- outl(0, ha->io_addr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
- status = inb(ha->io_addr + IPS_REG_FLDP);
- if (status & 0xC0)
- break;
- MDELAY(1);
- timeout--;
- }
- return (1);
- }
- /* check for valid VPP */
- if (status & 0x08)
- /* VPP failure */
- return (1);
- /* check for succesful flash */
- if (status & 0x30)
- /* sequence error */
- return (1);
- /* Otherwise, we were successful */
- /* clear status */
- outb(0x50, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* enable reads */
- outb(0xFF, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- return (0);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_erase_bios_memio */
- /* */
- /* Routine Description: */
- /* Erase the BIOS on the adapter */
- /* */
- /****************************************************************************/
- static int
- ips_erase_bios_memio(ips_ha_t *ha) {
- int timeout;
- uint8_t status;
- METHOD_TRACE("ips_erase_bios_memio", 1);
- status = 0;
- /* Clear the status register */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* Erase Setup */
- writeb(0x20, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* Erase Confirm */
- writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* Erase Status */
- writeb(0x70, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- timeout = 80000; /* 80 seconds */
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
- status = readb(ha->mem_ptr + IPS_REG_FLDP);
- if (status & 0x80)
- break;
- MDELAY(1);
- timeout--;
- }
- /* check for timeout */
- if (timeout <= 0) {
- /* timeout */
- /* try to suspend the erase */
- writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* wait for 10 seconds */
- timeout = 10000;
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
- status = readb(ha->mem_ptr + IPS_REG_FLDP);
- if (status & 0xC0)
- break;
- MDELAY(1);
- timeout--;
- }
- return (1);
- }
- /* check for valid VPP */
- if (status & 0x08)
- /* VPP failure */
- return (1);
- /* check for succesful flash */
- if (status & 0x30)
- /* sequence error */
- return (1);
- /* Otherwise, we were successful */
- /* clear status */
- writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* enable reads */
- writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- return (0);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_program_bios */
- /* */
- /* Routine Description: */
- /* Program the BIOS on the adapter */
- /* */
- /****************************************************************************/
- static int
- ips_program_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
- int i;
- int timeout;
- uint8_t status=0;
- METHOD_TRACE("ips_program_bios", 1);
- status = 0;
- for (i = 0; i < buffersize; i++) {
- /* write a byte */
- outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- outb(0x40, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- outb(buffer[i], ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* wait up to one second */
- timeout = 1000;
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- outl(0, ha->io_addr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
- status = inb(ha->io_addr + IPS_REG_FLDP);
- if (status & 0x80)
- break;
- MDELAY(1);
- timeout--;
- }
- if (timeout == 0) {
- /* timeout error */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- outb(0xFF, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- return (1);
- }
- /* check the status */
- if (status & 0x18) {
- /* programming error */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- outb(0xFF, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- return (1);
- }
- } /* end for */
- /* Enable reading */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- outb(0xFF, ha->io_addr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- return (0);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_program_bios_memio */
- /* */
- /* Routine Description: */
- /* Program the BIOS on the adapter */
- /* */
- /****************************************************************************/
- static int
- ips_program_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
- int i;
- int timeout;
- uint8_t status=0;
- METHOD_TRACE("ips_program_bios_memio", 1);
- status = 0;
- for (i = 0; i < buffersize; i++) {
- /* write a byte */
- writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- writeb(0x40, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- /* wait up to one second */
- timeout = 1000;
- while (timeout > 0) {
- if (ha->revision_id == IPS_REVID_TROMBONE64) {
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- udelay(25); /* 25 us */
- }
- status = readb(ha->mem_ptr + IPS_REG_FLDP);
- if (status & 0x80)
- break;
- MDELAY(1);
- timeout--;
- }
- if (timeout == 0) {
- /* timeout error */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- return (1);
- }
- /* check the status */
- if (status & 0x18) {
- /* programming error */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- return (1);
- }
- } /* end for */
- /* Enable reading */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- return (0);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_verify_bios */
- /* */
- /* Routine Description: */
- /* Verify the BIOS on the adapter */
- /* */
- /****************************************************************************/
- static int
- ips_verify_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
- uint8_t checksum;
- int i;
- METHOD_TRACE("ips_verify_bios", 1);
- /* test 1st byte */
- outl(0, ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
- return (1);
- outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
- return (1);
- checksum = 0xff;
- for (i = 2; i < buffersize; i++) {
- outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
- }
- if (checksum != 0)
- /* failure */
- return (1);
- else
- /* success */
- return (0);
- }
- /****************************************************************************/
- /* */
- /* Routine Name: ips_verify_bios_memio */
- /* */
- /* Routine Description: */
- /* Verify the BIOS on the adapter */
- /* */
- /****************************************************************************/
- static int
- ips_verify_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
- uint8_t checksum;
- int i;
- METHOD_TRACE("ips_verify_bios_memio", 1);
- /* test 1st byte */
- writel(0, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
- return (1);
- writel(1, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
- return (1);
- checksum = 0xff;
- for (i = 2; i < buffersize; i++) {
- writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
- if (ha->revision_id == IPS_REVID_TROMBONE64)
- udelay(25); /* 25 us */
- checksum = (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
- }
- if (checksum != 0)
- /* failure */
- return (1);
- else
- /* success */
- return (0);
- }
- /*---------------------------------------------------------------------------*/
- /* Routine Name: ips_version_check */
- /* */
- /* Dependencies: */
- /* Assumes that ips_read_adapter_status() is called first filling in */
- /* the data for SubSystem Parameters. */
- /* Called from ips_write_driver_status() so it also assumes NVRAM Page 5 */
- /* Data is availaible. */
- /* */
- /*---------------------------------------------------------------------------*/
- static void ips_version_check(ips_ha_t *ha, int intr) {
- IPS_VERSION_DATA VersionInfo;
- uint8_t FirmwareVersion[ IPS_COMPAT_ID_LENGTH + 1 ];
- uint8_t BiosVersion[ IPS_COMPAT_ID_LENGTH + 1];
- int MatchError;
- int rc;
- METHOD_TRACE("ips_version_check", 1);
- memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
- memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
- /* Get the Compatible BIOS Version from NVRAM Page 5 */
- memcpy(BiosVersion, ha->nvram->BiosCompatibilityID, IPS_COMPAT_ID_LENGTH);
- rc = IPS_FAILURE;
- if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) /* If Versioning is Supported */
- {
- /* Get the Version Info with a Get Version Command */
- rc = ips_get_version_info(ha, &VersionInfo, intr);
- if (rc == IPS_SUCCESS)
- memcpy(FirmwareVersion, VersionInfo.compatibilityId, IPS_COMPAT_ID_LENGTH);
- }
- if (rc != IPS_SUCCESS) /* If Data Not Obtainable from a GetVersion Command */
- {
- /* Get the Firmware Version from Enquiry Data */
- memcpy(FirmwareVersion, ha->enq->CodeBlkVersion, IPS_COMPAT_ID_LENGTH);
- }
- /* printk(KERN_WARNING "Adapter's BIOS Version = %sn", BiosVersion); */
- /* printk(KERN_WARNING "BIOS Compatible Version = %sn", IPS_COMPAT_BIOS); */
- /* printk(KERN_WARNING "Adapter's Firmware Version = %sn", FirmwareVersion); */
- /* printk(KERN_WARNING "Firmware Compatible Version = %s n", Compatable[ ha->nvram->adapter_type ]); */
- MatchError = 0;
- if (strncmp(FirmwareVersion, Compatable[ ha->nvram->adapter_type ], IPS_COMPAT_ID_LENGTH) != 0)
- {
- if (ips_cd_boot == 0)
- printk(KERN_WARNING "Warning: Adapter %d Firmware Compatible Version is %s, but should be %sn",
- ha->host_num, FirmwareVersion, Compatable[ ha->nvram->adapter_type ]);
- MatchError = 1;
- }
- if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0)
- {
- if (ips_cd_boot == 0)
- printk(KERN_WARNING "Warning: Adapter %d BIOS Compatible Version is %s, but should be %sn",
- ha->host_num, BiosVersion, IPS_COMPAT_BIOS);
- MatchError = 1;
- }
- ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */
- if (MatchError)
- {
- ha->nvram->version_mismatch = 1;
- if (ips_cd_boot == 0)
- printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatchn");
- }
- else
- {
- ha->nvram->version_mismatch = 0;
- }
- return;
- }
- /*---------------------------------------------------------------------------*/
- /* Routine Name: ips_get_version_info */
- /* */
- /* Routine Description: */
- /* Issue an internal GETVERSION ServeRAID Command */
- /* */
- /* Return Value: */
- /* 0 if Successful, else non-zero */
- /*---------------------------------------------------------------------------*/
- static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ) {
- ips_scb_t *scb;
- int rc;
- METHOD_TRACE("ips_get_version_info", 1);
- memset(Buffer, 0, sizeof(IPS_VERSION_DATA));
- scb = &ha->scbs[ha->max_cmds-1];
- ips_init_scb(ha, scb);
- scb->timeout = ips_cmd_timeout;
- scb->cdb[0] = IPS_CMD_GET_VERSION_INFO;
- scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO;
- scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb);
- scb->cmd.version_info.reserved = 0;
- scb->cmd.version_info.count = sizeof( IPS_VERSION_DATA);
- scb->cmd.version_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(Buffer));
- scb->cmd.version_info.reserved2 = 0;
- /* issue command */
- rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
- return( rc );
- }
- #if defined (MODULE) || (LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0))
- static Scsi_Host_Template driver_template = IPS;
- #include "scsi_module.c"
- #endif
- #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
- /*---------------------------------------------------------------------------*/
- /* Routine Name: ips_remove_device */
- /* */
- /* Routine Description: */
- /* Remove one Adapter ( Hot Plugging ) */
- /*---------------------------------------------------------------------------*/
- static void __devexit ips_remove_device(struct pci_dev *pci_dev)
- {
- int i;
- struct Scsi_Host *sh;
- ips_ha_t *ha;
- for (i = 0; i < IPS_MAX_ADAPTERS; i++) {
- ha = ips_ha[i];
- if (ha) {
- if ( (pci_dev->bus->number == ha->pcidev->bus->number) &&
- (pci_dev->devfn == ha->pcidev->devfn)) {
- sh = ips_sh[i];
- ips_release(sh);
- }
- }
- }
- }
- /*---------------------------------------------------------------------------*/
- /* Routine Name: ips_insert_device */
- /* */
- /* Routine Description: */
- /* Add One Adapter ( Hot Plug ) */
- /* */
- /* Return Value: */
- /* 0 if Successful, else non-zero */
- /*---------------------------------------------------------------------------*/
- static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent)
- {
- int index;
- int rc;
- METHOD_TRACE("ips_insert_device", 1);
- if (pci_enable_device(pci_dev))
- return -1;
- rc = ips_init_phase1(pci_dev, &index);
- if (rc == SUCCESS)
- rc = ips_init_phase2(index);
- if (rc == SUCCESS)
- ips_num_controllers++;
- ips_next_controller = ips_num_controllers;
- return rc;
- }
- /*---------------------------------------------------------------------------*/
- /* Routine Name: ips_init_phase1 */
- /* */
- /* Routine Description: */
- /* Adapter Initialization */
- /* */
- /* Return Value: */
- /* 0 if Successful, else non-zero */
- /*---------------------------------------------------------------------------*/
- static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
- {
- struct Scsi_Host *sh;
- ips_ha_t *ha;
- uint32_t io_addr;
- uint32_t mem_addr;
- uint32_t io_len;
- uint32_t mem_len;
- uint8_t revision_id;
- uint8_t bus;
- uint8_t func;
- uint8_t irq;
- uint16_t subdevice_id;
- int j;
- int index;
- uint32_t count;
- char *ioremap_ptr;
- char *mem_ptr;
- uint32_t IsDead
- METHOD_TRACE("ips_init_phase1", 1);
- index = IPS_MAX_ADAPTERS;
- for (j = 0; j < IPS_MAX_ADAPTERS; j++) {
- if (ips_ha[j] ==0) {
- index = j;
- break;
- }
- }
- if (index >= IPS_MAX_ADAPTERS)
- return -1;
- /* stuff that we get in dev */
- irq = pci_dev->irq;
- bus = pci_dev->bus->number;
- func = pci_dev->devfn;
- /* Init MEM/IO addresses to 0 */
- mem_addr = 0;
- io_addr = 0;
- mem_len = 0;
- io_len = 0;
- for (j = 0; j < 2; j++) {
- if (!pci_resource_start(pci_dev, j))
- break;
- if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) {
- io_addr = pci_resource_start(pci_dev, j);
- io_len = pci_resource_len(pci_dev, j);
- } else {
- mem_addr = pci_resource_start(pci_dev, j);
- mem_len = pci_resource_len(pci_dev, j);
- }
- }
- /* setup memory mapped area (if applicable) */
- if (mem_addr) {
- uint32_t base;
- uint32_t offs;
- if (check_mem_region(mem_addr, mem_len)) {
- printk(KERN_WARNING "Couldn't allocate IO Memory space %x len %d.n", mem_addr, mem_len);
- return -1;
- }
- request_mem_region(mem_addr, mem_len, "ips");
- base = mem_addr & PAGE_MASK;
- offs = mem_addr - base;
- ioremap_ptr = ioremap(base, PAGE_SIZE);
- mem_ptr = ioremap_ptr + offs;
- } else {
- ioremap_ptr = NULL;
- mem_ptr = NULL;
- }
- /* setup I/O mapped area (if applicable) */
- if (io_addr) {
- if (check_region(io_addr, io_len)) {
- printk(KERN_WARNING "Couldn't allocate IO space %x len %d.n", io_addr, io_len);
- return -1;
- }
- request_region(io_addr, io_len, "ips");
- }
- /* get the revision ID */
- if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) {
- printk(KERN_WARNING "Can't get revision id.n" );
- return -1;
- }
- subdevice_id = pci_dev->subsystem_device;
- /* found a controller */
- sh = scsi_register(&driver_template, sizeof(ips_ha_t));
- if (sh == NULL) {
- printk(KERN_WARNING "Unable to register controller with SCSI subsystemn" );
- return -1;
- }
- ha = IPS_HA(sh);
- memset(ha, 0, sizeof(ips_ha_t));
- /* Initialize spin lock */
- spin_lock_init(&ha->scb_lock);
- spin_lock_init(&ha->copp_lock); spin_lock_init(&ha->ips_lock);
- spin_lock_init(&ha->copp_waitlist.lock);
- spin_lock_init(&ha->scb_waitlist.lock);
- spin_lock_init(&ha->scb_activelist.lock);
- ips_sh[index] = sh;
- ips_ha[index] = ha;
- ha->active = 1;
- ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL);
- if (!ha->enq) {
- printk(KERN_WARNING "Unable to allocate host inquiry structuren" );
- ha->active = 0;
- ips_free(ha);
- scsi_unregister(sh);
- ips_ha[index] = 0;
- ips_sh[index] = 0;
- return -1;
- }
- ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_KERNEL);
- if (!ha->adapt) {
- printk(KERN_WARNING "Unable to allocate host adapt structuren" );
- ha->active = 0;
- ips_free(ha);
- scsi_unregister(sh);
- ips_ha[index] = 0;
- ips_sh[index] = 0;
- return -1;
- }
- ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL);
- if (!ha->conf) {
- printk(KERN_WARNING "Unable to allocate host conf structuren" );
- ha->active = 0;
- ips_free(ha);
- scsi_unregister(sh);
- ips_ha[index] = 0;
- ips_sh[index] = 0;
- return -1;
- }
- ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL);
- if (!ha->nvram) {
- printk(KERN_WARNING "Unable to allocate host NVRAM structuren" );
- ha->active = 0;
- ips_free(ha);
- scsi_unregister(sh);
- ips_ha[index] = 0;
- ips_sh[index] = 0;
- return -1;
- }
- ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL);
- if (!ha->subsys) {
- printk(KERN_WARNING "Unable to allocate host subsystem structuren" );
- ha->active = 0;
- ips_free(ha);
- scsi_unregister(sh);
- ips_ha[index] = 0;
- ips_sh[index] = 0;
- return -1;
- }
- ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_KERNEL);
- if (!ha->dummy) {
- printk(KERN_WARNING "Unable to allocate host dummy structuren" );
- ha->active = 0;
- ips_free(ha);
- scsi_unregister(sh);
- ips_ha[index] = 0;
- ips_sh[index] = 0;
- return -1;
- }
- for (count = PAGE_SIZE, ha->ioctl_order = 0;
- count < ips_ioctlsize;
- ha->ioctl_order++, count <<= 1);
- ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order);
- ha->ioctl_datasize = count;
- if (!ha->ioctl_data) {
- printk(KERN_WARNING "Unable to allocate IOCTL datan" );
- ha->ioctl_data = NULL;
- ha->ioctl_order = 0;
- ha->ioctl_datasize = 0;
- }
- /* Store away needed values for later use */
- sh->io_port = io_addr;
- sh->n_io_port = io_addr ? 255 : 0;
- sh->unique_id = (io_addr) ? io_addr : mem_addr;
- sh->irq = irq;
- sh->select_queue_depths = ips_select_queue_depth;
- sh->sg_tablesize = sh->hostt->sg_tablesize;
- sh->can_queue = sh->hostt->can_queue;
- sh->cmd_per_lun = sh->hostt->cmd_per_lun;
- sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
- sh->use_clustering = sh->hostt->use_clustering;
- #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
- sh->max_sectors = 128;
- #endif
- /* Store info in HA structure */
- ha->irq = irq;
- ha->io_addr = io_addr;
- ha->io_len = io_len;
- ha->mem_addr = mem_addr;
- ha->mem_len = mem_len;
- ha->mem_ptr = mem_ptr;
- ha->ioremap_ptr = ioremap_ptr;
- ha->host_num = ( uint32_t) index;
- ha->revision_id = revision_id;
- ha->slot_num = PCI_SLOT(pci_dev->devfn);
- ha->device_id = pci_dev->device;
- ha->subdevice_id = subdevice_id;
- ha->pcidev = pci_dev;
- /*
- * Setup Functions
- */
- if (IPS_IS_MORPHEUS(ha)) {
- /* morpheus */
- ha->func.isintr = ips_isintr_morpheus;
- ha->func.isinit = ips_isinit_morpheus;
- ha->func.issue = ips_issue_i2o_memio;
- ha->func.init = ips_init_morpheus;
- ha->func.statupd = ips_statupd_morpheus;
- ha->func.reset = ips_reset_morpheus;
- ha->func.intr = ips_intr_morpheus;
- ha->func.enableint = ips_enable_int_morpheus;
- } else if (IPS_USE_MEMIO(ha)) {
- /* copperhead w/MEMIO */
- ha->func.isintr = ips_isintr_copperhead_memio;
- ha->func.isinit = ips_isinit_copperhead_memio;
- ha->func.init = ips_init_copperhead_memio;
- ha->func.statupd = ips_statupd_copperhead_memio;
- ha->func.statinit = ips_statinit_memio;
- ha->func.reset = ips_reset_copperhead_memio;
- ha->func.intr = ips_intr_copperhead;
- ha->func.erasebios = ips_erase_bios_memio;
- ha->func.programbios = ips_program_bios_memio;
- ha->func.verifybios = ips_verify_bios_memio;
- ha->func.enableint = ips_enable_int_copperhead_memio;
- if (IPS_USE_I2O_DELIVER(ha))
- ha->func.issue = ips_issue_i2o_memio;
- else
- ha->func.issue = ips_issue_copperhead_memio;
- } else {
- /* copperhead */
- ha->func.isintr = ips_isintr_copperhead;
- ha->func.isinit = ips_isinit_copperhead;
- ha->func.init = ips_init_copperhead;
- ha->func.statupd = ips_statupd_copperhead;
- ha->func.statinit = ips_statinit;
- ha->func.reset = ips_reset_copperhead;
- ha->func.intr = ips_intr_copperhead;
- ha->func.erasebios = ips_erase_bios;
- ha->func.programbios = ips_program_bios;
- ha->func.verifybios = ips_verify_bios;
- ha->func.enableint = ips_enable_int_copperhead;
- if (IPS_USE_I2O_DELIVER(ha))
- ha->func.issue = ips_issue_i2o;
- else
- ha->func.issue = ips_issue_copperhead;
- }
- if ( IPS_IS_MORPHEUS( ha ) ) {
- /* If Morpheus appears dead, reset it */
- IsDead = readl( ha->mem_ptr + IPS_REG_I960_MSG1 );
- if ( IsDead == 0xDEADBEEF ) {
- ips_reset_morpheus( ha );
- }
- }
- /*
- * Initialize the card if it isn't already
- */
- if (!(*ha->func.isinit)(ha)) {
- if (!(*ha->func.init)(ha)) {
- /*
- * Initialization failed
- */
- printk(KERN_WARNING "Unable to initialize controllern" );
- ha->active = 0;
- ips_free(ha);
- scsi_unregister(sh);
- ips_ha[index] = 0;
- ips_sh[index] = 0;
- return -1;
- }
- }
- /* Install the interrupt handler */
- if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
- printk(KERN_WARNING "Unable to install interrupt handlern" );
- ha->active = 0;
- ips_free(ha);
- scsi_unregister(sh);
- ips_ha[index] = 0;
- ips_sh[index] = 0;
- return -1;
- }
- /*
- * Allocate a temporary SCB for initialization
- */
- ha->max_cmds = 1;
- if (!ips_allocatescbs(ha)) {
- printk(KERN_WARNING "Unable to allocate a CCBn" );
- ha->active = 0;
- free_irq(ha->irq, ha);
- ips_free(ha);
- scsi_unregister(sh);
- ips_ha[index] = 0;
- ips_sh[index] = 0;
- return -1;
- }
- *indexPtr = index;
- return SUCCESS;
- }
- #endif
- /*---------------------------------------------------------------------------*/
- /* Routine Name: ips_init_phase2 */
- /* */
- /* Routine Description: */
- /* Adapter Initialization Phase 2 */
- /* */
- /* Return Value: */
- /* 0 if Successful, else non-zero */
- /*---------------------------------------------------------------------------*/
- static int ips_init_phase2( int index )
- {
- struct Scsi_Host *sh;
- ips_ha_t *ha;
- ha = ips_ha[index];
- sh = ips_sh[index];
- METHOD_TRACE("ips_init_phase2", 1);
- if (!ha->active) {
- scsi_unregister(sh);
- ips_ha[index] = NULL;
- ips_sh[index] = NULL;
- return -1;;
- }
- if (!ips_hainit(ha)) {
- printk(KERN_WARNING "Unable to initialize controllern" );
- ha->active = 0;
- ips_free(ha);
- free_irq(ha->irq, ha);
- scsi_unregister(sh);
- ips_ha[index] = NULL;
- ips_sh[index] = NULL;
- return -1;
- }
- /* Free the temporary SCB */
- ips_deallocatescbs(ha, 1);
- /* allocate CCBs */
- if (!ips_allocatescbs(ha)) {
- printk(KERN_WARNING "Unable to allocate CCBsn" );
- ha->active = 0;
- ips_free(ha);
- free_irq(ha->irq, ha);
- scsi_unregister(sh);
- ips_ha[index] = NULL;
- ips_sh[index] = NULL;
- return -1;
- }
- /* finish setting values */
- sh->max_id = ha->ntargets;
- sh->max_lun = ha->nlun;
- sh->max_channel = ha->nbus - 1;
- sh->can_queue = ha->max_cmds-1;
- return SUCCESS;
- }
- #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,9)
- MODULE_LICENSE("GPL");
- #endif
- /*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 2
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -2
- * c-argdecl-indent: 2
- * c-label-offset: -2
- * c-continued-statement-offset: 2
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */