/** * aac_get_containers - list containers * @common: adapter to probe * * Make a list of all containers on this controller */ int aac_get_containers(struct aac_dev *dev) { struct fsa_scsi_hba *fsa_dev_ptr; u32 index; int status = 0; struct aac_query_mount *dinfo; struct aac_mount *dresp; struct fib * fibptr; unsigned instance; fsa_dev_ptr = &(dev->fsa_dev); instance = dev->scsi_host_ptr->unique_id; if (!(fibptr = fib_alloc(dev))) return -ENOMEM; for (index = 0; index < MAXIMUM_NUM_CONTAINERS; index++) { fib_init(fibptr); dinfo = (struct aac_query_mount *) fib_data(fibptr); dinfo->command = cpu_to_le32(VM_NameServe); dinfo->count = cpu_to_le32(index); dinfo->type = cpu_to_le32(FT_FILESYS); status = fib_send(ContainerCommand, fibptr, sizeof (struct aac_query_mount), FsaNormal, 1, 1, NULL, NULL); if (status < 0 ) { printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n"); break; } dresp = (struct aac_mount *)fib_data(fibptr); if ((le32_to_cpu(dresp->status) == ST_OK) && (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { fsa_dev_ptr->valid[index] = 1; fsa_dev_ptr->type[index] = le32_to_cpu(dresp->mnt[0].vol); fsa_dev_ptr->size[index] = le32_to_cpu(dresp->mnt[0].capacity); if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) fsa_dev_ptr->ro[index] = 1; } fib_complete(fibptr); /* * If there are no more containers, then stop asking. */ if ((index + 1) >= le32_to_cpu(dresp->count)){ break; } } fib_free(fibptr); fsa_dev[instance] = fsa_dev_ptr; return status; }
static int probe_container(struct aac_dev *dev, int cid) { struct fsa_scsi_hba *fsa_dev_ptr; int status; struct aac_query_mount *dinfo; struct aac_mount *dresp; struct fib * fibptr; unsigned instance; fsa_dev_ptr = &(dev->fsa_dev); instance = dev->scsi_host_ptr->unique_id; if (!(fibptr = fib_alloc(dev))) return -ENOMEM; fib_init(fibptr); dinfo = (struct aac_query_mount *)fib_data(fibptr); dinfo->command = cpu_to_le32(VM_NameServe); dinfo->count = cpu_to_le32(cid); dinfo->type = cpu_to_le32(FT_FILESYS); status = fib_send(ContainerCommand, fibptr, sizeof(struct aac_query_mount), FsaNormal, 1, 1, NULL, NULL); if (status < 0) { printk(KERN_WARNING "aacraid: probe_containers query failed.\n"); goto error; } dresp = (struct aac_mount *) fib_data(fibptr); if ((le32_to_cpu(dresp->status) == ST_OK) && (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { fsa_dev_ptr->valid[cid] = 1; fsa_dev_ptr->type[cid] = le32_to_cpu(dresp->mnt[0].vol); fsa_dev_ptr->size[cid] = le32_to_cpu(dresp->mnt[0].capacity); if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) fsa_dev_ptr->ro[cid] = 1; } error: fib_complete(fibptr); fib_free(fibptr); return status; }
int aac_send_shutdown(struct aac_dev * dev) { struct fib * fibctx; struct aac_close *cmd; int status; fibctx = aac_fib_alloc(dev); if (!fibctx) return -ENOMEM; aac_fib_init(fibctx); cmd = (struct aac_close *) fib_data(fibctx); cmd->command = cpu_to_le32(VM_CloseAll); cmd->cid = cpu_to_le32(0xffffffff); status = aac_fib_send(ContainerCommand, fibctx, sizeof(struct aac_close), FsaNormal, -2 /* Timeout silently */, 1, NULL, NULL); if (status == 0) aac_fib_complete(fibctx); aac_fib_free(fibctx); return status; }
static int aac_send_shutdown(struct aac_dev * dev) { struct fib * fibctx; struct aac_close *cmd; int status; fibctx = fib_alloc(dev); fib_init(fibctx); cmd = (struct aac_close *) fib_data(fibctx); cmd->command = cpu_to_le32(VM_CloseAll); cmd->cid = cpu_to_le32(0xffffffff); status = fib_send(ContainerCommand, fibctx, sizeof(struct aac_close), FsaNormal, 1, 1, NULL, NULL); if (status == 0) fib_complete(fibctx); fib_free(fibctx); return status; }
int main(int argc, char **argv) { int n; int ephi; int phi; int tfib; int fudge; for (n=2; n<N_MAX; n++) { fib_data(n, &ephi, &phi, &tfib, &fudge); printf("%3d %4d %3d %3d %3d\n", n, tfib, phi, ephi, fudge); } return 0; }
int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *callback_data) { struct aac_dev * dev = fibptr->dev; struct hw_fib * hw_fib = fibptr->hw_fib; struct aac_queue * q; unsigned long flags = 0; unsigned long qflags; if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) return -EBUSY; /* * There are 5 cases with the wait and reponse requested flags. * The only invalid cases are if the caller requests to wait and * does not request a response and if the caller does not want a * response and the Fib is not allocated from pool. If a response * is not requesed the Fib will just be deallocaed by the DPC * routine when the response comes back from the adapter. No * further processing will be done besides deleting the Fib. We * will have a debug mode where the adapter can notify the host * it had a problem and the host can log that fact. */ if (wait && !reply) { return -EINVAL; } else if (!wait && reply) { hw_fib->header.XferState |= cpu_to_le32(Async | ResponseExpected); FIB_COUNTER_INCREMENT(aac_config.AsyncSent); } else if (!wait && !reply) { hw_fib->header.XferState |= cpu_to_le32(NoResponseExpected); FIB_COUNTER_INCREMENT(aac_config.NoResponseSent); } else if (wait && reply) { hw_fib->header.XferState |= cpu_to_le32(ResponseExpected); FIB_COUNTER_INCREMENT(aac_config.NormalSent); } /* * Map the fib into 32bits by using the fib number */ hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2); hw_fib->header.SenderData = (u32)(fibptr - dev->fibs); /* * Set FIB state to indicate where it came from and if we want a * response from the adapter. Also load the command from the * caller. * * Map the hw fib pointer as a 32bit value */ hw_fib->header.Command = cpu_to_le16(command); hw_fib->header.XferState |= cpu_to_le32(SentFromHost); fibptr->hw_fib->header.Flags = 0; /* 0 the flags field - internal only*/ /* * Set the size of the Fib we want to send to the adapter */ hw_fib->header.Size = cpu_to_le16(sizeof(struct aac_fibhdr) + size); if (le16_to_cpu(hw_fib->header.Size) > le16_to_cpu(hw_fib->header.SenderSize)) { return -EMSGSIZE; } /* * Get a queue entry connect the FIB to it and send an notify * the adapter a command is ready. */ hw_fib->header.XferState |= cpu_to_le32(NormalPriority); /* * Fill in the Callback and CallbackContext if we are not * going to wait. */ if (!wait) { fibptr->callback = callback; fibptr->callback_data = callback_data; } fibptr->done = 0; fibptr->flags = 0; FIB_COUNTER_INCREMENT(aac_config.FibsSent); dprintk((KERN_DEBUG "Fib contents:.\n")); dprintk((KERN_DEBUG " Command = %d.\n", le32_to_cpu(hw_fib->header.Command))); dprintk((KERN_DEBUG " SubCommand = %d.\n", le32_to_cpu(((struct aac_query_mount *)fib_data(fibptr))->command))); dprintk((KERN_DEBUG " XferState = %x.\n", le32_to_cpu(hw_fib->header.XferState))); dprintk((KERN_DEBUG " hw_fib va being sent=%p\n",fibptr->hw_fib)); dprintk((KERN_DEBUG " hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa)); dprintk((KERN_DEBUG " fib being sent=%p\n",fibptr)); q = &dev->queues->queue[AdapNormCmdQueue]; if(wait) spin_lock_irqsave(&fibptr->event_lock, flags); spin_lock_irqsave(q->lock, qflags); if (dev->new_comm_interface) { unsigned long count = 10000000L; /* 50 seconds */ list_add_tail(&fibptr->queue, &q->pendingq); q->numpending++; spin_unlock_irqrestore(q->lock, qflags); while (aac_adapter_send(fibptr) != 0) { if (--count == 0) { if (wait) spin_unlock_irqrestore(&fibptr->event_lock, flags); spin_lock_irqsave(q->lock, qflags); q->numpending--; list_del(&fibptr->queue); spin_unlock_irqrestore(q->lock, qflags); return -ETIMEDOUT; } udelay(5); } } else { u32 index; unsigned long nointr = 0; aac_queue_get( dev, &index, AdapNormCmdQueue, hw_fib, 1, fibptr, &nointr); list_add_tail(&fibptr->queue, &q->pendingq); q->numpending++; *(q->headers.producer) = cpu_to_le32(index + 1); spin_unlock_irqrestore(q->lock, qflags); dprintk((KERN_DEBUG "aac_fib_send: inserting a queue entry at index %d.\n",index)); if (!(nointr & aac_config.irq_mod)) aac_adapter_notify(dev, AdapNormCmdQueue); } /* * If the caller wanted us to wait for response wait now. */ if (wait) { spin_unlock_irqrestore(&fibptr->event_lock, flags); /* Only set for first known interruptable command */ if (wait < 0) { /* * *VERY* Dangerous to time out a command, the * assumption is made that we have no hope of * functioning because an interrupt routing or other * hardware failure has occurred. */ unsigned long count = 36000000L; /* 3 minutes */ while (down_trylock(&fibptr->event_wait)) { if (--count == 0) { spin_lock_irqsave(q->lock, qflags); q->numpending--; list_del(&fibptr->queue); spin_unlock_irqrestore(q->lock, qflags); if (wait == -1) { printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n" "Usually a result of a PCI interrupt routing problem;\n" "update mother board BIOS or consider utilizing one of\n" "the SAFE mode kernel options (acpi, apic etc)\n"); } return -ETIMEDOUT; } udelay(5); } } else down(&fibptr->event_wait); if(fibptr->done == 0) BUG(); if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){ return -ETIMEDOUT; } else { return 0; } } /* * If the user does not want a response than return success otherwise * return pending */ if (reply) return -EINPROGRESS; else return 0; }