aachba.c
来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 1,659 行 · 第 1/4 页
C
1,659 行
sense_buf[15] = 0xc0;/* Std sense key specific field */ /* Illegal parameter is in the CDB block */ sense_buf[15] |= bit_pointer; sense_buf[16] = field_pointer >> 8; /* MSB */ sense_buf[17] = field_pointer; /* LSB */ }}static void aac_io_done(struct scsi_cmnd * scsicmd){ unsigned long cpu_flags; struct Scsi_Host *host = scsicmd->device->host; spin_lock_irqsave(host->host_lock, cpu_flags); scsicmd->scsi_done(scsicmd); spin_unlock_irqrestore(host->host_lock, cpu_flags);}static void __aac_io_done(struct scsi_cmnd * scsicmd){ scsicmd->scsi_done(scsicmd);}int aac_get_adapter_info(struct aac_dev* dev){ struct fib* fibptr; struct aac_adapter_info* info; int rcode; u32 tmp; if (!(fibptr = fib_alloc(dev))) return -ENOMEM; fib_init(fibptr); info = (struct aac_adapter_info*) fib_data(fibptr); memset(info,0,sizeof(struct aac_adapter_info)); rcode = fib_send(RequestAdapterInfo, fibptr, sizeof(struct aac_adapter_info), FsaNormal, 1, 1, NULL, NULL); memcpy(&dev->adapter_info, info, sizeof(struct aac_adapter_info)); tmp = dev->adapter_info.kernelrev; printk(KERN_INFO"%s%d: kernel %d.%d.%d build %d\n", dev->name, dev->id, tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff, dev->adapter_info.kernelbuild); tmp = dev->adapter_info.monitorrev; printk(KERN_INFO"%s%d: monitor %d.%d.%d build %d\n", dev->name, dev->id, tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff, dev->adapter_info.monitorbuild); tmp = dev->adapter_info.biosrev; printk(KERN_INFO"%s%d: bios %d.%d.%d build %d\n", dev->name, dev->id, tmp>>24,(tmp>>16)&0xff,(tmp>>8)&0xff, dev->adapter_info.biosbuild); printk(KERN_INFO"%s%d: serial %x%x\n", dev->name, dev->id, dev->adapter_info.serial[0], dev->adapter_info.serial[1]); dev->nondasd_support = 0; if(dev->adapter_info.options & AAC_OPT_NONDASD){// dev->nondasd_support = 1;// dmb - temporarily disable nondasd } if(nondasd != -1) { dev->nondasd_support = (nondasd!=0); } if(dev->nondasd_support != 0){ printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id); } dev->pae_support = 0; if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){ printk(KERN_INFO "%s%d: 64bit support enabled.\n", dev->name, dev->id); dev->pae_support = 1; } if(paemode != -1){ dev->pae_support = (paemode!=0); } if(dev->pae_support != 0) { printk(KERN_INFO"%s%d: 64 Bit PAE enabled\n", dev->name, dev->id); pci_set_dma_mask(dev->pdev, (dma_addr_t)0xFFFFFFFFFFFFFFFFULL); } fib_complete(fibptr); fib_free(fibptr); return rcode;}static void read_callback(void *context, struct fib * fibptr){ struct aac_dev *dev; struct aac_read_reply *readreply; struct scsi_cmnd *scsicmd; u32 lba; u32 cid; scsicmd = (struct scsi_cmnd *) context; dev = (struct aac_dev *)scsicmd->device->host->hostdata; cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); if (fibptr == NULL) BUG(); if(scsicmd->use_sg) pci_unmap_sg(dev->pdev, (struct scatterlist *)scsicmd->buffer, scsicmd->use_sg, scsicmd->sc_data_direction); else if(scsicmd->request_bufflen) pci_unmap_single(dev->pdev, (dma_addr_t)(ulong)scsicmd->SCp.ptr, scsicmd->request_bufflen, scsicmd->sc_data_direction); readreply = (struct aac_read_reply *)fib_data(fibptr); if (le32_to_cpu(readreply->status) == ST_OK) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; else { printk(KERN_WARNING "read_callback: read failed, status = %d\n", readreply->status); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; set_sense((u8 *) &sense_data[cid], HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 0, 0); memcpy(scsicmd->sense_buffer, &sense_data[cid], sizeof(struct sense_data)); } fib_complete(fibptr); fib_free(fibptr); aac_io_done(scsicmd);}static void write_callback(void *context, struct fib * fibptr){ struct aac_dev *dev; struct aac_write_reply *writereply; struct scsi_cmnd *scsicmd; u32 lba; u32 cid; scsicmd = (struct scsi_cmnd *) context; dev = (struct aac_dev *)scsicmd->device->host->hostdata; cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); if (fibptr == NULL) BUG(); if(scsicmd->use_sg) pci_unmap_sg(dev->pdev, (struct scatterlist *)scsicmd->buffer, scsicmd->use_sg, scsicmd->sc_data_direction); else if(scsicmd->request_bufflen) pci_unmap_single(dev->pdev, (dma_addr_t)(ulong)scsicmd->SCp.ptr, scsicmd->request_bufflen, scsicmd->sc_data_direction); writereply = (struct aac_write_reply *) fib_data(fibptr); if (le32_to_cpu(writereply->status) == ST_OK) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; else { printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; set_sense((u8 *) &sense_data[cid], HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 0, 0); memcpy(scsicmd->sense_buffer, &sense_data[cid], sizeof(struct sense_data)); } fib_complete(fibptr); fib_free(fibptr); aac_io_done(scsicmd);}int aac_read(struct scsi_cmnd * scsicmd, int cid){ u32 lba; u32 count; int status; u16 fibsize; struct aac_dev *dev; struct fib * cmd_fibcontext; dev = (struct aac_dev *)scsicmd->device->host->hostdata; /* * Get block address and transfer length */ if (scsicmd->cmnd[0] == READ_6) /* 6 byte command */ { dprintk((KERN_DEBUG "aachba: received a read(6) command on id %d.\n", cid)); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; count = scsicmd->cmnd[4]; if (count == 0) count = 256; } else { dprintk((KERN_DEBUG "aachba: received a read(10) command on id %d.\n", cid)); lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; } dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); /* * Alocate and initialize a Fib */ if (!(cmd_fibcontext = fib_alloc(dev))) { return -1; } fib_init(cmd_fibcontext); if(dev->pae_support == 1){ struct aac_read64 *readcmd; readcmd = (struct aac_read64 *) fib_data(cmd_fibcontext); readcmd->command = cpu_to_le32(VM_CtHostRead64); readcmd->cid = cpu_to_le16(cid); readcmd->sector_count = cpu_to_le16(count); readcmd->block = cpu_to_le32(lba); readcmd->pad = cpu_to_le16(0); readcmd->flags = cpu_to_le16(0); aac_build_sg64(scsicmd, &readcmd->sg); if(readcmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT) BUG(); fibsize = sizeof(struct aac_read64) + ((readcmd->sg.count - 1) * sizeof (struct sgentry64)); /* * Now send the Fib to the adapter */ status = fib_send(ContainerCommand64, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) read_callback, (void *) scsicmd); } else { struct aac_read *readcmd; readcmd = (struct aac_read *) fib_data(cmd_fibcontext); readcmd->command = cpu_to_le32(VM_CtBlockRead); readcmd->cid = cpu_to_le32(cid); readcmd->block = cpu_to_le32(lba); readcmd->count = cpu_to_le32(count * 512); if (count * 512 > (64 * 1024)) BUG(); aac_build_sg(scsicmd, &readcmd->sg); if(readcmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT) BUG(); fibsize = sizeof(struct aac_read) + ((readcmd->sg.count - 1) * sizeof (struct sgentry)); /* * Now send the Fib to the adapter */ status = fib_send(ContainerCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) read_callback, (void *) scsicmd); } /* * Check that the command queued to the controller */ if (status == -EINPROGRESS) { dprintk("read queued.\n"); return 0; } printk(KERN_WARNING "aac_read: fib_send failed with status: %d.\n", status); /* * For some reason, the Fib didn't queue, return QUEUE_FULL */ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; aac_io_done(scsicmd); fib_complete(cmd_fibcontext); fib_free(cmd_fibcontext); return -1;}static int aac_write(struct scsi_cmnd * scsicmd, int cid){ u32 lba; u32 count; int status; u16 fibsize; struct aac_dev *dev; struct fib * cmd_fibcontext; dev = (struct aac_dev *)scsicmd->device->host->hostdata; /* * Get block address and transfer length */ if (scsicmd->cmnd[0] == WRITE_6) /* 6 byte command */ { lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; count = scsicmd->cmnd[4]; if (count == 0) count = 256; } else { dprintk((KERN_DEBUG "aachba: received a write(10) command on id %d.\n", cid)); lba = (scsicmd->cmnd[2] << 24) | (scsicmd->cmnd[3] << 16) | (scsicmd->cmnd[4] << 8) | scsicmd->cmnd[5]; count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; } dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %u, t = %ld.\n", smp_processor_id(), lba, jiffies)); /* * Allocate and initialize a Fib then setup a BlockWrite command */ if (!(cmd_fibcontext = fib_alloc(dev))) { scsicmd->result = DID_ERROR << 16; aac_io_done(scsicmd); return -1; } fib_init(cmd_fibcontext); if(dev->pae_support == 1){ struct aac_write64 *writecmd; writecmd = (struct aac_write64 *) fib_data(cmd_fibcontext); writecmd->command = cpu_to_le32(VM_CtHostWrite64); writecmd->cid = cpu_to_le16(cid); writecmd->sector_count = cpu_to_le16(count); writecmd->block = cpu_to_le32(lba); writecmd->pad = cpu_to_le16(0); writecmd->flags = cpu_to_le16(0); aac_build_sg64(scsicmd, &writecmd->sg); if(writecmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT) BUG(); fibsize = sizeof(struct aac_write64) + ((writecmd->sg.count - 1) * sizeof (struct sgentry64)); /* * Now send the Fib to the adapter */ status = fib_send(ContainerCommand64, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) write_callback, (void *) scsicmd); } else { struct aac_write *writecmd; writecmd = (struct aac_write *) fib_data(cmd_fibcontext); writecmd->command = cpu_to_le32(VM_CtBlockWrite); writecmd->cid = cpu_to_le32(cid); writecmd->block = cpu_to_le32(lba); writecmd->count = cpu_to_le32(count * 512); writecmd->sg.count = cpu_to_le32(1); /* ->stable is not used - it did mean which type of write */ if (count * 512 > (64 * 1024)) { BUG(); } aac_build_sg(scsicmd, &writecmd->sg); if(writecmd->sg.count > MAX_DRIVER_SG_SEGMENT_COUNT) BUG(); fibsize = sizeof(struct aac_write) + ((writecmd->sg.count - 1) * sizeof (struct sgentry)); /* * Now send the Fib to the adapter */ status = fib_send(ContainerCommand, cmd_fibcontext, fibsize, FsaNormal, 0, 1, (fib_callback) write_callback, (void *) scsicmd); } /* * Check that the command queued to the controller */ if (status == -EINPROGRESS) { dprintk("write queued.\n"); return 0; } printk(KERN_WARNING "aac_write: fib_send failed with status: %d\n", status); /* * For some reason, the Fib didn't queue, return QUEUE_FULL */ scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_TASK_SET_FULL; aac_io_done(scsicmd); fib_complete(cmd_fibcontext); fib_free(cmd_fibcontext); return -1;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?