📄 aachba.c
字号:
for ( ; *findit != ' '; findit++); /* walk till we find a space then incr by 1 */ findit++; if (tindex < (sizeof(container_types)/sizeof(char *))){ inqstrcpy (container_types[tindex], findit); } inqstrcpy ("V1.0", str->prl);}void set_sense(u8 *sense_buf, u8 sense_key, u8 sense_code, u8 a_sense_code, u8 incorrect_length, u8 bit_pointer, u16 field_pointer, u32 residue){ sense_buf[0] = 0xF0; /* Sense data valid, err code 70h (current error) */ sense_buf[1] = 0; /* Segment number, always zero */ if (incorrect_length) { sense_buf[2] = sense_key | 0x20; /* Set ILI bit | sense key */ sense_buf[3] = BYTE3(residue); sense_buf[4] = BYTE2(residue); sense_buf[5] = BYTE1(residue); sense_buf[6] = BYTE0(residue); } else sense_buf[2] = sense_key; /* Sense key */ if (sense_key == SENKEY_ILLEGAL) sense_buf[7] = 10; /* Additional sense length */ else sense_buf[7] = 6; /* Additional sense length */ sense_buf[12] = sense_code; /* Additional sense code */ sense_buf[13] = a_sense_code; /* Additional sense code qualifier */ if (sense_key == SENKEY_ILLEGAL) { sense_buf[15] = 0; if (sense_code == SENCODE_INVALID_PARAM_FIELD) sense_buf[15] = 0x80; /* Std sense key specific field */ /* Illegal parameter is in the parameter block */ if (sense_code == SENCODE_INVALID_CDB_FIELD) 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(Scsi_Cmnd * scsicmd){ unsigned long cpu_flags; spin_lock_irqsave(&io_request_lock, cpu_flags); scsicmd->scsi_done(scsicmd); spin_unlock_irqrestore(&io_request_lock, cpu_flags);}static void __aac_io_done(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->pae_support = 0; dev->nondasd_support = 0; if( BITS_PER_LONG >= 64 && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){ printk(KERN_INFO "%s%d: 64 Bit PAE enabled\n", dev->name, dev->id); dev->pae_support = 1; } /* TODO - dmb temporary until fw can set this bit */ dev->pae_support = (BITS_PER_LONG >= 64); if(dev->pae_support != 0) { printk(KERN_INFO "%s%d: 64 Bit PAE enabled\n", dev->name, dev->id); } if(dev->adapter_info.options & AAC_OPT_NONDASD){ dev->nondasd_support = 1; } return rcode;}static void read_callback(void *context, struct fib * fibptr){ struct aac_dev *dev; struct aac_read_reply *readreply; Scsi_Cmnd *scsicmd; u32 lba; u32 cid; scsicmd = (Scsi_Cmnd *) context; dev = (struct aac_dev *)scsicmd->host->hostdata; cid =TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; dprintk((KERN_DEBUG "read_callback[cpu %d]: lba = %d, 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, scsi_to_pci_dma_dir(scsicmd->sc_data_direction)); else if(scsicmd->request_bufflen) pci_unmap_single(dev->pdev, (dma_addr_t)(unsigned long)scsicmd->SCp.ptr, scsicmd->request_bufflen, scsi_to_pci_dma_dir(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 | GOOD; else { printk(KERN_WARNING "read_callback: read failed, status = %d\n", readreply->status); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION; set_sense((u8 *) &sense_data[cid], SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 0, 0); } 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; Scsi_Cmnd *scsicmd; u32 lba; u32 cid; scsicmd = (Scsi_Cmnd *) context; dev = (struct aac_dev *)scsicmd->host->hostdata; cid = TARGET_LUN_TO_CONTAINER(scsicmd->target, scsicmd->lun); lba = ((scsicmd->cmnd[1] & 0x1F) << 16) | (scsicmd->cmnd[2] << 8) | scsicmd->cmnd[3]; dprintk((KERN_DEBUG "write_callback[cpu %d]: lba = %d, 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, scsi_to_pci_dma_dir(scsicmd->sc_data_direction)); else if(scsicmd->request_bufflen) pci_unmap_single(dev->pdev, (dma_addr_t)(unsigned long)scsicmd->SCp.ptr, scsicmd->request_bufflen, scsi_to_pci_dma_dir(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 | GOOD; else { printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | CHECK_CONDITION; set_sense((u8 *) &sense_data[cid], SENKEY_HW_ERR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 0, 0); } fib_complete(fibptr); fib_free(fibptr); aac_io_done(scsicmd);}int aac_read(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->host->hostdata; /* * Get block address and transfer length */ if (scsicmd->cmnd[0] == SS_READ) /* 6 byte command */ { dprintk((KERN_DEBUG "aachba: received a read(6) command on target %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 target %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))) { scsicmd->result = DID_ERROR << 16; aac_io_done(scsicmd); 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) 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 | QUEUE_FULL; aac_io_done(scsicmd); fib_complete(cmd_fibcontext); fib_free(cmd_fibcontext); return -1;}static int aac_write(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->host->hostdata; /* * Get block address and transfer length */ if (scsicmd->cmnd[0] == SS_WRITE) /* 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 target %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 = %lu, 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -