* (at your option) any later version. *
* *
***************************************************************************/
* (at your option) any later version. *
* *
***************************************************************************/
+/***************************************************************************
+ * Sat Dec 20 2003 Go Taniguchi <go@turbolinux.co.jp>
+ - Support 2.6 kernel and DMA-mapping
+ - ioctl fix for raid tools
+ - use schedule_timeout in long long loop
+ **************************************************************************/
-// On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates
-// high pages. Keep the macro around because of the broken unmerged ia64 tree
+/* On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates
+ high pages. Keep the macro around because of the broken unmerged ia64 tree */
#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/smp_lock.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <asm/processor.h> /* for boot_cpu_data */
#include <asm/pgtable.h>
#include <asm/io.h> /* for virt_to_bus, etc. */
#include <asm/processor.h> /* for boot_cpu_data */
#include <asm/pgtable.h>
#include <asm/io.h> /* for virt_to_bus, etc. */
#endif
FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
#endif
FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
for (pHba = hba_chain; pHba; pHba = pHba->next) {
printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
if (adpt_i2o_lct_get(pHba) < 0){
for (pHba = hba_chain; pHba; pHba = pHba->next) {
printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
if (adpt_i2o_lct_get(pHba) < 0){
adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
// adpt_i2o_quiesce_hba(pHba);
adpt_i2o_delete_hba(pHba);
adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
// adpt_i2o_quiesce_hba(pHba);
adpt_i2o_delete_hba(pHba);
if (rcode != 0) {
sprintf(pHba->detail, "Adaptec I2O RAID");
printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
if (rcode != 0) {
sprintf(pHba->detail, "Adaptec I2O RAID");
printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
} else {
memset(pHba->detail, 0, sizeof(pHba->detail));
memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
} else {
memset(pHba->detail, 0, sizeof(pHba->detail));
memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
memcpy(&(pHba->detail[40]), " FW: ", 4);
memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
pHba->detail[48] = '\0'; /* precautionary */
memcpy(&(pHba->detail[40]), " FW: ", 4);
memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
pHba->detail[48] = '\0'; /* precautionary */
{
adpt_hba* pHba = NULL; /* host bus adapter structure */
struct adpt_device* dptdevice; /* dpt per device information */
{
adpt_hba* pHba = NULL; /* host bus adapter structure */
struct adpt_device* dptdevice; /* dpt per device information */
// This is the same for BLK and SCSI devices
// NOTE this is wrong in the i2o.h definitions
// This is not currently supported by our adapter but we issue it anyway
// This is the same for BLK and SCSI devices
// NOTE this is wrong in the i2o.h definitions
// This is not currently supported by our adapter but we issue it anyway
base_addr0_phys = pci_resource_start(pDev,0);
hba_map0_area_size = pci_resource_len(pDev,0);
base_addr0_phys = pci_resource_start(pDev,0);
hba_map0_area_size = pci_resource_len(pDev,0);
timeout *= HZ;
if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
set_current_state(TASK_INTERRUPTIBLE);
timeout *= HZ;
if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
set_current_state(TASK_INTERRUPTIBLE);
}
spin_lock_irq(&adpt_wq_i2o_post.lock);
__remove_wait_queue(&adpt_wq_i2o_post, &wait);
}
spin_lock_irq(&adpt_wq_i2o_post.lock);
__remove_wait_queue(&adpt_wq_i2o_post, &wait);
} while (m == EMPTY_QUEUE);
status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
} while (m == EMPTY_QUEUE);
status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
- u32* user_msg = (u32*)arg;
- u32* user_reply = NULL;
- ulong sg_list[pHba->sg_tablesize];
+ u32 __user *user_msg = arg;
+ u32 __user * user_reply = NULL;
+ void *sg_list[pHba->sg_tablesize];
printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
pHba->name,sg_size,i,sg_count);
rcode = -ENOMEM;
printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
pHba->name,sg_size,i,sg_count);
rcode = -ENOMEM;
/* Copy in the user's SG buffer if necessary */
if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
// TODO 64bit fix
/* Copy in the user's SG buffer if necessary */
if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
// TODO 64bit fix
// This state stops any new commands from enterring the
// controller while processing the ioctl
// pHba->state |= DPTI_STATE_IOCTL;
// We can't set this now - The scsi subsystem sets host_blocked and
// the queue empties and stops. We need a way to restart the queue
rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
// This state stops any new commands from enterring the
// controller while processing the ioctl
// pHba->state |= DPTI_STATE_IOCTL;
// We can't set this now - The scsi subsystem sets host_blocked and
// the queue empties and stops. We need a way to restart the queue
rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
- if (copy_to_user((void*)sg[j].addr_bus,(void*)sg_list[j], sg_size)) {
- printk(KERN_WARNING"%s: Could not copy %lx TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
+ if (copy_to_user((void __user *)sg[j].addr_bus,sg_list[j], sg_size)) {
+ printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
HbaInfo.pciDeviceNum=PCI_SLOT(pHba->pDev->devfn);
HbaInfo.Interrupt = pHba->pDev->irq;
HbaInfo.hbaFlags = FLG_OSD_PCI_VALID | FLG_OSD_DMA | FLG_OSD_I2O;
HbaInfo.pciDeviceNum=PCI_SLOT(pHba->pDev->devfn);
HbaInfo.Interrupt = pHba->pDev->irq;
HbaInfo.hbaFlags = FLG_OSD_PCI_VALID | FLG_OSD_DMA | FLG_OSD_I2O;
if(cmd != NULL) {
printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
}
}
adpt_i2o_post_wait_complete(context, status);
} else { // SCSI message
if(cmd != NULL) {
printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
}
}
adpt_i2o_post_wait_complete(context, status);
} else { // SCSI message
if(cmd != NULL){
if(cmd->serial_number != 0) { // If not timedout
adpt_i2o_to_scsi(reply, cmd);
if(cmd != NULL){
if(cmd->serial_number != 0) { // If not timedout
adpt_i2o_to_scsi(reply, cmd);
/* Now fill in the SGList and command */
if(cmd->use_sg) {
struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
/* Now fill in the SGList and command */
if(cmd->use_sg) {
struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
- for(i = 0 ; i < cmd->use_sg; i++) {
- *mptr++ = direction|0x10000000|sg->length;
- len+=sg->length;
- *mptr++ = virt_to_bus(sg->address);
+ for(i = 0 ; i < sg_count; i++) {
+ *mptr++ = direction|0x10000000|sg_dma_len(sg);
+ len+=sg_dma_len(sg);
+ *mptr++ = sg_dma_address(sg);
}
msg = (u32*)(pHba->msg_addr_virt + m);
writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
}
msg = (u32*)(pHba->msg_addr_virt + m);
writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
rmb();
if(time_after(jiffies,timeout)){
printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
rmb();
if(time_after(jiffies,timeout)){
printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
int group, int field, void *buf, int buflen)
{
u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
int group, int field, void *buf, int buflen)
{
u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
if (field == -1) /* whole group */
opblk[4] = -1;
size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid,
if (field == -1) /* whole group */
opblk[4] = -1;
size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid,
- opblk, sizeof(opblk), resblk, sizeof(resblk));
+ opblk, sizeof(opblk), resblk, sizeof(u8)*(8+buflen));
+ if (size == -ETIME) {
+ printk(KERN_WARNING "%s: issue params failed; Timed out.\n", pHba->name);
+ return -ETIME;
+ } else if (size == -EINTR) {
+ printk(KERN_WARNING "%s: issue params failed; Interrupted.\n", pHba->name);
+ return -EINTR;
+ }
msg[8] = virt_to_bus(resblk);
if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
msg[8] = virt_to_bus(resblk);
if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {