Changeset 66cb7a2 in mainline
- Timestamp:
- 2013-06-27T07:27:53Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a8196c9
- Parents:
- ccf282f
- Files:
-
- 3 added
- 3 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
boot/arch/amd64/Makefile.inc
rccf282f r66cb7a2 31 31 $(USPACE_PATH)/srv/hw/irc/i8259/i8259 32 32 33 RD_SRVS_NON_ESSENTIAL += \34 $(USPACE_PATH)/srv/bd/ata_bd/ata_bd35 36 33 RD_DRVS += \ 37 34 infrastructure/rootpc \ 35 block/ata_bd \ 38 36 bus/pci/pciintel \ 39 37 bus/isa \ -
uspace/Makefile
rccf282f r66cb7a2 94 94 srv/taskmon \ 95 95 srv/vfs \ 96 srv/bd/ata_bd \97 96 srv/bd/sata_bd \ 98 97 srv/bd/file_bd \ … … 119 118 drv/infrastructure/rootvirt \ 120 119 drv/block/ahci \ 120 drv/block/ata_bd \ 121 121 drv/char/i8042 \ 122 122 drv/char/ps2mouse \ -
uspace/drv/block/ata_bd/Makefile
rccf282f r66cb7a2 1 1 # 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 2 # Copyright (c) 2013 Jiri Svoboda 4 3 # All rights reserved. 5 4 # … … 29 28 30 29 USPACE_PREFIX = ../../.. 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include 31 32 BINARY = ata_bd 32 33 33 34 SOURCES = \ 34 ata_bd.c 35 ata_bd.c \ 36 main.c 35 37 36 38 include $(USPACE_PREFIX)/Makefile.common -
uspace/drv/block/ata_bd/ata_bd.c
rccf282f r66cb7a2 67 67 #include "ata_hw.h" 68 68 #include "ata_bd.h" 69 #include "main.h" 69 70 70 71 #define NAME "ata_bd" … … 88 89 }; 89 90 90 /** Controller */ 91 static ata_ctrl_t ata_ctrl; 92 93 static void print_syntax(void); 94 static int ata_bd_init(ata_ctrl_t *ctrl); 95 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *); 91 static int ata_bd_init_io(ata_ctrl_t *ctrl); 92 static void ata_bd_fini_io(ata_ctrl_t *ctrl); 96 93 97 94 static int ata_bd_open(bd_srvs_t *, bd_srv_t *); … … 126 123 uint8_t *pstatus, unsigned timeout); 127 124 128 staticbd_ops_t ata_bd_ops = {125 bd_ops_t ata_bd_ops = { 129 126 .open = ata_bd_open, 130 127 .close = ata_bd_close, … … 146 143 } 147 144 148 int main(int argc, char **argv) 149 { 150 char name[16]; 145 /** Initialize ATA controller. */ 146 int ata_ctrl_init(ata_ctrl_t *ctrl) 147 { 151 148 int i, rc; 152 149 int n_disks; 153 150 unsigned ctl_num; 154 char *eptr; 155 ata_ctrl_t *ctrl = &ata_ctrl; 156 157 printf(NAME ": ATA disk driver\n"); 158 159 if (argc > 1) { 160 ctl_num = strtoul(argv[1], &eptr, 0); 161 if (*eptr != '\0' || ctl_num == 0 || ctl_num > 4) { 162 printf("Invalid argument.\n"); 163 print_syntax(); 164 return -1; 165 } 166 } else { 167 ctl_num = 1; 168 } 169 151 152 printf(NAME ": ata_ctrl_init()\n"); 153 154 ctl_num = 1; 155 156 fibril_mutex_initialize(&ctrl->lock); 170 157 ctrl->cmd_physical = legacy_base[ctl_num - 1].cmd; 171 158 ctrl->ctl_physical = legacy_base[ctl_num - 1].ctl; … … 174 161 (void *) ctrl->ctl_physical); 175 162 176 if (ata_bd_init(ctrl) != EOK) 177 return -1; 163 rc = ata_bd_init_io(ctrl); 164 if (rc != EOK) 165 return rc; 178 166 179 167 for (i = 0; i < MAX_DISKS; i++) { … … 196 184 if (ctrl->disk[i].present == false) 197 185 continue; 198 199 snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i); 200 rc = loc_service_register(name, &ctrl->disk[i].service_id); 186 187 rc = ata_fun_create(&ctrl->disk[i]); 201 188 if (rc != EOK) { 202 printf(NAME ": Unable to register device %s.\n", name); 189 printf(NAME ": Unable to create function for disk %d.\n", 190 i); 191 goto error; 192 } 193 ++n_disks; 194 } 195 196 if (n_disks == 0) { 197 printf("No disks detected.\n"); 198 rc = EIO; 199 goto error; 200 } 201 202 return EOK; 203 error: 204 for (i = 0; i < MAX_DISKS; i++) { 205 if (ata_fun_remove(&ctrl->disk[i]) != EOK) { 206 printf(NAME ": Unable to clean up function for disk %d.\n", 207 i); 208 } 209 } 210 ata_bd_fini_io(ctrl); 211 return rc; 212 } 213 214 /** Remove ATA controller. */ 215 int ata_ctrl_remove(ata_ctrl_t *ctrl) 216 { 217 int i, rc; 218 219 printf(NAME ": ata_ctrl_remove()\n"); 220 221 fibril_mutex_lock(&ctrl->lock); 222 223 for (i = 0; i < MAX_DISKS; i++) { 224 rc = ata_fun_remove(&ctrl->disk[i]); 225 if (rc != EOK) { 226 printf(NAME ": Unable to clean up function for disk %d.\n", 227 i); 203 228 return rc; 204 229 } 205 ++n_disks; 206 } 207 208 if (n_disks == 0) { 209 printf("No disks detected.\n"); 210 return -1; 211 } 212 213 printf("%s: Accepting connections\n", NAME); 214 task_retval(0); 215 async_manager(); 216 217 /* Not reached */ 218 return 0; 219 } 220 221 222 static void print_syntax(void) 223 { 224 printf("Syntax: " NAME " <controller_number>\n"); 225 printf("Controller number = 1..4\n"); 230 } 231 232 ata_bd_fini_io(ctrl); 233 fibril_mutex_unlock(&ctrl->lock); 234 235 return EOK; 236 } 237 238 /** Surprise removal of ATA controller. */ 239 int ata_ctrl_gone(ata_ctrl_t *ctrl) 240 { 241 int i, rc; 242 243 printf(NAME ": ata_ctrl_gone()\n"); 244 245 fibril_mutex_lock(&ctrl->lock); 246 247 for (i = 0; i < MAX_DISKS; i++) { 248 rc = ata_fun_unbind(&ctrl->disk[i]); 249 if (rc != EOK) { 250 printf(NAME ": Unable to clean up function for disk %d.\n", 251 i); 252 return rc; 253 } 254 } 255 256 ata_bd_fini_io(ctrl); 257 fibril_mutex_unlock(&ctrl->lock); 258 259 return EOK; 226 260 } 227 261 … … 260 294 } 261 295 262 /** Register driver and enable device I/O. */ 263 static int ata_bd_init(ata_ctrl_t *ctrl) 264 { 265 async_set_client_connection(ata_bd_connection); 266 int rc = loc_server_register(NAME); 267 if (rc != EOK) { 268 printf("%s: Unable to register driver.\n", NAME); 269 return rc; 270 } 271 296 /** Enable device I/O. */ 297 static int ata_bd_init_io(ata_ctrl_t *ctrl) 298 { 299 int rc; 272 300 void *vaddr; 301 273 302 rc = pio_enable((void *) ctrl->cmd_physical, sizeof(ata_cmd_t), &vaddr); 274 303 if (rc != EOK) { … … 276 305 return rc; 277 306 } 278 307 279 308 ctrl->cmd = vaddr; 280 309 281 310 rc = pio_enable((void *) ctrl->ctl_physical, sizeof(ata_ctl_t), &vaddr); 282 311 if (rc != EOK) { … … 284 313 return rc; 285 314 } 286 315 287 316 ctrl->ctl = vaddr; 288 289 return EOK; 290 } 291 292 /** Block device connection handler */ 293 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 294 { 295 service_id_t dsid; 296 int i; 297 disk_t *disk; 298 299 /* Get the device service ID. */ 300 dsid = IPC_GET_ARG1(*icall); 301 302 /* Determine which disk device is the client connecting to. */ 303 disk = NULL; 304 for (i = 0; i < MAX_DISKS; i++) 305 if (ata_ctrl.disk[i].service_id == dsid) 306 disk = &ata_ctrl.disk[i]; 307 308 if (disk == NULL || disk->present == false) { 309 async_answer_0(iid, EINVAL); 310 return; 311 } 312 313 bd_conn(iid, icall, &disk->bds); 317 318 return EOK; 319 } 320 321 /** Clean up device I/O. */ 322 static void ata_bd_fini_io(ata_ctrl_t *ctrl) 323 { 324 (void) ctrl; 325 /* XXX TODO */ 314 326 } 315 327 … … 334 346 d->disk_id = disk_id; 335 347 d->present = false; 336 fibril_mutex_initialize(&d->lock); 337 338 bd_srvs_init(&d->bds); 339 d->bds.ops = &ata_bd_ops; 340 d->bds.sarg = d; 348 d->afun = NULL; 341 349 342 350 /* Try identify command. */ … … 685 693 uint16_t val; 686 694 687 fibril_mutex_lock(& disk->lock);695 fibril_mutex_lock(&ctrl->lock); 688 696 689 697 /* New value for Drive/Head register */ … … 692 700 693 701 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) { 694 fibril_mutex_unlock(& disk->lock);702 fibril_mutex_unlock(&ctrl->lock); 695 703 return EIO; 696 704 } … … 699 707 700 708 if (wait_status(ctrl, 0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) { 701 fibril_mutex_unlock(& disk->lock);709 fibril_mutex_unlock(&ctrl->lock); 702 710 return EIO; 703 711 } … … 710 718 711 719 if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 712 fibril_mutex_unlock(& disk->lock);720 fibril_mutex_unlock(&ctrl->lock); 713 721 return EIO; 714 722 } … … 719 727 720 728 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 721 fibril_mutex_unlock(& disk->lock);729 fibril_mutex_unlock(&ctrl->lock); 722 730 return EIO; 723 731 } 724 732 725 733 if ((status & SR_DRQ) == 0) { 726 fibril_mutex_unlock(& disk->lock);734 fibril_mutex_unlock(&ctrl->lock); 727 735 return EIO; 728 736 } … … 735 743 if (data_size > obuf_size) { 736 744 /* Output buffer is too small to store data. */ 737 fibril_mutex_unlock(& disk->lock);745 fibril_mutex_unlock(&ctrl->lock); 738 746 return EIO; 739 747 } … … 745 753 } 746 754 747 if (status & SR_ERR) { 748 fibril_mutex_unlock(&disk->lock); 749 return EIO; 750 } 751 752 fibril_mutex_unlock(&disk->lock); 755 fibril_mutex_unlock(&ctrl->lock); 756 757 if (status & SR_ERR) 758 return EIO; 753 759 754 760 return EOK; … … 886 892 (bc.h & 0x0f); 887 893 888 fibril_mutex_lock(& disk->lock);894 fibril_mutex_lock(&ctrl->lock); 889 895 890 896 /* Program a Read Sectors operation. */ 891 897 892 898 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 893 fibril_mutex_unlock(& disk->lock);899 fibril_mutex_unlock(&ctrl->lock); 894 900 return EIO; 895 901 } … … 898 904 899 905 if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 900 fibril_mutex_unlock(& disk->lock);906 fibril_mutex_unlock(&ctrl->lock); 901 907 return EIO; 902 908 } … … 909 915 910 916 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 911 fibril_mutex_unlock(& disk->lock);917 fibril_mutex_unlock(&ctrl->lock); 912 918 return EIO; 913 919 } … … 922 928 } 923 929 930 fibril_mutex_unlock(&ctrl->lock); 931 924 932 if ((status & SR_ERR) != 0) 925 933 return EIO; 926 934 927 fibril_mutex_unlock(&disk->lock);928 935 return EOK; 929 936 } … … 960 967 (bc.h & 0x0f); 961 968 962 fibril_mutex_lock(& disk->lock);969 fibril_mutex_lock(&ctrl->lock); 963 970 964 971 /* Program a Write Sectors operation. */ 965 972 966 973 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 967 fibril_mutex_unlock(& disk->lock);974 fibril_mutex_unlock(&ctrl->lock); 968 975 return EIO; 969 976 } … … 972 979 973 980 if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 974 fibril_mutex_unlock(& disk->lock);981 fibril_mutex_unlock(&ctrl->lock); 975 982 return EIO; 976 983 } … … 983 990 984 991 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 985 fibril_mutex_unlock(& disk->lock);992 fibril_mutex_unlock(&ctrl->lock); 986 993 return EIO; 987 994 } … … 995 1002 } 996 1003 997 fibril_mutex_unlock(& disk->lock);1004 fibril_mutex_unlock(&ctrl->lock); 998 1005 999 1006 if (status & SR_ERR) -
uspace/drv/block/ata_bd/ata_bd.h
rccf282f r66cb7a2 36 36 #define __ATA_BD_H__ 37 37 38 #include <async.h> 38 39 #include <bd_srv.h> 40 #include <ddf/driver.h> 39 41 #include <sys/types.h> 40 42 #include <fibril_synch.h> 41 43 #include <str.h> 44 #include "ata_hw.h" 45 46 #define NAME "ata_bd" 42 47 43 48 /** Base addresses for ATA I/O blocks. */ … … 96 101 bool present; 97 102 struct ata_ctrl *ctrl; 103 struct ata_fun *afun; 98 104 99 105 /** Device type */ … … 117 123 char model[STR_BOUNDS(40) + 1]; 118 124 119 fibril_mutex_t lock;120 service_id_t service_id;121 125 int disk_id; 122 bd_srvs_t bds;123 126 } disk_t; 124 127 125 128 /** ATA controller */ 126 129 typedef struct ata_ctrl { 130 /** DDF device */ 131 ddf_dev_t *dev; 127 132 /** I/O base address of the command registers */ 128 133 uintptr_t cmd_physical; … … 137 142 /** Per-disk state. */ 138 143 disk_t disk[MAX_DISKS]; 144 145 fibril_mutex_t lock; 139 146 } ata_ctrl_t; 147 148 typedef struct ata_fun { 149 ddf_fun_t *fun; 150 disk_t *disk; 151 bd_srvs_t bds; 152 } ata_fun_t; 153 154 extern int ata_ctrl_init(ata_ctrl_t *); 155 extern int ata_ctrl_remove(ata_ctrl_t *); 156 extern int ata_ctrl_gone(ata_ctrl_t *); 157 158 extern bd_ops_t ata_bd_ops; 140 159 141 160 #endif -
uspace/drv/bus/isa/isa.dev
rccf282f r66cb7a2 31 31 match 100 isa/cmos-rtc 32 32 io_range 70 2 33 34 ata_bd: 35 match 100 isa/ata_bd
Note:
See TracChangeset
for help on using the changeset viewer.